GUI 图形用户接口

(Graphical User Interface)

已不在使用的基础类库AWT(Abstract Window Toolkit),抽象窗口工具包。
缺点,可移植性兼容性差,是个重量级组件,使用麻烦,并且图形界面不够美观功能有限。
Swing在AWT的基础上进行了补充和改进,进行了AWT增强。来满足GUI设计需求。

Swing概述
继承自Container类,然后根据GUI开发的功能扩展了2个分支如下:
容器分支(包括Window窗口和Panel面板):实现图形用户界面窗口容器
组件分支:实现向容器中填充数据、元素以及人机交互组件等

通俗的理解就是容器是用来装东西的,组件则是要装的东西。

Swing组件类中常用的顶级容器有如下三个:
JApplet
JFrame
JDialog

JFrame实现样例

JFrame是一个独立存在的顶级容器,也就是窗口,不能放置在其他容器之中
JFrame支持通用窗口所有基本功能,如最大最小化等
样例代码:具体代码解释见代码注释

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import javax.swing.*;

public class javagui {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {//保证线程安全,和窗口刷新,不清楚的可以暂时不用管这一部分,直接调用method()方法即可
@Override
public void run() {
method();
}
});
}

private static void method() {
JFrame jf = new JFrame("First window");
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置关闭窗口时,一同结束掉java控制台程序
jf.setSize(400,300);//设置窗体的大小,像素为单位
jf.setVisible(true);//设置窗体的可见性
}
}

效果图:

JDialog实现样例:

JDialog也是一个顶级容器,通常用来表示对话框窗口,例如提示你是否保存文档的小窗口
JDialog对话框可分为两种:
模态对话框:必须先处理完当前窗口才能处理其他窗口
非模态对话框:当前窗口未处理完也可以处理其他窗口
默认情况下未非模态的对话框。

常用构造方法:
JDialog(Frame owner) 构造方法,用来创建一个非模态的对话框,owner为对话框所有者(顶级窗口JFrame)
JDialog(Frame owner, String title) 构造方法,创建一个具有指定标题的非模态对话框
JDialog(Frame owner, boolean modal) 创建一个有指定模式的无标题对话框,默认值false(即非模态对话框)

样例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import javax.swing.*;

public class javagui {
public static void main(String[] args) {
//线程
SwingUtilities.invokeLater(() -> method());
}

private static void method() {
//创建主窗体
JFrame jf = new JFrame("JDialog");
jf.setSize(400,400);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setVisible(true);

//创建JDialog
JDialog dialog = new JDialog(jf,"abc",true);//title为设置dialog的窗口标题,modal为true则是设置模式为模态对话框,反之为非模态,默认也为非模态
//dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);//当点击关闭的时候默认不进行任何操作
dialog.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);//当点击关闭时关闭当前对话框
dialog.setSize(100,200);//设置JDialog大小
dialog.setVisible(true);//设置JDialog的可见性,不设置的话是看不到的
}

}

效果截图:

布局管理器

布局管理器决定组件在容器中的位置,Swing组件不能单独存在,必须放置于容器当中

BorderLayout:边界布局管理器
BoxLayout:箱式布局管理器
CardLayout:卡片布局管理器
FlowLayout:流式布局管理器
GridBagLayout:网格包布局管理器
GridLayout:网格布局管理器
GroupLayout:分组布局管理器
SpringLayout:弹性布局管理器

BorderLayout边界布局管理器

放置的五个区域:
页头:PAGE_START
页尾:PAGE_END
行首:LINE_START
行尾:LINE_END
中部:CENTER
额外的常量(不建议用,老版本用的)
NORTH、SOUTH、EAST、WEST、CENTER
位置同对应单词意思

添加组件的方法
add(Component comp, Object constraints)
comp表示要添加的组件
constraints表示添加的位置,5个常量见上方

BorderLayout的特性:
1、用户改变容器窗口大小时,组件相对位置不变
2、添加组件时如果不指定位置,默认为CENTER区域
3、一个区域只能放置一个组件,若添加多个,后放入的会覆盖掉先放入的组件

样例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import javax.swing.*;
import java.awt.*;

public class javagui {
public static void main(String[] args) {
//线程
SwingUtilities.invokeLater(() -> method());
}

private static void method() {
//创建主窗体
JFrame jf = new JFrame("布局管理器");
jf.setLayout(new BorderLayout());//指定布局

jf.setSize(400,300);
jf.setLocation(400,200);//刚打开的主窗口在电脑桌面的位置,电脑屏幕左上角为(0,0)坐标位置
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

JButton btn_1 = new JButton("PAGE_START页头位置");
JButton btn_2 = new JButton("PAGE_END页尾位置");
JButton btn_3 = new JButton("LINE_START行首位置");
JButton btn_4 = new JButton("LINE_END行尾位置");
JButton btn_5 = new JButton("CENTER中部位置");

jf.add(btn_1,BorderLayout.PAGE_START);//btn_1添加到页头
jf.add(btn_2,BorderLayout.PAGE_END);//btn_2添加到页尾
jf.add(btn_3,BorderLayout.LINE_START);//btn_3添加到行首
jf.add(btn_4,BorderLayout.LINE_END);//btn_4添加到行尾
jf.add(btn_5,BorderLayout.CENTER);//btn_5添加到中部

jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setVisible(true);
}
}

效果截图:

FlowLayout流式布局管理器

容器会将组件按照添加的顺序从左向右放置,当达到容器的边界时,会自动换行
组件可以按左对齐,居中对齐(默认),右对齐的方式排列

样例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import javax.swing.*;
import java.awt.*;

public class javagui {
public static void main(String[] args) {
//线程
SwingUtilities.invokeLater(() -> method());
}

private static void method() {
//创建主窗体
JFrame jf = new JFrame("FlowLayout");
jf.setBounds(100,300,400,200);//可以用这一个方法设定窗口的位置和大小,前两个参数为位置坐标x,y后两个参数为宽和高
//jf.setLayout(new FlowLayout());//指定布局为FlowLayout流式布局,默认CTENTER
jf.setLayout(new FlowLayout(FlowLayout.LEFT,20,30));//第一个参数为布局的对其方式(默认CENTER),后两个参数分别为水平和垂直间距

jf.add(new JButton("第1个按钮"));
jf.add(new JButton("第2个按钮"));
jf.add(new JButton("第3个按钮"));
jf.add(new JButton("第4个按钮"));
jf.add(new JButton("第5个按钮"));

jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setVisible(true);
}

}

效果截图:

GridLayout网格布局管理器

使用纵横线将容器分成n行m列大小相等的网格,每个网格可以添加一个组件。
添加到容器中的组件会从左向右、从上向下一次填充到网格中。与FlowLayout不同的是放置在 GridLayout布局管理器中的组件将自动占据网格的整个区域。

构造方法;
GridLayout():默认只有一行,每个组件占一行
GirdLayout(int rows, int cols):指定容器的行数和列数,rows代表行数,cols代表列数
GridLayout(int rows, int cols, int hgap, int vgap):指定容器的行数和列数以及组件之间的水平(hgap)、垂直(vgap)距离

特性:
1、组件自身大小会随着窗体大小进行改变,占满整个。
2、组件的相对位置不随区域的缩放而改变。
3、总是忽略组件的最佳大小,所有组件的宽高都相同。

样例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import javax.swing.*;
import java.awt.*;

public class javagui {
public static void main(String[] args) {
//线程
SwingUtilities.invokeLater(() -> method());
}

private static void method() {
//创建主窗体
JFrame jf = new JFrame("GridLayout");
jf.setBounds(100,300,400,200);//可以用这一个方法设定窗口的位置和大小,前两个参数为位置坐标x,y后两个参数为宽和高
jf.setLayout(new GridLayout(3,3));

for (int i=1;i<=9;i++){
JButton btn = new JButton("btn_"+i);
jf.add(btn);
}

jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setVisible(true);
}

}

效果截图:

事件处理

上面的一些工作都是集中在布局方面,但是光有布局没有用呀,上面我们制作的按钮都没有任何的效果,虽然可以点击,但是什么反应都没有,那么我们就需要给按钮添加事件处理。

Swing组件中的事件处理专门用于响应用户的操作,可以响应用户的点击鼠标,或者是按下键盘等操作。

三类对象:
事件源(Event Source):事件的发生场所,也就是产生事件的组件,如窗口、按钮、菜单等。
事件对象(Event):封装了GUI组件上发生的特定事件,通常是用户的一次操作。
监听器(Listener):负责监听事件源上发生的事件,并对各种事件做出相应处理的对象(对象中包含事件处理器)。

具体处理过程:
1、监听器注册到事件源。通俗理解就是盯着这个按钮看看是否有人点击。
2、触发事件源上的事件,点击操作等。通俗理解就是一个人去用鼠标进行了点击等操作。
3、产生并传递事件对象。通俗理解就是我知道有人点击按钮了,我得赶快汇报给监听器。
4、接受事件对象,激活事件处理器,实现功能。通俗理解就是,我收到了返回的消息(指有人按按钮的消息),然后我开始让处理器处理这个消息,比如说这个按钮是2个数相加的功能,那么处理器就开始让两个数相加,并返回计算结果。

样例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class javagui {
public static void main(String[] args) {
//线程
SwingUtilities.invokeLater(() -> method());
}

private static void method() {
//创建主窗体
JFrame jf = new JFrame("GridLayout");
jf.setBounds(100,300,200,200);//可以用这一个方法设定窗口的位置和大小,前两个参数为位置坐标x,y后两个参数为宽和高

//创建按钮组件
JButton btn = new JButton("按钮");//此处的按钮就是事件源
//为事件源注册监听器
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {//方法重写
System.out.println("进行了按钮点击");//控制台输出信息
}
});
//将组件嵌入窗体
jf.add(btn);

jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setVisible(true);
}

}

效果截图:

我们每点击一次按钮就会在控制台输出一次信息。

到此基本的处理就介绍完了,后期的GUI处理还会用到JavaFX图形用户界面工具,这个以后再介绍。