admin 管理员组

文章数量: 1086019


2024年3月9日发(作者:谈谈自己对数据库的理解)

第4章 图形用户界面设计

本章要点

 Java图形用户界面设计的基本知识

 布局管理器的应用

 Java常用图形用界面设计组件的应用

 Java常用组件事件处理的应用

4.1 认识AWT包和Swing包

用户界面是计算机用户与软件之间的交互接口。一个功能完善,使用方便的用户界面可以使软件的操作更加简单,使用户与程序之间的交互更加有效。因此图形用户界面(graphics

user interface,GUI)的设计和开发已经成为软件开发中的一项重要的工作。

Java语言提供的开发图形用户界面(GUI)的功能包括AWT(Abstract Window Toolkit)和Swing两部分。这两部分功能由Java的两个包来完成-awt和swing。虽然这两个包都是用于图形用户界面的开发,但是它们不是同时被开发出来了。awt包是最早被开发出来的。但是使用awt包开发出来的图形用户界面并不完美,在使用上非常的不灵活。比如awt包所包含的组件,其外观是固定的,无法改变,这就使得开发出来的界面非常死板。这种设计是站在操作系统的角度开发图形用户界面,主要考虑的是程序与操作系统的兼容性。这样做的最大问题就是灵活性差,而且程序在运行时还会消耗很多系统资源。

由于awt包的不足表现,SUN公司于1998年针对它存在的问题,对其进行了扩展,开发出了Swing,即swing包。但是,SUN公司并没有让swing包完成替代awt包,而是让这两个包共同存在,互取所需。awt包虽然存在缺点,但是仍然有可用之处,比如在图形用户界面中用到的布局管理器、事件处理等依然采用的是awt包的内容。

Java有两个主要类库分别是Java包和Javax包。在Java包中存放的是Java语言的核心包。Javax包是Sun公司提供的一个扩展包,它是对原Java包的一些优化处理。

swing包由于是对awt包的扩展和优化,所以是存放在Javax包下的,而awt包是存放在Java包下的。虽然swing是扩展包,但是,现在的图形用户界面基本都是基于swing包开发的。

swing包的组件大部分是采用纯Java语言进行开发的,这就大大增加了组件的可操作性,尤其是组件的外观。通常情况下,只要通过改变所传递的参数的值,就可以改变组件的外观。而且swing包还提供Look and Feel功能,通过此功能可以动态改变外观。Swing包中也有一些组件不是用纯Java语言编写的,这些组件一般用于直接和操作系统进行交互的。

4.2 布局管理器

在本节中将对图形用户界面中的布局管理器进行介绍。

【任务1】认识图形用户界面。

1.

基础知识

先来看一个用Java语言编写的图形用户界面的例子,如图4-1所示。

图4-1 一个图形用户界面

图4-1是一个帮助文件的用户界面。通过这个界面,我们来介绍三个与图形用户界面有关的术语。

(1) 组件:构成图形用户界面的各种元素称为组件。图4-1中,放在“帮助窗口”中的每个一信息都是一个组件。例如“确定”按钮就是一种组件。

(2) 容器:是图形用户界面中容纳组件的部分,一个容器可容纳一个或多个组件,甚至可以容纳其他容器。窗口就是一种容器。例如图4-1中的组件全部都是放在“帮助窗口”这个容器中的。容器与组件的的关系就像杯子和水的关系。需要说明的是,容器也可以被称为组件。

(3) 布局管理器:组件在被放到容器中时,要遵循一定的布局方式。在Java的图形用户界面中,有专门的类来管理组件的布局,称这些类为布局管理器。在“帮助窗口”中每一条信息都是一个组件,这些组件应该如何安排就是由布局管理器负责的。所谓的布局管理器,实际上就是能够对组件进行布局管理的类。

用吃饭的例子就能很好的说明这三个术语之间的关系。容器就是吃饭的桌子,组件就是一盘盘的菜。我们放菜的时候总要安排一下哪个菜应该放在什么位置,这就是布局管理器。

2.

任务实施

本任务的代码内容如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

import .*;

import .*;

public class FrameEx

{

public void go()

{

JFrame win = new JFrame("帮助窗口");

Container contentPane = tentPane();

out(new GridLayout(5,1));

JLabel labOne = new JLabel("计算机基础模拟练习系统的1.0",);

JLabel labTwo = new JLabel("北京信息职业技术学院",);

JLabel labThree = new JLabel("软件工程系制作",);

JLabel labFour = new JLabel("(c)版权所有2010年6月",);

JButton queding = new JButton("确定");

15

16

17

18

19

20

21

22

23

24

25

26

27

(labOne);

(labTwo);

(labThree);

(labFour);

(queding);

e(200,200);

ible(true);

}

public static void main(String arg[]){

FrameEx fe = new FrameEx();

();

}

}

3.

分析与提高

(1) 第1行和第2行的作用就是将awt包和swing包引入到该程序中,因为该程序中要用到awt包和swing包中的类。例如第8行用到的Container类和第9行的GridLayout类都属于awt包。其他以“J”开头的类都属于swing包。这样做的目的很容易理解。例如,Containe类是Java语言的开发者事先定义好的类。关于这个类的一些功能也是设定好的。作为使用者,只要将这个类用import的方式引入到自己的程序中就可以使用它了。这两个包的引用会在图形用户界面的程序中经常用到。

(2) 第7行定义的是一个窗口。第8行是开发图形用户界面必须要用到的类,这个类的作用会在后面的章节进行更详细的解释。

(3) 第9行是对窗口进行了布局管理器设置,通过GridLayout布局管理器,将窗口划分成5行,1列。

(4) 第10行至第13行定义了窗口要显示的信息。

(5) 第14行定义了“确定”按钮。

(6) 第15至第19行是将定义好的组件放入到窗口中。

(7) 第20行定义了窗口的初始大小。

(8) 第21行定义了窗口的可显示性。

(9) 第24行和第25行是FrameEx类的对象,并通过这个对象调用go()方法,使这个帮助窗口运行起来。

在此只对程序进行粗略解释,目的只是让读者对图形用户界面有个初步的认识。在后面的任务中会逐个对各种组件和它们的应用进行详细介绍。

4.2.1 FlowLayout布局管理器应用

【任务2】认识FlowLayout布局管理器。

1.

基础知识

FlowLayout是一个最简单的布局管理器,这个布局管理器的功能就是将容器中的组件从左到右,从上到下的排列。因此,它又被称为流布局管理器。例如图4-1中,帮助窗口共有五个组件。它们在窗口中的排列方式是5行,1列。如果采用FlowLayut布局管理器,那

么窗口的执行结果应该是图4-2的样式。所有组件是按照添加时的顺序,按从左到右,从上到下的顺序排列的。默认情况下,第一个被添加的组件摆放在第1行居中位置,其后添加的组件摆放在第一个组件的后面。当第1行再也放不下组件的时候,其后的组件从第2行开始从左到右摆放。以此类推,直到添加完所有组件。

图4-2 FlowLayout布局管理器

2.

任务实施

任务1中的第9行就是对窗口布局的设置语句。语句如下:

out(new GridLayout(5,1));

只要对这一行进行更改,就可以达到应用FLowLayout布局管理器的目的。

contentPane是一个对象,它指向的是Container类。关于这个类的含义和作用会在以后的章节中详细讲解。读者暂时只需要知道contentPane引用是指向所建立的“帮助窗口”就可以了。

从contentPane所调用的setLayout()方法的方法名的含义就可以知道这个方法的作用—设置(set)布局(layout)。通过对这个方法的参数赋予不同布局管理器的引用,达到对窗口进行布局设置的目的。

要实现将“帮助窗口”的布局管理器设置为FlowLayout,只需要做如下的更改。

out(new FlowLayout());

其中的参数new FlowLayout()实际上是FlowLayout类的一个引用。这条语句的含义就是:将contentPane所指向窗口的布局管理器设置成FlowLayout。

还有另外一种设置布局管理器的方法。如下语句所示。

语句1:FlowLayout flow= new FlowLayout();

语句2:out(flow);

语句1创建了FlowLayout布局管理器的引用。语句2将语句1所创建的flow引用作为参数传递给setLayout ()方法。

flow引用等价于new FlowLayout()。因此,语句out(new FlowLayout())实际上是语句1和语句2的组合写法。

3.

分析与提高

FlowLayout布局管理器是Panel和Applet容器的默认局管理器。如果不专门对Panel和Applet进行布局管理器设置的话,它们的组件的布局将按FlowLayout进行管理。Panel和Applet都是一种容器。Panel和窗口很类似,Applet是嵌在浏览器中使用的一种客容器。这两个容器会在后面的章节中介绍。

FlowLayout布局管理器对窗口中的组件的管理是与窗口的大小有关的。在任务1中有如下的语句:

e(200,200);

这条语句设置了窗口的初始值大小。第一个参数为窗口的宽度,第二个参数为窗口的高度。FlowLayout布局管理器会根据这个大小来摆放组件。如果我们使用拖动的方法,改变窗口的大小,窗口中组件的排列方式也会跟着改变。

每个组件也有自己的初始大小。当窗口设置的宽度小于组件的初始宽度时,窗口宽度会自动变为组件的宽度,但窗口高度不会改变。

在摆放组件时,如果不设定组件的对齐方式,那么FlowLayout布局管理器是按居中对齐的方式摆放组件的。也可以通过向FlowLayout构造方法传递参数的方式设置所需的对齐方式。FlowLayout布局管理器的对齐方式有:、NG和G。分别表示居中对齐、右对齐和左对齐。

设置的方法如下面的语句所示:

out(new FlowLayout(G));

这语句可以将组件的对齐方式设置为左对齐

还可以设置组件之间的水平和垂直间距。

设置的方法如下面的语句所示:

out(new FlowLayout(G , 50 , 50));

这条语句的含义就是将组件间的水平和垂直间距都设置为50。

4.2.2 BorderLayout布局管理器应用

【任务3】认识BorderLayout布局管理器。

1.

基础知识

BorderLayout又称边界布局管理器,它将窗口划分为上北、下南、左西、右东和中央五个区域,分别用参数、、、和来表示。在窗口中添加组件时,系统会根据参数将组件摆放到窗口的相应位置。如图4-3所示。

图4-3 BorderLayout布局管理器

如果某个区域没有摆放组件,则其他组件会占用此位置。规则如下:

当上北或下南没有摆放组件时,左西、右东和中央的组件会占用上北或下南的位置。

当左西或右东没有摆放组件时,上北、下南和中央的组件会占用左西或右东的位置。

当上北、下南、左西和右东都没有摆放组件时,中央的组件会占用这些位置。

当中央位置没有摆放组件时,位置被空缺,其他位置的组件不会占用中央的位置。

2.

任务实施

通过setLayout()方法可以完成BorderLayout布局管理器的设置,语句如下:

out(new BorderLayout());

在添加组件时,要对组件摆放的位置进行说明。语句如下:

(queding,);

此语句的含义是将queding按钮摆放在窗口的中央位置。

如果在添加组件时不进行位置说明,系统则默认将组件放在中央位置的。当添加的组件大于一个时,只有最后添加的组件被显示。

3.

分析与提高

BorderLayout是Frame容器的默认布局管理器。当Frame容器中没有指定布局管理器时,系统就会默认采用BorderLayout布局管理器。

采用BorderLayout布局管理器还可以设置组件之间的间距。格式如下:

new BorderLayout(int hGap,int vGap);

参数hGap和vGap分别表示组件之间的水平间距和垂直间距。如果不指定组件间的间距,则组件之间没有间距。

指定组件位置还有另外一组参数值,分别是_START、_END、_START、_END和。这两组参数的对应关系如表4-1表示。

表4-1 两组位置参数对照表

参数组1

NORTH

SOUTH

WEST

EAST

CENTER

PAGE_START

PAGE_END

LINE_START

LINE_END

CENTER

参数组2

这两组参数在使用时没有区别,读者可以根据习惯使用。参数组1相对参数组2要好记忆一些。

4.2.3 GridLayout布局管理器应用

【任务4】认识GridLayout布局管理器。

1.

基础知识

GridLayout又称网格布局管理器。相对于FlowLayout和BorderLayout来说,GridLayout布局管理器是比较灵活的一种管理器。它可以通过行数和列数的设置,把窗口划分成若干个单元格,将组件放在这些单元格里。任务1中采用的就是这种布局管理器。

2.

任务实施

任务1将窗口设置为5行1列的表格,各个组件分别放在这个表格中的五个单元格中。这种布局的设置通过语句out(new GridLayout(5,1))实现的。

GridLayout的括号中两个参数的含义就是(行数,列数)。通过改变这两个参数的值,将窗口划分成不同的单元格。

3.

分析与提高

GridLayout布局管理器也可以不设置行数和列数,这时系统会默认行数和列数均为1。

GridLayout布局管理器同样可以对组件之间的间距进行设置。格式如下:

new GridLayout(int rows,int columns,int hGap,int vGap)

rows和columns分别表示行数和列数。hGap和vGap分别表示组件之间的水平间距和垂直间距。

如果要摆放的组件大于GridLayout所设置的单元格个数,多出来的组件也会被摆放在窗口中,但是会破坏原来的单元格样式。

4.2.4 自定义布局管理器的应用

【任务5】认识自定义布局管理器。

1.

基础知识

FlowLayout、BoderLayout和GridLayout布局管理器有一个共同的特点就是布局是固定的。因此组件的摆放也就被固化了。比如BorderLayout只能把组件摆放在五个区域内,不可能有第六个区域。然后有很多界面中的组件摆放非常灵活。虽然GridLayout可以将窗口设置成不同的单元格,但是碰到组件摆放没有规律可寻的情况时,也会无能为力。有时候,为了达到窗口中组件的不规则摆放,需要对这三种布局管理器进行综合应用,实现起来非常麻烦。于是,Java就提供了一种不使用布局管理器的方法,即自定义布局。

这种方法的理念是这样的:所有图形用户界面都是平面的,界面上的每个点都可以用x和y两个坐标来确定。在一个界面上如果选取一个点,再确定好要摆放组件的宽度和高度,就可以确定出一个区域。如图4-4所示。

图4-4 一个平面中两点坐标确定一个区域

(10,30)是起始坐标。80和40是组件的宽度和高度,从而确定出一个区域,就可以把一个组件放在这个区域中。这样的布局方式就非常灵活,可以根据需要在窗口的任意位置摆放组件。事先只要给每个组件在窗口中确定一个摆放的位置就可以了。这时的布局不是针对窗口的了,而是针对每一个组件。例如,一个“确定”按钮。我们给它起个名字叫button。下面的语句就可以在窗口中设置出用于摆放该按钮的区域。

nds(10,30,80,40);

setBounds是设置(set)边界(bound)的意思。因此这条语句的含义就是将宽度为80,高度为40的button放在以坐标(10,30)为起始点的区域中。

2.

任务实施

本任务的代码内容如下:

1 import .*;

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

import .*;

public class FrameEx

{

public void go()

{

JFrame win = new JFrame("帮助窗口");

Container contentPane = tentPane();

out(null);

JButton queding = new JButton("确定");

nds(10, 30, 80, 40);

(queding);

e(200,200);

ible(true);

}

public static void main(String arg[]){

FrameEx fe = new FrameEx();

();

}

}

这段代码是对任务1的代码进行了部分修改得出的。只保留任务1中的“确定”按钮组件,并利用自定义布局方式将这个按钮摆放在窗口中。

3.

分析与提高

(1) 第9行将窗口的布局管理器设置为null。意思就是这个窗口不使用布局管理器。既然要应用自定义的布局,就应该将容器原有的布局管理器去掉。虽然我们可以不进行布局管理器设置,但是每种容器都有默认的布局管理器,因此,必须将这种默认值去掉,自定义的布局才能发挥作用。比如这段程序采用是JFrame容器,这种容器属于Frame容器。Frame容器的默认布局管理器是BorderLayout。必须通过第9行的方法,使BorderLayout布局管理器不起作用,才能达到自定义布局的效果。

(2) 第11行设置了“确定”按钮在窗口中的坐标位置。其中前两组参数表示按钮左上角的坐标,后两组参数确定了组件的宽度和高度。

(3) 第12行将“确定”按钮添加到窗口时,会按照第11行确定的区域进行摆放。需要注意的是,组件的宽度和高度要设计得合理,否则,可能会使组件不能完全显示或者出现显示变形。

4.3 常用组件和事件处理

这一节将介绍一些在设计图形用户界面时常用的组件,以及与这些组件有关的事件处理。

4.3.1 学习JFrame和JPanel的使用

JFrame和JPanel都属于swing包下的类,它们都是容器组件。Swing对AWT进行了扩展,增加了awt包下组件的功能,为了与原来组件进行区别,在swing包下的所有组件名称

都在原来名字的前面加了一个“J”。 因此,在Java的图形用户界面中,以“J”为首字母的组件都归属于swing包。在awt包下有Frame和Panel组件,JFrame和JPanel就是对它们进行扩展得到的。

【任务6】利用JFrame组件建立一个窗口。

1.

基础知识

JFrame是Java图形用户界面中最底层的容器之一。前面的章节中,曾用吃饭的例子来比喻容器,组件和布局管理器之间的关系。JFrame就相当于“桌子”, 它可以用来容纳用户界面中的所有组件。

JFrame在图形用户界面中的表现形式就是窗口。

通过JFrame创建窗口的常用方式有两种:

方式一:JFrame 对象名 = new JFrame();

方式二:JFrame 对象名 = new JFrame(String s);

窗口在标题栏部分都会显示其提示性信息,以表明这个窗口的作用。方法二可以实现这一功能。其中String s就是用于存放标题栏要显示的信息的参数。

语句JFrame win = new JFrame(“帮助窗口”)的含义是:创建名字为win的JFrame窗口,标题栏要显示的信息为“帮助窗口”。

用方式一创建的窗口,标题栏内容为空。

JFrame类包括一些方法,这些方法帮助我们完成与窗口有关的操作。

(1) 设置窗口大小的方法

pack()和setSize(w,h)都可以用于控制窗口的大小。pack()方法会根据所容纳的组件自定义窗口的大小。setSize(w,h)方法设置的窗口大小是固定的,不受组件的影响。如果设置的窗口小于组件大小,会出现部分组件不能显示的情况。这种情况在使用pakc()方法时不会出现。

以上两种方法设置的窗口默认显示在屏幕的左上角。如果要改变初始显示的位置就要用setBounds(x,y,w,h)方法。这个方法不但可以设置窗口的大小,而且可以设置窗口在屏幕上显示的位置。其中x和y是设置窗口在屏幕上显示的起始坐标,w和h是设置窗口的大小。

(2) 标题设置方法

通过setTitle(String s)方法可以设置窗口的标题。例如,le(“提示信息”),这条语句可以将win所指向的窗口标题设置为“提示信息”。

(3) 设置窗口前景色和背景色方法

方法setForeground(Color c)用于设置窗口前景色。方法setBackground(Color c)用于设置窗口背景色。这两个方法的参数都是颜色参数,Color是专门用于处理颜色的类。

下面的语句是将win指向的窗口背景色设置为蓝色。

kground();

(4) 显示窗口方法

对窗口进行各种设置后,需要执行setVisible(boolean b)方法,将窗口显示在屏幕上。其中的参数是布尔值。当参数值为true时,显示窗口;当参数值为false时,不显示窗口。show()方法也可以实现显示窗口的功能,它与setVisible(boolean b)方法在应用上没有区别。

2.

任务实施

以下程序创建了一个不含任何组件的窗口。

1

2

import .*;

import .*;

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

public class FrameEx

{

public void go()

{

JFrame win = new JFrame("帮助窗口");

e(200,200);

//();

//nds(50,50,200,200);

ible(true);

//();

}

public static void main(String arg[]){

FrameEx fe = new FrameEx();

();

}

}

这段程序的执行结果如图4-5所示。

图4-5 不包含组件的窗口

3.

分析与提高

(1) 第1行和第2行是引用语句。

(2) 第7行是最关键的。JFrame win = new JFrame("帮助窗口"); 它创建了一个名字为win,标题为“帮助窗口”的窗口。

(3) 第8行e(200,200)的作用就是设置这个窗口有多大,参数的含义是(宽度,高度)。这句话的含义就是将win这个窗口的大小(size)设置(set)为宽200,高200。

(4) 第9行和第10行被注释掉的。这两条语句同样是用于设置窗口大小。读者自行实验,尝试采用三种窗口大小设置方法的不同。

(5) 第11行ible(true)中,setVisible的含义就是设置(set)显示(visible)状态。显示状态只有两种:显示(true)和不显示(false)。所以第11行的含义就是将win窗口的显示状态设置为显示。只有参数是true的时候,才会看到图4-5的窗口。

(6) 第12行被注释掉的语句,这条语句同第11行的作用一样,用于显示窗口。

【任务7】在窗口中加入JPanel容器,将窗口划分成两个区域。

1.

基础知识

(1) JPanel的应用与JFrame几乎完全一样,JFrame能容纳的组件都能摆放在JPanel容器中。在布局管理器的应用上也是一样的。但是不同的是JFrame可以独立应用,而JPanel只能依附于JFrame才能应用。也就是说,如果想应用JPanel的话,之前必须有一个JFrame建立的容器存在,才可以在这个已经存在的容器上再应用JPanel。

(2) JPanel是隐性显示的。它并不像JFrame建立的窗口那样可以显示出来。利用这一特点,就可以在JFrame建立的窗口上应用若干个JPanel,把JFrame制作出来的容器划分成若干个区域,每个区域都可以独立应用。这样做的目的显而易见。如果在JFrame制作出来的窗口中只用到一种布局管理器,是没有必要再用JPanel的,但是如果要在一个窗口中以不同的布局方式摆放组件,就要用到JPanel了。因为JPanel可以独立应用,就可以让一个窗口具有更多的布局方式,使窗口的组件摆放更加灵活。

(3) 创建JPanel的常用方式有两种。

(4) 方式一:JPanel 对象名 = new JPanel();

(5) 方式二:JPanel 对象名 = new JPanel(布局管理器);

(6) 应用方式二创建JPanel时,同时就可以设置它的布局管理器。如下面的语句:

JPanel jp = new JPanel(new FlowLayout());

2.

任务实施

本任务的代码内容如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

import .*;

import .*;

public class FrameEx

{

public void go()

{

JFrame win = new JFrame("帮助窗口");

JPanel jpOne = new JPanel();

JPanel jpTwo = new JPanel();

out(new GridLayout(2,1));

(jpOne);

(jpTwo);

e(200,200);

ible(true);

}

public static void main(String arg[]){

FrameEx fe = new FrameEx();

();

}

}

程序的执行结果同图4-5一样。但是,这个窗口已经被分为上下两个区域,分别被jpOne和jpTwo容器占用。之所以看不出变化,是因为JPanel是隐性显示的。

图4-6更加详尽的说明了JPanel的应用情况。窗口应用了两个JPanel,划分出两个区域,上面的区域应用了GridLayout布局管理器,把这个区域划分成了两行两列。下面的区域应用了BorderLayout布局处理器。

图4-6 应用了JPanel的窗口

3.

分析与提高

(1) 第8行和第9行创建了两个JPanel容器。

(2) 第10行利用GridLayout布局管理器将窗口划分成2行1列。准备摆放两个JPanel容器。

(3) 第11行和第12行将两个JPanel容器放入窗口中。

4.3.2 使用标签、按钮、复选框和单选框表组件制作调查问卷

在本节中上,在前面任务所学知识的基础上,结合本节的新知识,通过4个任务来完成一个调查问卷程序。

【任务8】

设计调查问卷的布局,并加入一个醒目的标题。

1.

基础知识

在窗口中经常会出现一些说明或提示性的信息,这些信息大多是文字,有时候也可能是图片。Java不允许将方字或图片直接显示在容器中。这些文字或图片性质的信息要借助组件显示在窗口中。能够实现这一功能的组件被称做标签。任务中提到的“标题”实际上就是调查问卷的“卷头”,它就可以用标签来实现。

JLabel是swing包中专门创建标签组件的类。

创建标签的方式有几种,这里只介绍常用的四种。

方式一:JLabel 对象名 = new Jlabel(String s);

方式二:JLabel 对象名 = new Jlabel(String s,int hAlignment);

方式三:JLabel 对象名 = new Jlabel(ImageIcon image);

方式四:JLabel 对象名 = new Jlabel(ImageIcon image,int hAlignment);

方式一和方式二是显示文字性信息时应用的标签。参数s用于存放要显示的信息,参数hAlignment是设置所显示的信息的对齐方式。共有五种对齐方式:、、、和,分别表示底端对齐、左对齐、右对齐、顶端对齐和居中对齐。采用方式一创建的标签,文字的对齐方式默认为左对齐。

方式三和方式四是显示图片信息时应用的标签。参数image是图片对象的引用。ImageIcon是Java处理图片的类。hAlignment是设置所显示的图片的对齐方式。也有五种,同文字采用的对齐式一样。采用方式三创建的标签,图片的对齐方式默认为左对齐。

2.

任务实施

首先要为这个调查问题设计一个布局。如图4-7所示。

调查问卷标题

调查问卷内容

…………

…………

…………

提交按钮

图4-7 调查问卷布局

这种布局设计与BorderLayout布局管理器所对应的布局形式有些接近。如图4-8所示。

图4-8 BorderLayout布局管理器布局形式

调查问卷的标题部分可以放在“North”,调查问卷内容部分放在“Center”,提交按钮可以放在 “South”。“West”和“East”舍弃不用。有的读者可能会想到用GridLayout布局管理器。从调查问卷的布局设计来看,是典型的n行1列。但是,用BorderLayout布局管理器的显示效果要好于GridLayout布局管理器。

布局设计好后,就要解决如何加入一个标题的问题。将调查问卷的标题设计成“基本情况调查表”的字符串。加入到窗口后的效果如图4-9所示。

图4-9 添加了标签的调查问卷

本任务的代码内容如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

import .*;

import .*;

public class Question

{ JFrame win = new JFrame("调查问卷");

Container contentPane = tentPane();

JLabel questionTest = new JLabel("基 本 情 况 调 查 表",);

public void go(){

out(new BorderLayout());

(questionTest,);

e(400,300);

ible(true);

}

public static void main(String arg[]){

Question be = new Question ();

(); }

}

3.

分析与提高

(1) 第5行要特别说明一下,这条语句将在以后的大部分程序中出现。Java在处理图形用户界面时,并不是将组件直接摆放在JFrame容器中,而是在JFrame容器上再加一个隐性层,组件是放在这个隐性层上的。这个隐性层是由Container类创建的。这个类归属于awt包。这个隐性层采用第5行的形式创建,其中contentPane就是这个隐性层的引用。

前面的章节曾用吃饭的例子来说明容器、组件和布局管理器三者之间的关系,却没有提到隐性层。这个隐性层相当于“桌布”的作用。为桌子加桌布的原因是要保护桌子,而为窗口加“桌布”的原因是为了要实现更多的功能。因为Container包含很多功能,这些功能JFrame不具备。

这样一来,JFrame创建了一个窗口(桌子),然后,通过第5行来为这个窗口加上隐性层(桌布)。所有的组件(菜)都是放在这张“桌布”上的。布局管理器也是针对这张“桌布”设置的。

那么,窗口的大小和窗口显示属性是不是也要对这张“桌布”进行操作呢?这实际上不是这样的。

这两个设置还是直接对窗口来操作。这用吃饭的例子还是可以讲得通的。设置“桌布”

的大小有什么意义呢?桌子(窗口)的大小才是决定能放下多少菜(组件)的关键。因为“桌布”只是一个附属品,它随着桌子(窗口)的存在而存在。

(2) 第6行就是这个任务的关键所在。这一行创建了一个标签,标签的名字为questionTest。将“基本情况调查表”作为标签的内容,并居中对齐。

(3) 第8行将containPane指向的隐性层,即“桌布”的布局管理器设置为BorderLayout。

(4) 第9行是将questionTest标签加入到窗口的上北位置。

【任务9】

在调查问卷中加入个人体育爱好的调查项。

1.

基础知识

一个人的体育爱好可能有一种,也可能是多种,因此,这部分调查内容应该是可以多选的。复选框组件可以帮助我们完成这一任务。复选框的主要功能就是使用户可以进行多项选择。负责复选框功能的类是JCheckBox。

常用的创建复选框方式有如下几种:

方式一:JCheckBox 对象名 = new JCheckBox(String s);

方式二:JCheckBox 对象名 = new JCheckBox(String s,boolean b);

方式三:JCheckBox 对象名 = new JCheckBox(ImageIcon image);

方式四:JCheckBox 对象名 = new JCheckBox(ImageIcon image,boolean b);

方式一和方式二创建的复选框显示的信息是字符串。其中参数s用于存放显示的字符串。方式二中的参数b是说明创建的复选框是否为默认选中。如下面语句:

JCheckBox c1 = new JCheckBox("足球",true)

这种方式的显示结果为,参数中的“true”是表明这个选项是默认选项。如果去。 掉这个参数,即JCheckBox c1 = new JCheckBox("足球"),那么显示的结果为方式三和方式四创建的复选框显示的信息是图片。其中参数image是图片的引用。方式四中的参数b同方式三中的参数b作用相同。

2.

任务实施

我们要将这部分调查内容放在窗口的“Center”部分。因为,调查项不只一项,所以,要事先安排“Center”部分的布局格式,才能将这些调查项逐一摆放。

如果要对“Center”部分进行布局设置,就必须在此处加入一个容器。这时就用到任务7中讲到的JPanel了。将这个用JPanel建立的容器命名为“p”,并将其布局管理局设置为GridLayout。这样,只要根据调查项的条数来设置GridLayout的行数就可以了,而列数肯定是1。

因为每一个调查项都由调查的问题和复选框组成,所以也存在布局的问题。处理方法就是为每一个调查项也创建一个JPanel容器,布局管理器同样设置为GridLayout型。调查项容器命名为“p1”,其他调查项容器依次命名为“p2”,“p3”……

布局设计好后,就要将调查项加入到窗口的“Center”部分。添加复选框后的窗口效果如图4-10所示。

图4-10 加入调查项后的窗口

从图4-10可以看出,关于体育运动的调查项实际由一个标签和三个复选框组成。程序源代码如下:

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 .*;

import .*;

public class Question

{ JFrame win = new JFrame("调查问卷");

Container contentPane = tentPane();

JLabel questionTest = new JLabel("基 本 情 况 调 查 表",);

JLabel JLabel1= new JLabel("1、喜欢的体育运动:",);

JCheckBox c1 = new JCheckBox("足球",true);

JCheckBox c2 = new JCheckBox("羽毛球");

JCheckBox c3 = new JCheckBox("篮球");

JPanel p = new JPanel();

JPanel p1 = new JPanel();

public void go(){

out(new BorderLayout());

//out(new GridLayout(?,1));

out(new GridLayout(4,1));

(JLabel1);

(c1);(c2);(c3);

(p1);

(questionTest,);

(p,);

e(400,300);

ible(true);

}

public static void main(String arg[]){

Question be = new Question ();

(); }

28 }

3.

分析与提高

(1) 第7行创建的标签是调查项的问题

(2) 第8行至第10行创建了三个复选框,其中“足球”项为默认选项。

(3) 第11行和第12行分别创建了用于“Center”部分的JPanel容器p和用于摆放调查项的JPanel容器p1。

(4) 第15行是注释行,这一行的作用是设置p的布局管理器为GridLayout。目前只有一个调查项,还不能确定最终会有几个调查项,所以不能确定到底要用到几行,因此,这行被注释掉,等确定好共有几个调查项后,再把注释取消。

(5) 第16行设置了“p1”的布局管理器为GridLayout,并设置为4行1列。第1行用于摆放调查项问题,其他3行用于摆放复选框。

(6) 第17行和第18行是把内容为“1、喜欢的体育运动:”的标签和三个复选框加入到p1容器中。

(7) 第19行是将含有调查项内容的p1容器加入到p容器中。

(8) 第21行是将p容器加入到窗口的“Center”部分。

【任务10】

在调查问卷中,加入关于被调查人性别的调查项。

1.

基础知识

单选框就是只能选择选项中的一个。性别选项恰恰就可以用单选框来实现。JRadioButton是专门处理单选框的类。

常用的创建单选框方式有如下几种:

方式一:JRadioButton 对象名 = new JRadioButton(String s);

方式二:JRadioButton 对象名 = new JRadioButton(String s,boolean b);

方式三:JRadioButton 对象名 = new JRadioButton(ImageIcon image);

方式四:JRadioButton 对象名 = new JRadioButton(ImageIcon image,boolean b);

创建单选框的这四种方式与创建复选框的方式含义基本一样,所以不再进行解释了。

下面的语句是采用方式二创建一个单选框。

JRadioButton r1 = new JRadioButton("男",true);

参数中的“true”是表明这个选项是默认选项。这句话的结果显示为“true”参数,显示结果为。

,如果去掉 与复选框不同的是,无论有多少选项,只能有一个选项被选中。因此,单选框要有另外一个类的配合,才能达到“单选”目的。这个类是ButtonGroup。

对于单选框只能选择其中的一项的特性,Java实际上是这样操作的:若干个选项组成一组,在这一组中只能选择一个选项。这个将若干选项划定为一组的工作就由ButtonGroup类来完成。它的创建方式为ButtonGroup 对象名 = new ButtonGroup()。

比如有r1和r2两个单选框,利用下面的语句,就可以将这两个单选框划定为一组。

ButtonGroup对象名.add(r1);

ButtonGroup对象名.add(r2);

这样一来,系统就认定r1和r2是属于一组,在进行操作时,只能有一个选项被选中。

2.

任务实施

在布局的设计方面,任务9已经说的很清楚。新的调查项的布局方式按照上一个调查项的布局进行设计就可以了。因为要加入新的调查项,所以容器p的布局应该为2行1列。如图4-11所示。

图4-11 加入“性别”调查项后的窗口

本任务的代码内容如下:

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 .*;

import .*;

public class Question

{ JFrame win = new JFrame("调查问卷");

Container contentPane = tentPane();

JLabel questionTest = new JLabel("基 本 情 况 调 查 表",);

JLabel JLabel1= new JLabel("1、喜欢的体育运动:",);

JCheckBox c1 = new JCheckBox("足球",true);

JCheckBox c2 = new JCheckBox("羽毛球");

JCheckBox c3 = new JCheckBox("篮球");

JLabel JLabel2= new JLabel("2、性别:",);

ButtonGroup bgroup = new ButtonGroup();

JRadioButton r1 = new JRadioButton("男",true);

JRadioButton r2 = new JRadioButton("女");

JPanel p = new JPanel();

JPanel p1 = new JPanel();

JPanel p2 = new JPanel();

public void go(){

out(new BorderLayout());

out(new GridLayout(2,1));

out(new GridLayout(4,1));

out(new GridLayout(3,1));

(r1);(r2);

(JLabel1);

25

26

27

28

29

30

31

32

33

34

35

36

37

(c1);(c2);(c3);

(JLabel2);

(r1);(r2);

(p1);(p2);

(questionTest,);

(p,);

e(400,300);

ible(true);

}

public static void main(String arg[]){

Question be = new Question ();

(); }

}

3.

分析与提高

(1) 第12行创建了与单选框配合使用的类的对象bgroup,用于划定单选框组。

(2) 第13行和第14行创建了两个单选框。其中,第13行创建的单选框为默认选项。

(3) 第17行创建了用于加载“性别”调查项的容器p2。

(4) 第20行设置了p的布局管理器为GridLayout型,并划分为2行1列。

(5) 第22行设置了p2的布局管理器为GridLayout型,并划分为3行1列。

(6) 第23行将r1和r2单选框加入到名字为bgroup的组中。

(7) 第26行和第27行是把内容为“2、性别:”的标签和两个单选框加入到p2容器中。

(8) 第29行将加载了两个调查项的p1和p2容器加入到p容器中。

【任务11】

在调查问卷中加入“提交”按钮。

1.

基础知识

按钮是图形用户界面中最常用的组件。Swing用JButton类来创建按钮。按钮可以用如下两种方式创建。

方式一:JButton 对象名 = new JButton(String s);

方式二:JButton 对象名 = new JButton(ImageIcon image);

方式一创建的按钮显示的信息是文字。方式二创建的按钮显示的信息是图片。

下面的语句创建了一个提交按钮:

JButton tiJiao = new JButton(“提交”);

这条语句的显示效果为2.

任务实施

在任务8中已经说明,提交按钮要放置在窗口的“South”部分。但是如果直接将按钮摆放在“Sourth”部分,显示的效果如图4-12所示。

图4-12 直接摆放“提交”按钮的窗口

显然,直接摆放的做法使得显示效果很不理想。如果想改变这种效果就必须创建一个JPanel容器,将按钮放入容器中,然后将容器放到窗口的“South”部分。JPanel的默认布局管理器是FlowLayout,这个布局管理器默认的对齐方式是居中对齐。所以,只要采用JPanel的默认布局管理器,就可以使“提交”按钮在窗口下端居中显示。添加“提交” 按钮后的窗口效果如图4-13所示。

图4-13 加入“提交”按钮后的窗口

本任务的代码内容如下:

1

2

3

4

5

6

7

8

9

10

import .*;

import .*;

public class Question

{ JFrame win = new JFrame("调查问卷");

Container contentPane = tentPane();

JLabel questionTest = new JLabel("基 本 情 况 调 查 表",);

JLabel JLabel1= new JLabel("1、喜欢的体育运动:",);

JCheckBox c1 = new JCheckBox("足球",true);

JCheckBox c2 = new JCheckBox("羽毛球");

JCheckBox c3 = new JCheckBox("篮球");

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

JLabel JLabel2= new JLabel("2、性别:",);

ButtonGroup bgroup = new ButtonGroup();

JRadioButton r1 = new JRadioButton("男",true);

JRadioButton r2 = new JRadioButton("女");

JButton tiJiao = new JButton("提交");

JPanel p = new JPanel();

JPanel p1 = new JPanel();

JPanel p2 = new JPanel();

JPanel p3 = new JPanel();

public void go(){

out(new BorderLayout());

out(new GridLayout(2,1));

out(new GridLayout(4,1));

out(new GridLayout(3,1));

(r1);(r2);

(JLabel1);

(c1);(c2);(c3);

(JLabel2);

(r1);(r2);

(tiJiao);

(p1);(p2);

(questionTest,);

(p,);

(p3,);

e(400,300);

ible(true);

}

public static void main(String arg[]){

Question be = new Question ();

(); }

}

3.

分析与提高

(1) 第15行创建了名字为tiJiao的按钮。按钮所显示的文字为“提交”。

(2) 第19行创建了用于加载按钮的容器p3。

(3) 第30行将按钮加入以p3容器中。

(4) 第34行将容器p3加入到窗口的 “South”部分。

4.3.3 向调查问卷中加入下拉列表

本节将在已经创建的调查问卷中加入新的调查项,这个调查项的表现形式是下拉列表。

【任务12】在调查问卷中增加调查者出生年份的调查项。

1.

基础知识

本调查问卷所调查的对象年龄在12-32岁之间,所以这个调查项应该具有21个选项。因为选项是固定的,所以采用下拉列表的方式让用户进行选择最为方便。

下拉列表就是其选项可以伸缩的列表,如Microsoft Word中字体、字号的选择就是下拉列表。

下面的语句是最常用的创建下拉列表的方法。

JComboBox 对象名 = new JComboBox(Object[]);

其中参数Object[]表示对象数组。因为下拉列表要显示是一组数据,所以采用数组的形式传递参数是再合适不过的了。但是,下拉列表要显示的数据的类型并不确定,所以采用Object作为数组的类型,使其可以接收任务数据类型的数据。一般情况下,采用的是String类型的数组来存储下拉列表所包含的内容。例如

String brand[] = {"雪佛兰","福特","大众","马自达","本田","丰田"};

JComboBox carBrand = new JComboBox(brand);

这两条语句可以建立以汽车品牌为内容的下拉列表。

2.

任务实施

新添加的年份调查项由调查项问题和下拉列表组成。同前面的任务一样,还是采用JPanel容器摆放调查项,然后再将容器摆放到窗口中的p容器中。年份调查项的容器布局管理器采用FlowLayout,而不采用GridLayout布局管理器。这主要出于显示效果的考虑,对于本任务的情况来说,FlowLayout比GridLayout布局管理器的显示效果要好。JPanel的默认布局管理器就是FlowLayout,但是,默认的对齐方式是居中对齐。这与前两项调查项的对齐方式不一致。因此,要把FlowLayout布局管理器的对齐方式设置成左对齐。

添加年份调查项后的窗口显示效果如图4-14所示。

图4-14 加入下拉表后的窗口

程序代码内容为:

1

2

3

4

5

6

import .*;

import .*;

public class Question

{ JFrame win = new JFrame("调查问卷");

Container contentPane = tentPane();

JLabel questionTest = new JLabel("基 本 情 况 调 查 表",);

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

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

JLabel JLabel1= new JLabel("1、喜欢的体育运动:",);

JCheckBox c1 = new JCheckBox("足球",true);

JCheckBox c2 = new JCheckBox("羽毛球");

JCheckBox c3 = new JCheckBox("篮球");

JLabel JLabel2= new JLabel("2、性别:",);

ButtonGroup bgroup = new ButtonGroup();

JRadioButton r1 = new JRadioButton("男",true);

JRadioButton r2 = new JRadioButton("女");

JLabel JLabel3 = new JLabel("3、出生的年份:",);

String year[] = {"1978","1979","1980","1981","1982","1983","1984",

"1985","1986","1987","1988","1989","1990","1991",

"1992","1993","1994","1995","1996","1997","1998"};

JComboBox jcmb = new JComboBox (year);

JButton tiJiao = new JButton("提交");

JPanel p = new JPanel();

JPanel p1 = new JPanel();

JPanel p2 = new JPanel();

JPanel p3 = new JPanel();

JPanel p4 = new JPanel();

public void go(){

out(new BorderLayout());

out(new GridLayout(3,1));

out(new GridLayout(4,1));

out(new GridLayout(3,1));

out(new FlowLayout(G));

(r1);(r2);

(JLabel1);

(c1);(c2);(c3);

(JLabel2);

(r1);(r2);

(tiJiao);

(JLabel3);(jcmb);

(p1);(p2);(p4);

(questionTest,);

(p,);

(p3,);

e(400,300);

ible(true);

}

public static void main(String arg[]){

Question be = new Question ();

(); }

}

3.

分析与提高

(1) 第15行创建调查问题标签JLabel3,标签内容为“3、出生的年份:”,对齐方式的左对齐。

(2) 第16行至第18行创建了String类型的数组year,它是下拉表要包含的年份内容。

(3) 第19行创建了以year数组为参数的下拉列表jcmb。

(4) 第25行创建了用于摆放年份调查项的JPanel容器p4。

(5) 由于添加了调查项,所以要把p窗口的行数增加到3行。见第28行。

(6) 第31行设置了p4容器的布局管理器,并将对齐方式设置为左对齐。

(7) 第38行将年份调查项问题和下拉列表添加到p4容器中。

(8) 第39行将p4容器加入到p容器中。

4.3.4 在调查问卷中加入文本输入区域-文本框和文本域

在本节中将主要对文本框和文本域的使用进行介绍。

【任务13】在调查问卷中加入调查者联系方式的调查项。

1.

基础知识

调查者的联系方式指的是电话或电子邮件。无论是哪一种,都需要用户进行输入。最常用的可供用户输入信息的就是文本框。比如,用户登录某系统时要输入用户名和密码等信息,所应用的就是文本框。swing包中的JTextField类是用于创建文本框的类。

创建文本框的方式有以下几种:

方式一:JTextField 对象名 = new JTextField();

方式二:JTextField 对象名 = new JTextField(String s);

方式三:JTextField 对象名 = new JTextField(int i);

方式四:JTextField 对象名 = new JTextField(String s,int i);

参数i是文本框的宽度。这个宽度指输入的字段长度。参数s是文本框的初始内容,即在第一次显示时,文本框里的内容。如果采用方式一或方式三,则文本框的初始内容为空。采用方式一创建的文本框宽度为0。采用方式二创建的文本框宽度即s字符串的字段长度。

其实,文本框的初始宽度与其所处的布局管理器有关。在FlowLayout布局管理器下,四种创建方式的文本框宽度都能如实表现出来。但是在BorderLayout和GridLayout布局管理器下,这些宽度设置就会失效。比如,用方式一创建的文本框的宽度应该是0。但是,在BorderLayout布局管理器下,文本框会充满其所在的区域,宽度与其所在区域的宽度一致。所以,在应用时要特别注意文本框的这一特性。

2.

任务实施

联系方式调查项的同年份调查项的处理方式完全一样,布局管理器采用FlowLayout,并设置为左对齐。

加入联系方式调查项的窗口显示效果如图4-15所示。

图4-15 加入文本框后的窗口

本任务的代码内容如下:

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

import .*;

import .*;

public class Question

{ JFrame win = new JFrame("调查问卷");

Container contentPane = tentPane();

JLabel questionTest = new JLabel("基 本 情 况 调 查 表",);

JLabel JLabel1= new JLabel("1、喜欢的体育运动:",);

JCheckBox c1 = new JCheckBox("足球",true);

JCheckBox c2 = new JCheckBox("羽毛球");

JCheckBox c3 = new JCheckBox("篮球");

JLabel JLabel2= new JLabel("2、性别:",);

ButtonGroup bgroup = new ButtonGroup();

JRadioButton r1 = new JRadioButton("男",true);

JRadioButton r2 = new JRadioButton("女");

JLabel JLabel3 = new JLabel("3、出生的年份:",);

String year[] = {"1978","1979","1980","1981","1982","1983","1984",

"1985","1986","1987","1988","1989","1990","1991",

"1992","1993","1994","1995","1996","1997","1998"};

JComboBox jcmb = new JComboBox (year);

JLabel JLabel4 = new JLabel("4、联系方式:",);

JTextField txt = new JTextField(10);

JButton tiJiao = new JButton("提交");

JPanel p = new JPanel();

JPanel p1 = new JPanel();

JPanel p2 = new JPanel();

JPanel p3 = new JPanel();

JPanel p4 = new JPanel();

JPanel p5 = new JPanel();

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

public void go(){

out(new BorderLayout());

out(new GridLayout(4,1));

out(new GridLayout(4,1));

out(new GridLayout(3,1));

out(new FlowLayout(G));

out(new FlowLayout(G));

(r1);(r2);

(JLabel1);

(c1);(c2);(c3);

(JLabel2);

(r1);(r2);

(tiJiao);

(JLabel3);(jcmb);

(JLabel4);(txt);

(p1);(p2);(p4);(p5);

(questionTest,);

(p,);

(p3,);

e(400,300);

ible(true);

}

public static void main(String arg[]){

Question be = new Question ();

(); }

}

3.

分析与提高

(1) 第20行创建包含调查项问题的标签JLabel4,内容为“4、联系方式:”,对齐方式为左对齐。

(2) 第21行创建了文本框txt,文本框宽度为10。

(3) 第28行创建了用于摆放年份调查项的JPanel容器p5。

(4) 由于增加了调查项,所以要把p窗口的行数增加到4行。见第31行。

(5) 第35行设置了p5容器的布局管理器,并将对齐方式设置为左对齐。

(6) 第43行将联系方式调查项问题和文本框添加到p5容器中。

(7) 第44行将p5容器加入到p容器中

【任务14】在调查问卷中加入调查者其他爱好的调查项。

1.

基础知识

调查者其他的爱好需要用户自己输入。这就要求给用户一个更大的文本输入区域。这可以用文本框来实现。但是,文本框是一种1行N列的文本输入区域,行数是不可变的。如果用户输入的内容大于文本框的宽度,则多出的内容不能显示。swing包中有一种更适合这

种情况的组件,即文本域JTextArea。这种文本输入区域不同于文本框,它可以设置区域的行数,可显示更多的文本内容。

创建文本域的方式有以下几种:

方式一:JTextArea 对象名 = new JTextField();

方式二:JTextArea 对象名 = new JTextField(String s);

方式三:JTextArea 对象名 = new JTextField(int rows,int columns);

方式四:JTextArea 对象名 = new JTextField(Sting s,int rows,int columns);

参数s是文本域中要显示的初始内容。rows和columns是文本域的行数和列数。同文本框一样,文本域的行数和列数与其所处的布局管理器有关。在特定的布局管理器中也会产生行数和列数失效的情况。

2.

任务实施

新加入的调查项仍然采用FlowLayout的布局方式,并且采用左对齐。目的是使文本域的行数和列数能够正常显示。

加入新调查项的窗口显示效果如图4-16所示。

图4-16 加入文本域后的窗口

本任务的代码内容如下:

1

2

3

4

5

6

7

8

9

import .*;

import .*;

public class Question

{ JFrame win = new JFrame("调查问卷");

Container contentPane = tentPane();

JLabel questionTest = new JLabel("基 本 情 况 调 查 表",);

JLabel JLabel1= new JLabel("1、喜欢的体育运动:",);

JCheckBox c1 = new JCheckBox("足球",true);

JCheckBox c2 = new JCheckBox("羽毛球");

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

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

JCheckBox c3 = new JCheckBox("篮球");

JLabel JLabel2= new JLabel("2、性别:",);

ButtonGroup bgroup = new ButtonGroup();

JRadioButton r1 = new JRadioButton("男",true);

JRadioButton r2 = new JRadioButton("女");

JLabel JLabel3 = new JLabel("3、出生的年份:",);

String year[] = {"1978","1979","1980","1981","1982","1983","1984",

"1985","1986","1987","1988","1989","1990","1991",

"1992","1993","1994","1995","1996","1997","1998"};

JComboBox jcmb = new JComboBox (year);

JLabel JLabel4 = new JLabel("4、联系方式:",);

JTextField txt = new JTextField(10);

JLabel JLabel5 = new JLabel("5、将您的其他爱好填写到下面的区域中:",);

JTextArea txtArea = new JTextArea(4,20);

JButton tiJiao = new JButton("提交");

JPanel p = new JPanel();

JPanel p1 = new JPanel();

JPanel p2 = new JPanel();

JPanel p3 = new JPanel();

JPanel p4 = new JPanel();

JPanel p5 = new JPanel();

JPanel p6 = new JPanel();

public void go(){

out(new BorderLayout());

out(new GridLayout(5,1));

out(new GridLayout(4,1));

out(new GridLayout(3,1));

out(new FlowLayout(G));

out(new FlowLayout(G));

out(new FlowLayout(G));

(r1);(r2);

(JLabel1);

(c1);(c2);(c3);

(JLabel2);

(r1);(r2);

(tiJiao);

(JLabel3);(jcmb);

(JLabel4);(txt);

(JLabel5);(txtArea);

(p1);(p2);(p4);(p5);(p6);

(questionTest,);

(p,);

(p3,);

53

54

55

56

57

58

59

e(400,400);

ible(true);

}

public static void main(String arg[]){

Question be = new Question ();

(); }

}

3.

分析与提高

(1) 第22行创建包含调查项问题的标签JLabel5,内容为“5、将您的其他爱好填写到下面的区域中:”,对齐方式为左对齐。

(2) 第23行创建了文本域txtArea,文本域为4行,20列。

(3) 第31行创建了用于摆放新调查项的JPanel容器p6。

(4) 由于添加了新调查项,所以要把p窗口的行数增加到5行。见第34行。

(5) 第39行设置了p6容器的布局管理器,并将对齐方式设置为左对齐。

(6) 第48行将新调查项的问题和文本域添加到p6容器中。

(7) 第49行将p6容器加入到p容器中

通常情况下,文本域的创建并不是到此为止的。在应用中,如果用户输入的内容大于4行,20列能显示的内容,文本域还是没法显示多出来的内容。有一个可以和文本域组件配合使用的类,它的名字是JScrollPane。这个类的作用是将文本域加上滚动条功能。如果用户输入的内容大于文本域名行数或列数,则会自动在文本域的底部或右则出现滚动条。

对于上面的程序可以做如下修改,就可以达到为文本域添加滚动条的功能。

创建JScrollPane对象:JScrollPane scollPane = new JScrollPane(txtArea)。其中的txtArea就是第23行创建的文本域。参数的作用就是要记JScrollPane类知道到底为谁加滚动条功能。这句话可以加在第23行之后。

将第48行的(txtArea)更改为(scollPane)。

完成以上修改后,就可以实现文本域的滚动条功能了。

4.3.5 学习JTable组件的使用

当我们进行数据统计时,如果采用表格的话,可以将数据更有条理的显示在用户界面中。swing包中的JTable类专门用于表格的创建。本节将重点介绍JTable组件的使用。

【任务15】制作一张成绩单。

1.

基础知识

在进行数据处理的软件中,经常使用的数据显示方式就是表格。这种数据结构简洁,一目了然。swing包中的JTable类可以完成表格的创建。常用创建表格的方式为:

JTable 对象名=new JTalbe(Object[][] rowData,Object[] columnNames);

两个参数均为数组。其中有rowData是二维数组,用于存放表格中的记录。columnNames是一维数组,用于存放表头,即列的名称。

2.

任务实施

设计一个成绩单,其中表头为:姓名、语文、数学、总分、及格和作弊。其中及格和作弊用布尔值表示。

本任务的代码内容如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

import .*;

import .*;

public class TableEx {

JFrame win = new JFrame("成绩单");

Container contentPane = tentPane();

public void go(){

Object[][] jilu = {

{"阿三", new Integer(66),new Integer(32), new Integer(98), new Boolean(false),new Boolean(false)},

{"阿四", new Integer(85), new Integer(69), new Integer(154), new Boolean(true),new Boolean(false)}

};

String[] lieming = {"姓名","语文","数学","总分","及格","作弊"};

JTable table = new JTable(jilu, lieming);

JScrollPane scrollPane = new JScrollPane(table);

(scrollPane, );

();

ible(true);

}

public static void main(String args[]) {

TableEx be = new TableEx();

();

}

}

程序的执行结果为如图4-17所示:

图4-17 使用表格的成绩单

3.

分析与提高

(1) 第4行和第5行创建了窗口win和它的隐性层。

(2) 第7行至第10行定义了表格的记录数组jilu。注意,这个数组的类型为Object型,所以,其中的元素必须使用包裹类类型。

(3) 第11行定义了表格的列名数组lieming。

(4) 第12行创建了表格table。将jiliu和lieming作为其参数。

(5) 第13行定义的是一个带滚动条的Panel,将table放入其中。如果表格内容过多,窗口会显示不下,加入滚动条后,会使窗口更美观,实用。

(6) 第14行将装载了表格的scrollPane,以BorederLayout布局方式摆放在窗口的中央位置。

(7) 窗口大小没有采用setSize()方法。而是采用pack()方法。这种方法会根据组件大小设置窗口大小。但是,如果使用了JScrollPane,窗口高度会超出摆放的组件的高度。

4.3.5 制作计算器的菜单

本节中将介绍菜单的使用方法。

【任务16】为计算器制作一个菜单。

1.

基础知识

菜单在图形用户界面中经常被使用。如Microsoft word的用户界面。菜单可以将各种操作集中起来,方便用户的操作。从显示效果来看,即美观又节省空间。

无论什么样的菜单,都是由三部分组成的,分别是菜单条、菜单和菜单项。如图4-18所示。

图4-18 菜单的组成

菜单条的作用就是摆放各种功能菜单,对这些菜单进行整合。“文件(F)”、“编辑(E)”等被称为功能菜单,这些功能菜单其实是功能组。每个功能菜单下都有若干的功能,即菜单项。比如,通常“文件”菜单中会包含“打开”、“保存”、“另存为”等菜单项。在Swing中,菜单的三个组成部分别对应三个类,即JMenuBar、JMenu和JMenuItem。

(1) JMenuBar类

JMenuBar用于创建整合菜单的菜单条。下面的语句是最常用的创建菜单条的方式:

JMenuBar 对象名 = new JMenuBar();

JMenuBar在添加功能菜单时采用的是add(Componet c)方法,参数c用于传递菜单对象。

菜单条组件与其他常用组件有一点不同。其他常用组件是摆放在由Container类创建的隐性层上的。而菜单条必须摆放在窗口中,而且不用add(Componet c)方法。JFrame采用专用的添加菜单条方法摆放菜单条。这个方法是setJMenuBar(JMenuBar mbar)。下面的语句是将MBar菜单条添加到win所指向的窗口中。

win. setJMenuBar(JMenuBar MBar);

(2) JMenu类

JMenu用于创建功能菜单。创建菜单的方式有如下两种:

方式一:JMenu 对象名 = new JMenu();

方式二:JMenu 对象名 = new JMenu(String s);

参数s是菜单要显示的信息。如“文件(F)”菜单的创建,其中的文字信息就要存放在参数s中。方式一所创建的菜单不显示任何文字信息。

JMenu类拥有一些常用方法。

 add(Componet c)

这个方法的作用是将菜单项加入到菜单中。

 addSeparator()

在菜单项中,有时会出现一些线条,将菜单项分隔成若干组。这个方法就可以在菜单项之间建立这样的分隔线。

(3) JMenuItem类

JMenuItem用于创建菜单项。可以通过如下几种方式创建菜单项。

方式一:JMenuItem 对象名 = new JMenuItem();

方式二:JMenuItem 对象名 = new JMenuItem(String s);

方式三:JMenuItem 对象名 = new JMenuItem(ImageIcon image);

方式四:JMenuItem 对象名 = new JMenuItem(String s,ImageIcon image);

参数s是菜单项要显示的文字信息。如创建“保存(S)”菜单项,其中的文字信息就要存放在参数s中。参数image可以为菜单项增加图片,使菜单项更加直观和美观。

采用方式一创建的菜单项为空菜单项。方式四创建的菜单项既包含图片又包含文字信息。

2.

任务实施

计算器由菜单、显示区和按钮区组成。本任务只制作出计算器的菜单和显示区。如图4-19所示。

图4-19 添加了菜单的计算器窗口

本任务的代码内容如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

import .*;

import .*;

public class Calculator

{ JFrame win = new JFrame("计算器");

Container contentPane = tentPane();

JTextField jTextField = new JTextField();

JMenuBar MBar = new JMenuBar();

JMenu file = new JMenu("文件(F)");

JMenu help = new JMenu("帮助(H)");

JMenuItem qingkong = new JMenuItem("清空");

JMenuItem exit = new JMenuItem("退出");

JMenuItem about = new JMenuItem("关于...");

public void go() {

(qingkong);

(exit);

(about);

(file);

(help);

(jTextField);

nuBar(MBar);

e(200,100);

ible(true);

23

24

25

26

27

}

public static void main(String arg[]) {

Calculator be = new Calculator ();

(); }

}

3.

分析与提高

(1) 第4行创建了计算器的窗口,标题为“计算器”。

(2) 第5行创建了计算器窗口的隐性层contentPane。

(3) 第6行创建了计算器的显示区文本框jTextField。

(4) 第7行创建了计算器的菜单条Mbar。

(5) 第8行创建了文件菜单。

(6) 第9行创建了帮助菜单。

(7) 第10行创建了清空菜单项。

(8) 第11行创建了退出菜单项。

(9) 第12行创建了关于菜单项。

(10) 第14行和第15行将“清空”菜单项和“退出”菜单项加入到文件菜单。

(11) 第16行将“关于”菜单项加入到帮助菜单。

(12) 第17行和第18行将file和help指向的菜单加入到MBar指向的菜单条中。

(13) 第19行将显示区加入到窗口中。

(14) 第20行利用setJMenuBar()方法,将Mbar菜单条加入到win指向的窗口中。注意,并不是加入到隐性层上。

读者是否注意到,本程序中并没有关于布局管理器的设置。而且,菜单条组件摆放在窗口中,显示区摆放在隐性层。是不是需要对这它们分别设置布局管理器呢?实际上,这样做对于本任务来说是不必要的。

窗口容器的默认布局管理器是BorderLayout。但是,菜单条有其自身特性,它并不占用窗口的布局。Java语言的开发者这样设计菜单条的原因可能是因为菜单条通常都是在窗口的上部,所以就将其位置固定下来,而不受布局管理器的控制。因此,在本任务中,关于窗口的布局管理器设置就省略了。

隐性层的布局管理器默认也是BorderLayout。在BorderLayout布局管理器中摆放组件时,如果不对摆放位置进行说明的话,系统默认的位置是“CENTER”。因此,第19行语句(jTextField)与语句(jTextField,)等价。

【任务17】为计算器添加工具栏

1.

基础知识

工具栏一般出现在菜单条的下方。一些常用操作会出现在工具栏中,使用户操作更加方便。

Swing采用JToolBar类创建工具栏组件。

最常用的创建工具栏的方法是:JToolBar 对象名 = new JToolBar();。

工具栏中整合的实际上是菜单项。这些菜单项是以按钮的形式展现的。例如文件菜单中有“清空”项,工具栏中也有“清空”项,它们完成的操作是一样的。但是,文件菜单中的“清空”是菜单项,是用JMenuItem类创建的。而工具栏中的“清空”是按钮,是用JButton类创建的。

创建按钮最常用的两种方式已经在任务11中讲解过了。如果工具栏采用方式一创建按钮,则工具栏中显示的是文字。如果工具栏采用方式二创建按钮,则工具栏中显示的是图片。本任务中,采用方式一创建工具栏中的按钮。

工具栏和菜单条不同,Java将其作为普通组件处理。因此,它受布局管理器的控制。从显示效果来看,工具栏的宽度可以随着窗口的变化而变化,但是高度应该保持不变。而且,工具栏一般摆放在菜单条的下方。从这些特性来看,最适合工具栏的布局管理器就是BorderLayout。可以将工具栏摆放在。

2.

任务实施

加入工具栏后的计算器如图4-20所示。

图4-20 加入工具栏后的计算器窗口

本任务的代码内容如下:

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 .*;

import .*;

public class JToolBarEx

{ JFrame win = new JFrame("计算器");

Container contentPane = tentPane();

JTextField jTextArea = new JTextField(10);

JMenuBar MBar = new JMenuBar();

JMenu file = new JMenu("文件(F)");

JMenuItem qingkong = new JMenuItem("清空");

JMenuItem exit = new JMenuItem("退出");

JMenu help = new JMenu("帮助(H)");

JMenuItem about = new JMenuItem("关于...");

JToolBar toolBar = new JToolBar();

JButton jb1 = new JButton("清空");

JButton jb2 = new JButton("退出");

JButton jb3 = new JButton("关于");

public void go() {

//out(new BorderLayout());

(qingkong);

(exit);

(about);

(file);

(help);

(jb1);

(jb2);

26

27

28

29

30

31

32

33

34

35

36

(jb3);

(jTextArea,);

(toolBar,);

nuBar(MBar);

e(200,120);

ible(true);

}

public static void main(String arg[]) {

JToolBarEx be = new JToolBarEx ();

();}

}

3.

分析与提高

(1) 第13行创建工具栏toolBar。

(2) 第14行至第16行创建了三个按钮。

(3) 第18行被注释掉的语句是对隐性层contentPane进行布局管理器设置。因为,隐性层的默认布局管理器就是BorderLayout,所以这句话是可有可无的。

(4) 第24行至第26行将第14行至第16行创建的按钮添加到工具栏中。

(5) 第28行将工具栏toolBar加入到contentPane的NORTH位置。

4.3.6 常用对话框

当用户对某系统进行操作时,经常会出现一些提示性的窗口。这些提示性窗口有时是指导用户如何进行下一步操作,有时是提醒用户出现了错误操作。比如某文本框中的内容要求是整数,位数不能大于8位,用户如果输入错误就要给出提示。这种提示性窗口被称为对话框。在这一节中就将介绍各种情况下使用的对话框。

Swing有多个类支持对话框,在这里只介绍JOptionPane类。关于这个类,只需要读者了解可以提供用户所需对话框的方法就可以了。另外,这些方法都是静态的,在使用时不必创建JOptionPane类的对象,可以直接引用。这些方法的名字都以showXxxxDialog的方式出现。其中Xxxx可以是:Message、Confirm、Input和Option。分别对应信息对话框、验证对话框、输入对话框和自定义对话框。以下任务中,将逐一对这些方法进行介绍。

【任务18】认识提示信息对话框

1.

基础知识

提示信息对话框在应用上最为广泛。可以通过方法showMessageDialog()完成提示信息对话框的创建。提示信息对话框最常用的创建方法如下:

showMessageDialog(Component c,Object message,String title,int messageType);

其中参数c表示对话框的上一级窗口。对话框不可能单独存在,它是由用户在操作某系统时产生的,所以要确定上一级窗口。这样做还有一个目的就是:对话框窗口不关闭,用户则无法操作其上一级窗口。这种做法不仅可以保证用户操作系统时的顺序性,有时还可以避免错误操作的升级,造成系统瘫痪。

对话框的上一级窗口通常就是JFrame容器。c即可以是上一级窗口的引用,也可以是上一级窗口的隐性层引用。

参数message是提示信息对话框中要显示的信息内容。通过是String型的字符串。

参数title通常也是String型的字符串,它要传递的是提示信息对话框窗口标题栏的内容。

参数messageType是指提示信息对话框的类型。这些类型如表4-2所示。

表4-2 提示信息对话框类型表

提示框名称

错误信息

资讯信息

警告信息

问题信息

通用信息

ERROR_MESSAGE

INFORMATION_MESSAGE

WARNING_MESSAGE

QUESTION_MESSAGE

PLAIN_MESSAGE

类型

这些类型在显示时,会有与其类型对应的图片,用来加强信息对话框的可读性。只有通用信息类型的对话框没有图片。

提示信息对话采用的方法是JOptionPane类的静态方法。所以在使用时,可以直接采用下面的格式:

ssageDialog(Component c,Object message,String title,int

messageType);

五种提示信息对话框如图4-21、4-22、4-23、4-24、4-25所示。

图4-21 错误信息提示对话框

图4-22 资讯信息提示对话框

图4-23 警告信息提示对话框

图4-24 问题信息提示对话框

图4-25 通用信息提示对话框

2.

任务实施

本任务的代码内容如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

import .*;

import .*;

public class MessageDialog {

void go(){

JFrame win = new JFrame("对话框上一级窗口");

Container contentPane = tentPane();

e(400,200);

ible(true);

ssageDialog(win,"错误提示","提示窗口", _MESSAGE);

}

}

public static void main(String arg[]){

MessageDialog fe = new MessageDialog();

ssageDialog(win,"信息提示","提示窗口", ATION_MESSAGE);

ssageDialog(win,"警告提示","提示窗口", G_MESSAGE);

ssageDialog(win,"问题提示","提示窗口", ON_MESSAGE);

ssageDialog(win,"简单提示","提示窗口", _MESSAGE);

();

}

程序在执行先显示win窗口,即对话框的上一级窗口。然后依次显示五种信息对话框。在这些对话框没有关闭时,win窗口不可操作。

3.

分析与提高

(1) 第5行至第8行创建对话框的上一级窗口win,设置窗口大小,并显示。其中第7

行创建的隐性层在本程序中并没有用到。把这条代码加上是让读者尝试一下,将隐性层作为对话框上一级窗口的效果。只要把showMessageDialog()方法中的参数c的位置用contentPane代替即可。两种方式产生的效果是一样的。

(2) 第9行至第13行用于依次显示五种信息对话框。

【任务19】认识验证对话框。

1.

基础知识

验证对话框与提示信息对话框很相似,不同之处在于,提示信息对话框只提供“确定”按钮,而验证对话框因为是要用户确认所做的操作是否正确,所以,提供的按钮内容要丰富一些。

验证对话框应用的是showConfirmDialog(),格式如下:

showConfirmDialog(Component c,Object message,String title,int optionType);

参数optionType表示验证对话框的类型,共有4种。类型决定着对话框的按钮样式。对应关系如表4-3所示。

表4-3 验证对话框类型对照表

类型

DEFAULT_OPTION

YES_NO_OPTION

YES_NO_CANEL_OPTION

OK_CANCEL_OPTION

确定

是 否

是 否 撤消

确定 撤消

按钮样式

其他参数的含义与showMessageDialog()方法相同。

4种验证对话框如图4-26、4-27、4-28、4-29所示。

图4-26 确定按钮的验证对话框

图4-27 是和否按钮的验证对话框

图4-28 是、否和撤消按钮的验证对话框

图4-29 确定和撤消按钮的验证对话框

2.

任务实施

本任务代码内容如下:

1

2

3

4

5

6

7

8

9

10

11

import .*;

import .*;

public class ConfirmDialog {

void go(){

JFrame win = new JFrame("对话框上一级窗口");

Container contentPane = tentPane();

e(400,200);

ible(true);

nfirmDialog(win,"确定按钮","验证窗口", T_OPTION);

nfirmDialog(win,"是和否按钮","验证窗口", _NO_OPTION);

nfirmDialog(win,"是、否和撤消按钮","验证窗口",

_NO_CANCEL_OPTION);

12

13

14

15

16

17

18

}

}

public static void main(String arg[]){

ConfirmDialog fe = new ConfirmDialog();

nfirmDialog(win,"确定和撤消按钮","验证窗口", _CANCEL_OPTION);

();

}

3.

分析与提高

(1) 第9行至第12行创建了4种类型的验证对话框。

(2) 隐性层仍然可以作为验证对话框的上一级容器。

【任务20】认识输入对话框。

1.

基础知识

输入对话框可以为用户提供与系统进行交互的功能,用户可以在对话框中选择或输入相应信息,系统会收集这些信息,为判断下一步操作提供数据。创建对话框的方法是showInputDialog()方法。格式如下:

showInputDialog(Component c,Object message,String title,int messageType,ImageIcon

image,Object[] selectionValues,Object initSelectionValue);

参数selectionValues是数组,用于传递用户可选择的值。参数image用于传递对话框中要显示的图片。如果为空,则系统会使用输入对话框的默认图片。参数initSelectionValue是对话框初始化时显示的默认值。如果为null,则默认参数selectionValues数组的第一个元素为初始值。

其它参数含义与提示信息对话框相同。

2.

任务实施

结合前面制作的调查问卷,设计一个输入对话框。用于调查本次调查问卷问题设置的全面程度。分为非常全面、全面、一般、不全面、非常不全面。参数image为空,以对话框采用系统默认图片。以“全面”作为对话框的默认值。

本任务的代码内容如下:

1

2

3

4

5

6

7

8

9

10

import .*;

import .*;

public class InputDialog {

void go(){

JFrame win = new JFrame("对话框上一级窗口");

Container contentPane = tentPane();

e(400,200);

ible(true);

Object[] selectionValues = {"非常全面","全面","一般","不全面","非常不全面"};

putDialog(win,"您觉得本次调查所涉及的问题是否全面:","调查窗口",

ATION_MESSAGE,null,selectionValues,"全面");

11

12

13

14

15

16

}

}

public static void main(String arg[]){

InputDialog fe = new InputDialog();

();

}

程序的执行结果如图4-30所示。

图4-30 问题全面性调查对话框

3.

分析与提高

(1) 第9行创建输入对话框要使用的调查信息数组selectionValues。

(2) 第10行创建输入对话框,以“您觉得本次调查所涉及的问题是否全面:”作为对话框中显示的信息。以“调查窗口”作为对话框的标题名。采用INFORMATION_MESSAGE信息类型和系统默认图片。将“全面”作为对话框的初始默认值。

【任务21】认识自定义对话框。

1.

基础知识

以上所讲的对话框都有一定的格式要求,如果想要设计出具有自身个性的对话框,就要采用于自定义对话框。其方法为showOptionDialog()。格式如下:

showOptionDialog(Component c,Object message,String title,int optionType,int

messageType,ImageIcon image,Object[] options,Object initValue);

参数optionType指按钮的类型,共有4种。这4种类型与验证对话框的按钮类型相同。

参数options是数组,用于存放对话框中按钮要显示的信息。

参数initValue是对话框初始化时按钮的默认值。

2.

任务实施

本任务设计的对话框用于调查的用户满意度。分为满意、一般和不满意。对话框采用系统默认图片。以满意作为对话框初始化的默认值。

本任务的代码内容如下:

1

2

3

4

5

6

7

8

9

10

import .*;

import .*;

public class OptionDialog {

void go(){

JFrame win = new JFrame("对话框上一级窗口");

Container contentPane = tentPane();

e(400,200);

ible(true);

Object[] optionValues = {"满意","一般","不满意"};

tionDialog(win,"您对本次调查是否满意:","调查窗口",_NO_CANCEL_OPTION,ON_MESSAGE,null,optionValues,optionValues[0]);

} 11

12

13

14

15

16

}

public static void main(String arg[]){

OptionDialog fe = new OptionDialog();

();

}

程序执行结果如图4-31所示。

图4-31 自定义的满意度调查对话框

3.

分析与提高

(1) 第9行定义optionValues数组,用于存放三种满意度。

(2) 第10行创建输入对话框,以“您对本次调查是否满意:”作为对话框中显示的信息。以“调查窗口”作为对话框的标题名。采用QUESTION_MESSAGE信息类型和系统默认图片。将“满意”按钮作为对话框的初始默认按钮。

对话框所显示的按钮信息和个数与参数options有直接关系。而不受参数optionType所设置的按钮类型的限制。比如在本任务中设置的optionType是YES_NO_CANCEL_OPTION。这种类型的按钮是:是、否和撤消。按钮个数与options数组元素个数相符。在显示对话框时,按options数组的内容显示。如果将optionType的类型换成YES_NO_OPTION,这种类型的按钮是:是和否。按钮个数小于options数组元素个数。但是,显示效果仍然如图4-30所示。这样看来,参数optionType似乎是没有用的,但实际上不是这样的。

窗口所展示出的效果只是表面现象,对于后台操作来说,仍然要依据参数optionType的值。比如本任务中,如果用户点击“满意”按钮,对话框向系统传递的实际上是“是”的信息。因为,这个对话框的“满意”、“一般”和“不满意”按钮,对于系统来说,实际上是“是”、“否”和“撤消”按钮。在后面对常用组件事件处理的介绍中,会更加详细的讲解这部分内容。

4.3.7 常用组件的事件处理

在前面的章节中只介绍了常用组件的使用,在本小节中,将进一步介绍与这些组件有关的方法和事件处理。

在图形用户界面运行时,用户会通过键盘或鼠标对系统进行操作。每一次敲击键盘或点击鼠标都是用户对系统的一个请求,系统要对这个请求做出反应,以完成用户的请求。在这一过程中,就包括了事件和事件的处理。

所谓事件就是对组件做的一个动作。用户敲击键盘或点击鼠标所产生的动作都被称为事件。比如用户用鼠标点击了按钮,就产生了对按钮的“点击事件”。

所谓的事件处理就是产生事件后,系统做出反映的过程。即事件产生后,系统要根据事件的请求做出相应的响应,以完所用户要达到的目的过程。处理事件的任务当然由程序来完成,一般称这类程序为事件处理器。比如用户点击某个按钮后,窗口就关闭了。点击按钮就是一个事件,用户要通过这个事件达到“窗口的关闭”的目的,系统要根据这个点击事件调

用用于关闭窗口的程序,执行完后,将窗口关闭,完成事件的处理。

在Java语言中,事件的处理并不是由组件本身来完成的。组件产生的事件和事件的处理过程是分开的。Java将事件的处理委托给叫做监听器的事件处理实体来完成。这种事件处理模式被称为委托处理模式。不同的组件产生的事件不同,比如对键盘的敲击和对按钮的点击,同样的动作但是产生的事件却不同,与此相关事件处理实体(监听器)和处理方法也不同。

事件的处理实体,即监听器,实际上是一个类的实例。这些监听器的格式一般为XxxListener。在这些监听器中都有如下格式方法:

addXxxListener(ListenerType listener);

其中,Xxx是事件的类型。例如,如果是键盘事件,该监听器的名字是KeyListener,方法的名字就是addKeyListener。如果是鼠标事件,该监听器的名字是MouseListener,方法的名字就是addMouseListener。

事件的处理过程中,如果搞清楚以下三方面知识,就可以很好的应用Java语言的事件处理功能。

(1) 谁产生了事件?

也就是事件源是哪种组件。上面提到的“点击某个按钮后,窗口就关闭”的例子中的事件源是按钮。不同的事件源产生的事件是不同的,所以只有搞清楚了事件源是什么,才能确定产生的是什么事件。

(2) 什么样的事件要被处理。

不同的事件要由不同的监听器来处理。搞清楚所产生的事件后,才知道事件要交给哪个监听器来处理。将组件监听起来的格式如下:

对象名.addXXXListener(this);

(3) 处理事件对应的代码。

因为组件已经被监听,所以产生事件后,系统会根据采用的监听器,去调用相应的方法。而这些方法的方法体是空的,事件处理的对应代码要由程序设计员自己编写。比如“点击某个按钮后,窗口就关闭”。点击事件产生后,要去调用一段能够把窗口关闭的代码,这段代码要由程序设计员来编写。

【任务22】对调查问题问卷的按钮加入事件处理。

1.

基础知识

对不同组件的操作会产生不同的事件,与之对应的事件处理也不同。点击按钮所产生的事件被称为ActionEvent事件。除了按钮能够产生ActionEvent事件外,点击菜单项、文本框中的回车和双击列表中的选项也可以产生ActionEvent事件。

ActionEvent提供名字为getActionCommand()的方法。这个方法可以返回产生事件的组件的字符串。如果产生事件的是按钮,那么这个方法可以返回按钮上的文字。比如“确定”按钮,可以通过这个方法返回“确定”字符串。这样做很有必要。因为在一个窗口中,有多个组件,必须通过这种方法让系统知道用户点击的是那个组件,系统才能做出与这个组件有关的事件处理。

ActionEvent还包含名字为getSource()的方法。这个方法的作用是获取产生事件组件的引用变量。在本任务中没有用到此方法。

当用户完成调查问题时,系统进行两次调查分别是问题完整性调查和满意度调查。这两种调查都是以对话框的形式展现。分别采用输入对话框(Input Dialog)和自定义对话框(Option

Dialog)。

现在,已经基本搞清楚了事件处理的三件事:产生事件的组件是按钮;产生的是ActionEvent事件;进行的事件处理是产生两个对话框。

因为产生是的ActionEvent事件,所以应用的监听器应该是ActionListener,采用的监听方法是addActionListener()。当点击按钮时,触发监听器,由监听器去调用事件处理的代码。但是,事件处理的代码要放在什么位置呢?监听器怎么才能找到它呢?

每个监听器都有自己固定的方法,这些方法在不同的事件产生时被调用。比如ActionEvent事件的监听器的方法是actionPerformed(ActionEvent e)。本任务中,对按钮的事件处理的代码就应该放在这个方法中。当监听器被触发时,会自动调用这个方法,于是事件就被处理了。

2.

任务实施

只需要对任务14的代码进行部分修改就可以实现本任务的功能。

首先要在程序中引入监听器。方法是import .*;,所有监听器都包含在awt包的event包下,因此,只要涉及到事件处理的程序都应该引用这个包。

第二步要使Question类实现监听器ActionListener。为什么是“实现”,而不是“继承”呢?因为,所有监听器都是接口,而不是类。

第三步要使按钮被监听器监听,格式为ionListener(this)。

第四步添加actionPerformed(ActionEvent e)方法,方法内容为创建问题完整性调查对话框和满意度调查对话框。这部分参考任务20和任务21。

本任务的主要代码内容如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

import .*;

import .*;

import .*;

public class QuestionActionEvent implements ActionListener

{ ……

public void go(){

ionListener(this);

……

}

public void actionPerformed(ActionEvent e) {

if(ionCommand()=="提交"){

Object[] selectionValues = {"非常全面","全面","一般","不全面","非常不全面"};

putDialog(win,"您觉得本次调查所设及的问题是否全面:","调查窗口",

ATION_MESSAGE,null,selectionValues,"全面");

14

15

Object[] optionValues = {"满意","一般","不满意"};

tionDialog(win,"您对本次调查是否满意:","调查窗口",_NO_CANCEL_OPTION,ON_MESSAGE,null,optionValues,optionValues[0]); }

16

17

18

19

20

21

else{ ssageDialog(win,"您的操作不正确!","提示窗口", _MESSAGE); }

}

public static void main(String arg[]){

QuestionActionEvent be = new QuestionActionEvent();

(); }

}

代码中的省略部分请参考任务14。

3.

分析与提高

(1) 第2行引入了与监听器有关的包。

(2) 第4行实现了监听器ActionListener接口。

(3) 第5行省略了任务14的第4行至第31行。

(4) 第7行对tijiao按钮进行了监听。这种监听就相当于有一个监视器在随时注意着“提交”按钮,当它产生ActionEvent事件事,监听器马上就可以做出反应,去调用事件对应的方法。

(5) 第8行省略了任务14的第33行至第54行。

(6) 第10行至第17行为事件处理的代码部分,由ActionListener接口的方法actionPerformed完成。方法中首先利用getActionCommand()方法判断用户点击的是否为“提交”按钮(第11行),如果是,则依次创建问题完整性调查对话框(第12和第13行)和调查满意度对话框(第14行和第15行)。否则,创建错误对话框,提示用户操作不正确(第16行)。

【任务23】认识与复选框和单选框有关的事件。

1.

基础知识

复选框和单选框所对应的事件者是ItemEvent事件。另外当选中列表中的一项或多项时,也产生ItemEvent事件。当双击列表中的某项时产生的是ActionEvent事件。

ItemEvent事件对应的监听器是ItemListener,其监听方法是addItemListener()。ItemListener监听器用于处理事件的方法是itemStateChanged(ItemEvent e)。

ItemEventgk事件有两个常用方法,分别是getStateChange()和getSource()。

getStateChange()方法用于判断组件的状态。复选框和单选框都有两种状态:选中和没选中,即SELECTED和DESELECTED。

getSource()方法与ActionEvent中的getSource()方法作用相同,都是用于获得组件的引用变量。例如有如下语句:

JCheckBox c1 = new JCheckBox("足球",true);

当c1复选框被选中,利用getSource ()方法可以获取这个复选框的引用变量c1。

复选框和单选框有一个共同的方法getText(),这个方法会在任务实施的代码中用到。它用于获取复选框和单选框的方字信息。

标签也包含getText()方法,用于获取标签的方字信息。同时标签还包含setText(String s)方法,这个方法用于设置标签的信息。在本任务中会用到这标签的这两个方法。

2.

任务实施

因为复选框和单选框的事件处理完全一样,所以本任务只对复选框的事件处理进行实验。在任务9代码的基础上,实现以下操作:在窗口的“South”位置加入标签,当选中某复选框时,复选框的文字信息显示在这个标签中。

事件处理代码的算法是:当ItemEvent事件产生时,利用复选框的getText()方法,获取被选中复选框的文字信息,再利用标签的setText(String s)方法,将所获取的文字信息传递给标签进行显示。复选框可能同时选取多项,因此,要有一个变量用于收集所有被选复选框的文字信息。

需要注意的是,复选框分为选中和取消两种操作,这两种操作都会触发ItemListener监

听器,在两种情况下都会执行上述算法。这就会造成如下情况:当选中复选框时,复选框的文字信息被显示在标签中,当取消选中时,文字信息会被再一次显示在标签上。

为了解决这个问题,实现只在复选框被选中时文字信息才会显示,就必须使用getStateChange()方法,只有当这个方法的值为SELECTED时,才执行上述算法。

对任务9的代码应做如下修改:

首先引入.*。

第二步,使Question类实现ItemListener监听器。

第三步,建立标签,并将其摆放在窗口的“South”位置。

第四步,对复选框c1、c2和c3进行监听,采用的方法是addItemListener()。

第五步,添加itemStateChanged(ItemEvent e)方法,按上面的算法编写事件处理代码。

本任务的代码内容如下:

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

import .*;

import .*;

import .*;

public class Question implements ItemListener

{ JFrame win = new JFrame("调查问卷");

Container contentPane = tentPane();

JLabel result = new JLabel("您选择的体育运动是:",);

JLabel questionTest = new JLabel("基 本 情 况 调 查 表",);

JLabel JLabel1= new JLabel("1、喜欢的体育运动:",);

JCheckBox c1 = new JCheckBox("足球",true);

JCheckBox c2 = new JCheckBox("羽毛球");

JCheckBox c3 = new JCheckBox("篮球");

JPanel p = new JPanel();

JPanel p1 = new JPanel();

public void go(){

mListener(this);

mListener(this);

mListener(this);

out(new BorderLayout());

//out(new GridLayout(?,1));

out(new GridLayout(4,1));

(JLabel1);

(c1);(c2);(c3);

(p1);

(questionTest,);

(p,);

(result,);

e(400,300);

ible(true);

}

public void itemStateChanged(ItemEvent e) {

String str="";

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

}

if(teChange()==ED)

{if(rce()==c1)

{str=t()+t();

t(str);}

if(rce()==c2)

{str=t()+t();

t(str);}

if(rce()==c3)

{str=t()+t();

t(str);}

}

public static void main(String arg[]){

Question be = new Question ();

(); }

}

程序执行结果如图4-32所示。

图4-32 复选框架事件处理

3.

分析与提高

(1) 第4行实现了ItemListener监听器接口。

(2) 第7行创建了用于显示复选框文字信息的标签result。第27行将result标签摆放在窗口的“South”位置。

(3) 第16行至第18行分别对c1、c2和c3复选框进行监听。

(4) 第31行至第44行是事件处理代码。当复选框被选中,产生ItemEvent事件,触发了ItemListener监听器后,监听器就会自动调用itemStateChanged(ItemEvent e)方法,这部分代码就被执行了。

(5) 第32行的str字符串变量是用于收集被选中的复选框的文字信息的。同时选中多个复选框后,它们的文字信息会连接成字符串,存放在str变量中。

(6) 第33行利用getStateChange()方法,判断复选框是不是被选中,即是否为SELECTED状态,如果是则执行第34行至第43行的代码,否则就什么都不做。这一行的作用就是解决前面提到的“取消选中时,仍然重写文字信息”的问题。

(7) 第34行至第36行的作用是:当c1复选框被选中时,则在标签中显示“足球”的文字信息。

(8) 第34行是利用getSource()方法判断被选中的对象是不是c1。

(9) 第35行中的t()用于获取标签当前的文字信息,t()用于获取复选框的文字信息。然后将两个文字信息相连形成新的字符串,存放到变量str中。之所以要获取标签当前的文字信息,是因为我们要将所有被选中的复选框的文字信息显示在标签中,那么,在选中c1前,可能已经有其它复选框被中了,因此,标签就可能已经存在了文字信息。必须获取标签已经存在的文字信息,然后将新文字信息与之相连,形成新的字符串,才能实现本任务的功能,否则就会产生丢失文字信息的情况。

(10) 第36行是利用标签的setText(String s)方法,将str字符串中存放的被中的复选框的文字信息显示在标签result中。

(11) 第37行至第39行是处理c2复选框的代码。第40行至第42行是处理c3复选框的代码。处理方法与c1复选框相同。

【任务24】认识与文件框和文本域有关的事件。

1.

基础知识

与文本框和文本域有关的事件有三个,分别是ActionEvent、TextEvent、KeyEvent。ActionEvent是在回车时产生的事件;TextEvent是当文本框或文本域中有文字变化时产生的事件;KeyEvent又称键盘事件,当对文本框或文本域进行文字输入时,产生此事件。

ActionEvent在任务22已经介绍过。TextEvent事件的处理大部分可以由KeyEvent事件处理来代替,所以在本任务中只介绍KeyEvent事件。

键盘产生的事件都是KeyEvent事件,这个事件是图形用户界面应用最多的事件之一。

键盘的动作分为三种:按下、松开和敲击。实际上敲击是按下和松开的组合操作过程。这三个动作可以产生KeyEvent事件。键盘中不同按键产生KeyEvent事件的情况有所不同。当对键盘中的26个英文字母进行敲击时,产生KeyEvent事件。其他按钮在进行按下和松开时,分别产生KeyEvent事件。

与KeyEvent对应的监听器是KeyListener接口。采用的监听方法是addKeyListener()。

由于不同按键产生事件的情况下不同,所以KeyListener接口用keyPress(KeyEvent e)、keyReleased(KeyEvent e)和keyTyped(KeyEvent e)三个方法,分别响应用户按下、松开和敲击按键时的操作。

KeyEvent有两个常用方法,分别是:getKeyChar()和getKeyCode()。

getKeyChar()方法用于返回用户所按的按键对应的字符。用户按下字母和数字时,多用这个方法获取数据。getKeyCode()返回的是按钮的数字编码。系统为某些按钮分配的是数字编码,如方向键中的向上键,在系统中对应_UP常量。这个常量存放着“向中键”的数字编码。

利用这两个方法,就可以获取键盘上所有按键的信息了。

2.

任务实施

本任务要在任务14的代码的基础上进行修改。对联系方式调查项加入事件处理。假设联系方式指用户的电话,那么,当用户输入0-9以外的字符时,系统就要报错。

用户输入数字属于敲击事件。要使用KeyListener接口中的keyTyped(KeyEvent e)方法。算法如下:

当用户输入信息敲击键盘按键时,产生KeyEvent事件。触发KeyListener监听器。监听器调用keyTyped(KeyEvent e)方法,进行事件处理。keyTyped(KeyEvent e)方法利用KeyEvent类的getKeyChar()方法获取用户输入的字符,判断是否为‘0’-‘9’之间的字符。如果判

断结果为false,则弹出错误提示对话框,如果是true,则不做任何操作,让用户继续输入。

需要注意的是getKeyChar()方法返回值的数据类型是char,所以在进行判断时,要将返回值与字符‘0’-‘9’进行比较,而不是数值0-9。

对任务14代码做如下修改:

首先,引入.*。

第二步,实现KeyListener监听器。

第三步,对联系方式文本框txt进行监听,格式为Listener(this)。

第四步,添加方法keyPressed(KeyEvent e)、keyReleased(KeyEvent e)和keyTyped(KeyEvent e)。但在本任务中只应用了keyTyped(KeyEvent e)。

第五步,按上述算法,编写事件处理代码。

本任务的代码内容如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

import .*;

import .*;

import .*;

public class Question implements KeyListener

{ ……

JLabel JLabel4 = new JLabel("4、联系方式:",);

JTextField txt = new JTextField(10);

……

public void go(){

Listener(this);

……

}

public void keyPressed(KeyEvent e) { }

public void keyReleased(KeyEvent e) { }

public void keyTyped(KeyEvent e) {

if(!(Char()>='0'&&Char()<='9')){

ssageDialog(win,"请输入0-9之间的数字","提示窗口", _MESSAGE);

}

}

public static void main(String arg[]){

Question be = new Question ();

(); }

}

程序执行结果如图4-33所示。


本文标签: 组件 布局 调查 对话框 显示