欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

第一章:用户界面(GUI)详解

最编程 2024-02-18 20:10:20
...

11.1 Swing概述

Swing是Java语言开发图形化界面的一个工具包。它以抽象窗口工具包(AWT)为基础,使跨平台应用程序可以使用可插拔的外观风格。Swing拥有丰富的库和组件,使用非常灵活,开发人员只用很少的代码就可以创建出优雅的用户界面。

在Java中,所有的Swing组件都保存在javax.swing包中,为了有效的使用Swing组件,必须了解Swing包的层次结构和继承关系。下面通过一张图描述Swing组件的继承关系。

从上图可以看出,Swing组件的所有类都继承自Container类,然后根据 GUI开发的功能扩展了两个主要分支,分别是容器分支(包括Window窗口和Panel面板)和组件分支。其中,容器分支是为了实现图形化用户界面窗口的容器而设计的,而组件分支则是为了实现向容器中填充数据、元素以及交互组件等功能。

Jcomponent类几乎是所有Swing组件的公共超类,Jcomponent类的所有子类都继承了它的全部公有方法,Jcomponent的常用子类如下图。

在容器分支中,Swing组件类中有三个组件是继承的AWT的Window类,而不是继承自JComponent类,这三个组件是Swing中的*容器类,它们分别是JWindow、JFrame、和JDialog。

11.2 常用窗口

11.2.1 JFrame

在Swing组件中,最常见的一个容器就是JFrame,它是一个独立存在的*容器(也叫窗口),不能放置在其他容器之中。JFrame支持通用窗口所有的基本功能,例如,窗口最小化、设定窗口大小等。

JFrame类的常用操作方法如下表。

方法 类型 功能描述
public JFrame() throws HeadlessException 构造方法 创建一个普通窗体对象
public JFrame(String title) throws HeadlessException 构造方法 创建一个窗体对象,并指定标题
public void setSize(int width,int height) 普通方法 设置窗体大小
public void setSize(Dimention d) 普通方法 通过Dimention设置窗体大小
public void Background(Color c) 普通方法 设置窗体的背景颜色
方法 类型 功能描述
public void setLocation(int x,int y) 普通方法 设置组件的显示位置
public void setLocation(Point p) 普通方法 通过Point设置组件的显示位置
public void setVisiable(boolean b) 普通方法 显示或隐藏组件
public Component add(Component comp) 普通方法 向容器中增加组件
Public setLayout(Component comp) 普通方法 设置布局管理器,如果设置为null表示不使用
public void pack() 普通方法 调整窗口大小,以适合其子组件的首选大小和布局
public Comntainer getContentPane() 普通方法 返回此窗体的容器对象

接下来通过一个案例演示一下JFrame的使用效果。

1 import java.awt.FlowLayout;
2 import javax.swing.*;
3 class Example01 extends JFrame {
4   private static void createAndShowGUI() {
5       //创建并设置JFrame容器窗口
6       JFrame frame = new JFrame("JFrameTest");
7       //设置关闭窗口时的默认操作
8       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
9        //设置窗口标题
10        frame.setTitle("JFrameTest");
11 //设置窗口尺寸 
12       frame.setSize(350, 300);
13        //设置窗口的显示位置
14        frame.setLocation(300,200);
15        //让组件显示
16       frame.setVisible(true);
17    }
18   public static void main(String[] args) {
19       //使用SwingUtilities工具调用createAndShowGUI()方法显示GUI程序
20        SwingUtilities.invokeLater(Example01::createAndShowGUI);
21    }
22 }       

上述代码中,第6行代码通过JFrame类创建了一个窗体对象frame,并在创建窗体对象的同时定义了窗体对象的标题为“JFrameTest”;第8行代码通过调用JFrame类的setDefaultCloseOperation()方法设置了窗体对象关闭时的默认操作;第10行代码通过调用JFrame类的setTitle()方法设置了窗口标题;第12行代码通过调用JFrame类的setSize()方法设置了窗口尺寸;

第14行代码通过调用JFrame类的setLocation()方法设置了窗口的显示位置;第16行代码通过调用JFrame类的setVisible()方法设置让组件显示;最后在main()方法中,调用javax.swing包中的SwingUtilities(封装有一系列操作Swing的方法集合工具类)工具类的invokeLater()方法执行了GUI程序。需要注意的是,invokeLater()方法需要传入一个接口作为参数。

11.2.2 JDialog

JDialog是Swing的另外一个*容器,它和Dialog一样都表示对话框窗口。JDialog对话框可分为两种,分别是模态对话框和非模态对话框。所谓模态对话框是指用户需要处理完当前对话框后才能继续与其他窗口交互的对话框,而非模态对话框是允许用户在处理对话框的同时与其他窗口交互的对话框。

对话框是模态或者非模态,可以在创建JDialog对象时为构造方法传入参数进行设置,也可以在创建JDialog对象后调用它的setModal()方法进行设置。JDialog常见的构造方法如下表。

方法声明 功能描述
JDialog(Frame owner) 用于创建一个非模态的对话框。参数owner为对话框所有者(*窗口JFrame)。
JDialog(Frame owner,String title) 创建一个具有指定标题的非模态对话框。
JDialog(Frame owner,boolean modal) 创建一个有指定模式的无标题对话框。

上表列举了JDialog三个常用的构造方法,这三个构造方法都需要接收一个Frame类型的对象,表示对话框所有者。如果该对话框没有所有者,参数owner可以传入null。第3个构造方法中,参数modal用来指定JDialog窗口是模态还是非模态,如果modal值设置为true,对话框就是模态对话框,反之则是非模态对话框,如果不设置modal的值,默认为false,也就是非模态对话框。

接下来通过一个案例学习JDialog对话框的创建。

1 import java.awt.*;
2 import java.awt.event.*;
3 import javax.swing.*;
4 public class Example02 {
5	public static void main(String[] args) {
6         // 建立两个按钮
7		JButton btn1 = new JButton("模态对话框"); 
8		JButton btn2 = new JButton("非模态对话框");
9		JFrame f = new JFrame("DialogDemo");
10		f.setSize(300, 250);
11		f.setLocation(300, 200);
12		f.setLayout(new FlowLayout());   // 为内容面板设置布局管理器
13		// 在Container对象上添加按钮
14		f.add(btn1);
15		f.add(btn2);
16		// 设置单击关闭按钮默认关闭窗口
17		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
18		f.setVisible(true);
19		final JLabel label = new JLabel();
20         // 定义一个JDialog对话框
21		final JDialog dialog = new JDialog(f, "Dialog"); 		
22         dialog.setSize(220, 150);                             // 设置对话框大小
23		dialog.setLocation(350, 250);                        // 设置对话框位置
24		dialog.setLayout(new FlowLayout());                 // 设置布局管理器
25		final JButton btn3 = new JButton("确定");          // 创建按钮对象
26		dialog.add(btn3); // 在对话框的内容面板添加按钮
27		// 为"模态对话框"按钮添加单击事件
28		btn1.addActionListener(new ActionListener() {
29			public void actionPerformed(ActionEvent e) {
30				// 设置对话框为模态
31				dialog.setModal(true);
32				// 如果JDialog窗口中没有添加了JLabel标签,就把JLabel标签加上
33				if (dialog.getComponents().length == 1) {
34					dialog.add(label);
35				}
36				// 否则修改标签的内容
37				label.setText("模式对话框,点击确定按钮关闭");
38				// 显示对话框
39				dialog.setVisible(true);
40			}
41		});
42	// 为"非模态对话框"按钮添加单击事件
43	btn2.addActionListener(new ActionListener() {
44		public void actionPerformed(ActionEvent e) {
45			// 设置对话框为非模态
46			dialog.setModal(false);
47			// 如果JDialog窗口中没有添加了JLabel标签,就把JLabel标签加上
48			if (dialog.getComponents().length == 1) {
49				dialog.add(label);
50			}
51			// 否则修改标签的内容
52			label.setText("非模式对话框,点击确定按钮关闭");
53			// 显示对话框
54			dialog.setVisible(true);
55		}
56	});
57		// 为对话框中的按钮添加单击事件
58		btn3.addActionListener(new ActionListener() {
59			public void actionPerformed(ActionEvent e) {
60				dialog.dispose();
61			}
62		});
63	}
64 }

在模态对话框中,用户只能操作当前对话框,其他对话框都会处于一种“冰封”的状态,不能进行任何操作,直到用户单击对话框中的“确定”按钮,把该对话框关闭后,才能继续其他操作。

在模态对话框中单击【确定】按钮关闭模态对话框,然后在运行结果图中单击【非模态对话框】按钮,弹出非模态对话框,如右图。

11.3 布局管理器

组件在容器中的位置和尺寸是由布局管理器决定的,每当需要重新调整屏幕大小时,都要用到布局管理器。Swing常用的布局管理器有4种,分别是FlowLayout(流式布局管理器)、BorderLayout(边界布局管理器)、GridLayout(网格布局管理器)、GridBagLayout(网格包布局管理器)。Swing容器在创建时都会使用一种默认的布局管理器,在程序中可以通过调用容器对象的setLayout()方法设置布局管理器,通过布局管理器自动进行组件的布局管理。

11.3.1 FlowLayout

FlowLayout属于流式布局管理器,是最简单的布局管理器。在这种布局下,容器会将组件按照添加顺序从左向右放置。当到达容器的边界时,自动将组件放到下一行的开始位置。这些组件可以左对齐、居中对齐(默认方式)或右对齐的方式排列。

FlowLayout类的常用方法及变量如下表。

方法及常量 类型 功能描述
public FlowLayout() 构造方法 组件默认居中对齐,水平、垂直间距默认为5个单位
public FlowLayout(int align) 构造方法 指定组件相对于容器的对齐方式,水平、垂直间距默认为5个单位
public FlowLayout(int align,int hgap,int vgap) 构造方法 指定组件的对齐方式和水平、垂直间距
public static final int CENTER 常量 居中对齐
public static final int LEADING 常量 与容器的开始端对齐方式一样
public static final int LEFT 常量 左对齐
public static final int RIGHT 常量 右对齐

上表列出了FlowLayout的三个构造方法及四个常量。构造方法中的参数align决定组件在每行中相对于容器边界的对齐方式,可以使用FlowLayout类中提供的常量作为参数传递给构造方法;参数hgap和参数vgap分别设定组件之间的水平和垂直间隙,可以填入一个任意数值。FlowLayout类的常量中,FlowLayout.LEFT表示左对齐、FlowLayout.RIGHT表示右对齐、FlowLayout.CENTER表示居中对齐。

接下来通过一个案例学习FlowLayout布局管理器的用法。

1 import javax.swing.*;
2 import java.awt.*;
3 class Example03 {
4   public static void main(String[] args) {
5       JFrame frame = new JFrame("hello world");
6      //设置窗体中的布局管理器为FlowLayout,所有的组件居中对齐,水平和垂直间距为3
7       frame.setLayout(new FlowLayout(FlowLayout.CENTER,3,3));
8 JButton button = null;
9       for(int i = 0; i <9; i++){
10           button = new JButton("按钮"+i);
11            frame.add(button);
12       }
13       frame.setSize(280,250);
14       frame.setVisible(true);
15    }
16 }

在上述代码中,使用流式布局管理器对按钮进行管理。在这个过程中,第5行代码创建了一个JFrame窗口frame并,在创建窗体对象的同时定义了窗体对象的标题为“hello world”,第7行代码通过JFrame的setLayout属性将该窗口的布局管理器设置为FlowLayout。在第8~12行代码中,定义了一个JButton的按钮,然后使用for循环向窗口中添加9个按钮。通过运行结果可以看出,frame窗口中的按钮按照流式布局进行排列。

FlowLayout布局管理器的特点就是可以将所有组件像流水一样依次进行排列,不需要用户明确的设定,但是在灵活性上相对差了点。例如,将上图中的窗体拉伸变宽,按钮的大小和按钮之间的间距将保持不变,但按钮相对于容器边界的距离会发生变化,窗体拉伸变宽效果如右图。

11.3.2 BorderLayout

BorderLayout(边界布局管理器)是一种较为复杂的布局方式,它将窗体划分为五个区域,分别是东(EAST)、南(SOUTH)、西(WEST)、北(NORTH)、中(CENTER)。组件可以被放置在这五个区域中的任意一个区域中。BorderLayout的布局效果如右图。

BorderLayout将窗体划分为五个区域,其中箭头是指改变容器大小时,各个区域需要改变的方向。也就是说,在改变窗体大小时,NORTH和SOUTH区域高度不变,宽度调整;WEST和EAST区域宽度不变,高度调整;CENTER会相应进行调整。

当向BorderLayout管理的窗体中添加组件时,需要调用add(Component comp,Object constraints)方法,其中,参数comp表示要添加的组件,参数constraints是一个Object类型的对象,用于指定组件添加方式以及添加位置。向add()方法传参时,可以使用BorderLayout类提供的5个常量,它们分别是EAST、SOUTH、WEST、NORTH和CENTER。

BorderLayout的常用方法及常量如下表。

方法及常量 类型 功能描述
public BorderLayout() 构造方法 构造没有间距的布局器
public BorderLayout(int align,int hgap,int vgap) 构造方法 构造有水平和垂直间距的布局器
public static final String EAST 常量 将组件设置在东区域
public static final String WEST 常量 将组件设置在西区域
public static final String SOUTH 常量 将组件设置在南区域
public static final String NORTH 常量 将组件设置在北区域
public static final String CENTER 常量 将组件设置在中区域

接下来通过一个案例演示BorderLayout布局管理器对组件布局的效果。

1 import javax.swing.*;
2 import java.awt.*;
3 class BorderLayoutDemo extends JFrame {
4     //构造函数,初始化对象值
5     public BorderLayoutDemo(){
6        //设置为边界布局,组件间横向、纵向间距均为5像素
7        setLayout(new BorderLayout(5,5));
8        setFont(new Font("Helvetica", Font.PLAIN, 14));
9        //将按钮添加到窗口中
10        getContentPane().add("North", new JButton(BorderLayout.NORTH));
11 getContentPane().add("East",new JButton(BorderLayout.EAST));
12        getContentPane().add("West",new JButton(BorderLayout.WEST));
13        getContentPane().add("Center",new JButton(BorderLayout.CENTER));
14 }
15    public static void main(String args[]) {
16        BorderLayoutDemo f = new BorderLayoutDemo();
17        f.setTitle("边界布局");
18        f.pack();
19        f.setVisible(true);
20        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
21        f.setLocationRelativeTo(null);//让窗体居中显示
22    }
23 }        

上述代码中,第7行代码为Frame容器设置了BorderLayout布局管理器(也可以不用设置,Frame默认使用BorderLayout布局管理器),第10~14行代码在容器的东、南、西、北、中五个区域各放置了1个按钮。

BorderLayout的优点就是可以限定各区域的边界,当用户改变容器窗口大小时,各个组件的相对位置不变。但需要注意的是,向BorderLayout管理的容器添加组件时,如果不指定添加到哪个区域,则默认添加到CENTER区域,并且只能放置一个组件,如果向一个区域中添加多个组件时,后放入的组件会覆盖先放入的组件。

11.3.3 GridLayout

GridLayout布局管理器是以网格的形式管理容器中组件布局的。GridLayout使用纵横线将容器分成n行m列大小相等的网格,每个网格中放置一个组件。添加到容器中的组件首先放置在第1行第1列(左上角)的网格中,然后在第1行的网格中从左向右依次放置其他组件。一行放满之后,继续在下一行中从左到右放置组件。GridLayout管理方式与FlowLayou类似,但与FlowLayout不同的是,使用GridLayout管理的组件将自动占据网格的整个区域。

GridLayout的常用构造方法如下表。

方法声明 功能描述
GridLayout() 默认只有一行,每个组件占一列
GridLayout(int rows,int cols) 指定容器的行数和列数
GridLayout(int rows,int cols,int hgap,int vgap) 指定容器的行数和列数以及组件之间的水平、垂直间距

列出了GridLayout的三个构造方法,其中,参数rows代表行数,cols代表列数,hgap和vgap规定水平和垂直方向的间隙。水平间隙指的是网格之间的水平距离,垂直间隙是指网格之间的垂直距离。

接下来通过一个案例演示GridLayout布局的用法。

1 import java.awt.*;
2 public class Example05 {
3	public static void main(String[] args) {
4		Frame f = new Frame("GridLayout");// 创建一个名为GridLayout的窗体
5		f.setLayout(new GridLayout(3, 3));// 设置该窗体为3*3的网格
6		f.setSize(300, 300);                 // 设置窗体大小
7		f.setLocation(400, 300);
8		// 下面的代码是循环添加9个按钮到GridLayout中
9		for (int i = 1; i <= 9; i++) {
10			Button btn = new Button("btn" + i);
11			f.add(btn); // 向窗体中添加按钮
12		}
13		f.setVisible(true);
14	}
15 }

11.3.4 GridBagLayout

GridBagLayout是最灵活、最复杂的布局管理器。GridBagLayout与GridLayout布局管理器类似,不同的是,GridBagLayout允许网格中的组件大小各不相同,而且允许一个组件跨越一个或者多个网格。

使用GridBagLayout布局管理器的步骤如下:

(1)创建GridbagLayout布局管理器,设置容器采用该布局管理器。具体示例如下:

GridBagLayout layout = new GridBagLayout();
container.setLayout(layout);

(2)创建GridBagContraints对象,并设置该对象的相关属性(设置布局约束条件)。具体示例如下:

GridBagConstraints constraints = new GridBagConstraints();
constraints.gridx = 1;     //设置网格的左上角横向索引
constraints.gridy = 1;     //设置网格的左上角纵向索引
constraints.gridwidth = 1;   //设置组件横向跨越的网格
constraints.gridheight = 1;  //设置组件纵向跨越的网格

(3)调用GridBagLayout对象的setConstraints()方法,建立GridBagConstraints对象和受控组件之间的关联。具体示例如下:

layout.setConstraints(component,constraints);

(4)向容器中添加组件。具体示例如下:

container.add(conponent);

GridBagConstraints对象可以重复使用。如果改变布局,只需要改变GridBagConstraints对象的属性即可。如果要向容器中添加多个组件,则重复(2)、(3)、(4)步骤。

从上面的步骤可以看出,使用GridBagLayout布局管理器的关键在于GridBagConstraints对象。GridBagConstraint类才是控制容器中每个组件布局的核心类,在GridBagConstraints类中有很多用于设置约束条件的属性。

GridBagConstraints类的常用属性如下表。

属性 作用
gridx和gridy 设置组件所在网格的横向和纵向索引(即所在的行和列)。如果将gridx和 gridy的值设置为GridBagConstraints.RELATIVE(默认值),表示当前组件紧跟在上一个组件后面。
gridwidth和gridheight 设置组件横向、纵向跨越几个网格,两个属性的默认值都是1。如果把这两个属性的值设为GridBagConstraints.REMAINER表示组件在当前行或列上为最后一个组件。如果把这两个属性的值设为GridBagConstraints.RELATIVE,表示组件在当前行或列上为倒数第二个组件。
属性 作用
fill 如果组件的显示区域大于组件需要的大小,设置组件改变方式,该属性接收以下几个属性值: lNONE:默认,不改变组件大小。 lHORIZONTAL:使组件水平方向足够长以填充显示区域,但是高度不变, lVERTICAL:使组件垂直方向足够高以填充显示区域,但长度不变。 lBOTH:使组件足够大,以填充整个显示区域。
weightx和weighty 设置组件占领容器中水平方向和垂直方向多余空白的比例(也称为权重)。假设容器的水平方向放置三个组件,组件的weightx属性值分别为1、2、3,当容器宽度增加60个像素时,这三个容器分别增加10、20、和30的像素。weightx和weighty属性的默认值是0,即不占领多余的空间。

如果希望组件的大小随着容器的增大而增大,必须同时设置GridBagConstraints对象的fill属性和weightx、weighty属性。

接下来通过一个案例演示GridBagLayout的用法。

1 import java.awt.*;
2 class Layout extends Frame {
3	public Layout(String title) {
4		GridBagLayout layout = new GridBagLayout();
5		GridBagConstraints c = new GridBagConstraints();
6		this.setLayout(layout);
7		c.fill = GridBagConstraints.BOTH; 	// 设置组件横向纵向可以拉伸
8		c.weightx = 1; 			// 设置横向权重为1
9		c.weighty = 1; 			// 设置纵向权重为1 
10		this.addComponent("btn1", layout, c);
11		this.addComponent("btn2", layout, c);
12		this.addComponent("btn3", layout, c);
13		c.gridwidth = GridBagConstraints.REMAINDER; 	
14         	this.addComponent("btn4", layout, c);
15		c.weightx = 0; 		// 设置横向权重为0
16		c.weighty = 0; 		// 设置纵向权重为0
17		addComponent("btn5", layout, c);
18		c.gridwidth = 1; 		// 设置组件跨一个网格(默认值)
19		this.addComponent("btn6", layout, c);
20		c.gridwidth = GridBagConstraints.REMAINDER; 	
21	     this.addComponent("btn7", layout, c);
22		c.gridheight = 2; 		// 设置组件纵向跨两个网格
23		c.gridwidth = 1;  		// 设置组件横向跨一个网格
24		c.weightx = 2;    		// 设置横向权重为2
25		c.weighty = 2;    		// 设置纵向权重为2
26		this.addComponent("btn8", layout, c);	
27		c.gridwidth = GridBagConstraints.REMAINDER;
28		c.gridheight = 1;
29		this.addComponent("btn9", layout, c);
30		this.addComponent("btn10", layout, c);
31		this.setTitle(title);
32		this.pack();
33		this.setVisible(true);
34	}
35	// 增加组件的方法
36	private void addComponent(String name, GridBagLayout layout,
37			GridBagConstraints c) {
38		Button bt = new Button(name); 	// 创建一个名为name的按钮
39		layout.setConstraints(bt, c); 
40		this.add(bt); 		// 增加按钮
41	}
42 }
43 public class Example06 {
44	public static void main(String[] args) {
45		new Layout("GridBagLayout");
46	}
47 }

在上述代码中,第10~30行代码向GridBagLayout管理的窗口中添加10个按钮。由于每次添加按钮的时候都需要调用该布局的setConstraints()方法,将GridBagConstraints对象与按钮组件相关联,因此,可以将这段起到关联作用的代码抽取到addComponent()方法当中,简化书写。

第10~14行代码在添加button1~button4按钮和第26~30行代码在添加button8~button10按钮时,都将权重weightx和weighty的值设置为大于0,因此在拉伸窗口时,这些按钮都会随着窗口增大。第17~21行代码在添加button5~button7按钮时,将权重值设置为0,这样它们的高度在拉伸时没有变化,但长度受上下组件的影响,还是会随窗口变大。

11.4 事件处理机制

Swing组件中的事件处理专门用于响应用户的操作,例如,响应用户的鼠标单击、按下键盘等操作。在Swing事件处理的过程中,主要涉及到三类对象:

● 事件源(Event Source):事件发生的场所,通常是产生事件的组件,如窗口、按钮、菜单等。

● 事件对象(Event):封装了GUI组件上发生的特定事件(通常就是用户的一次操作)。

● 监听器(Listener):负责监听事件源上发生的事件,并对各种事件做出相应处理(监听器对象中包含事件处理器)。

上面提到的事件源、事件对象、监听器在整个事件处理过程中都起着非常重要的作用,它们彼此之间有着非常紧密的联系。接下来用一个图例来描述事件处理的工作流程。

事件源是一个组件,当用户进行一些操作时,例如,按下鼠标或者释放键盘等,都会触发相应的事件,如果事件源注册了监听器,则触发的相应事件将会被处理。

接下来通过一个案例演示Swing中的事件处理。

1 import java.awt.event.*;
2 import javax.swing.*;
3 // 自定义事件监听器类
4 class MyListener implements ActionListener{
5	// 实现监听器方法,对监听事件进行处理
6	public void actionPerformed(ActionEvent e) {
7		System.out.println("用户点击了JButton按钮组件");
8	}
9 }
10 public class Example07 {
11	private static void createAndShowGUI() {
12		JFrame f = new JFrame("JFrame窗口");
13		f.setSize(200, 100); 
14		// 创建一个按钮组件,作为事件源
15		JButton btn = new JButton("按钮");  
16		// 为按钮组件事件源添加自定义监听器
17		btn.addActionListener(new MyListener());
18		f.add(btn);
19		f.setVisible(true);
20		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
21	}
22	public static void main(String[] args) {
23		// 使用SwingUtilities工具类调用createAndShowGUI()方法并显示GUI程序
24		SwingUtilities.invokeLater(Example07::createAndShowGUI);
25	}
26 }

上述代码中,第15行代码定义了一个btn的JButton的按钮,在第18行代码中将btn添加到JFrame窗口中,同时在第17行代码中使用addActionListener()方法为JButton按钮组件添加了一个自定义事件监听器,当单击JButton按钮组件时,自定义的事件监听器,进行事件处理。

从上面的程序可以看出,实现Swing事件处理的主要步骤如下:

(1)创建事件源:除了一些常见的按钮、键盘等组件可以作为事件源外,还可以使用JFrame窗口在内的*容器作为事件源。

(2)自定义事件监听器:根据要监听的事件源创建指定类型的监听器进行事件处理。监听器是一个特殊的Java类,必须实现XxxListener接口。根据组件触发的动作进行区分,例如,WindowListener用于监听窗口事件,ActionListener用于监听动作事件。

(3)为事件源注册监听器:使用addXxxListener()方法为指定事件源添加特定类型的监听器。当事件源上发生监听事件后,就会触发绑定的事件监听器,由监听器中的方法对事件进行相应处理。

11.4.1 Swing常用事件处理

1.窗体事件

大部分GUI应用程序都需要使用Window窗体对象作为最外层的容器,可以说窗体对象是所有GUI应用程序的基础,应用程序中通常都是将其他组件直接或者间接地添加到窗体中。

当对窗体进行操作时,例如,窗体的打开、关闭、激活、停用等,这些动作都属于窗体事件。Java提供了一个WindowEvent类用于表示窗体事件。在应用程序中,当对窗体事件进行处理时,首先需要定义一个实现了WindowListener接口的类作为窗体监听器,然后通过addWindowListener()方法将窗体对象与窗体监听器进行绑定。

接下来通过一个案例实现对窗体事件的监听。

1 import java.awt.event.*;
2 import javax.swing.*;
3 public class Example08 {
4	private static void createAndShowGUI() {
5		JFrame f = new JFrame("WindowEvent");
6		f.setSize(400, 300);
7		f.setLocation(300, 200);
8		f.setVisible(true);
9         f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
10		// 使用内部类创建WindowListener实例对象,监听窗体事件
11		f.addWindowListener(new WindowListener() {
12			public void windowOpened(WindowEvent e) {
13				System.out.println("windowOpened---窗体打开事件");
14			}
15	public void windowIconified(WindowEvent e) {
16		System.out.println("windowIconified---窗体图标化事件");
17	}
18	public void windowDeiconified(WindowEvent e) {
19	  System.out.println("windowDeiconified---窗体取消图标化事件");
20	}
21	public void windowDeactivated(WindowEvent e) {
22		System.out.println("windowDeactivated---窗体停用事件");
23	}
24	public void windowClosing(WindowEvent e) {
25		System.out.println("windowClosing---窗体正在关闭事件");
26	}
27	public void windowClosed(WindowEvent e) {
28		System.out.println("windowClosed---窗体关闭事件");
29	}
30				public void windowActivated(WindowEvent e) {
31				System.out.println("windowActivated---窗体激活事件");
32			}
33		});
34	}
35	public static void main(String[] args) {
36		// 使用SwingUtilities工具类调用createAndShowGUI()方法并显示GUI程序
37		SwingUtilities.invokeLater(Example08::createAndShowGUI);
38	}
39 }

上述代码中,第11~33行代码通过WindowListener对操作窗口的窗体事件进行监听,当接收到特定的操作后,就将所触发事件的名称打印出来。对图11-16所示的窗体事件源进行事件操作,分别执行最小化、单击任务栏图标、单击关闭按钮时,窗口事件监听器就会对相应的操作进行监听并响应,响应结果如下图。

2.鼠标事件

在图形用户界面中,用户会经常使用鼠标进行选择、切换界面等操作,这些操作被定义为鼠标事件,包括鼠标按下、鼠标松开、鼠标单击等。Java提供了一个MouseEvent类描述鼠标事件。处理鼠标事件时,首先需要通过实现MouseListener接口定义监听器(也可以通过继承适配器MouseAdapter类定义监听器),然后调用addMouseListener()方法将监听器绑定到事件源对象。

接下来通过一个案例学习如何监听鼠标事件。

1 import java.awt.*;
2 import java.awt.event.*;
3 import javax.swing.*;
4 public class Example09 {
5	private static void createAndShowGUI() {
6		JFrame f = new JFrame("MouseEvent");
7		f.setLayout(new FlowLayout());       	// 为窗口设置布局
8		f.setSize(300, 200);
9		f.setLocation(300, 200);
10		f.setVisible(true);
11         f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
12	JButton but = new JButton("Button");	// 创建按钮对象
13	f.add(but);                              	// 在窗口添加按钮组件
14	// 为按钮添加鼠标事件监听器
15	but.addMouseListener(new MouseListener() {
16		public void mouseReleased(MouseEvent e) {
17			System.out.println("mouseReleased-鼠标放开事件");
18		}
19		public void mousePressed(MouseEvent e) {
20			System.out.println("mousePressed-鼠标按下事件");
21		}
22		public void mouseExited(MouseEvent e) {
23			System.out.println("mouseExited—鼠标移出按钮区域事件");
24		}
25			public void mouseEntered(MouseEvent e) {
26				System.out.println("mouseEntered—鼠标进入按钮区域事件");
27			}
28			public void mouseClicked(MouseEvent e) {
29				System.out.println("mouseClicked-鼠标完成单击事件");
30			}
31		});
32	}
33	public static void main(String[] args) {
34		// 使用SwingUtilities工具类调用createAndShowGUI()方法并显示GUI程序
35		SwingUtilities.invokeLater(Example09::createAndShowGUI);
36	}
37 }
    

上述代码中,第15~31行代码通过MouseEvent对鼠标事件进行监听,当接收到特定的操作后,就将所触发事件的名称打印出来。在图11-18中,用鼠标对窗口上的按钮进行操作,先把鼠标移进按钮区域,接着单击按钮然后释放,再移出按钮区域,控制台的输出信息如下图。

MouseEvent类中定义了很多常量来识别鼠标操作,包括鼠标左键单/双击、滚轮操作等。如下面的代码所示:

public void mouseClicked(MouseEvent e) {
	if(e.getButton()==MouseEvent.BUTTON1){
		System.out.println("鼠标左击事件");
	}	
	if(e.getButton()==MouseEvent.BUTTON3){
		System.out.println("鼠标右击事件");
	}
	if(e.getButton()==MouseEvent.BUTTON2){
		System.out.println("鼠标中键单击事件");
	}
}

3.键盘事件

键盘操作也是最常用的用户交互方式,例如,键盘按下、释放等,这些操作被定义为键盘事件。Java提供了一个KeyEvent类表示键盘事件,处理KeyEvent事件的监听器对象需要实现KeyListener接口或者继承KeyAdapter类,然后调用addKeyListener()方法将监听器绑定到事件源对象。

接下来通过一个案例学习如何监听键盘事件。

1 import java.awt.*;
2 import java.awt.event.*;
3 import javax.swing.*;
4 public class Example10 {
5	private static void createAndShowGUI() {
6		JFrame f = new JFrame("KeyEvent");
7		f.setLayout(new FlowLayout());
8		f.setSize(400, 300);
9		f.setLocation(300, 200);
10		JTextField tf = new JTextField(30); // 创建文本框对象
11		f.add(tf);                               // 在窗口中添加文本框组件
12		f.setVisible(true);
13		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
14 // 为文本框添加键盘事件监听器
15		tf.addKeyListener(new KeyAdapter() {
16			public void keyPressed(KeyEvent e) {
17				// 获取对应的键盘字符
18				char keyChar = e.getKeyChar();
19				// 获取对应的键盘字符代码
20				int keyCode = e.getKeyCode();
21				System.out.print("键盘按下的字符内容为:" + keyChar+" ");
22				System.out.println("键盘按下的字符代码为:" + keyCode);
23			}
24		});
25	}
26	public static void main(String[] args) {
27		// 使用SwingUtilities工具类调用createAndShowGUI()方法并显示GUI程序
28		SwingUtilities.invokeLater(Example10::createAndShowGUI);
29	}
30  }         

上述代码中,第10行代码使用JTextComponent类的子类JtextField定义文本框,这里需要注意的是,JtextField类只允许编辑单行文本。在运行结果中的文本框中键入字符时,便触发了键盘事件。程序会执行代码第16~23行的keyPressed()方法。通过调用KeyEvent类的getKeyChar()方法获取键盘键入的字符,通过调用getKeyCode()方法获取输入字符对应的整数值。

在运行结果图中,依次从键盘输入a、1、2、3字符,程序会在控制台将按键对应的名称和键值(keyCode)打印出来,控制台输出结果如下图。

4.动作事件

动作事件与前面3种事件有所不同,它不代表某类事件,只是表示一个动作发生了。例如,在关闭一个文件时,可以通过键盘关闭,也可以通过鼠标关闭。在这里读者不需要关心使用哪种方式关闭文件,只要是对关闭按钮进行操作,就会触发动作事件。

在Java中,动作事件用ActionEvent类表示,处理ActionEvent事件的监听器对象需要实现ActionListener接口。监听器对象在监听动作时,不会像鼠标事件一样处理鼠标的移动和单击的细节,而是去处理类似于“按钮按下”这样“有意义”的事件。

11.5 Swing常用组件

前面几个小节讲解了Swing中的容器,以及开发过程中需要用到的布局管理器和事件处理机制,完成这些内容的学习后,还需要学习Swing中的组件,这样才能实现完整的GUI程序。

11.5.1 面板组件

Swing组件中不仅具有JFrame和JDialog这样的*容器,还提供了一些面板组件(也称之为中间容器)。面板组件不能单独存在,只能放置在*窗口容器中。最常见的面板组件有两种,分别是JPanel和JScrollPane。

1.JPanel

JPanel面板组件是一个无边框,不能被移动、放大、缩小或者关闭的面板,它的默认布局管理器是FlowLayout。也可以使用JPanel带参数的构造函数JPanel(LayoutManager layout)或者setLayout()成员方法设置JPanel布局管理器。

JPanel面板组件类并没有包含多少特殊的组件操作方法,大多数都是从父类(如Container)继承过来的,使用也非常简单。

2.JScrollPane

JScrollPane是一个带有滚动条的面板,面板上只能添加一个组件。如果想向JScrollPane面板中添加多个组件,应该先将这多个组件添加到某个组件中,然后再将这个组件添加到JScrollPane中。

JScrollPane的常用构造方法如下表。

方法声明 功能描述
JScrollPane() 创建一个空的JScrollPane面板。
JScrollPane(Component view) 创建一个显示指定组件的JScrollPane面板,一旦组件的内容超过视图大小就会显示水平或垂直滚动条。
JScrollPane(Component view, int vsbPolicy,int hsbPolicy) 创建一个显示指定容器、并具有指定滚动条策略的JScrollPane。参数vsbPolicy和hsbPolicy分别表示垂直滚动条策略和水平滚动条策略。

如果在构造方法中没有指定显示组件和滚动条策略,可以调用JScrollPane提供的成员方法进行设置,JScrollPane设置面板滚动策略的方法如下表。

方法声明 功能描述
void setHorizontalBarPolicy(int policy) 指定水平滚动条策略,即水平滚动条何时显示在滚动面板上。
void setVerticalBarPolicy(int policy) 指定垂直滚动条策略,即垂直滚动条何时显示在滚动面板上。
void setViewportView(Component view) 设置在滚动面板显示的组件。

关于上述介绍的JScrollPane面板组件滚动策略的设置方法,ScrollPaneConstants接口声明了多个常量属性,可以用来设置不同的滚动策略。JscrollPane的滚动属性如下表。

方法声明 功能描述
VERTICAL_SCROLLBAR_AS_NEEDED 当填充的组件视图超过客户端窗口大 小时,自动显示水平和竖直滚动条(JscrollPane组件的默认值)。
HORIZONTAL_SCROLLBAR_AS_NEEDED 当填充的组件视图超过客户端窗口大 小时,自动显示水平和竖直滚动条(JscrollPane组件的默认值)。
VERTICAL_SCROLLBAR_ALWAYS 无论填充的组件视图大小,始终显示水平和竖直滚动条。
HORIZONTAL_SCROLLBAR_ALWAYS 无论填充的组件视图大小,始终显示水平和竖直滚动条。
VERTICAL_SCROLLBAR_NEVER 无论填充的组件视图大小,始终不显示水平和竖直滚动条。
HORIZONTAL_SCROLLBAR_NEVER 无论填充的组件视图大小,始终不显示水平和竖直滚动条。

接下来通过一个案例演示面板组件的基本用法。

import java.awt.*;
import javax.swing.*;
public class Example11 {
	private static void createAndShowGUI() {
		// 1、创建一个JFrame容器窗口
		JFrame f = new JFrame("PanelDemo");
		f.setLayout(new BorderLayout());
		f.setSize(350, 200);
		f.setLocation(300, 200);
		f.setVisible(true);
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		// 2、创建JScrollPane滚动面板组件
		JScrollPane scrollPane = new JScrollPane();
		// 设置水平滚动条策略--滚动条需要时显示
		scrollPane.setHorizontalScrollBarPolicy
				(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
		// 设置垂直滚动条策略--滚动条一直显示
		scrollPane.setVerticalScrollBarPolicy
				(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
		// 定义一个JPanel面板组件
		JPanel panel = new JPanel();
		// 在JPanel面板中添加四个按钮
		panel.add(new JButton("按钮1"));
		panel.add(new JButton("按钮2"));
		panel.add(new JButton("按钮3"));
		panel.add(new JButton("按钮4"));
		// 设置JPanel面板在滚动面板JScrollPane中显示
		scrollPane.setViewportView(panel);
		// 向JFrame容器窗口中添加JScrollPane滚动面板组件
		f.add(scrollPane, BorderLayout.CENTER);
	}
	public static void main(String[] args) {
	// 使用SwingUtilities工具类调用createAndShowGUI()方法并显示GUI程序
		SwingUtilities.invokeLater(Example11::createAndShowGUI);
	}
}

上述代码中,第4~31行定义了createAndShowGUI()方法,在createAndShowGUI()方法中,第6~11行代码创建了一个名为f的容器窗口;第13行代码创建了名为scrollPane滚动面板组件;第15~16行代码设置水平滚动条策略为滚动条需要时显示;第18~19行代码设置垂直滚动条策略为滚动条一直显示;第21~26行代码创建了一个pannel的面板组件,并在pannel的面板组件中添加了四个按钮;第28行代码设置pannnel面板在scrollPane滚动面板中显示。第30行代码向f容器窗口中添加scrollPane滚动面板组件。最后在main()方法中使用SwingUtilities工具类调用封装好的createAndShowGUI()方法并显示GUI程序。

11.5.2 文本组件

文本组件用于接收用户输入的信息,包括文本框(JTextField)、文本域(JTextArea)等。文本组件都有一个共同父类JTextComponent,JTextComponent类是一个抽象类,它提供了文本组件常用的方法。

方法声明 功能描述
String getText() 返回文本组件中所有的文本内容
String getSelectedText() 返回文本组件中选定的文本内容
void selectAll() 在文本组件中选中所有内容
void setEditable() 设置文本组件为可编辑或者不可编辑状态
void setText(String text) 设置文本组件的内容
void replaceSelection(String content) 用给定的内容替换当前选定的内容

上表列出了文本组件常用的几种操作方法,其中包括选中文本内容、设置文本内容以及获取文本内容等。由于JTextField和JTextArea这两个文本组件继承了JTextComponent类,因此它们都具有上表中的方法。但是在使用上,JtextField和JTextArea还有一定的区别。

1.JTextField

JTextField称为文本框,它只能接收单行文本的输入。 JTextField常用的构造方法如下表。

方法声明 功能描述
JTextField() 创建一个空的文本框,初始字符串为null
JTextFiled(int columns) 创建一个具有指定列数的文本框,初始字符串为null
JTextField(String text) 创建一个显示指定初始字符串的文本框
JTextField(String text,int column) 创建一个具有指定列数、并显示指定初始字符串的文本框

JTextField有一个子类JPasswordField,表示密码框,JpasswordField文本框也是只能接收用户的单行输入,但是文本框中不显示用户输入的真实信息,而是通过显示指定的回显字符作为占位符,新创建的密码框默认的回显字符为“*”。JPasswordField和JTextField的构造方法相似,这里就不再介绍了。

2.JTextArea

JTextArea称为文本域,它能接收多行文本的输入,使用JTextArea构造方法创建对象时可以设定区域的行数、列数。 JTextArea常用的构造方法如下表。

方法声明 功能描述
JTextArea() 创建一个空的文本域
JTextArea(String text) 创建显示指定初始字符串的文本域
JTextArea(int rows,int columns) 创建具有指定行和列的空文本域
JTextArea(String text,int rows,int columns) 创建显示指定初始文本并指定了行列的文本域

接下来通过一个案例演示文本组件JTextField和JTextArea的基本用法,在该案例中,编写一个聊天窗口。

import java.awt.*;
import javax.swing.*;
public class Example12 {
	private static void createAndShowGUI() {
		// 创建一个JFrame聊天窗口
		JFrame f = new JFrame("聊天窗口");
		f.setLayout(new BorderLayout());
		f.setSize(400, 300);
		f.setLocation(300, 200);
		f.setVisible(true);
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		// 创建一个JTextArea文本域,用来显示多行聊天信息
		JTextArea showArea = new JTextArea(12, 34);
		// 创建一个JScrollPane滚动面板组件,将JTextArea文本域作为其显示组件
		JScrollPane scrollPane = new JScrollPane(showArea);
		showArea.setEditable(false); 				// 设置文本域不可编辑
		// 创建一个JTextField文本框,用来输入单行聊天信息
		JTextField inputField = new JTextField(20);
		JButton btn = new JButton("发送"); 
		// 为按钮添加监听事件
		btn.addActionListener(e -> {
			String content = inputField.getText();
			// 判断输入的信息是否为空
			if (content != null && !content.trim().equals("")) {
				// 如果不为空,将输入的文本追加到到聊天窗口
				showArea.append("本人输入信息:" + content + "\n");
			} else {
				// 如果为空,提示聊天信息不能为空
				showArea.append("聊天信息不能为空!!!" + "\n");
			}
			inputField.setText(""); // 将输入的文本域内容置为空
		});
		// 创建一个JPanel面板组件
		JPanel panel = new JPanel();
		JLabel label = new JLabel("聊天信息");   // 创建一个标签
		panel.add(label);                   		// 将标签组件添加到JPanel面板
		panel.add(inputField);             		// 将文本框添加到JPanel面板
		panel.add(btn);                     		// 将按钮添加到JPanel面板
	// 向JFrame聊天窗口的顶部和尾部分别加入面板组件JScrollPane和JPanel
		f.add(scrollPane, BorderLayout.PAGE_START);
		f.add(panel, BorderLayout.PAGE_END);
	}
	public static void main(String[] args) {
	// 使用SwingUtilities工具类调用createAndShowGUI()方法并显示GUI程序
		SwingUtilities.invokeLater(Example12::createAndShowGUI);
	}
}

上述代码中,第4~42行代码定义了createAndShowGUI()方法,在createAndShowGUI()方法中,第6~11行代码创建了一个名称为f的容器窗口;第13行代码创建了一个名为showArea的文本域,用于显示多行聊天信息;第15行代码创建了一个名为inputField的滚动面板组件,并将文本域showArea作为显示组件;第16行代码设置showArea文本域不可编辑。第18~19行代码创建了一个名称为inputField的文本框和一个名称为btn的按钮;第24~32行代码判断输入的信息是否为空,如果不为空,将输入的文本发送到聊天窗口;如果为空,提示聊天信息不能为空。文本发送到聊天窗口之后,再将输入的文本域内容置为空。

第34~38行代码创建了一个名称为panel的面板组件,并将需要用到的组件添加到panel 中,第40~41行代码将容器窗口f的顶部和尾部分别加入scrollPane与panel中。最后在main()方法中使用SwingUtilities工具类调用封装好的createAndShowGUI()方法并显示GUI程序。

需要说明的是,文件11-12中第35行代码用到的JLabel组件是一个静态组件,用于显示一行静态文本和图标。它的作用只是信息说明,不接收用户的输入,也不能添加事件,Jlabel的具体用法会在下一小节讲解。

在运行结果的聊天窗口中输入聊天信息,并单击【发送】按钮,结果如右图。

11.5.3 标签组件

除了有用于输入功能的文本组件外,Swing还提供了用于仅供展示的标签组件,标签组件也是Swing中很常见的组件。常用的Swing标签组件是JLabel,JLabel组件可以显示文本、图像,还可以设置标签内容的垂直和水平对齐方式。

JLabel的构造方法如下表。

方法声明 功能描述
JLabel() 创建无标题的JLabel实例
JLabel(Icon image) 创建具有指定图像的JLabel实例
JLabel(Icon image, int horizontalAlignment) 创建具有指定图像和水平对齐方式的JLabel实例
JLabel(String text) 创建具有指定文本的JLabel实例
JLabel(String text, Icon icon, int horizontalAlignment) 创建具有指定文本、图像和水平对齐方式的 JLabel 实例
JLabel(String text, int horizontalAlignment) 创建具有指定文本和水平对齐方式的 JLabel 实例

接下来通过一个案例演示JLabel标签组件的基本用法。

import java.awt.*;
import javax.swing.*;
public class Example13 {
	private static void createAndShowGUI() {
		// 1、创建一个JFrame容器窗口
		JFrame f = new JFrame("JFrame窗口");
		f.setLayout(new BorderLayout());
		f.setSize(300, 200);
		f.setLocation(300, 200);
		f.setVisible(true);
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		// 2、创建一个JLabel标签组件,用来展示图片
		JLabel label1 = new JLabel();
		// 2.1、创建一个ImageIcon图标组件,并加入JLabel中
		ImageIcon icon = new  ImageIcon("FruitStore.jpg");
		Image img = icon.getImage();
		// 2.2、用于设置图片大小尺寸
		img = img.getScaledInstance(300, 150, Image.SCALE_DEFAULT);  
		icon.setImage(img);  
		label1.setIcon(icon);
		// 3、创建一个页尾JPanel面板,并加入JLabel标签组件
		JPanel panel = new JPanel();
		JLabel label2 = new JLabel("欢迎进入水果超市",JLabel.CENTER);
		panel.add(label2);
		// 4、向JFrame聊天窗口容器的顶部和尾部分别加入JLabel和JPanel组件
		f.add(label1, BorderLayout.PAGE_START);
		f.add(panel, BorderLayout.PAGE_END);
	}
	public static void main(String[] args) {
	// 使用SwingUtilities工具类调用createAndShowGUI()方法并显示GUI程序
		SwingUtilities.invokeLater(Example13::createAndShowGUI);
	}
}

上述代码中,第6行代码是使用JFrame*容器创建了一个窗口容器。第7~11行代码依次设置了窗口容器的布局模式、窗口大小、位置、是否可见以及设置用户在此窗体上发起 "close" 时执行关闭操作。第13~24行代码创建了标签组件lable1、lable2、图标组件icon和面板组件panel,并分别将图标组件icon和面板组件panel添加到标签组件lable1、lable2中,其中,ImageIcon图标组件用来显示背景图片。第26~27行代码通过BorderLayout布局管理器将窗口分为上下两个区域。

11.5.4 按钮组件

Swing常用的按钮组件有JButton、JCheckBox、JRadioButton等,它们都是抽象类AbstractButton类的直接或间接子类。AbstractButton的常用方法如下表。

方法声明 功能描述
Icon getIcon() 获取按钮的图标
void setIcon(Icon icon) 设置按钮的图标
String getText() 获取按钮的文本
void setText(String text) 设置按钮的文本
void setEnable(boolean b) 设置按钮是否可用
boolean setSelected(boolean b) 设置按钮是否为选中状态
boolean isSelected() 返回按钮的状态(true为选中,反之为未选中)

1.JCheckBox

JCheckBox组件被称为复选框组件,它有选中和未选中两种状态。通常复选框会有多个,用户可以选中其中一个或者多个。JCheckBox的常用构造方法如下表。

方法声明 功能描述
JCheckBox() 创建一个没有文本信息,初始状态未被选中的复选框
JCheckBox(String text) 创建一个带有文本信息,初始状态未被选定的复选框
JCheckBox(String text,boolean selected) 创建一个带有文本信息,并指定初始状态(选中/未选中)的复选框

上表列出了创建JCheckBox对象的三个构造方法。第一个构造方法没有指定复选框的文本信息以及状态,如果想设置文本信息,可以通过调用JCheckBox从父类继承的方法进行设置。例如,调用setText(String text)方法设置复选框文本信息;调用setSelected(boolean b)方法设置复选框状态(是否被选中),也可以调用isSelected()方法判断复选框是否被选中。第二个和第三个构造方法都指定了复选框的文本信息,而且第三个构造方法还指定了复选框初始化状态是否被选中。

接下来通过一个案例演示JCheckBox复选框组件的基本用法。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Example14 {
	private static void createAndShowGUI() {
		// 1、创建一个JFrame容器窗口
		JFrame f = new JFrame("JFrame窗口");
		f.setLayout(new BorderLayout());
		f.setSize(300, 300);
		f.setLocation(300, 200);
		f.setVisible(true);
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		// 2、创建一个JLabel标签组件,标签文本居中对齐
		JLabel label = new JLabel("Hello World!", JLabel.CENTER);
		label.setFont(new Font("宋体", Font.PLAIN, 20));
		// 3、创建一个JPanel面板组件
		JPanel panel = new JPanel();
		// 3.1、创建两个JCheckBox复选框,并添加到JPanel组件中
		JCheckBox italic = new JCheckBox("ITALIC");
		JCheckBox bold = new JCheckBox("BOLD");
		// 3.2、为复选框定义ActionListener监听器
		ActionListener listener = new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int mode = 0;
				if (bold.isSelected())
					mode += Font.BOLD;
				if (italic.isSelected())
					mode += Font.ITALIC;
				label.setFont(new Font("宋体", mode, 20));
			}
		};
		// 3.3、为两个复选框添加监听器
		italic.addActionListener(listener);
		bold.addActionListener(listener);
		// 3.4、在JPanel面板添