java的GUI就是java的图形用户界面,我看网上很多人都说java其实不太适合做GUI,因为太麻烦,也不太美观,要想美观一点就非常麻烦,但是对于为了完成实验的大二学生是足够用了。
我接触java的GUI是为了给软件构造的实验应用做一个图形界面,因为我觉得这个应用用命令行实现实在是太难看了,所以决定用Java的GUI。本文章适合急需使用java GUI的童鞋。
我实验里的应用是一个航班管理系统,需要实现设置资源,设置位置,设立航班,分配飞机等等功能,所以我们的应用主体是一个菜单,在上面设置各种功能按钮来进行管理操作,先看成果:由于我要同时实现三个App,所以我先创建了一个App抽象类,创建按钮。
//App抽象类
public abstract class App <R>{
protected JButton AddResource = new JButton("添加资源");
protected JButton DeleteResource = new JButton("删除资源");
protected JButton Addlocation = new JButton("添加位置");
protected JButton Deletelocation = new JButton("删除位置");
protected JButton addEntry = new JButton("添加计划项");
protected JButton cancelEntry = new JButton("取消计划项");
protected JButton setResource = new JButton("设置资源");
protected JButton runEntry = new JButton("启动计划项");
protected JButton changeLocation = new JButton("更改教室位置");
protected JButton endEntry = new JButton("结束计划项");
protected JButton findState = new JButton("查看当前状态");
protected JButton findConflict = new JButton("检查冲突");
protected JButton findPre = new JButton("查找前序计划项");
protected JButton board = new JButton("显示时间表");
protected JButton blockEntry = new JButton("阻塞计划项");
protected JButton fileEntry = new JButton("读入计划项");
protected JButton searchLog = new JButton("日志查询");
//设置按钮监听,点击一个按钮执行相应的功能
public App () {
AddResource.addActionListener((e)->{
Addresource();
});
DeleteResource.addActionListener((e)->{
DeleteResource();
});
Addlocation.addActionListener((e)->{
AddLocation();
});
Deletelocation.addActionListener((e)->{
deleteLocation();
});
addEntry.addActionListener((e)->{
addEntry();
});
cancelEntry.addActionListener((e)->{
cancelEntry();
});
setResource.addActionListener((e)->{
setResource();
});
runEntry.addActionListener((e)->{
runEntry();
});
changeLocation.addActionListener((e)->{
changeLocation();
});
endEntry.addActionListener((e)->{
endEntry();
});
findState.addActionListener((e)->{
findState();
});
findConflict.addActionListener((e)->{
findConflict();
});
findPre.addActionListener((e)->{
findPre();
});
board.addActionListener((e)->{
showBoard();
});
blockEntry.addActionListener((e)->{
blockEntry();
});
fileEntry.addActionListener((e)->{
construct();
});
searchLog.addActionListener((e)->{
searchLog();
});
}
}
//航班管理系统继承App抽象类
public class FlightScheduleApp extends App<Plane> {
public FlightScheduleApp(){
schedule = new FlightSchedule();
}
@Override
public void init() {
//创建窗口
JFrame jf = new JFrame("航班管理系统");
//设置中间容器
JPanel panel1 = new JPanel();
//添加按钮
panel1.add(AddResource);
panel1.add(DeleteResource);
panel1.add(Addlocation);
panel1.add(Deletelocation);
panel1.add(addEntry);
panel1.add(cancelEntry);
panel1.add(setResource);
panel1.add(runEntry);
panel1.add(endEntry);
panel1.add(findState);
panel1.add(findConflict);
panel1.add(findPre);
panel1.add(board);
panel1.add(fileEntry);
panel1.add(searchLog);
//设置为2行2列的网格布局,由于我的组件过多,自动增加网格列数,行数不变
GridLayout gf = new GridLayout(2, 2);
panel1.setLayout(gf);
//添加中间容器
jf.add(panel1);
//设置窗口大小
jf.setSize(1000, 500);
jf.setLocation(200, 200);
//设置关闭方式,由于该窗口为应用主菜单,设置为点击关闭即为所有窗口全部关闭,程序运行结束
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//可视化
jf.setVisible(true);
}
主菜单就设置好了,然后我挑一个按钮展示一下。第一个功能添加资源,点击该按钮,弹出一个新的窗口,供用户设立一个新的飞机,用户填写飞机编号,机龄,座位数等,注意此时主菜单没有关闭。
这个窗口的构建,需要标签,输入框,按钮三个组件,分别用Jlabel,JTextField,JButton来实现。
@Override
public void Addresource() {
java.awt.Dimension dim2 = new java.awt.Dimension(50, 50);// 标签的大小
java.awt.Dimension dim3 = new java.awt.Dimension(250, 30);// 输入框的大小
java.awt.Dimension dim4 = new java.awt.Dimension(100, 40);
JFrame jf = new JFrame("添加资源");
JPanel jPanel = new JPanel();
JLabel namelabel = new JLabel("编号:");
namelabel.setPreferredSize(dim2);//设置大小
jPanel.add(namelabel);
JTextField nametext = new JTextField();
nametext.setPreferredSize(dim3);
jPanel.add(nametext);
JLabel sexlabel = new JLabel("类型:");
sexlabel.setPreferredSize(dim2);
jPanel.add(sexlabel);
JTextField sextext = new JTextField();
sextext.setPreferredSize(dim3);
jPanel.add(sextext);
JLabel idlabel = new JLabel("座位数:");
idlabel.setPreferredSize(dim2);
jPanel.add(idlabel);
JTextField idtext = new JTextField();
idtext.setPreferredSize(dim3);
jPanel.add(idtext);
JLabel worklabel = new JLabel("机龄:");
worklabel.setPreferredSize(dim2);
jPanel.add(worklabel);
JTextField worktext = new JTextField();
worktext.setPreferredSize(dim3);
jPanel.add(worktext);
JButton button = new JButton("确定");
button.setPreferredSize(dim4);
//设立监听
button.addActionListener((e) -> {
String a = nametext.getText();
String b = sextext.getText();
String c = idtext.getText();
String d = worktext.getText();
if (!a.isEmpty() && !b.isEmpty() && !c.isEmpty() && !d.isEmpty()) {
try {
schedule.addResource(a, b, c, d);
input("操作成功!");
} catch (Exception e2) {
input(e2.getMessage());
}
} else {
input("操作失败!");
}
});
jPanel.add(button);
// 选择布局类型,定义流式布局的对象,并且设置每个组件之间相隔5cm
java.awt.FlowLayout fl = new java.awt.FlowLayout(FlowLayout.CENTER, 5, 5);
jPanel.setLayout(fl);// 设置顶级容器的布局为流式布局
jf.add(jPanel);
jf.setSize(350, 400);
jf.setLocation(200, 200);
jf.setResizable(false);
//设置关闭方式为只关闭当前窗口
jf.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
jf.setVisible(true);
}
/**
* 输出警告
*/
public void input(String data) {
JFrame jf = new JFrame();
JLabel label = new JLabel(data);
jf.add(label, BorderLayout.CENTER);
jf.setSize(410, 150);
jf.setLocation(200, 200);
jf.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
jf.setVisible(true);
}
我采用input函数输出相应信息,一个窗口加一个标签就可以完成,如下图:
除了主菜单关闭为全部关闭外,其他窗口关闭都设置为仅关闭当前窗体,这样一个应用模型就完成了,相关功能的函数就不涉及GUI了,将所有功能全都整合到一个schedule类里,实现了应用与操作的分离。