java 语言程序设计 李尊朝 第11章 图形用户界面设计
11.1 AWT组件概述
AWT(abstract Window Toolkit)抽象窗口工具集,其目的是为程序员创建界面提供支持。AWT组件定义在java.awt包中,包括组件类、组件
布局类等
图11-1 java.awt的继承关系
1.组件:
组件(component)是构成图形用户界面的基本成分和核心元素。组件类(Component)是一个抽象类,是AWT组件类层次结构的根类,实际使用的组件都是Component类的子类。Component类提供对组件操作的通用方法,包括设置组件位置、设置组件大小、设置组件字体、响应鼠标或键盘事件、组件重绘等
2.容器
容器(container)是一种特殊组件,它能容纳其他组件。它在可视区域内显示其它组件。容器是组件,在容器之中还可以放置其它容器,可以使用多层容器构成富于变化的界面
3.窗口与面板
容器有2种:窗口(window)和面板(panel)。
窗口可独立存在,可被移动,也可被最大化和最小化,有标题栏、边框,可添加菜单栏。
面板不能独立存在,必须包含在另一个容器中。
面板没有标题,没有边框,不可添加菜单栏。
一个窗口可以包含多个面板,一个面板也可以包含另一个面板,但面板不能包含窗口。
窗口类Window和面板类Panel都是容器类Container的子类
4.框架与对话框
窗口类Window主要有2个子类:框架类(Frame)和对话框类(Dialog)。
框架(frame)是一种带标题栏并且可以改变大小的窗口。
应用程序中,使用框架作为容器,在框架中放置组件。
框架类在实例化时默认是最小化的、不可见的,必须通过setSize()方法设置框架大小,通过setVisible(true)方法使框架可见。
表11-1 Frame 的构造方法
Frame类的构造方法
主要功能
Frame()
创建没有标题的窗口
Frame(String title)
创建以title为标题的窗口
表11-2 Frame 的成员方法
Frame类的成员方法
主要功能
int getState()
获得Frame窗口的状态(Frame.Normal表示一般状态,Frame.ICONIFIED表示最小化状态)
void setState(int state)
设置Frame窗口的状态(Frame.Normal表示一般状态,Frame.ICONIFIED表示最小化状态)
String getTitle()
获得Frame窗口的标题
void setTitle(String title)
设置Frame窗口的标题
boolean isResizable()
测试Frame窗口是否可以改变大小
void setResizable(boolean r)
设置Frame窗口是否可以改变大小
Image getIconImage()
返回窗口的最小化图标
void setIconImage(Image img)
设置窗口的最小化图标为img
对话框(dialog)也是一种可移动的窗口,它比框架简单,没有太多的控制元素,如最大化按钮、状态栏等
对话框不能作为应用程序的主窗口,它依赖于一个框架窗口而存在,当框架窗口关闭时,对话框也关闭。
对话框类Dialog的构造方法必须声明对话框所依赖的框架窗口
例11-1 创建窗口
package example11_1; import java.awt.*; //要创建组件,需要导入java.awt包中的类。 public class FrmApp { static Frame fra=new Frame("FrmApp"); public static void main(String args[]) { fra.setSize(250,150); fra.setLocation(100,200); fra.setVisible(true); System.out.println("State:"+fra.getState()); System.out.println("Title:"+fra.getTitle()); System.out.println("Visible:"+fra.isVisible()); } }
运行结果:
State:0
Title:FrmApp
Visible:true
5.标签
标签类(Label)组件用于显示一行文本信息。标签只能显示信息,不能用于输入。
表11-3 Label的构造方法
Label类的构造方法
主要功能
Label()
创建1个没有标题的标签
Label(String str)
创建1个以str为标题的标签
Label(String str,int align)
创建1个以str为标题的标签,并以align为对齐方式,其中Label.LEFT、Label.CENTER、Label.RIGHT分别为居左、居中和居右
表11-4 Label的成员方法
Label类的成员方法
主要功能
int getAlignment()
返回标签标题的对齐方式
Void setAlignment(int align)
设置标签标题的对齐方式
String getText()
获得标签标题
Void setText(String text)
设置标签标题为text
例11-2 在窗口中建立一个标签
package example11_2; import java.awt.*; public class LabApp { public static void main(String args[]) { Frame fra=new Frame("LabApp"); Label lab=new Label(); //创建1个空标签 fra.setSize(250,150); lab.setText("This is a label"); //为标签添加标题 lab.setAlignment(Label.CENTER); lab.setBackground(Color.white); //引用Component类的方法设置标签背景颜色 lab.setForeground(Color.black); //引用Component类的方法设置标签标题颜色 Font fnt=new Font("Serief", Font.ITALIC+Font.BOLD,22); lab.setFont(fnt); fra.add(lab); fra.setVisible(true); } }
程序运行时,出现如图所示的窗口
6.按钮
按钮是最常见的一种组件,用来控制程序运行的方向。用户单击按钮时,计算机将执行一系列命令,完成一定的功能。
按钮通过java.awt包的Button类创建。
表11-5 Button的构造方法
Button类的构造方法
主要功能
Button()
创建一个没有标题的按钮
Button(String str)
创建一个以str为标题的按钮
表11-6 Button的方法
Button类的成员方法
主要功能
String getLabel()
获得按钮的标题
Void setLabel(String str)
设置按钮的标题为str
例11-3 在窗口中建立一个按钮
package example11_3; import java.awt.*; public class ButtApp { public static void main(String args[]) { Frame fra=new Frame("ButtApp"); fra.setSize(250,170); fra.setLayout(null); //关闭页面设置 Button butt=new Button("click"); butt.setSize(100,50); butt.setLocation(75,60); fra.add(butt); fra.setVisible(true); } }
程序运行时,出现如图所示的窗口
7. 文本编辑组件
文本编辑组件有文本行和文本区
文本编辑组件有文本行和文本区。
文本行是一个单行文本编辑框,用于输入一行文字。文本行由java.awt包中的TextField类来创建
表11-7 TextField构造方法
TextField类的构造方法
主要功能
TextField()
创建空的文本行
TextField(int columns)
创建空的文本行,具有指定列数
TextField(String text)
创建文本为text的文本行
TextField(String text,int culumns)
创建具有指定列数、文本为text的文本行
表11-8 TextField的成员方法
TextField类的成员方法
主要功能
String getText()
获得文本行的文本
int getColumns()
获得文本行的列数
void setText(String text)
设置文本行的文本为text
void setColumns(int columns)
设置文本行的列数
例11-4 创建文本行
package example11_4; import java.awt.*; public class TextApp { public static void main(String args[]) { Frame fra=new Frame("文本框程序"); TextField txt1=new TextField(50); TextField txt2=new TextField("Text Field", 50); fra.setBounds(0,0,300,200); fra.setLayout(null); txt1.setBounds(50,50,130,20); //设置文本框的大小 txt2.setBounds(50,100,130,30); fra.add(txt1); fra.add(txt2); fra.setVisible(true); } }
11.2 布局管理
Java提供了多种风格和特点的布局管理器,每一种布局管理器指定一种组件相对位置和大小布局。布局管理器是容器类所具有的特性,每种容器都有一种默认的布局管理器。
在java.awt包中共提供了5个布局管理器类:
Ø FlowLayout
Ø BorderLayout
Ø CardLayout
Ø GridLayout
Ø GridBagLayout
每个类都是java.lang.Object类的子类。
11.2.1 BorderLayout类
BorderLayout(边布局)的布局策略是把容器内的空间划分为东、西、南、北、中5个区域,这5个区域分别用英文的East、West、South、North、Center表示。向容器中加入每个组件都要指明它放在容器的哪个区域。如果某个区域没有分配组件,则其他组件可以占据它的空间。
表11-9 BorderLayout布局
BorderLayout类的构造方法
功能说明
BorderLayout ()
创建新的BorderLayout布局
BorderLayout(int hgap,int vgap)
创建组件之间水平和垂直间距分别为hgap和vgap的BorderLayout布局
例11-5 应用BorderLayout布局
package example11_5; import java.awt.*; public class BorLay { public static void main(String args[]) { Frame frm=new Frame("BorderLayout"); BorderLayout layout=new BorderLayout(5,7); frm.setBounds(0,0,300,200); frm.setLayout(layout); Button butN,butS,butW,butE,butC; butN=new Button("north button"); butS=new Button("south button"); butW=new Button("west button"); butE=new Button("east button"); butC=new Button("center button"); frm.add(butN, BorderLayout.NORTH); frm.add(butS, BorderLayout.SOUTH); frm.add(butW, BorderLayout.WEST); frm.add(butE, BorderLayout.EAST); frm.add(butC, BorderLayout.CENTER); frm.setVisible(true); } }
运行结果如图11-6所示
11.2.2 FlowLayout类
FlowLayout(流式布局)的布局策略提供按行布局组件方式,将组件按照加入的先后顺序从左向右排列,当一行排满之后转到下一行继续按照从左向右的顺序排列。组件保持自己的尺寸,一行能容纳的组件的数目随容器的宽度变化。
表11-10 FlowLayout类的构造方法
FlowLayout类的构造方法
功能说明
FlowLayout ()
创建FlowLayout布局,组件使用缺省的居中对齐方式,各组件的垂直与水平间距都是5个像素。
FlowLayout (int align)
创建FlowLayout布局,组件使用align指定的对齐方式,各组件的垂直与水平间距都是5个像素。align的取值可以是FlowLayout.LEFT、FlowLayout.CENTER和FlowLayout.RIGHT,分别代表靠左、居中和靠右对齐。
FlowLayout(int align,int hgap,int vgap)
创建FlowLayout布局,组件使用align指定的对齐方式,各组件的垂直与水平间距分别为hgap和vgap。
例11-6 使用FlowLayout布局
public static void main(String args[]) { Frame frm=new Frame("BorderLayout"); FlowLayout layout=new FlowLayout(); frm.setBounds(0,0,200,200); frm.setLayout(layout); Button but1,but2; TextField txt1,txt2; but1=new Button("button 1"); but2=new Button("button 2"); txt1=new TextField("text 1",10); txt2=new TextField("text 2",10); frm.add(but1); frm.add(but2); frm.add(txt1); frm.add(txt2); frm.setVisible(true); } }
运行程序出现如图11-7 a所示的界面
11.2.3 GridLayout类
GridLayout(网格布局)管理器将容器划分为大小相等的若干行乘若干列的网格,组件按照从左到右、从上到下的的顺序依此放入各网格中。每个组件占满1格。组件大小随网格大小变化。如果组件数比网格数多,系统将自动增加网格数;如果组件数比网格数少,未用的网格区空闲。
表11-11 GridLayout类的构造方法
GridLayout类构造方法
功能说明
GridLayout ()
创建具有1行1列的GridLayout布局。
GridLayout(int rows, int cols)
创建具有rows行和cols列的GridLayout布局。
GridLayout(int rows, int cols, int hgap, int vgap)
创建具有rows行和cols列的GridLayout(GridLayout)布局,组件的行间距和列间距分别是hgap和vgap像素。
例 11-7 使用GridLayout布局。
package example11_7;
import java.awt.*;
public class GridLay {
public static void main(String args[])
{
Frame frm=new Frame("GridLayout");
GridLayout layout=new GridLayout(2,2); //定义2行2列的GridLayout
frm.setBounds(0,0,200,200);
frm.setLayout(layout);
String names[]={ "butt1","butt2","butt3","butt4"};
for(int i=0; i<names.length; i++)
{
frm.add( new Button(names[i]));
}
frm.setVisible(true);
}
}
运行结果
11.3 事件处理
11.3 事优处理
11.3.1 委托事件模型
JDK1.1之后采用委托事件模型
(delegation event model)。
1.事件
事件(event)是指一个状态的改变,或者一个动作的发生。例如,单击一个按钮,将产生单击事件;单击窗口关闭按钮,产生窗口关闭事件
2.事件类
在Java中,用不同的类处理不同的事件。在java.awt.event包中定义了许多事件类,如单击事件类(ActionEvent)和窗口事件类(WindowEvent)
3.事件源
事件由用户操作组件产生,被操作的组件称为事件源。
例如,用户单击一个按钮,产生单击事件,按钮则是事件源;用户单击窗口关闭按钮,产生窗口关闭事件,窗口组件是事件源。
4.事件监听器
在图形界面程序中,不仅需要创建组件,而且还需指定组件所能响应的事件,以及该事件发生时需要执行的动作(语句序列)。
一个组件能响应哪些事件,响应事件后需执行的语句序列存放在什么位置,这些功能由事件监听器负责。为了实现此功能,在开发程序时,
用户需要做以下2件事:
(1).向事件源注册事件监听器
向事件源注册一个事件监听器,需要调用事件源的addXXXListener()之类的方法。例如,向按钮button注册单击事件监听器需调用以下方法:
button.addActionListener(this);
当程序运行时,事件监听器一直监视按钮button,一量用户单了该按钮,事件监听器将创建一个单击事件类ActionEvent的对象
(2).实现事件处理方法
事件处理方法是事件发生时需要执行的方法,其方法体是事件发生时需要执行的语句序例。
java为每个事件定义了一个相应的事件监听器接口(listener interface),其中声明了事件得理的抽象方法.例如,单击事件的监听器接口是
ActionLisstener,其中声明了actionPerformed()方法。程序运行过程中,当用户单击一个按钮时,事件监听器将通知执行actionPerformed()
方法。
由于事件监听器接口中声明的都是抽象方法,所以用户需要在程序中实现接口中声明抽象方法。
如果一个组件需要响应多个事件,则必须向它注册多个事件监听器;如果多个组件需要响应同一个事件,则必须向它们注册同一个事件监听器。
5.事件运作流程
按照委托事件模型,事件运作流程如下:
1.在程序中,实现事件监听器接口(实现接口中声明的所有抽象方法),向事件源注册事件监听器;
2.程序运行过程中,用户在事件源上引发某种事件(执行某种操作)时,Java产生事件对象;
3.事件源将事件对象传递给事件监听器;
4.事件监听器根据事件对象的种类,调用相应的事件处理方法进行事件处理
6.确定事件监听器
在编写事件处理的程序代码时,首先必须确定事件源与事件监听器。事件源的选择通常比较容易。事件监听器必须是实现事件监听器
接口的类对象。
7.编写事件处理程序代码
在事件处理程序中,必须实现事件监听器接口中声明的事件处理方法。事件处理方法以事件对象作为参数。当事件源上发生事件时,产生的事件
对象将以参数形式传递事件处理方法。在事件处理方法中,可以访问事件对象的成员。
例如,要创建一个窗口程序类ButtEvent,当用户单击窗口中的按钮button时,需要将窗口的前景设置为灰色。选择button为事件源,选择Butt
Event类的对象明为事件监听器。事件处理方法actionPerformed(ActionEvent e)的参数是事件类ActionEvent的对象,在actionPerformed
(ActionEvent e)的方法体中执行将窗口的背景设置为灰色的命令:
setBackground(Color.gray);
例11-8 处理按钮单击事件
package example11_8; import java.awt.*; import java.awt.event.*;//导入java.awt.event包中的类 public class ButtEventApp extends Frame implements ActionListener{ static ButtEventApp frm=new ButtEventApp();//之所以将frm声明为static,是由于在main()方法和actionPerformed()方法中都要
//访问frm public static void main(String args[]) { frm.setTitle("ButtEventApp"); frm.setSize(300,160); frm.setLayout(null); Button btn; btn=new Button("push"); btn.setBounds(120,80,60,30); btn.addActionListener(frm); frm.add(btn,BorderLayout.CENTER); frm.setVisible(true); } public void actionPerformed (ActionEvent e)//实现ActionListener接口中声的抽象方法actionPerformed(), { frm.setBackground(Color.red); }
解析: 要进行事件处理,需导入java.awt.event包中的类。本例中将选择ButtEventApp的类对象作为事件监听器,所以ButtEventApp必须实现
ActionListerner接口,实现ActionListener接口中声明的抽象方法ActionPerformed(),将设置窗口背景为红色的命令“setBackground(Color.red)”
置于actionPerformed()方法体中.语句“btn.addActionListener(frm)”将ButtEventApp的对象frm作为事件监听器给事件源btn.之所以将frm声明为
static,是由于在main()方法和actionPerformed()方法中都要访问frm.
程序运行过程中,当用户单击按钮btn时,将执行actionPerformed()方法,将窗口背景设置为红色。
例11-9利用内部类处理按钮单击事件。
内部类是在其他类的内部声明的类,包含内部类的类称为外部类,此时内部类成为外部类的称为外部
类,此时内部类成为外部类的成员,内部类具有成员的四种访问权限,也可以声明为static.
本例程序的功能与上例相同,程序代码不同之处 采用内部类对象作为事件监听器。
package example11_9; import java.awt.*; import java.awt.event.*; public class InnClassEvent { static Frame frm=new Frame(); public static void main(String args[]) { frm.setTitle("ButtEventApp"); frm.setSize(300,160); frm.setLayout(null); Button btn; btn=new Button("push"); btn.setBounds(120,80,60,30); btn.addActionListener(new InnCla()); frm.add(btn,BorderLayout.CENTER); frm.setVisible(true); } static class InnCla implements ActionListener { public void actionPerformed(ActionEvent e) { frm.setBackground(Color.red); } } }
11.3.2 事件类和监听器接口
1.事件类
Java定义的多数事件类在java.awt.event包中。AWTEvent类是所有事件类的祖先类,它又继承了java.util.EventObject类,而EventObject类又继承了
java.lang.Object类
2.事件监听器接口
Java中的每个事件类都有一个监听器接口,接口中声明了一个或多个抽象的事件处理方法。如果一个类实现事件监听器接口,其对象就可以作为对应事件的监听器,
具备监视和处理事件的能力。
AWT中的主要事件类、所对应的事件监听器接口及接口所提供的方法如表11-12所示。
表11-12事件监听器接口和事件监听器接口中的方法
AWT中的组件和可触发的事件类的对应关系如表11-13所示
表11-13 AWT中组件和可触发的事件类
3.事件适配器类
根据接口性质,一个类如果实现一个事件监听器接口,则必须实现该接口中所有的抽象方法。如果事件监听器接中中所包含多个方法,既使只需要处理一
个事件,也必须实现接口中的所有事件处理方法,不需响应的事件处理方法体设置为空,编写程序较麻烦。
Java提供了一种简便办法,为包含多个事件处理方法的每个事件监听器接口提供了一个抽象类,称为适配器(adapt)类,类名带有Adapter标记
每个适配器类实现一个事件监听器接口,用空方法体实现该接口中的每个抽象方法。
例如,WindowAdapter类实现WindowListener接口,用空方法体实现WindowListener接口中声明的以下方法:
windowClosing(WindowEvent e)
windowClosed(WindowEvent e)
windowOpened(WindowEvent e)
windowActivated(WindowEvent e)
windowDeactivated(WindowEvent e)
windowIconified(WindowEvent e)
windowDeiconified(WindowEvent e)
这样一来,一个需要处理事件类可以声明为继承适配器类,仅需要覆盖所响应的事件处理方法,再也不需要将其他方法体实现了。
例如,处理窗口事件的类,可以声明为继承WindowAdapter类,仅需要覆盖所响应的窗口事件处理方法。
监听器接口与适配器类的对应关系如表11-14所示。
11-14 监听器接口与对应的适配器类
4.注册事件监听器的方法
向组件类对象注册及撤销事件监听器的方法如表11-15所示。
11.3.3 处理ActionEvent事件
当用户单击按钮(Button)、选择列表框(List)选项、选择菜单项(MenuItem),或是在文本行(TextField)输入文字并按下Enter键,便触发动作事件
(ActionEvent),触发事件的组件将ActionEvent类的对象传递给事件监听器,事件监听器负责执行actionPerformed()方法进行相应的事件处理
ActionEvent类继承了EventObject类的一个常用的方法getSource(),其功能是返回事件源(对象)名。ActionEvent类本身还定义了一些成员,如
getActionCommand(),其功能是返回事件源的字符串信息。
例11-10 处理ActionEvent事件
编程实现:窗口中有标题为button1和button2的2个按钮和1个标签,当单击任一按钮时,标签显示该按钮的标题。
package example11_10;
import java.awt.*;
import java.awt.event.*;
public class ActEvent extends Frame implements ActionListener {
static ActEvent frm = new ActEvent(); //事件监听器
static Button btn1, btn2; //将btn1 设置为static类 actionperformed()和main()方法中都要访问它们
static Label lbl;
public static void main(String args[]) {
frm.setTitle("ActionEvent");
frm.setSize(240, 160);
frm.setLayout(new FlowLayout());
btn1 = new Button(" button 1 ");
btn2 = new Button(" button 2 ");
lbl = new Label(" no clicking ");
btn1.addActionListener(frm); //通过btn1.addActionListener(frm)分别向btn1注册frm.
btn2.addActionListener(frm);
frm.add(btn1);
frm.add(btn2);
frm.add(lbl);
frm.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == btn1) //得到触发事件的事件源
lbl.setText("button 1 clicked");
else
lbl.setText("button 2 clicked");
}
}
11.3.4 处理ItemEvent事件
当窗口中的选项组件Checkbox(选择框)和List(列表框)等被选择时,发生选项事件(item event)。
Java用ItemEvent类处理选项事件。ItemEvent类事件的监听器必须实现ItemListener接口,实现其中声明的itemStsteChanged()方法:
public void itemStateChanged(ItemEvent e)
程序运行过程中,当用户选择选项组件时,该方法被执行。
例11-11 处理ItemEvent事件
编程实现:窗口中有标题为green和yellow的2个单选按钮和1个文本行,当选择任一单选按钮时,文本行中显示该单选按钮的标题。
package example11_11;
import java.awt.*;
import java.awt.event.*;
public class IteEvent extends Frame implements ItemListener {
static IteEvent frm = new IteEvent();
static Checkbox chb1, chb2;
static TextField txt1;
public static void main(String args[]) {
frm.setTitle("ItemEvent");
frm.setSize(240, 160);
frm.setLayout(new FlowLayout());
CheckboxGroup grp = new CheckboxGroup();
chb1 = new Checkbox("green");
chb2 = new Checkbox("yellow");
txt1 = new TextField(" None is selected ");
chb1.setCheckboxGroup(grp);
chb2.setCheckboxGroup(grp);
chb1.addItemListener(frm);
chb2.addItemListener(frm);
frm.add(chb1);
frm.add(chb2);
frm.add(txt1);
frm.setVisible(true);
}
public void itemStateChanged(ItemEvent e) {
if (e.getSource() == chb1)
txt1.setText("green is selected");
else if (e.getSource() == chb2)
txt1.setText("yellow is selected");
}
}
处理ItemEvent事件。
11.3.5 处理TextEvent事件
当TextField或TextArea组件中的文本改变时,触发文本事件(TextEvent),Java用TextEvent类处理该事件。
TextEvent类事件的监听器必须实现TextListener接口,实现其中声明的textValueChanged()方法:
public void textValueChanged(TextEvent e)
程序运行过程中,当TextField或TextArea组件中文本改变时,该方法被执行
例11-12 处理textEvent事件
package example11_12;
import java.awt.*;
import java.awt.event.*;
public class TextEvent extends Frame implements TextListener{
static TextEvent frm = new TextEvent();
static TextField txt1, txt2;
public static void main(String args[]) {
frm.setTitle("TextEvent");
frm.setSize(240, 160);
frm.setLayout(new FlowLayout());
txt1 = new TextField(20);
txt2 = new TextField(20);
txt1.addTextListener(frm);
frm.add(txt1);
txt2.setEditable(false);
frm.add(txt1);
frm.add(txt2);
frm.setVisible(true);
}
public void textValueChanged(TextEvent e)
{
txt2.setText(txt1.getText());
}
}
11.3.6 处理KeyEvent事件
当按下键盘中的任一键时,将触发键盘事件(key event), Java用KeyEvent类处理该事件。
KeyEvent类的成员方法
TextEvenT类事件的监听器必须实现KeyListener接口中声明的三个方法,如表11-17所示。
Keylistener接口的成员方法。
例11-13 处理TextEvent事件
编程实现:窗口中有1个文本行和1个文本区,当按下某字符时,在文本行中显示该字符;当键被按下事件发生时,在文本区显示被按下的字符;当键被释放事件发生时,
在文本区显示被释放的字符;当键入字符事件发生时,在文本区显示被输入的字符。
package example11_13;
import java.awt.*;
import java.awt.event.*;
public class KeysEvent extends Frame implements KeyListener{
static KeysEvent frm=new KeysEvent(); //事件监听器
static TextField txf;
static TextArea txa;
public static void main(String args[])
{
frm.setTitle("KeyEvent");
frm.setSize(240,200);
frm.setLayout(new FlowLayout());
txf=new TextField(20);
txa=new TextArea(6,20);
txa.setEditable(false);
txf.addKeyListener(frm);
frm.add(txf);
frm.add(txa);
frm.setVisible(true);
}
public void keyPressed(KeyEvent e)
{
txa.setText("");
txa.append(e.getKeyChar()+" is pressed!\n");
}
public void keyReleased(KeyEvent e)
{
txa.append(e.getKeyChar()+" is released!\n");
}
public void keyTyped(KeyEvent e)
{
txa.append(e.getKeyChar()+" is typed!\n");
}
}例11-14 利用KeyAdapter类处理TextEvent事件编程实现:窗口中有2个文本行,当键入某字符时,在第1个文本行中显示该字符,并利用KeyAdapter类处理键入字符事件,在第1个文本行中显示“x is entered”,其中x表示被键入的字符。
package example11_14;
import java.awt.*;
import java.awt.event.*;
public class KeysEvent2 extends Frame {
static KeysEvent2 frm = new KeysEvent2();
static TextField txt1, txt2;
public static void main(String args[]) {
frm.setTitle("KeyEvent");
frm.setSize(240, 130);
frm.setLayout(new FlowLayout());
txt1 = new TextField(20);
txt2 = new TextField(20);
txt2.setEditable(false);
txt1.addKeyListener(new KeysAdapter());//
frm.add(txt1);
frm.add(txt2);
frm.setVisible(true);
}
static class KeysAdapter extends KeyAdapter {
public void keyTyped(KeyEvent e) {
txt2.setText(e.getKeyChar() + " is entered!");
}
}
}keysadpater类位于keyEvent2类内,称为内部类。内部类的存取权限除public和缺省外,还可以是private和protected,也可以是static 型的,例如,本例中可以用private或protected修饰keyAdapter类。在使用适配器类处理事件时,为了方便,常常使用继承适配器类的内部类。
11.3.7处理MouseEvent事件
当按下鼠标键、鼠标指针进入或离开某一区域,或者移动、拖动鼠标时,触发鼠标事件(mouse event)。Java用MouseEvent类处理该事件
表11-8 moseevent类的成员方法
Java提供了MouseListener和MouseMotionListener接口,用来处理MouseEvent事件。MouseListener接口用来处理以下事件:
1. 鼠标指针进入某一区域
2. 按下鼠标键
3. 释放鼠标键
4. 鼠标单击(按下和释放鼠标键的整个过程)
5. 鼠标指针离开某一区域
处理这五个事件的监听器必须实现mouselistener接口,实现mouselistener声明的五个方法,如表
MouseMotionListener接口用来处理以下两个事件:
1.鼠标在某一区域移动。
2.鼠标在某一区域拖动
处理这两个事件的监听器必须实现MouseMotionListener接口,实同MouseMotionListener声明的两个方法,如表11-20所示。
表 11-20 MouseMotionListener接口的成员方法
由于Mouserlistener接口中有五个方法,为了方便用户编程,java也提供了适配器类MouseAdapter,用空方法体实现MouseListener接口中的五个方法
处理鼠标指针进入和离开某一区域、按下鼠标键、释放鼠标键及鼠标单击事件时,其监听器也是继承MouseAdapter类的类对象,在其中只需覆盖要处理的
事件所对应的方法。
例 11-15 编程实现:窗口中有2个文本区,当鼠标指针进入和离开第1个文本区时,在第2个文本区显示相应信息;当在第1个文本区单击鼠标、
按下和释放鼠标键时,分别显示其事件及发生的位置信息。
package example11_15; import java.awt.*; import java.awt.event.*; public class MouEvent extends Frame implements MouseListener { static MouEvent frm = new MouEvent(); static TextArea txa1, txa2; public static void main(String args[]) { frm.setTitle("MouEvent"); frm.setSize(240, 300); frm.setLayout(new FlowLayout()); txa1 = new TextArea(5, 30); txa2 = new TextArea(8, 30); txa2.setEditable(false); txa1.addMouseListener(frm); frm.add(txa1); frm.add(txa2); frm.setVisible(true); } public void mouseEntered(MouseEvent e) //鼠标进入事件处理 { txa2.setText("Mouse enters txa1\n"); } public void mouseClicked(MouseEvent e) //鼠标单击事件处理 { txa2.append("Mouse is clisked at[" + e.getX() + "," + e.getY() + "]\n"); } public void mousePressed(MouseEvent e) //鼠标按键事件处理 { txa2.append("Mouse is pressed at [" + e.getX() + "," + e.getY()+ "]\n"); } public void mouseReleased(MouseEvent e) //鼠标键释放事件处理 { txa2.append("Mouse is released at [" + e.getX() + "," + e.getY()+ "]\n"); } public void mouseExited(MouseEvent e) //鼠标离开事件处理 { txa2.append("Mouse exits from txa1 "); } }
例11-16 利用MouseMotionListener接口处理MouseEvent事件
编程实现:窗口中有1个文本区和2个文本行,当鼠标在文本区内移动时,在第1个文本行显示移动信息;当鼠标在文本区内拖动时,在第1个文本行显示拖动信息
package example11_16; import java.awt.*; import java.awt.event.*; public class MouEvent2 extends Frame implements MouseMotionListener{ static MouEvent2 frm=new MouEvent2(); static TextArea txa; static TextField txt1,txt2; public static void main(String args[]) { frm.setTitle("MouEvent"); frm.setSize(240,200); frm.setLayout(new FlowLayout()); txa=new TextArea(5,30); txt1=new TextField(30); txt2=new TextField(30); txa.setEditable(false); txa.addMouseMotionListener(frm); frm.add(txa); frm.add(txt1); frm.add(txt2); frm.setVisible(true); } public void mouseMoved(MouseEvent e) //处理鼠标移动事件 { txt1.setText("Mouse is moved in txa"); } public void mouseDragged(MouseEvent e) //处理鼠标拖动事件 { txt2.setText("Mouse is dragged in txa"); } }
a.初始界面 b.发生MouseEvent事件后的界面
例11-17 利用MouseMotionAdapter类处理MouseEvent事件,实现上例功能
package example11_17; import java.awt.*; import java.awt.event.*; public class MouEvent3 extends Frame { static MouEvent3 frm = new MouEvent3(); static TextArea txa; static TextField txt1, txt2; public static void main(String args[]) { frm.setTitle("MouEvent"); frm.setSize(240, 200); frm.setLayout(new FlowLayout()); txa = new TextArea(5, 30); txt1 = new TextField(30); txt2 = new TextField(30); txa.setEditable(false); txa.addMouseMotionListener(new MouMotionAdapter()); frm.add(txa); frm.add(txt1); frm.add(txt2); frm.setVisible(true); } static class MouMotionAdapter extends MouseMotionAdapter { public void mouseMoved(MouseEvent e) //处理鼠标移动事件 { txt1.setText("Mouse is moved in txa"); } public void mouseDragged(MouseEvent e) //处理鼠标拖动事件 { txt2.setText("Mouse is dragged in txa"); } } }
程序解析: MouEvent3 的类对象不作为事件监听器,所以MouEvent3不用实现MouseMotionListener接口。由于内部类MouMotionAdapter的类对象要作为MouseEvent
事件的监听器,MouMotionAdapter需要继承MouseMotionAdapter类,覆盖MouseMotionAdapter类中的mouseMoved()和mouseDragged()方法,响应鼠标移动和拖动事优。
本例中的程序与例11-16的程序完全相同的功能。
11.3.8 处理WindowsEvent事件
当创建窗口,将窗口缩小成图标,由图标转成正常大小,或关闭窗口时,触发窗口事件(window event)。Java用WindowEvent类处理该类事件,并提供了WindowListener接口, 用来监听该类事件。 windwosListerner接口中声明的七个抽象方法,如表11-21所示。
WindowListener接口的成员方法 |
功能说明 |
windowActivated(WindowEvent, e) |
对应窗口由“非活动”状态转变为“活动”状态事件。 |
windowClosed(WindowEvent, e) |
对应窗口已关闭事件。 |
windowClosing(WindowEvent, e) |
对应窗口关闭(按下窗口关闭按钮)事件。 |
windowDeactivated(WindowEvent, e) |
对应窗口由“活动”状态转变为“非活动”状态事件。 |
windowIconified(WindowEvent, e) |
对应窗口由一般状态转变为最小化状态事件。 |
windowDeiconified(WindowEvent, e) |
对应窗口由最小化状态转变为一般状态事件。 |
windowOpened(WindowEvent, e) |
对应窗口打开事件。 |
由于WindowListener接口中有七个方法,为了方便用户编程,Java也提供了适配器类WindowAdapter,用空方法体实现WindowListener接口中的七个方法。处理窗口事件
时,其监听器也可以是继承WindowAdapter的类对象,在其中只需覆盖需要处理的事件所对应的方法。
例11-18 处理WindowEvent事件
编程实现:当窗口打开、关闭、缩小为图标和由图标转换成一般状态时,在屏幕上显示相应信息。
package example11_18; import java.awt.*; import java.awt.event.*; public class WinEvent extends Frame implements WindowListener { static WinEvent frm = new WinEvent(); public static void main(String args[]) { frm.setTitle("MouEvent"); frm.setSize(240, 200); frm.addWindowListener(frm); frm.setVisible(true); } public void windowClosing(WindowEvent e) { System.out.println("windowClosing() method"); System.exit(0); } public void windowClosed(WindowEvent e) { } public void windowActivated(WindowEvent e) { } public void windowDeactivated(WindowEvent e) { } public void windowIconified(WindowEvent e) { System.out.println("windowIconified() method"); } public void windowDeiconified(WindowEvent e) { System.out.println("windowDeiconified() method"); } public void windowOpened(WindowEvent e) { System.out.println("windowOpened() method"); } }