AWT图形用户界面设计(一)
5.1 用AWT生成图形化用户界面
抽象窗口工具包AWT (Abstract Window Toolkit) 是 API为Java 程序提供的建立图形用户界面GUI (Graphics User Interface)工具集,AWT可用于Java的applet和applications中。它支持图形用户界面编程的功能包括: 用户界面组件;事件处理模型;图形和图像工具,包括形状、颜色和字体类;布局管理器,可以进行灵活的窗口布局而与特定窗口的尺寸和屏幕分辨率无关;数据传送类,可以通过本地平台的剪贴板来进行剪切和粘贴。
5.1.1 java.awt包
java.awt包中提供了GUI设计所使用的类和接口,可从图5.1中看到主要类之间的关系。
java.awt包提供了基本的java程序的GUI设计工具。主要包括下述三个概念:
组件--Component
容器--Container
布局管理器--LayoutManager
5.1.2 组件和容器
Java的图形用户界面的最基本组成部分是组件(Component),组件是一个可以以图形化的方式显示在屏幕上并能与用户进行交互的对象,例如一个按钮,一个标签等。组件不能独立地显示出来,必须将组件放在一定的容器中才可以显示出来。
类java.awt.Component是许多组件类的父类,Component类中封装了组件通用的方法和属性,如图形的组件对象、大小、显示位置、前景色和背景色、边界、可见性等,因此许多组件类也就继承了Component类的成员方法和成员变量,相应的成员方法包括:
getComponentAt(int x, int y)
getFont()
getForeground()
getName()
getSize()
paint(Graphics g)
repaint()
update()
setVisible(boolean b)
setSize(Dimension d)
setName(String name)等
容器(Container)也是一个类,实际上是Component的子类,因此容器本身也是一个组件,具有组件的所有性质,但是它的主要功能是容纳其它组件和容器。
布局管理器(LayoutManager):每个容器都有一个布局管理器,当容器需要对某个组件进行定位或判断其大小尺寸时,就会调用其对应的布局管理器。
为了使我们生成的图形用户界面具有良好的平台无关性,Java语言中,提供了布局管理器这个工具来管理组件在容器中的布局,而不使用直接设置组件位置和大小的方式。
在程序中安排组件的位置和大小时,应该注意以下两点:
1.容器中的布局管理器负责各个组件的大小和位置,因此用户无法在这种情况下设置组件的这些属性。如果试图使用Java 语言提供的setLocation(),setSize(),setBounds() 等方法,则都会被布局管理器覆盖。
2.如果用户确实需要亲自设置组件大小或位置,则应取消该容器的布局管理器,方法为:
setLayout(null);
5.1.3 常用容器
容器java.awt.Container是Component的子类,一个容器可以容纳多个组件,并使它们成为一个整体。容器可以简化图形化界面的设计,以整体结构来布置界面。所有的容器都可以通过add()方法向容器中添加组件。
有三种类型的容器:Window、Panel、ScrollPane,常用的有Panel, Frame, Applet。
1.Frame
以下是容器的例子:
例5.1
import java.awt.*;
public class MyFrame extends Frame{
public static void main(String args[ ]){
MyFrame fr = new MyFrame("Hello Out There!");
//构造方法
fr.setSize(200,200);
//设置Frame的大小,缺省为(0,0)
fr.setBackground(Color.red);
//设置Frame的背景,缺省为红色
fr.setVisible(true);
//设置Frame为可见,缺省为不可见
}
public MyFrame (String str){
super(str); //调用父类的构造方法
}
}
一般我们要生成一个窗口,通常是用Window的子类Frame来进行实例化,而不是直接用到Window类。Frame的外观就像我们平常在windows系统下见到的窗口,有标题、边框、菜单、大小等等。每个Frame的对象实例化以后,都是没有大小和不可见的,因此必须调用setSize( )来设置大小,调用setVisible(true)来设置该窗口为可见的。
另外,AWT在实际的运行过程中是调用所在平台的图形系统,因此同样一段AWT程序在不同的操作系统平台下运行所看到的图形系统是不一样的。例如在windows下运行,则显示的窗口是windows风格的窗口;而在UNIX下运行时,则显示的是UNIX风格的窗口。
2. Panel
例5.2
import java.awt.*;
public class FrameWithPanel extends Frame{
public FrameWithPanel(String str){
super(str);
}
public static void main(String args[]){
FrameWithPanel fr = new FrameWithPanel("Frame with Panel");
Panel pan=new Panel();
fr.setSize(200,200);
fr.setBackground(Color.red);
//框架fr的背景颜色设置为红色
fr.setLayout(null);
//取消布局管理器
pan.setSize(100,100);
pan.setBackground(Color.yellow);
//设置面板pan的背景颜色为黄色
fr.add(pan); //用add方法把面板pan添加到框架fr中
fr.setVisible(true);
}
}
一般我们要生成一个窗口,通常是用Window的子类Frame来进行实例化,而不是直接用到Window类。Frame的外观就像我们平常在windows系统下见到的窗口,有标题、边框、菜单、大小等等。每个Frame的对象实例化以后,都是没有大小和不可见的,因此必须调用setSize( )来设置大小,调用setVisible(true)来设置该窗口为可见的。
另外,AWT在实际的运行过程中是调用所在平台的图形系统,因此同样一段AWT程序在不同的操作系统平台下运行所看到的图形系统是不一样的。例如在windows下运行,则显示的窗口是windows风格的窗口;而在UNIX下运行时,则显示的是UNIX风格的窗口。
5.1.4 layoutmanager 布局管理器(1)
java为了实现跨平台的特性并且获得动态的布局效果,java将容器内的所有组件安排给一个"布局管理器"负责管理,如:排列顺序,组件的大小、位置,当窗口移动或调整大小后组件如何变化等功能授权给对应的容器布局管理器来管理,不同的布局管理器使用不同算法和策略,容器可以通过选择不同的布局管理器来决定布局。
布局管理器主要包括:flowlayout,borderlayout,gridlayout,cardlayout,gridbaglayout
例5.3
import java.awt.*;
public class exgui<
private frame f;
private button b1;
private button b2;
public static void main(string args[])<
exgui that = new exgui();
that.go();
>
public void go()<
f = new frame("gui example");
f.setlayout(new flowlayout());
//设置布局管理器为flowlayout
b1 = new button("press me");
//按钮上显示字符"press me"
b2 = new button("dont press me");
f.add(b1);
f.add(b2);
f.pack();
//紧凑排列,其作用相当于setsize(),即让窗口
尽量小,小到刚刚能够包容住b1、b2两个按钮
f.setvisible(true);
>
>
1. flowlayout
flowlayout 是panel,applet的缺省布局管理器。其组件的放置规律是从上到下、从左到右进行放置,如果容器足够宽,第一个组件先添加到容器中第一行的最左边,后续的组件依次添加到上一个组件的右边,如果当前行已放置不下该组件,则放置到下一行的最左边。
构造方法主要下面几种:
flowlayout(flowlayout.right,20,40);
flowlayout(flowlayout.left);
//居左对齐,横向间隔和纵向间隔都是缺省值5个象素
flowlayout();
//缺省的对齐方式居中对齐,横向间隔和纵向间隔都是缺省值5个象素
例5.4
import java.awt.*;
public class mybuttons<
public static void main(string args[])
<
frame f = new frame();
f.setlayout(new flowlayout());
button button1 = new button("ok");
button button2 = new button("open");
button button3 = new button("close");
f.add(button1);
f.add(button2);
f.add(button3);
f.setsize(300,100);
f.setvisible(true);
>
>
当容器的大小发生变化时,用flowlayout管理的组件会发生变化,其变化规律是:组件的大小不变,但是相对位置会发生变化。例如上图中有三个按钮都处于同一行,但是如果把该窗口变窄,窄到刚好能够放下一个按钮,则第二个按钮将折到第二行,第三个按钮将折到第三行。按钮"open"本来在按钮"ok"的右边,但是现在跑到了下面,所以说"组件的大小不变,但是相对位置会发生变化"。
2. borderlayout
borderlayout 是window,frame和dialog的缺省布局管理器。borderlayout布局管理器把容器分成5个区域:north,south,east,west和center,每个区域只能放置一个组件。
例5.5
import java.awt.*;
public class buttondir<
public static void main(string args[])<
frame f = new frame("borderlayout");
f.setlayout(new borderlayout());
f.add("north", new button("north"));
//第一个参数表示把按钮添加到容器的north区域
f.add("south", new button("south"));
//第一个参数表示把按钮添加到容器的south区域
f.add("east", new button("east"));
//第一个参数表示把按钮添加到容器的east区域
f.add("west", new button("west"));
//第一个参数表示把按钮添加到容器的west区域
f.add("center", new button("center"));
//第一个参数表示把按钮添加到容器的center区域
f.setsize(200,200);
f.setvisible(true);
>
>
在使用borderlayout的时候,如果容器的大小发生变化,其变化规律为:组件的相对位置不变,大小发生变化。例如容器变高了,则north、south区域不变,west、center、east区域变高;如果容器变宽了,west、east区域不变,north、center、south区域变宽。不一定所有的区域都有组件,如果四周的区域(west、east、north、south区域)没有组件,则由center区域去补充,但是如果center区域没有组件,则保持空白。
3. gridlayout
使容器中各个组件呈网格状布局,平均占据容器的空间。
例5.6
import java.awt.*;
public class buttongrid <
public static void main(string args[]) <
frame f = new frame("gridlayout");
f.setlayout(new gridlayout(3,2));
//容器平均分成3行2列共6格
f.add(new button("1")); //添加到第一行的第一格
f.add(new button("2")); //添加到第一行的下一格
f.add(new button("3")); //添加到第二行的第一格
f.add(new button("4")); //添加到第二行的下一格
f.add(new button("5")); //添加到第三行的第一格
f.add(new button("6")); //添加到第三行的下一格
f.setsize(200,200);
f.setvisible(true);
>
>
5.1.4 layoutmanager 布局管理器(2)
4. cardlayout
cardlayout布局管理器能够帮助用户处理两个以至更多的成员共享同一显示空间,它把容器分成许多层,每层的显示空间占据整个容器的大小,但是每层只允许放置一个组件,当然每层都可以利用panel来实现复杂的用户界面。牌布局管理器(cardlayout)就象一副叠得整整齐齐的扑克牌一样,有54张牌,但是你只能看见最上面的一张牌,每一张牌就相当于牌布局管理器中的每一层。
例5.7
import java.awt.*;
import java.awt.event.*; //事件处理机制,下一节的内容
public class threepages implements mouslistener <
cardlayout layout=new cardlayout(); //实例化一个牌布局管理器对象
frame f=new frame("cardlayout");
button page1button;
label page2label; //label是标签,实际上是一行字符串
textarea page3text; //多行多列的文本区域
button page3top;
button page3bottom;
public static void main(string args[])
< new threepages().go(); >
public void go()
< f.setlayout(layout); //设置为牌布局管理器layout
f.add(page1button=new button("button page"),"page1button");
page1button.addmouselistener(this); //注册监听器
f.add(page2label=new label("label page"),"page2label");
page2label.addmouselisener(this); //注册监听器
panel panel=new panel();
panel.setlayout(new borderlayout());
panel.add(page3text=new textarea("composite page"),"center");
page3text.addmouselistener(this);
panel.add(page3top=new button("top button") , "north");
page3top.addmouselistener(this);
panel.add(page3bottom=new button("bottom button") ,"south");
page3bottom.addmouselistener(this);
f.add(panel,"panel");
f.setsize(200,200);
f.setvisible(true);
>
……
>
5.容器的嵌套
在复杂的图形用户界面设计中,为了使布局更加易于管理,具有简洁的整体风格,一个包含了多个组件的容器本身也可以作为一个组件加到另一个容器中去,容器中再添加容器,这样就形成了容器的嵌套。下面是一个容器嵌套的例子。
例5.8
import java.awt.*;
public class exgui3<
private frame f;
private panel p;
private button bw,bc;
private button bfile,bhelp;
public static void main(string args[])
<
exgui3 gui = new exgui3();
gui.go();
>
public void go()<
f = new frame("gui example 3");
bw=new button("west");
bc=new button("work space region");
f.add(bw,"west");
f.add(bc,"center");
p = new panel();
f.add(p,"north");
bfile= new button("file");
bhelp= new button("help");
p.add(bfile);
p.add(bhelp);
f.pack();
f.setvisible(true);
>
>
小 结:
1.Frame是一个顶级窗口。Frame的缺省布局管理器为BorderLayout。
2.Panel 无法单独显示,必须添加到某个容器中。 Panel 的缺省布局管理器为FlowLayout。
3.当把Panel 作为一个组件添加到某个容器中后,该Panel 仍然可以有自己的布局管理器。因此,可以利用Panel 使得BorderLayout 中某个区域显示多个组件,达到设计复杂用户界面的目的 。
4.如果采用无布局管理器 setLayout(null),则必须使用setLocation(),setSize(),setBounds()等方法手工设置组件的大小和位置,此方法会导致平台相关,不鼓励使用。
5.2 AWT事件处理模型
上一节中的主要内容是如何放置各种组件,使图形界面更加丰富多彩,但是还不能响应用户的任何操作,要能够让图形界面接收用户的操作,就必须给各个组件加上事件处理机制。在事件处理的过程中,主要涉及三类对象:
◇ Event-事件,用户对界面操作在java语言上的描述,以类的形式出现,例如键盘操作对应的事件类是KeyEvent。
◇ Event Source-事件源,事件发生的场所,通常就是各个组件,例如按钮Button。
◇ Event handler-事件处理者,接收事件对象并对其进行处理的对象
例如,如果用户用鼠标单击了按钮对象button,则该按钮button就是事件源,而java运行时系统会生成ActionEvent类的对象actionE,该对象中描述了该单击事件发生时的一些信息,然后,事件处理者对象将接收由java运行时系统传递过来的事件对象actionE并进行相应的处理。
由于同一个事件源上可能发生多种事件,因此java采取了授权处理机制(Delegation Model),事件源可以把在其自身所有可能发生的事件分别授权给不同的事件处理者来处理。比如在Canvas对象上既可能发生鼠标事件,也可能发生键盘事件,该Canvas对象就可以授权给事件处理者一来处理鼠标事件,同时授权给事件处理者二来处理键盘事件。有时也将事件处理者称为监听器,主要原因也在于监听器时刻监听着事件源上所有发生的事件类型,一旦该事件类型与自己所负责处理的事件类型一致,就马上进行处理。授权模型把事件的处理委托给外部的处理实体进行处理,实现了将事件源和监听器分开的机制。事件处理者(监听器)通常是一个类,该类如果要能够处理某种类型的事件,就必须实现与该事件类型相对的接口。例如例5.9中类ButtonHandler之所以能够处理ActionEvent事件,原因在于它实现了与ActionEvent事件对应的接口ActionListener。每个事件类都有一个与之相对应的接口。
将事件源对象和事件处理器(事件监听器)分开。
打个不太恰当的比喻,比如说有一位李先生,李先生可能会发生很多法律纠纷,可能是民事法律纠纷,也可能是刑事法律纠纷,那么李先生可以请律师,他可以授权王律师负责帮他打民事法律的官司,同时也可以授权张律师帮他打刑事法律的官司。这个请律师的过程从李先生的角度来看,就是授权的过程,而从王律师和张律师的角度来看,一旦被授权,他们就得时刻对李先生负责,"监听"着李先生,一旦发生民事纠纷了,王律师就要马上去处理,而一旦发生刑事纠纷了,张律师就要马上进行处理。此时此刻,李先生就是事件源,王律师是一个事件处理者,张律师是另外一个事件处理者,民事纠纷和刑事纠纷就是不同类型的事件。
例5.9
import java.awt.*;
import java.awt.event.*;
public class TestButton {
public static void main(String args[])
{
Frame f = new Frame("Test");
Button b = new Button("Press Me!");
b.addActionListener(new ButtonHandler());
f.setLayout(new FlowLayout()); //设置布局管理器
f.add(b);
f.setSize(200,100);
f.setVisible(true);
}
}
class ButtonHandler implements ActionListener {
//实现接口ActionListener才能做事件ActionEvent的处理者
public void actionPerformed(ActionEvent e)
//系统产生的ActionEvent事件对象被当作参数传递给该方法
{
System.out.println("Action occurred");
//本接口只有一个方法,因此事件发生时,系统会自动调用本方法,需要做的操作就把代码写在则个方法里。
}
}
使用授权处理模型进行事件处理的一般方法归纳如下:
1.对于某种类型的事件XXXEvent, 要想接收并处理这类事件,必须定义相应的事件监听器类,该类需要实现与该事件相对应的接口XXXListener;
2.事件源实例化以后,必须进行授权,注册该类事件的监听器,使用addXXXListener(XXXListener ) 方法来注册监听器。
Swing
9.1 Swing
概述
9.2
事件响应原理
9.3
JLable
组件
9.4
JButton
组件与JToggleButton
组件
9.5
JCheckBox
和JRadioButton
组件
9.6
JComboBox
组件
9.7
JList
组件
9.8
JTextField
与JTextArea
组件
9.1 Swing
概
述
图9.1 图形用户界面中常用的组件
9.1.1
JApplet
由于所有的Swing GUI组件都应该包含在JApplet小程序
中,且javax.Swing.JApplet是java.applet.Applet的子类,所以本章
主要介绍javax.Swing的“J组件”,应用程序均以JApplet小程序为
例。JApplet的使用与Applet小程序相似,它们与HTML文件的
配合没有什么差别,差别仅在默认布局策略与个别方法的使用
上,这将在讲述到有关内容时加以讨论。
9.1.2 Swing
中常用的包
由于Swing功能相当强大且复杂,考虑到功能分解的原
则,Java系统将Swing按不同功能分为表9.1所示的若干个包,
它们分别针对于不同的组件及事件。
表9.1 Swing
中常用的包
包 名说 明
javax.swing 最常用的包,包含了各种Swing组件的类
javax.swing.border 包含与Swing组件外框有关的类
javax.swing.colorchooser 针对Swing调色版组件(JColorChooser)设计的类
javax.swing.event 处理由Swing组件产生的事件
javax.swing.filechooser 包含针对Swing文件选择对话框(JFileChooser)所设计的类
javax.swing.plaf 处理Swing组件外观的相关类
javax.swing.table 针对Swing组件表格(JTable)所设计的类
javax.swing.text
包含与Swing文字组件相关的类
javax.swing.text.html
javax.swing.text.html.parser
javax.swing.text.rtf
javax.swing.tree 针对Swing树状元素(JTree)所设计的类
javax.swing.undo 提供Swing文字组件的Redo与Undo功能
表9.1 Swing
中常用的包
9.1.3
常用组件的继承关系
由于本章所述组件所使用的成员方法主要是继承其直接父类
或更高层父类的成员方法,为了正确地使用这些组件,有必要
了解每个组件的继承关系。本章所述组件的继承关系如下:
java.lang.Object
java.awt.Component
java.awt.Container
javax.swing.JComponent
javax.swing.JLabel
javax.swing.JTextField
javax.swing.JTextArea
javax.swing.JList
javax.swing.JComboBox
javax.swing.AbstractButton
javax.swing.JButton
javax.swing.JToggleButton
javax.swing.JCheckBox
javax.swing. JRadioButton
9.2
事件响应原理
设计和实现图形用户界面的工作主要有两个:一是创建组
成界面的各种成分和元素,指定它们的属性和位置关系,根据
具体需要排列它们,从而构成完整的图形用户界面的物理外
观;二是定义图形用户界面的事件和各界面元素对不同事件的
响应,从而实现图形用户界面与用户的交互功能。
图形用户界面之所以能为广大用户所喜爱并最终成为事实
上的标准,很重要的一点就在于图形用户界面的事件驱动机
制,它可以根据产生的事件来决定执行相应的程序段。事件
(event)代表了某对象可执行的操作及其状态的变化。例如,在
图形用户界面中,用户可以通过移动鼠标对特定图形界面元素
进行单击、双击等操作来实现输入/输出操作。
9.2.1
委托事件模型
Java采用委托事件模型来处理事件。委托事件模型的特点是
将事件的处理委托给独立的对象,而不是组件本身,从而将使用
者界面与程序逻辑分开。整个“委托事件模型”由产生事件的对象
(事件源)、事件对象及监听者对象之间的关系所组成。
产生事件的对象会在事件产生时,将与该事件相关的信息封
装在一个称之为“事件对象”的对象中,并将该对象传递给监听者
对象,监听者对象根据该事件对象内的信息决定适当的处理方式。
监听者对象要收到事件发生的通知,必须在程序代码中向产生事
件的对象注册,当事件产生时,产生事件的对象就会主动通知监
听者对象,监听者对象就可以根据产生该事件的对象来决定处理
事件的方法。
监听者对象(listener)就是用来处理事件的对象。监听者对象
等候事件的发生,并在事件发生时收到通知。
9.2.2 Swing
组件的事件及监听者
不同事件源上发生的事件种类不同,不同的事件由不同的
监听者处理。表9.2列出了Swing中各种组件可激发的事件及事
件监听者之间的对应关系。表9.3列出了Swing提供的各事件监
听者与各事件类成员方法之间的关系。请读者务必注意:对应
不同事件需要不同的事件监听者,而每个事件监听者都有相应
的成员方法,我们处理事件的程序代码要写在对应的成员方法
体中。
表9.2 Swing
中组件、事件及事件监听者之间的对应关系
组 件
可激发的事件
(Event) 事件监听者(EventListener)
AbstractButton
(JButton,JToggleButton,
JCheckBox,JRadioButton
)
ActionEvent
ChangeEvent
ItemEvent
ActionListener
ChangeListener
ItemListener
JFileChooser ActionEvent ActionListener
JTextField
JPasswordField
ActionEvent
CaretEvent
DocumentEvent
UndoableEvent
ActionListener
CaretListener
DocumentListener
UndoableListener
表9.2 Swing
中组件、事件及事件监听者之间的对应关系
JTextArea
CaretEvent
DocumentEvent
UndoableEvent
CaretListener
DocumentListener
UndoableListener
JTextPane
JEditorPane
CaretEvent
DocumentEvent
UndoableEvent
HyperlinkEvent
CaretListener
DocumentListener
UndoableListener
HyperlinkListener
JComboBox ActionEvent
ItemEvent
ActionListener
ItemListener
JList ListSelectionEvent
ListDataEvent
ListSelectionListener
ListDataListener
表9.2 Swing
中组件、事件及事件监听者之间的对应关系
JMenuItem
ActionEvent
ChangeEvent
ItemEvent
MenuKeyEvent
MenuDragMouseEvent
ActionListener
ChangeListener
ItemListener
MenuKeyListener
MenuDragMouseListener
JMenu MenuEvent MenuListener
JPopupMenu PopupMenuEvent PopupMenuListener
JProgressBar ChangeEvent ChangeListener
JSlider ChangeEvent ChangeListener
JScrollBar AdjustmentEvent AdjustmentListener
表9.2 Swing
中组件、事件及事件监听者之间的对应关系
JTable
ListSelectionEvent
TableModeEvent
TableColumnModelEvent
CellEditorEvent
ListSelectionListener
TableModeListener
TableColumnModelListener
CellEditorListener
JTabbedPane ChangeEvent ChangeListener
JTree
TreeSelectionEvent
TreeExpansionEvent
TreeWillExpandEvent
TreeModeEvent
TreeSelectionListener
TreeExpansionListener
TreeWillExpandListener
TreeModeListener
JTimer ActionEvent ActionListener
表9.3 Swing
提供的各监听者与各事件类成员方法之间的关系
事件监听者成 员 方 法
CaretListener caretUpdate(CaretEvent e)
CellEditorListener editingCanceled(ChangeEvent e)
editingStopped(ChangeEvent e)
ChangeListener stateChanged(ChangeEvent e)
DocumentListener
changedUpdate(DocumentEvent e)
insertUpdate(DocumentEvent e)
removeUpdate(DocumentEvent e)
HyperlinkListener hyperlinkUpdate(HyperlinkEvent e)
表9.3 Swing
提供的各监听者与各事件类成员方法之间的关系
ListDataListener
contentsChanged(ListDataEvent e)
intervalAdded(ListDataEvent e)
intervalRemoved(ListDataEvent e)
ListSelectionListener valueChanged(ListSelectionEvent e)
MenuDragMouseListener
menuDragMouseDragged(MenuDragMouseEvent e)
menuDragMouseEntered(MenuDragMouseEvent e)
menuDragMouseExited(MenuDragMouseEvent e)
menuDragMouseReleased(MenuDragMouseEvent e)
MenuKeyListener
menuKeyPressed(MenuKeyEvent e)
menuKeyReleased(MenuKeyEvent e)
menuKeyTyped(MenuKeyEvent e)
MenuListener
menuCanceled(MenuEvent e)
menuDeselected(MenuEvent e)
menuSelected(MenuEvent e)
PopupMenuListener
popupMenuCanceled(PopupMenuEvent e)
popupMenuWillBecomelavisible(PopupMenuEvent e)
popupMenuWillB ecomeVisible(PopupMenuEvent e)
表9.3 Swing
提供的各监听者与各事件类成员方法之间的关系
TableColumnModelListener
columnAdded(TableColumnModelEvent e)
columnMarginChanged(ChangeEvent e)
columnMoved(TableColumnModelEvent e)
columnRemoved(TableColumnModelEvent e)
columnSelectionChanged(ListSelectionEvent e)
TableModelListener tableChanged(TableModelEvent e)
表9.3 Swing
提供的各监听者与各事件类成员方法之间的关系
9.2.3
Java.awt
事件类继承关系
Java语言提供了一组事件类来处理不同对象产生的事件。
Java.awt事件类的继承关系如下:
java.awt.Object
java.util.Event
Java.util.Event.Object
. java.awt.AWTEvent
java.awt.event.ActionEvent.
java.awt.event.AdjustmentEvent
java.awt.event.InvocationEvent
java.awt.event.ItemEvent
java.awt.event.TextEvent
java.awt.event.ComponentEvent
java.awt.event.ContainerEvent
java.awt.event.FocusEvent
java.awt.event.PaintEvent
java.awt.event.WindowEvent
java.awt.event.InputEvent
java.awt.event.KeyEvent
java.awt.event.MouseEvent
9.2.4 AWT
中的事件与事件监听者
Swing并不是用来取代原有的AWT的,事实上当我们使用
Swing组件时常常还是需要使用AWT功能的。例如,鼠标和键盘
操作、窗口的变化、组件的增加或删除等都是比较低层的事
件,对于这些事件我们必须使用AWT包提供的处理方法来处理。
所有的Swing组件都是java.awt.Component的子类,它们具有
如下继承关系:
java.lang.Object
java.awt.Component
java.awt.Container
javax.swing.JComponent
javax.swing的各种swing组件
所以,可以利用java.awt.Component类与java.awt.Container
类提供的事件及事件监听者来处理诸如鼠标和键盘操作等低层
事件。
表9.4列出了java.awt.Component与java.awt.Container类提供
的事件与事件监听者之间的关系。表9.5列出了各事件监听者与
各成员方法之间的对应关系。同理,对于AWT中的不同事件需
要不同的事件监听者,而每个监听者都有相应的成员方法,我
们处理事件的程序代码要写在对应的成员方法体中。
表9.4 Component
类与Container
类提供的事件
与事件监听者之间的关系
事 件
(Event) 事件监听者(Listener) 说 明
ComponentEvent ComponentListener 主要处理组件大小的改变,位置的改变
及可见与不可见状态等
ContainerEvent ContainerListener 主要处理组件的加入或移出容器
FocusEvent FocusListener 主要处理取得焦点或移开焦点等操作
KeyEvent KeyListener 主要处理键盘的操作
MouseEvent MouseListener 主要处理鼠标是否在某个组件上、是否
按下鼠标等操作
MouseMotionEve
nt
MouseMotionListene
r 主要追踪鼠标的位置
WindowEvent WindowListener 主要处理窗口问题,如打开、关闭、最
大或最小化等
表9.5 AWT
的各事件监听者与各成员方法之间的关系
AWT事件监听者成 员 方 法
ActionListener actionPerformed(ActionEvent e)
WindowListener
windowActivated(WindowEvent e)
windowClosed(WindowEvent e)
windowClosing(WindowEvent e)
windowDeactivated(WindowEvent e)
windowDeiconified(WindowEvent e)
windowIconified(WindowEvent e)
windowOpened(WindowEvent e)
MouseListener
mouseClicked(MouseEvent e)
mouseEntered(MouseEvent e)
mouseExited(MouseEvent e)
mousePressed(MouseEvent e)
mouseReleased(MouseEvent e)
表9.5 AWT
的各事件监听者与各成员方法之间的关系
MouseMotionListener
mouseDragged(MouseEvent e)
mouseMoved(MouseEvent e)
ContainerListener
componentAdded(ContainerEvent e)
componentRemoved(ContainerEvent e)
ComponentListener
componentHidden(ComponentEvent e)
componentMoved(ComponentEvent e)
componentResized(ComponentEvent e)
componentShown(ComponentEvent e)
FocusListener
focusGained(FocusEvent e)
focusLost(FocusEvent e)
ItemListener itemStateChanged(ItemEvent e)
KeyListener
keyPressed(KeyEvent e)
keyReleased(KeyEvent e)
keyTyped(KeyEvent e)
AdjustmentListener adjustmentValueChanged(AdjustmentEvent e)
9.3
JLable
组
件
JLable组件被称为标签,它是一个静态组件,也是标准组
件中最简单的一个组件。每个标签用一个标签类的对象表示,
可以显示一行静态文本。标签只起信息说明的作用,而不接受
用户的输入,也无事件响应。
创建标签JLable类对象的构造方法如表9.6所示。
表9.6
JLable
类对象的构造方法构
造
方
法
构 造 方 法功能及参数说明
JLable( ) 创建一个空标签
JLable(Icon icon) 创建图标为icon的标签
JLable(Icon icon,int halig)
创建图标为icon的标签,并指定水平排列方式(LEFT、
CENTER、RIGHT、LEADING和TRAILING)
JLable(String text) 创建一个含有文字的标签
JLable(String text,int halig) 创建一个含有文字的标签,并指定水平排列方式
JLable(String text,Icon icon,int halig) 创建一个含有文字及图标的标签,并指定水平排列方
式
表9.7
JLable
类常用成员方法
成 员 方 法功 能 说 明
Icon getIcon( ) 获取此标签的图标
void setIcon(Icon icon) 设置标签的图标
String getText( ) 获取此标签的文本
void setText(String lable) 设置标签的文本
void setHorizontalAlignment(int alig) 设置标签内组件的水平对齐方式
void setVerticalAlignment(int alig) 设置标签内组件的垂直对齐方式
void setHorizontalTextPosition(int tp) 设置标签内文字与图标的水平相对位
置
void setVerticalTextPosition (int tp) 设置标签内文字与图标的垂直相对位
置
9.4
JButton
组件与JToggleButton
组件
JButton组件与JToggleButton组件通常被称为按钮,它是一个
具有按下、抬起两种状态的组件。用户可以指定按下按钮(单击事
件)时所执行的操作(事件响应)。按钮上通常有一行文字(标签)或
一个图标以表明它的功能。此外,Swing组件中的按钮还可以实现
下述效果:
(1) 改变按钮的图标,即一个按钮可以有多个图标,可根据
Swing按钮所处的状态而自动变换不同的图标。
(2) 为按钮加入提示,即当鼠标在按钮上稍做停留时,在按钮
边可出现提示,当鼠标移出按钮时,提示自动消失。
(3) 在按钮上设置快捷键。
(4) 设置默认按钮,即通过回车键运行此按钮的功能。
9.4.1
AbstractButton
类的常用成员方法
表9.8
AbstractButton
类常用成员方法
成 员 方 法功 能 说 明
Icon getIcon( ) 获取默认图标
void setIcon(Icon icon) 设置此按钮的默认图标
String getLabel( ) 获取标签文本
void setLabel(String lable) 设置标签的文本
void setHorizontalAlignment(int alig) 设置文本与图标的水平对齐方式(CENTER,LEFT,
RIGHT,LEADING,TRAILING)
void setVerticalAlignment(int alig) 设置文本与图标的垂直对齐方式(CENTER,TOP,
BOTTOM)
表9.8
AbstractButton
类常用成员方法
void setHorizontalTextPosition(int tp)
设置文本与图标的水平相对位置CENTER,LEFT,
RIGHT,LEADING,TRAILING)
void setVerticalTextPosition (int tp)
设置文本与图标的垂直相对位置(CENTER,TOP,
BOTTOM)
String getText( ) 获取此按钮的文本
void addChangeListener(Change
Listener I) 给按钮添加指定的ChangeListener
void addActionListener(ActionListener I) 给按钮添加指定的ActionListener
void addItemListener(ItemListener I) 给按钮添加指定的ItemListener
void removeActionListener(ActionListener
I)
从按钮中删除指定的ActionListener
void remove
ChangeListener(ChangeListener I)
从按钮中删除指定的ChangeListener
表9.8
AbstractButton
类常用成员方法
void remove
ItemListener(ItemListener I) 从按钮中删除指定的ItemListener
void setPressedIcon(Icon pricon) 设置按钮按下时的图标
void setRolloverIcon(Icon roicon) 设置鼠标经过时按钮的图标
void setRolloverEnabled(boolean b) 设置翻转效果是否有效
void setRolloverSelectedIcon(Icon
seicon) 设置按钮的翻转并选择图标
void setEnabled(boolean b) 设定按钮是否禁用
void setSelected(boolean b) 设置按钮的状态
void setText(String text) 设置按钮的文本
boolean isSelected( ) 获取按钮的状态
Icon getSelectedIcon( ) 获取按钮的图标
9.4.2
JButton
类的构造方法
按钮可分为有、无标签的和有、无图标的等几种情况,因
此,系统提供了表9.9所示的JButton类的构造方法来创建这几种
按钮对象。
表9.9
JButton
类构造方法
构 造 方 法功 能 说 明
JButton( ) 创建一个无标签的按钮
JButton(String text) 创建一个有标签的按钮
JButton(Icon icon) 创建一个有图标的按钮
JButton(String text, Icon icon) 创建一个有标签和图标的按钮
9.4.3
JToggleButton
类的构造方法
JToggleButton按钮与JButton按钮的区别仅在于:当按下
JButton按钮并释放鼠标后,按钮会自动弹起;按下
JToggleButton按钮并释放鼠标后,按钮不会自动弹起,除非再
按一次。表9.10列出了JToggleButton类的构造方法。
表9.10
JToggleButton
类构造方法
构 造 方 法功 能 说 明
JToggleButton( ) 创建一个无标签的按钮
JToggleButton(String text) 创建一个标签为text的按钮
JToggleButton(String text, boolean selected) 创建一个有标签的按钮,且初始状态为false
JToggleButton(Icon icon) 创建一个图标为icon的按钮
JToggleButton(Icon icon, boolean selected) 创建一个有图标的按钮,且初始状态为false
JToggleButton(String text, Icon icon) 创建一个既有标签又有图标的按钮
JToggleButton(String text, Icon icon, boolean selected) 创建一个有标签和图标的按钮,且初始状态为
false
9.4.4
ActionEvent
事件及其响应
按照Java的委托事件模型,当我们在所设计的用户界面上
按下一个按钮时会激发一个事件,这个事件称为动作事件。动
作事件由AWT的ActionEvent类的方法来处理。
1
.动作事件
ActionEvent类含有ACTION_PERFORMED事件,它是引
发某个动作的执行事件。能触发这个事件的动作包括:单击按
钮;双击一个列表中的选项;选择菜单项;在文本框中输入回
车等。
2
.ActionEvent
类可使用的主要方法
getSource( )方法:用来获取引发事件的对象名。
getActionCommand( )方法:用来获取对象的标签或事先为
这个对象设置的命令名。
getSource( )方法是EventObject类提供的,
getActionCommand( )方法是ActionEvent类提供的。由于
ActionEvent类继承了EventObject类,因此,ActionEvent类可以
使用这两个方法。
3
.事件响应
当用户点击对象时,就会引发ActionEvent类代表的动作事件。
例如,下面的语句:
对象名.addActionListener(this);
注册事件源对象的监听者对象为this,而且要求this对象的类
必须声明该类并实现ActionListener接口。当事件发生时,引发
的事件将被此事件的监听者监听到,并引用ActionListener的
actionPerformed(ActionEvent e)方法响应动作事件。在此方法体
中可以引用ActionEvent事件的getSource( )方法来获取引发事件
的对象,也可以引用getActionCommand( )方法来获取对象标签
或事先为这个对象设置的命令名。用户可在actionPerformed( )方
法体中写入处理此事件的程序代码。
9.4.5
应用举例
【示例程序c9_1.java】 编写一个单击按钮时改变标签文本与按
钮文本的内容的程序。
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
//声明该类实现ActionListener 接口,监听者对象是c9_1类的对象
public class c9_1 extends JApplet implements ActionListener
//JApplet是Applet的子类
{ Container cp=getContentPane( ); //创建窗口容器对象
Icon ro=new ImageIcon("g1.gif"); //创建图标对象
Icon ge=new ImageIcon("g2.gif");
Icon pr=new ImageIcon("g3.gif");
JButton bt=new JButton( ); //创建按钮对象
Icon icon=new ImageIcon("g4.jpg");
JLabel lb=new JLabel("Java",icon,JLabel.CENTER); //创建标签对象
public void init( )
{
bt.setRolloverEnabled(true); //将按钮图标变化功能打开
bt.setText("OK"); //添加按钮文本
bt.setHorizontalTextPosition(JLabel.CENTER); //将按钮文字放在图标中间
bt.setVerticalTextPosition(JLabel.BOTTOM); //设置按钮文字在图标下方
cp.add(lb,BorderLayout.NORTH); //添加标签在JApple界面的北部位置上
cp.add(bt,BorderLayout.SOUTH);
bt.setIcon(ge); //设置鼠标离开按钮的图标
bt.setRolloverIcon(ro); //设置鼠标在按钮上的图标
bt.setPressedIcon(pr); //设置鼠标按下按钮的图标
bt.addActionListener(this); //注册bt的监听者对象this
}
// actionPerformed( )方法在单击bt时被系统自动调用
public void actionPerformed(ActionEvent e)
{ if(e.getSource( )==bt) //判断动作事件是否由bt1引发的
{
if(lb.getText( )=="Hello") //修改标签文本
lb.setText(“你好!”);
else
lb.setText("Hello");
if(bt.getText( )=="OK") //修改按钮文本
bt.setText("确定");
else
bt.setText("OK");
}
}
}
图9.2 程序c9_1的运行结果
程序说明:
(1) javax.swing.JApplet是java.awt.Applet的子类,当向
JApplet中添加Swing组件时要使用JApplet的getContentPane( )方
法获得一个Container对象,再引用这个Container对象的add( )方
法将JComponent及其子类对象添加到JApplet中。
(2) 程序中创建的按钮有一个图标,根据鼠标的移动来改
变图标。
(3) 当单击一个按钮时,按钮为监听者对象发送一个称为“动
作事件”的事件对象。产生事件的按钮是事件源,通常说这个按
钮激活一个事件。在这个程序中,bt是事件源,为了能够让按钮
知道为哪个监听对象发送动作事件对象,必须注册按钮的监听
者对象。我们通过调用按钮对象的addActionListener( )方法来实
现,即bt.addActionListener(this),其中this为监听者对象,即
c9_1类的对象(通常把包含事件源的对象作为监听对象)。为了把
c9_1类指定为一个动作监听对象,必须声明该类实现
ActionListener接口,即
public class c9_1 extends JApplet implements ActionListener
其中,ActionListener 接口仅仅包含了一个抽象方法
actionPerformed( )。ActionEvent的对象e代表一个动作事件,并
且支持那些用来发现所产生事件的特征的方法。
当按钮激活一个动作事件时,则此按钮引发的事件将被此
事件的监听者监听到并调用actionPerformed(ActionEvent e)方法
对该事件进行处理。
在方法体中调用e.getSource( )方法来获取引发事件的按钮对
象。
(4) 把组件放到用户希望的位置,在Java语言中是通过布局
来实现的。JApplet界面上的默认布局是BordLayout布局,它将
界面划分为东、南、西、北、中五个区域,我们把组件添加到
JApplet界面时,可以将组件放在这五个区域的任一位置上。更
复杂的内容我们将在后面的章节介绍。
(5) 程序中使用了AbstractButton类的成员方法,详细描述见
表9.8。
9.5
JCheckBox
和JRadioButton
组件
JCheckBox组件被称为复选框(也称检测框),它提供 “选中
/ON”和“未选中/OFF”两种状态。用户点击某复选框就会改变该
复选框原有的状态。
JRadioButton组件被称为选项按钮,在Java中JRadioButton组
件与JCheckBox组件功能完全一样,只是图形不同,复选框为方
形图标,选项按钮为圆形图标。由于目前所使用软件的
RadioButton多为单选按钮,即在同类的一组组件中,用户只能选
择其中之一为ON,其余为OFF。
Java为了与其他系统一致,专门
提供了javax.swing.ButtonGroup类,这个类的功能就是实现诸如
JRadioButton、JRadioButtonMenuItem与JToggleButton等组件的多
选一功能。ButtonGroup类可被AbstractButton类的子类所使用。
9.5.1
JCheckBox
类的构造方法
表9.11
JCheckBox
类构造方法
构 造 方 法功 能 说 明
JCheckBox( ) 创建一个无标签的复选框对象
JCheckBox(String text) 创建一个有标签的复选框对象
JCheckBox(String text,boolean selected) 创建一个有标签的复选框对象,且初始状态为
false
JCheckBox(Icon icon) 创建一个有图标的复选框对象
JCheckBox(Icon icon,boolean selected) 创建一个有图标的复选框对象,且初始状态为
false
JCheckBox(String text, Icon icon) 创建一个有标签和图标的复选框对象
JCheckBox(String text, Icon icon,boolean
selected)
创建一个有标签和图标的复选框对象,且初始
状态为false
9.5.2
JRadioButton
的构造方法
表9.12
JRadioButton
类构造方法
构 造 方 法功 能 说 明
JRadioButton( ) 创建一个无标签的JRadioButton对象
JRadioButton(String text) 创建一个有标签的JRadioButton对象
JRadioButton(String text,boolean selected) 创建一个有标签的JRadioButton对象,且初始
状态为false
JRadioButton(Icon icon) 创建一个有图标的JRadioButton对象
JRadioButton(Icon icon,boolean selected) 创建一个有图标的JRadioButton对象,且初始
状态为false
JRadioButton(String text, Icon icon) 创建一个有标签和图标的JRadioButton对象
JRadioButton(String text, Icon icon,boolean
selected)
创建一个有标签和图标的JRadioButton对象,
且初始状态为false
9.5.3
ItemEvent
事件
1
.选择事件
ItemEvent类只包含一个事件ITEM_STATE_CHANGED,引
发这类事件的动作包括:
(1) 改变复选框JCheckbox对象的选中或不选中状态;
(2) 改变单选按钮JRadioButton对象的选中或不选中状态;
(3) 改变下拉列表框JComboBox对象中选项的选中或不选中状
态;
(4) 改变菜单项JMenuItem对象中选项的选中或不选中状态;
(5) 改变JCheckboxMenuItem对象中选项的选中或不选中状态。
2
.ItemEvent
类的主要方法
(1) ItemSelectable getItemSelectable( )。getItemSelectable( )
方法返回引发选中状态变化的事件源,例如JCheckbox对象。能
引发选中状态变化的事件都必须是实现了ItemSelectable接口类
的对象,该方法的返回值就是这些类的对象的引用。此外,
ItemEvent类的事件也可以使用其父类EventObject类提供的
getSource( )方法返回引发选中状态变化的事件源。
(2) Object getItem( )。getItem( )方法返回引发选中状态变化
事件的具体选择项,例如JComboBox中的具体item。通过调用这
个方法可以知道用户选中了哪个选项。
(3) int getStateChange( )。getStateChange( )方法返回此组件
到底有没有被选中。它的返回值是一个整型值,通常用
ItemEvent类的静态常量SELECTED(代表选项被选中)和
DESELECTED(代表选项被放弃或不选)来表达。
3
.事件响应
当用户点击对象使其选中状态发生变化时,就会引发
ItemEvent类代表的选择事件。例如下面的语句:
对象名.addItemListener(this);
注册事件源对象的监听者对象为this,而且要求this对象的类必须
声明该类实现ItemListener接口。当事件发生时,引发的事件将被
此事件的监听者监听到,并引用ItemListener中的
itemStateChanged(ItemEvent e)方法响应对象的状态改变。在此方
法体中,引用ItemEvent事件的e.getItemSelectable( )方法以获得引
发选择事件的事件源对象,再引用getStateChange( )方法获取选
择事件之后的状态。用户在itemStateChanged( )方法体中编写处
理事件的程序代码。
9.5.4
应用举例
【示例程序c9_2.java】 根据复选框及选择按钮来改变标签
组件的文本大小及颜色。
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class c9_2 extends JApplet implements
ItemListener,ActionListener
{ int i1=0,i2=0,i3=0;
int fonti=10;
Font font;
Container ctp=getContentPane( );
JLabel lb=new JLabel("请选择");
JCheckBox cb1,cb2,cb3; //声明复选框对象
JRadioButton r1,r2,r3; //声明按钮对象
ButtonGroup bg=new ButtonGroup( ); //创建按钮组对象,实现JRadioButton
多选一功能
public void init( )
{ ctp.setLayout(new FlowLayout( )); //设置布局方式为流式布局
cb1=new JCheckBox("红色",false); //创建复选框
cb1.addItemListener(this); //注册cb给监听者this
ctp.add(cb1); //添加复选框在界面上
cb2=new JCheckBox("绿色",false);
cb2.addItemListener(this);
ctp.add(cb2);
cb3=new JCheckBox("蓝色",false);
cb3.addItemListener(this);
ctp.add(cb3);
r1=new JRadioButton("10");
r1.addActionListener(this);
ctp.add(r1); //加载按钮到界面上
r2=new JRadioButton("16");
r2.addActionListener(this);
ctp.add(r2);
r3=new JRadioButton("24");
r3.addActionListener(this);
ctp.add(r3);
bg.add(r1); //加载按钮到按钮组
bg.add(r2);
bg.add(r3);
ctp.add(lb); //加载标签到界面上
}
public void itemStateChanged(ItemEvent e)
{ JCheckBox cbx=(JCheckBox)e.getItem( );
if (cbx.getText( )=="红色")
{ if(e.getStateChange( )==e.SELECTED)i1=255; //判断组件是否被选
else i1=0;}
if (cbx.getText( )=="绿色")
{if(e.getStateChange( )==e.SELECTED)i2=255;
else i2=0; }
if (cbx.getText( )=="蓝色")
{if(cbx.isSelected( ))i3=255; //判断组件是否被选
else i3=0; }
font=new Font("宋体",Font.BOLD,fonti);
lb.setFont(font);
lb.setForeground(new Color(i1,i2,i3));
}
public void actionPerformed(ActionEvent e)
{ String rbt=e.getActionCommand( );
if (rbt=="10") fonti=10;
else if (rbt=="16") fonti=16;
else fonti=24;
font=new Font("宋体",Font.BOLD,fonti);
lb.setFont(font);
lb.setForeground(new Color(i1,i2,i3));
}
}
图9.3 程序c9_2的运行结果
9.6
JComboBox
组件
9.6.1
JComboBox
类的构造方法及成员方法
表9.13
JComboBox
类的构造方法和常用成员方法
方 法说 明
JComboBox(Vector items) 使用向量表items构造一个JComboBox对象
JComboBox( )
JComboBox(ComboBoxModel
a Model)
从已有的Model获取选项,构造
JComboBox对象
JComboBox(Object[ ] items) 使用数组构造一个JComboBox
对象
构造一个空的JComboBox对象。必要时可使用addItem方法
添加选项
表9.13
JComboBox
类的构造方法和常用成员方法
方 法说 明
void
addActionListener(ActionListener e) 添加指定的ActionListener
void addItemListener(ItemListener
aListener) 添加指定的ItemListener
void addItem(Object anObject) 给选项表添加选项
String getActionCommand( ) 获取动作命令
Object getItemAt(int index) 获取指定下标的列表项
int getItemCount( ) 获取列表中的选项数
int getSelectedIndex( ) 获取当前选择的下标
int getSelectedItem( ) 获取当前选择的项
9.6.2
事件响应
JComboBox组件能够响应的事件分为选择事件与动作事件。
若用户选取下拉列表中的选择项时,则激发选择事件,使用
ItemListener事件监听者进行处理;若用户在JComboBox上直接
输入选择项并回车时,则激发动作事件,使用ActionListener事
件监听者进行处理。
下面通过一个具体的程序来说明按钮的事件响应。
【示例程序c9_3.java】 在JComboBox组件中添加4个学生的
名字选项,当点击下拉列表选择项时得到学生的名字,将他的
成绩用标签文本显示。
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class c9_3 extends JApplet implements ItemListener
{
Container ctp=getContentPane( );
JLabel lb1=new JLabel("姓名:"),
lb2=new JLabel("英语:"),
lb3=new JLabel(" ");
String name[ ]={"李林","赵欣","张扬","童梅"},
score[ ]={"80","94","75","87"};
JComboBox cbx=new JComboBox( ); //创建下拉式列表框对象
public void init( )
{
ctp.setLayout(new FlowLayout( )); //设置流式布局
for (int j=0;j<name.length;j++) //添加选项到下拉式列表框对象中
cbx.addItem(name[j]);
ctp.add(lb1);
ctp.add(cbx); //添加下拉式列表框对象到容器上
cbx.addItemListener(this); //注册cbx给监听对象
ctp.add(lb2);
ctp.add(lb3);
}
public void itemStateChanged(ItemEvent e)
{
int c=0;
String str=(String)e.getItem( ); //获取所选项给str
for(int i=0;i<name.length;i++)
if(str==name[i]) //判断str是否是name数组中某个元素的内容
c=cbx.getSelectedIndex( ); //将该选项的下标给c
lb3.setText(score[c]); //获取该学生的成绩
}
}
程序说明:
下拉式列表框产生ItemEvent代表的选择事件。该程序中的
语句cbx.addItemListener(this);表示注册JComboBox类的对象cbx
给监听者对象。当用户单击下拉列表的某个选项时,系统自动
产生一个包含这个事件有关信息的ItemEvent类的对象e,并把该
对象作为实际参数传递给被自动调用的监听者的选择事件响应
方法:itemStateChanged(ItemEvent e)。在这个方法中通过调用
ItemEvent 事件的方法e.getItem( )获得引发当前选择事件的下拉
列表事件源(被选中的项),再调用getSelectedIndex( )获取该选项的
下标值,从而得到name数组的下标值,最终将这个元素的内容
作为新的标签文本输出。
图9.4 c9_3运行结果
9.7
JList
组
件
JList称为列表组件,它将所有选项放入列表框中。如果将
JList放入滚动面板(JScrollPane)中,则会出现滚动菜单效果。利
用JList提供的成员方法,用户可以指定显示在列表框中的选项
个数,而多余的选项则可通过列表的上下滚动来显现。
JList组件与JComboBox组件的最大区别是:JComboBox组
件一次只能选择一项,而JList组件一次可以选择一项或多项。
选择多项时可以是连续区间选择(按住Shift键进行选择),也可以
是不连续的选择(按住Ctrl键进行选择)。
9.7.1
JList
类的构造方法及成员方法
表9.14
JList
类的构造方法和成员方法
构
造
方
法
方 法说 明
JList(Vectorl istData) 使用包含元素的向量构造JList对象
JList( ) 使用空的模式构造JList对象
JList(ListModel dataModel) 使用dataModel模式构造JList对象
JList(Object[ ] listData) 使用指定的数组构造JList对象
成
员
方
法
void
addListSelectionListener(ListSelectionListener e) 添加指定的ListSelectionListener
int getSelectedIndex( ) 获取所选项的第一个下标
int getSelectedIndices( ) 获取所有选项的下标
void setSelection Background(Color c) 设置单元格的背景颜色
void setSelection Foreground(Color c) 设置单元格的前景颜色
int getVisibleRowCount( ) 得到可见的列表选项值
void setVisibleRowCount (int num) 设置可见的列表选项
9.7.2
ListSelectionEvent
事件
JList组件的事件处理一般可分为两种:一种是当用户单击列
表框中的某一个选项并选中它时,将产生ListSelectionEvent类的
选择事件,此事件是Swing的事件;另一种是当用户双击列表框
中的某个选项时,则产生MouseEvent类的动作事件。JList类通过
locatToindex( )方法来得知是单击还是双击。
若希望实现JList的ListSelectionEvent事件,首先必须声明实
现监听者对象的类接口ListSelectionListener,并通过JList类的
addListSelectionListener( )方法注册文本框的监听者对象,再在
ListSelectionListener接口的valueChanged (ListSelectionEvent e)方
法体中写入有关代码,就可以响应ListSelectionEvent事件了。下
面通过示例程序来加以说明。
【示例程序c9_4.java】 设置一个JLabel组件和JList组件,
点击列表框中的选项,将所选项的值作为JLabel组件的文本输出。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class c9_4 extends JApplet implements ListSelectionListener
{ JList lis=null;
JLabel lb=null;
String[ ] s={"小学","初中","高中","大学","研究生"};
public void init( )
{ Container cp=getContentPane( );
cp.setLayout(new BorderLayout( ));
lb=new JLabel( );
lis=new JList(s);
lis.setVisibleRowCount(3); //设置列表框的可见选项行数,
选项超过则出现滚动条
lis.setBorder(BorderFactory.createTitledBorder("请选择"));//
设置列表框的边框文本
lis.addListSelectionListener(this); //注册lis给监听者对象
cp.add(lb,BorderLayout.NORTH);
//将lis对象放入滚动容器,再将此容器加载到界面上。
cp.add(new JScrollPane(lis),BorderLayout.CENTER);
}
public void valueChanged(ListSelectionEvent e)
{ int m=0;
String str="选取的是:";
//取得所有选项的下标值给index数组
int[ ] index = lis.getSelectedIndices( );
for(int i=0;i<index.length;i++)
{ //根据取得的下标值,找到相应的数组元素
m=index[i];
str=str+s[m]+" ";
}
lb.setText(str);//输出选中项的值
}
}
上述程序中的语句:
lis.addListSelectionListener(this);
表示把lis注册给ListSelectionEvent的监听者
ListSelectionListener。当用户单击某个选项时,系统会自动引用
ListSelectionListener的valueChanged( )方法来处理选项的改变。
程序c9_4的运行结果见图9.5。
图9.5 程序c9_4的运行结果
9.8
JTextField
与JTextArea
组件
9.8.1
JTextField
组件的构造方法及成员方法
JtextField被称为文本框。它定义了一个单行条形文本区,
可以输出任何基于文本的信息,也可以接受用户的输入。表9.15
列出了JTextField类的构造方法和成员方法。
表9.15
JTextField
类构造方法和成员方法
方
法
JTextField( )
JTextField(int n)
JTextField(String s)
JTextField(String s,int n)
JTextField(Document doc,String s, int n)
int getColumns( )
void setColumns(int Columns)
void addActionListener(ActionListener e)
void setFont(Font f)
void setHorizontalAlignment(int alig)
void setActionCommand(String com)
功 能 说 明
创建一个JTextField对象
创建一个列宽为n的空JTextField对象
创建一个JTextField对象,并显示字符串s
创建一个JTextField对象,并以指定的字宽n显示字符串s
使用指定的文件存储模式创建一个JTextField对象,并以指定的
字宽n显示字符串s
获取此对象的列数
设置此对象的列数
添加指定的动作事件监听程序
设置字体
设置文本的水平对齐方式(LEFT、CENTER、RIGHT)
设置动作事件使用的命令字符串
9.8.2
JTextArea
组件的构造方法及成员方法
JTextArea被称为文本域。它与文本框的主要区别是:文本
框只能输入/输出一行文本,而文本域可以输入/输出多行文本。
表9.16列出了JTextArea类的构造方法和成员方法。
表9.16
JTextArea
类构造方法和成员方法
方 法功 能 说 明
构
造
方
法
JTextArea ( ) 创建一个JTextArea对象
JTextArea (int n,int m) 创建一个具有n行m列的空JTextArea对
象
JTextArea(String s) 创建一个JTextArea对象,并显示字符
串s
JTextArea(String s,int n,int m) 创建一个JTextArea对象并以指定的行
数n和列数m显示字符串联s
JTextArea(String s,int n,int m,
int k)
创建一个JTextArea对象,并以指定的
行数n、列数m和滚动条的方向显示字
符串s
JTextArea(Document doc) 使用指定的文件存储模式创建一个
JTextArea对象
JTextArea(Document doc,String s,int
n)
使用指定的文件存储模式创建一个
JTextArea对象,并以指定的字宽n显
示字符串s
成
员
方
法
void setFont(Font f) 设置字体
void insert(String str,int pos) 在指定的位置插入指定的文本
void append(String str) 将指定的文本添加到末尾
void replaceRange(String str,int
start,int end)
将指定范围的文本用指定的新文
本替换
public int getRows( ) 返回此对象的行数
public void setRows(int rows) 设置此对象的行数
public int getColumns( ) 获取此对象的列数
public void setColumns(int
Columns) 设置此对象的列数
9.8.3
事件处理
JTextField类只引发ActionEvent事件,当用户在文本框中按
回车键时引发。JTextArea的事件响应由JTextComponent类决定。
JTextComponent类可以引发两种事件:DocumentEvent事件与
UndoableEditEvent事件。当用户修改了文本区域中的文本,如
做文本的增、删、改等操作时,TextComponent类将引发
DocumentEvent事件;当用户在文本区域上撤消所做的增、删、
改时,TextComponent类将引发UndoableEditEvent事件。
(1) 实现文本框的ActionEvent事件。当监听者对象的类声明
实现了ActionListener接口,并且通过
textField.addActionListener(this)语句注册文本框的监听者对象
后,监听程序内部动作事件的actionPerformed(ActionEvent e) 方
法就可以响应动作事件了。
(2) 实现文本区域的DocumentEvent事件。当监听者对象的
类声明实现了DocumentEditListener接口,并且通过
textArea.addDocumentListener(this)语句注册文本区域的监听者
对象后,监听程序内部的DocumentListener接口的下列三个方法
之一就可以响应DocumentEvent事件了。
changedUpdate(DocumentEvent e); //修改文本操作
inset Update(DocumentEvent e); //增加文本操作
remove Update(DocumentEvent e); //删除文本操作
(3) 实现文本区域的UndoableEditEvent事件。当监听者对
象的类声明实现了UndoableEditListener接口,并且通过
textArea.addUndoableEditListener(this)语句注册文本区域的监听
者对象后,监听程序内部的UndoableEditListener接口的
UndoableEditHappened
(UndoableEditEvent e)方法就可以响应UndoableEditEvent事件了。
9.8.4
应用举例
【示例程序c9_5.java】 文本框和文本域组件的使用。
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class c9_5 extends JApplet implements ActionListener
{
Container ctp=getContentPane( );
ImageIcon icon1=new ImageIcon("g1.gif"),
icon2=new ImageIcon("g2.gif");
JLabel lb1=new JLabel("输入文字后按回车:",icon1,JLabel.CENTER),
lb2=new JLabel("输出结果:",icon2,JLabel.CENTER);
JTextField tf1=new JTextField(10); //创建文本框对象
JTextArea tf2=new JTextArea(5,10); //创建文本区域对象
public void init( )
{
ctp.setLayout(new FlowLayout( ));
ctp.add(lb1);
ctp.add(tf1);
ctp.add(lb2);
ctp.add(tf2);
tf1.addActionListener(this);
}
public void actionPerformed(ActionEvent e)
{
String str;
str=tf1.getText( ); //获得文本框的文本给str(此方法是
JTextComponent类的方法)
// tf2.setText(str);
tf2.append(str+"/n"); //将str添加到文本区域中(append方法是
JTextArea类的方法)
}
}
图9.6 程序c9_5的运行结果