Swing用于开发桌面窗体程序,是JDK的第二代GUI框架,其功能比JDK第一代GUI框架AWT更为强大、性能更加优良。但因为Swing技术推出时间太早,其性能、开发效率等不及一些其他流行技术,所以目前市场上大多数桌面窗体程序都不是由Java开发的,Swing技术也逐渐被广大开发人员放弃了。
不过,Swing是JDK自带的功能,并且能非常好地体现Java语言在面向对象、接口事件等方面的设计模式,又能提供直观地呈现运行效果,所以本书还是纳入此内容。本章不会深入地讲解Swing技术,仅会介绍一些常用组件的使用方法,读者了解即可。
Swing中的大多数组件均为轻量级组件,使用Swing开发出的窗体风格会与当前平台(如Windows、Linux等)的窗体风格保持一致。本章主要介绍Swing中的基本要素,包括窗体的布局、容器、常用组件、如何创建表格等内容。
本章的知识架构及重难点如下。
18.1 Swing概述
Swing主要用来开发GUI(Graphical User Interface)程序,GUI是应用程序提供给用户操作的图形界面,包括窗口、菜单、按钮等图形界面元素,我们经常使用的QQ软件、360安全卫士等均为GUI程序。Java语言为Swing程序的开发提供了丰富的类库,这些类分别被存储在java.awt和javax.swing包中。Swing提供了丰富的组件,在开发Swing程序时,这些组件被广泛地应用。
Swing组件是完全由Java语言编写的组件。因为Java语言不依赖于本地平台(即“操作系统”),所以Swing组件可以被应用于任何平台。基于“跨平台”这一特性,Swing组件被称作“轻量级组件”;反之,依赖于本地平台的组件被称作“重量级组件”,
在Swing包的层次结构和继承关系中,比较重要的类是Component类(组件类)、Container类(容器类)和JComponent类(Swing组件父类)。Swing包的层次结构和继承关系如图18.1所示。
图18.1 Swing包的层次结构和继承关系
图18.1包含了一些Swing组件,常用的Swing组件如表18.1所示。
表18.1 常用的Swing组件
18.2 Swing常用窗体
18.2.1 JFrame窗体
开发Swing程序的流程可以被简单地概括为首先通过继承javax.swing.JFrame类创建一个窗体,然后向这个窗体中添加组件,最后为添加的组件设置监听事件。下面将详细讲解JFrame窗体的使用方法。
JFrame类的常用构造方法包括以下两种形式:
ublic JFrame():创建一个初始不可见、没有标题的窗体。
ublic JFrame(String title):创建一个不可见、具有标题的窗体。
例如,创建一个不可见、具有标题的窗体,关键代码如下:
JFrame jf = new JFrame("登录系统");
Container container = jf.getContentPane();
在创建窗体后,先调用getContentPane()方法将窗体转换为容器,再调用add()方法或者remove()方法向容器中添加组件或者删除容器中的组件。向容器中添加按钮,关键代码如下:
JButton okBtn = new JButton("确定")
container.add(okBtn);
删除容器中的按钮,关键代码如下:container.remove(okBtn);
创建窗体后,要对窗体进行设置,如设置窗体的位置、大小、是否可见等。JFrame类提供的相应方法可实现上述设置操作,具体如下:
etBounds(int x, int y, int width, int leight):设置窗体左上角在屏幕中的坐标为(x, y),窗体的宽度为width,窗体的高度为height。
etLocation(int x, int y):设置窗体左上角在屏幕中的坐标为(x, y)。
etSize(int width, int height):设置窗体的宽度为width,高度为height。
etVisibale(boolean b):设置窗体是否可见。b为true时,表示可见;b为false时,表示不可见。
setDefaultCloseOperation(int operation):设置窗体的关闭方式,默认值为DISPOSE_ON_CLOSE。Java语言提供了多种窗体的关闭方式,常用的有4种,如表18.2所示。
表18.2 JFrame窗体关闭的几种方式
etVisibale(boolean b):设置窗体是否可见。b为true时,表示可见;b为false时,表示不可见。
setDefaultCloseOperation(int operation):设置窗体的关闭方式,默认值为DISPOSE_ON_CLOSE。Java语言提供了多种窗体的关闭方式,常用的有4种,如表18.2所示。
表18.2 JFrame窗体关闭的几种方式
【例18.1】第一个窗体程序
创建JFreamTest类,在JFreamTest类中创建一个内容为“这是一个JFrame窗体”的标签后,把这个标签添加到窗体中。
18.2.2 JDialog对话框
JDialog对话框继承了java.awt.Dialog类,其功能是从一个窗体中弹出另一个窗体,如使用IE浏览器时弹出的确定对话框。JDialog对话框与JFrame窗体类似,被使用时也需要先调用getContentPane()方法把JDialog对话框转换为容器,再对JDialog对话框进行设置。JDialog类常用的构造方法如下:
ublic JDialog():创建一个没有标题和父窗体的对话框。ublic JDialog(Frame f):创建一个没有标题,但指定父窗体的对话框。
ublic JDialog(Frame f, boolean model):创建一个没有标题,但指定父窗体和模式的对话框。如果model为true,那么弹出对话框后,用户无法操作父窗体。
ublic JDialog(Frame f, String title):创建一个指定标题和父窗体的对话框。
ublic JDialog(Frame f, String title, boolean model):创建一个指定标题、父窗体和模式的对话框。
【例18.2】在窗体中弹出对话框
创建MyJDialog类,使之继承JDialog窗体,在父窗体中添加按钮,当用户单击按钮时,弹出对话框。
18.2.3 JOptionPane小型对话框
Java API中的javax.swing.JOptionPane类是一个非常简便的小型对话框类,该类用于创建对话框的方法都是静态方法,无须创建对象即可弹出。在日常开发中经常使用该类弹出提示、确认用户需求、调试程序等。JOptionPane提供了4种创建对话框的方法
表18.3 JOptionPane类提供的4种创建对话框的方法
下面分别介绍这4种对话框的外观样式和使用方法。
1.自定义对话框
首先介绍一个自定义的对话框,这个对话框可以说是一块白板,开发者可以自行定义对话框中显示的元素。创建自定义对话框的方法如下:
arentComponent:指明对话框在哪个窗体上显示,如果传入具体的窗体对象,对话框会在该窗体居中位置显示,如果传入null则在屏幕中间弹出对话框。
message:提示的信息。
title:对话框的标题。
ptionType:指定可用于对话框的选项的整数:DEFAULT_OPTION、YES_NO_OPTION、YES_NO_CANCEL_OPTION或OK_CANCEL_OPTION。
essageType:指定消息种类的整数,主要用于确定来自可插入外观的图标:ERROR_MESSAGE、INFORMATION_MESSAGE、WARNING_MESSAGE、QUESTION_MESSAGE或PLAIN_MESSAGE。
con:在对话框中显示的图标。
ptions:指示用户可能选择的对象组成的数组。如果对象是组件,则可以正确呈现,非String对象使用其toString方法呈现;如果此参数为null,则由外观确定选项。
nitialValue:表示对话框的默认选择的对象,只有在使用options时才有意义,可以为null,则由外观确定选项。
nitialValue:表示对话框的默认选择的对象,只有在使用options时才有意义,可以为null。
【例18.3】弹出会话框,问用户准备好了吗
在自定义对话框中显示“你做好准备了吗?”,并添加两个JButton按钮,分别显示“是的”和“再想想”。
出带有选项Yes、No和Cancel的对话框;标题为Select an Option。
static int showConfirmDialog(Component parentComponent, Object message)
出一个由optionType参数确定其中选项数的对话框。
static int showConfirmDialog(Component parentComponent, Object message, String title, int optionType)
用一个由optionType参数确定其中选项数的对话框,messageType参数确定要显示的图标。
static int showConfirmDialog{Component parentComponent,
Object message,
String title,
int optionType,
int messageType}
出一个带有指定图标的对话框,其中的选项数由optionType参数确定。
static int showConfirmDialog{Component parentComponent,
Object message,
String title,
int optionType,
int messageType,
Icon icon}
【例18.4】弹出会话框,询问用户是否离开
弹出一个确认框,询问用户是否离开,提供“是”“否”“取消”3个按钮。
此确认框弹出效果,如图18.5所示。如果用户单击“是”按钮,变量answer获得的值为0;如果用户单击“否”按钮,变量answer获得的值为1;如果用户单击“取消”按钮,变量answer获得的值为2。
如果只想弹出“是”和“否”两个按钮,可以使用JOptionPane.YES_NO_OPTION类型,该类型对话框效果如图18.6所示。
3.输入框
输入框已经封装好了一套外观样式,弹出后要求用户在文本框中输入文本,用户完成输入操作后,输入框可以返回用户输入的结果。创建输入框的方法有以下几种重载形式:
示请求用户输入内容的问题消息对话框,它以parentComponent为父级。
static String showInputDialog(Component parentComponent, Object message)
示请求用户输入内容的问题消息对话框,它以parentComponent为父级。
static String showInputDialog(Component parentComponent, Object message, Object initialSelectionValue)
示请求用户输入内容的对话框,它以parentComponent为父级,该对话框的标题为title,消息类型为messageType。
static String showInputDialog(Component parentComponent, Object message, String title, int messageType)
示用户在可以指定初始选择、可能选择及其他所有选项的模块化的对话框中输入内容。
static Object showlnputDialog{Component parentComponent,
Object message,
String title,
int messageType,
Icon icon,
Object| selectionValues,
Object initialSelectionValue}
示请求用户输入的问题消息对话框。
static String showInputDialog(Object message)
示请求用户输入的问题消息对话框,它带有已初始化为initialSelectionValue的输入值。
static String showInputDialog(Object message, Object initialSelectionValue)
【例18.5】弹出会话框,让用户输入自己的姓名
弹出一个输入框,让用户输入自己的姓名。
出标题为Message的信息消息对话框。
static void showMessageDialog(Component parentComponent, Object message)
出对话框,它显示使用由messageType参数确定的默认图标的message。
static void showMessageDialog{Component parentComponent.
Object message,
String title,
int messageType}
出一个显示信息的对话框,为其指定了所有参数。
static void showMessageDialog{Component parentComponent
Object message,
String title,
int messageType,
Icon icon}
【例18.6】弹出警告对话框
弹出一个警告提示,告知用户已与服务器断开连接。
18.3 常用布局管理器
开发Swing程序时,在容器中使用布局管理器能够设置窗体的布局,进而控制Swing组件的位置和大小。Swing常用的布局管理器为绝对布局管理器、流布局管理器、边界布局管理器和网格布局管理器。
18.3.1 null绝对布局
绝对布局也叫null布局,其特点是硬性指定组件在容器中的位置和大小,组件的位置通过绝对坐标的方式来指定。使用绝对布局首先要使用Container.setLayout(null)方法取消容器的布局管理器,然后再使用Component.setBounds(int x, int y, int width, int height)方法设置每个组件在容器中的位置和大小。
【例18.7】使用绝对布局定位按钮位置和大小
创建继承JFrame窗体的AbsolutePosition类,设置布局管理器为绝对布局,在窗体中创建两个按钮组件,将按钮分别定位在不同的位置上。
使用绝对布局设置两个按钮在窗体中的位置
流布局(FlowLayout)管理器是Swing中最基本的布局管理器。使用流布局管理器摆放组件时,组件被从左到右摆放。当组件占据了当前行的所有空间时,溢出的组件会被移动到当前行的下一行。默认情况下,行组件的排列方式被指定为居中对齐,但是通过设置可以更改每一行组件的排列方式。
FlowLayout类具有以下常用的构造方法:
public FlowLayout()。
ublic FlowLayout(int alignment)。
ublic FlowLayout(int alignment,int horizGap,int vertGap)。
构造方法中的alignment参数表示使用流布局管理器时每一行组件的排列方式,该参数可以被赋予FlowLayout.LEFT、FlowLayout.CENTER或FlowLayout.RIGHT,这3个值的详细说明如表18.4所示。
表18.4 ailgnment参数值及其说明
在public FlowLayout(int alignment, int horizGap, int vertGap)构造方法中,还存在horizGap与vertGap两个参数,这两个参数分别以像素为单位指定组件与组件之间的水平间隔与垂直间隔。
【例18.8】使用流布局排列按钮
创建FlowLayoutPosition类,并继承JFrame类。设置当前窗体的布局管理器为流布局管理器,运行程序后调整窗体大小,查看流布局管理器对组件的影响。
18.3.3 BorderLayout边界布局管理器
使用Swing创建窗体后,容器默认的布局管理器是边界布局(BorderLayout)管理器,边界布局管理器把容器划分为东、南、西、北、中5个区域,如图18.11所示。
当组件被添加到被设置为边界布局管理器的容器时,需要使用BorderLayout类中的成员变量指定被添加的组件在边界布局管理器中的区域,BorderLayout类中的成员变量及其说明如表18.5所示。
如果使用了边界布局管理器,在向容器中添加组件时,如果不指定要把组件添加到哪个区域,那么当前组件会被默认添加到CENTER区域;如果向同一个区域中添加多个组件,那么后放入的组件会覆盖先放入的组件。
add()方法被用于实现向容器中添加组件的功能,它可以设置组件的摆放位置。add()方法常用的语法格式如下:
public void add(Component comp, Object constraints)
comp:被添加的组件。
onstraints:被添加组件的布局约束对象。
【例18.9】使用边界布局排列按钮
创建BorderLayoutPosition类,并继承JFrame类,设置该窗体的布局管理器为边界布局管理器,分别在窗体的东、南、西、北、中添加5个按钮。
网格布局(GridLayout)管理器能够把容器划分为网格,组件可以按行、列进行排列。在网格布局管理器中,网格的个数由行数和列数决定,且每个网格的大小都相同。例如,一个两行两列的网格布局管理器能够产生4个大小相等的网格。组件从网格的左上角开始,按照从左到右、从上到下的顺序被添加到网格中,且每个组件都会填满整个网格。改变窗体大小时,组件的大小也会随之改变。
网格布局管理器主要有以下两个常用的构造方法:
ublic GridLayout(int rows, int columns)。
ublic GridLayout(int rows, int columns, int horizGap, int vertGap)。
其中,参数rows和columns分别代表网格的行数和列数,这两个参数只允许有一个参数可以为0,被用于表示一行或一列可以排列任意多个组件;参数horizGap和vertGap分别代表网格之间的水平间距和垂直间距。
【例18.10】使用网格布局排列按钮
创建GridLayoutPosition类,并继承JFrame类,设置该窗体使用网格布局管理器,实现一个7行3列的网格后,向每个网格中添加按钮组件。
18.4 常用面板
在Swing程序设计中,面板是一个容器,被用于容纳其他组件,但面板必须被添加到其他容器中。Swing中常用的面板包括JPanel面板和JScrollPane面板。下面将分别予以讲解。
18.4.1 JPanel面板
JPanel面板继承java.awt.Container类。JPanel面板必须在窗体容器中使用,无法脱离窗体显示。
【例18.11】在一个窗体中显示4种布局风格的面板
创建JPanelTest类,并继承JFrame类。首先设置窗体的布局管理器为2行2列的网格布局管理器,然后创建4个面板,并为这4个面板设置不同的布局管理器,最后向每个面板中添加按钮。
JScrollPane面板是带滚动条的面板,被用于在较小的窗体中显示较大篇幅的内容。需要注意的是,JScrollPane滚动面板不能使用布局管理器,且只能容纳一个组件。如果需要向JScrollPane面板中添加多个组件,那么需要先将多个组件添加到JPanel面板,再将JPanel面板添加到JScrollPane滚动面板。
【例18.12】为窗体添加上下滚动条
创建JScrollPaneTest类,并继承JFrame类。首先初始化文本域组件,并指定文本域组件的大小;然后创建一个JScrollPane面板,并把文本域组件添加到JScrollPane面板;最后把JScrollPane面板添加到窗体。
18.5 文字标签组件与图标
在Swing程序设计中,标签(JLabel)被用于显示文本、图标等内容。在Swing应用程序的用户界面中,用户能够通过标签上的文本、图标等内容获得相应的提示信息。本节将对Swing标签的用法、如何创建标签和如何在标签上显示文本及图标等内容予以讲解。
18.5.1 JLabel标签
标签(JLabel)的父类是JComponent类。虽然标签不能被添加监听器,但是标签显示的文本、图标等内容可以被指定对齐方式。
通过JLabel类的构造方法,可以创建多种标签,如显示只有文本的标签、只有图标的标签以及同时包含文本和图标的标签等。JLabel类常用的构造方法如下:
ublic JLabel():创建一个不带图标或文本的标签。
ublic JLabel(Icon icon):创建一个带图标的标签。
ublic JLabel(Icon icon, int aligment):创建一个带图标的标签,并设置图标的水平对齐方式。
ublic JLabel(String text, int aligment):创建一个带文本的标签,并设置文本的水平对齐方式。
ublic JLabel(String text, Icon icon, int aligment):创建一个带文本和图标的JLabel对象,并设置文本和图标的水平对齐方式。
【例18.13】在窗体中显示文字标签
向JPanel面板中添加一个JLabel标签组件,在标签中显示“这是一个JFrame窗体”。
在Swing程序设计中,图标经常被添加到标签、按钮等组件,使用javax.swing.ImageIcon类可以依据现有的图片创建图标。ImageIcon类实现了Icon接口,它有多个构造方法,常用的如下:
ublic ImageIcon():创建一个ImageIcon对象,创建ImageIcon对象后,使用其调用setImage(Image image)方法设置图片。
ublic ImageIcon(Image image):依据现有的图片创建图标。
ublic ImageIcon(URL url):依据现有图片的路径创建图标。
【例18.14】在窗体中演示图标
创建MyImageIcon类,并继承JFrame类,在类中创建ImageIcon对象,首先使用ImageIcon对象依据现有的图片创建图标,然后使用public JLabel(String text, int aligment)构造方法创建一个JLabel对象,最后使用JLabel对象调用setIcon()方法为标签设置图标。
注意
java.lang.Class类中的getResource()方法可以获取本类(编译后的class文件)所在的完整路径。
18.6 按钮组件
在Swing程序设计中,按钮是较为常见的组件,被用于触发特定的动作。Swing提供了多种按钮组件:按钮、单选按钮、复选框等,本节将分别对这些按钮组件进行讲解。
18.6.1 JButton按钮
Swing按钮由JButton对象表示,JButton常用的构造方法如下:
ublic JButton():创建一个不带文本或图标的按钮。
ublic JButton(String text):创建一个带文本的按钮。
ublic JButton(Icon icon):创建一个带图标的按钮。
ublic JButton(String text, Icon icon):创建一个带文本和图标的按钮。
创建JButton对象后,如果要对JButton对象进行设置,那么可以使用JButton类提供的方法。JButton类的常用方法及其说明如表18.6所示:
表18.6 JButton类的常用方法及其说明
【例18.15】演示不同效果的按钮
创建JButtonTest类,并继承JFrame类,在窗体中创建按钮组件,设置按钮的图标,为按钮添加动作监听器。
Swing单选按钮由JRadioButton对象表示。在Swing程序设计中,需要把多个单选按钮添加到按钮组,当用户选中某个单选按钮时,按钮组中的其他单选按钮将不能被同时选中。
1.单选按钮
创建JRadioButton对象需要使用JRadioButton类的构造方法。JRadioButton类常用的构造方法如下:
ublic JRadioButton():创建一个未被选中、文本未被设定的单选按钮。
ublic JRadioButton(Icon icon):创建一个未被选中、文本未被设定,但具有指定图标的单选按钮。
ublic JRadioButton(Icon icon, boolean selected):创建一个具有指定图标、选择状态,但文本未被设定的单选按钮。
ublic JRadioButton(String text):创建一个具有指定文本,但未被选中的单选按钮。
ublic JRadioButton(String text, Icon icon):创建一个具有指定文本、指定图标,但未被选中的单选按钮。
ublic JRadioButton(String text, Icon icon, boolean selected):创建一个具有指定的文本、指定图标和选择状态的单选按钮。
根据上述构造方法的相关介绍,不难发现,单选按钮的图标、文本和选择状态等属性能够被同时设定。例如,使用JRadioButton类的构造方法创建一个文本为“选项A”的单选按钮,关键代码如下:
JRadioButton rbtn = new JRadioButton("选项A");
2.按钮组
Swing按钮组由ButtonGroup对象表示,多个单选按钮被添加到按钮组后,能够实现“选项有多个,但只能选中一个”的效果。ButtonGroup对象被创建后,可以使用add()方法把多个单选按钮添加到ButtonGroup对象中。例如,在应用程序窗体中定义一个单选按钮组,代码如下:
JRadioButton jr1 =new JRadioButton();
JRadioButton jr2 = new JRadioButton();
JRadioButton jr3 = new JRadioButton();
ButtonGroup group = new ButtonGroup(); //按钮组
group.add(jr1);
group.add(jr2);
group.add(jr3);
【例18.16】性别选择
创建RadioButtonTest类,并继承JFrame类,窗体中有男女两个性别可以选择,且只能选择其一。
18.6.3 JCheckBox复选框
复选框组件由JCheckBox对象表示。与单选按钮不同的是,窗体中的复选框可以被选中多个,这是因为每一个复选框都提供“被选中”和“不被选中”两种状态。JCheckBox的常用构造方法如下:
ublic JCheckBox():创建一个文本、图标未被设定且默认未被选中的复选框。
ublic JCheckBox(Icon icon, Boolean checked):创建一个具有指定图标、指定初始时是否被选中,但文本未被设定的复选框。
ublic JCheckBox(String text, Boolean checked):创建一个具有指定文本、指定初始时是否被选中,但图标未被设定的复选框。
【例18.17】打印用户的所选内容
创建CheckBoxTest类,并继承JFrame类,窗体中有3个复选框按钮和一个普通按钮,当单击普通按钮时,在控制台上分别输出3个复选框的选中状态。
18.7 列表组件
Swing中提供两种列表组件,分别为下拉列表框(JComboBox)与列表框(JList)。下拉列表框与列表框都是带有一系列列表项的组件,用户可以从中选择需要的列表项。列表框较下拉列表框更直观,它将所有的列表项罗列在列表框中。但是,下拉列表框较列表框更为便捷、美观,它将所有的列表项隐藏起来,当用户选用其中的列表项时才会显现出来。本节将详细讲解列表框与下拉列表框的使用。
18.7.1 JComboBox下拉列表框
初次使用Swing中的下拉列表框时,会感觉到Swing中的下拉列表框与Windows操作系统中的下拉列表框有一些相似,实质上两者并不完全相同,因为Swing中的下拉列表框不仅可以供用户从中选择列表项,也提供编辑列表项的功能。
下拉列表框是一个条状的显示区,它具有下拉功能,在下拉列表框的右侧存在一个倒三角形的按钮,当用户单击该按钮时,下拉列表框中的项目将会以列表形式显示出来。
下拉列表框组件由JComboBox对象表示,JComboBox类是javax.swing.JComponent类的子类。JComboBox类的常用构造方法如下:
ublic JComboBox(ComboBoxModel dataModel):创建一个JComboBox对象,下拉列表中的列表项使用ComboBoxModel中的列表项,ComboBoxModel是一个用于组合框的数据模型。
ublic JComboBox(Object[] arrayData):创建一个包含指定数组中的元素的JComboBox对象。
ublic JComboBox(Vector vector):创建一个包含指定Vector对象中的元素的JComboBox对象。Vector对象中的元素可以通过整数索引进行访问,而且Vector对象中的元素可以根据需求被添加或者移除。
JComboBox类的常用方法及其说明如表18.7所示。
表18.7 JComboBox类的常用方法及其说明
【例18.18】在下拉列表框中显示用户的所选内容
创建JComboBoxTest类,并继承JFrame类,窗体中有一个包含多个列表项的下拉列表框,当单击“确定”按钮时,把被选中的列表项显示在标签上。
列表框组件被添加到窗体中后,就会被指定长和宽。如果列表框的大小不足以容纳列表项的个数,那么需要设置列表框具有滚动效果,即把列表框添加到滚动面板。用户在选择列表框中的列表项时,既可以通过单击列表项的方式选择列表项,也可以通过“单击列表项+按住Shift键”的方式连续选择列表项,还可以通过“单击列表项+按住Ctrl键”的方式跳跃式选择列表项,并能够在非选择状态和选择状态之间反复切换。列表框组件由JList对象表示,JList类的常用构造方法如下:
ublic void JList():创建一个空的JList对象。ublic void JList(Object[] listData):创建一个显示指定数组中的元素的JList对象。
ublic void JList(Vector listData):创建一个显示指定Vector中的元素的JList对象。
ublic void JList(ListModel dataModel):创建一个显示指定的非null模型的元素的JList对象。
例如,使用数组类型的数据作为创建JList对象的参数,关键代码如下:
String[] contents = {"列表1","列表2","列表3","列表4"};
JList jl = new JList(contents);
再如,使用Vector类型的数据作为创建JList对象的参数,关键代码如下:
Vector contents = new Vector();
JList jl = new JList(contents);
contents.add("列表1");
contents.add("列表2");
contents.add("列表3");
contents.add("列表4");
【例18.19】在列表框显示用户的所选内容
创建JListTest类,并继承JFrame类,在窗体中创建列表框对象,当单击“确认”按钮时,把被选中的列表项显示在文本域上。
18.8 文本组件
文本组件在开发Swing程序过程中经常被用到,尤其是文本框组件和密码框组件。使用文本组件可以很轻松地操作单行文字、多行文字、口令字段等文本内容。
18.8.1 JTextField文本框
文本框组件由JTextField对象表示。JTextField类的常用构造方法如下:
ublic JTextField():创建一个文本未被指定的文本框。
ublic JTextField(String text):创建一个指定文本的文本框。
ublic JTextField(int fieldwidth):创建一个指定列宽的文本框。ublic JTextField(String text, int fieldwidth):创建一个指定文本和列宽的文本框。
ublic JTextField(Document docModel, String text, int fieldWidth):创建一个指定文本模型、文本内容和列宽的文本框。
如果要为一个文本未被指定的文本框设置文本内容,那么需要使用setText()方法。setText()方法的语法如下:
public void setText(String t)
其中,t表示文本框要显示的文本内容。
【例18.20】在文本框中显示默认文字并清除
创建JTextFieldTest类,并继承JFrame类,在窗体中创建一个指定文本的文本框,当单击“清除”按钮时,文本框中的文本内容将被清除。
18.8.2 JPasswordField密码框
密码框组件由JPasswordField对象表示,其作用是把用户输入的字符串以某种符号进行加密。JPasswordField类的常用构造方法如下:
ublic JPasswordField():创建一个文本未被指定的密码框。
ublic JPasswordFiled(String text):创建一个指定文本的密码框。
ublic JPasswordField(int fieldwidth):创建一个指定列宽的密码框。ublic JPasswordField(String text, int fieldwidth):创建一个指定文本和列宽的密码框。
ublic JPasswordField(Document docModel, String text, int fieldWidth):创建一个指定文本模型和列宽的密码框。
JPasswordField类提供了setEchoChar()方法,这个方法被用于改变密码框的回显字符。setEchoChar()方法的语法如下:
public void setEchoChar(char c)
其中,c表示密码框要显示的回显字符。
例如,创建JPasswordField对象,并设置密码框的回显字符为“#”。关键代码如下:
JPasswordField jp = new JPasswordField();
jp.setEchoChar('#'); //设置回显字符
那么,如何获取JPasswordField对象中的字符呢?关键代码如下:
JPasswordField passwordField = new JPasswordField() //密码框对象
char ch[] = passwordField.getPassword(); //获取密码字符数组
String pwd = new String(ch); //将字符数组转换为字符串
18.8.3 JTextArea文本域
文本域组件由JTextArea对象表示,其作用是接受用户的多行文本输入。JTextArea类的常用构造方法如下:
ublic JTextArea():创建一个文本未被指定的文本域。
ublic JTextArea(String text):创建一个指定文本的文本域。
ublic JTextArea(int rows,int columns):创建一个指定行高和列宽,但文本未被指定的文本域。
ublic JTextArea(Document doc):创建一个指定文档模型的文本域。
ublic JTextArea(Document doc,String Text,int rows,int columns):创建一个指定文档模型、文本内容以及行高和列宽的文本域。
JTextArea类提供了一个setLineWrap(boolean wrap)方法,这个方法被用于设置文本域中的文本内容是否可以自动换行。如果参数wrap的值为true,那么文本域中的文本内容会自动换行;否则不会自动换行。
此外,JTextArea类还提供了一个append(String str)方法,这个方法被用于向文本域中添加文本内容。
【例18.21】在文本域中显示默认文字
创建JTextAreaTest类,并继承JFrame类,在窗体中创建文本域对象,设置文本域自动换行,向文本域中添加文本内容。
18.9 表格组件
Swing表格由JTable对象表示,其作用是把数据以表格的形式显示给用户。本节将对Swing表格组件进行讲解。
18.9.1 创建表格
JTable类除提供了默认的构造方法外,还提供了被用于显示二维数组中的元素的构造方法,这个构造方法的语法如下:
JTable(Object[][] rowData, Object[] columnNames)
owData:存储表格数据的二维数组。
olumnNames:存储表格列名的一维数组。
在使用表格时,要先把表格添加到滚动面板,再把滚动面板添加到窗体的相应位置。
【例18.22】创建带滚动条的表格
利用构造方法JTable(Object[][] rowData, Object[] columnNames)创建一个具有滚动条的表格。
18.9.2 DefaultTableModel表格数据模型
Swing使用TableModel接口定义了一个表格模型,AbstractTableModel抽象类实现了TableModel接口的大部分方法,只有以下3个抽象方法没有实现:
public int getRowCount();
ublic int getColumnCount();
ublic Object getValueAt(int rowIndex, int columnIndex);
为了实现使用表格模型创建表格的功能,Swing提供了表格模型类,即DefaultTableModel类。DefaultTableModel类继承了AbstractTableModel抽象类且实现了上述3个抽象方法。DefaultTableModel类提供的常用构造方法如表18.8所示。
表18.8 DefaultTableModel类提供的常用构造方法
表格模型被创建后,使用JTable类的构造方法JTable(TableModel dm)即可创建表格。表格被创建后,还可以使用setRowSorter()方法为表格设置排序器:当单击表格的某一列的列头时,在这一列的列名后将出现▲标记,说明将按升序排列表格中的所有行;当再次单击这一列的列头时,标记将变为▼,说明按降序排列表格中的所有行。
【例18.23】表格自动排序
利用表格模型创建表格,并对表格使用表格排序器。
18.9.3 维护表格模型
表格中的数据内容需要予以维护,如使用getValueAt()方法获得表格中某一个单元格的值,使用addRow()方法向表格中添加新的行,使用setValueAt()方法修改表格中某一个单元格的值,使用removeRow()方法从表格中删除指定行等。
注意
当删除表格模型中的指定行时,每删除一行,其后所有行的索引值将相应地减1,所以当连续删除多行时,需要注意对删除行索引的处理。
【例18.24】对表格内容进行增删改查
维护表格模型。本例通过维护表格模型,实现向表格中添加新的数据行、修改表格中某一单元格的值以及从表格中删除指定的数据行。
18.10 事件监听器
前文中一直在讲解组件,这些组件本身并不带有任何功能。例如,在窗体中定义一个按钮,当用户单击该按钮时,虽然按钮可以凹凸显示,但在窗体中并没有实现任何功能。这时需要为按钮添加特定的事件监听器,该监听器负责处理用户单击按钮后实现的功能。本节将着重讲解Swing中常用的3种事件监听器,即动作事件监听器、键盘事件监听器、鼠标事件监听器。
18.10.1 ActionEvent动作事件
动作事件(ActionEvent)监听器是Swing中比较常用的事件监听器,很多组件的动作都会使用它监听,如按钮被单击等。表18.9描述了动作事件监听器的接口与事件源等。
表18.9 动作事件监听器
下面以单击按钮事件为例来说明动作事件监听器,当用户单击按钮时,将触发动作事件。
【例18.25】单击按钮后,修改按钮文本
创建SimpleEvent类,使该类继承JFrame类,在类中创建按钮组件,为按钮组件添加动作监听器,然后将按钮组件添加到窗体中。
点击后:
在本实例中,为按钮设置了动作监听器。由于获取事件监听时需要获取实现ActionListener接口的对象,所以定义了一个内部类jbAction实现ActionListener接口,同时在该内部类中实现了actionPerformed()方法,也就是在actionPerformed()方法中定义当用户单击该按钮后实现怎样的功能。
18.10.2 KeyEvent键盘事件
当向文本框中输入内容时,将发生键盘事件。KeyEvent类负责捕获键盘事件,可以通过为组件添加实现了KeyListener接口的监听器类来处理相应的键盘事件。
KeyListener接口共有3个抽象方法,分别在发生击键事件(按下并释放键)、按键被按下(手指按下键但不松开)和按键被释放(手指从按下的键上松开)时被触发,具体如下:
public interface KeyListener extends EventListener {
public void keyTyped(KeyEvent e); /1发生击键事件时被触发
public void keyPressed(KeyEvent e); //按键被按下时被触发
public void keyReleased(KeyEvent e); /1按键被释放时被触发}
在上述每个抽象方法中,均传入了KeyEvent类的对象。KeyEvent类中比较常用的方法如表18.10所示。
表18.10 KeyEvent类中的常用方法
在KeyEvent类中,以“VK_”开头的静态常量代表各个按键的keyCode,可以通过这些静态常量判断事件中的按键,获得按键的标签。
【例18.26】虚拟键盘
通过键盘事件模拟一个虚拟键盘。首先需要自定义一个addButtons()方法,用来将所有的按键添加到一个ArrayList集合中,然后添加一个JTextField组件,并为该组件添加addKeyListener事件监听,在该事件监听中重写keyPressed()和keyReleased()方法,分别用来在按下和释放键时执行相应的操作。关键代码如下:
18.10.3 MouseEvent鼠标事件
所有组件都能发生鼠标事件,MouseEvent类负责捕获鼠标事件,可以通过为组件添加实现了MouseListener接口的监听器类来处理相应的鼠标事件。
MouseListener接口共有5个抽象方法,分别在光标移入或移出组件、鼠标按键被按下或释放和发生单击事件时被触发。所谓单击事件,就是按键被按下并释放。需要注意的是,如果按键是在移出组件之后才被释放,则不会触发单击事件。MouseListener接口的具体定义如下:
public interface MouseListener extends EventListener {
public void mouseEntered(MouseEvent e); //光标移入组件时被触发public void mousePressed(MouseEvent e); //鼠标按键被按下时被触发public void mouseReleased(MouseEvent e); //鼠标按键被释放时被触发public void mouseClicked(MouseEvent e); //发生单击事件时被触发public void mouseExited(MouseEvent e); //光标移出组件时被触发}
在上述每个抽象方法中,均传入了MouseEvent类的对象。MouseEvent类中比较常用的方法如表18.11所示。
表18.11 MouseEvent类中的常用方法
当需要判断触发此次事件的按键时,可以通过表18.12中的静态常量判断由getButton()方法返回的int型值代表的键。
表18.12 MouseEvent类中代表鼠标按键的静态常量
【例18.27】捕捉鼠标在窗体中的行为
创建一个窗体,在窗体中捕捉鼠标进入、移出和点击事件,关键代码如下: