第9章事件处理.docx
- 文档编号:7724518
- 上传时间:2023-01-26
- 格式:DOCX
- 页数:40
- 大小:129.05KB
第9章事件处理.docx
《第9章事件处理.docx》由会员分享,可在线阅读,更多相关《第9章事件处理.docx(40页珍藏版)》请在冰豆网上搜索。
第9章事件处理
第9章Java事件处理
第8章介绍了常用的GUI组件对象的创建、布局以及设置观感效果。
在实际运用中,这些内容只是图形界面设计的一部分,要充分体现GUI用户交互性,就需要这些GUI组件能完成具体的动作。
本章将对Java事件处理做一个详细介绍。
具体涉及到事件处理机制、常用的事件处理等内容。
9.1事件处理概述
9.1.1事件处理模式
从JDK1.1开始起,Java语言采用基于代理的事件处理模型。
基于代理事件处理模型是引进了监听器接口,每个事件类都有相关联的监听器接口。
当用户对GUI组件有所动作,GUI组件会自动产生相应的事件来响应用户的动作。
假设这些GUI组件已经注册了相关的监听器对象,监听器对象会一直监听已注册的组件对象是否有事件发生。
当监听器对象监听到组件有相对应的事件发生,就会调用监听器对象中方法,即事件处理器来实现一定的动作。
就这样,通过对目标监听器对象的相关Java方法调用,实现事件从事件源到监听者的传递。
从上面描述,可以归纳出采用基于代理的事件处理模式涉及到三个基本概念:
事件源、事件对象和事件监听器。
(1)事件源。
事件的产生者,通常是GUI组件对象,如按钮、窗口以及文本框等组件的实例对象;发出某种特定事件的事件源的标识是:
通过指定方法注册到事件监听器对象,并接受对指定事件监听器对象的引用。
(2)事件对象。
所有的事件对象继承自java.util.EventObject类的子类对象。
伴随着事件的发生,会产生相应的状态(如事件发生、监听器要求处理事件等信息),而这些状态信息封装在事件对象中。
事件对象作为单参数传递给响应该事件的监听器对象中的方法。
(3)事件监听器。
每个明确的事件的发生,会有一个对应的Java方法执行事件处理。
这些方法都集中定义在继承java.util.EventListener的某事件监听器接口中。
事件监听器实际上指的是监听器接口的实例对象,可以实现监听器接口的一个或多个方法。
监听器对象可以根据事件对象的状态来响应事件。
为了实现事件的处理,需要执行如下四个步骤:
第1步,程序导入java.awt.event包或javax.swing.event包,即
importjava.awt.event.*;或importjavax.swing.event.*;
通过导入这些关于事件处理的包,可以引入关于事件处理的监听接口,如java.awt.event.ActionListener等以及事件处理中事件类,如java.awt.event.ActionEvent等。
第2步,创建事件源,实际上就是通过调用GUI组件的构造方法,创建和初始化GUI组件对象。
第3步,给事件源注册事件监听器,形如:
事件源对象.addXXXListener(XXXListener);对于同一个事件源而言,允许有多个事件监听器;但是同一个监听器只能被同一个事件源注册一次。
第4步,根据监听得到事件的类型,实现事件监听器接口的对应方法。
例9.1利用Swing包的类JColorChooser,设计一个文字框的文字颜色设置的程序。
importjavax.swing.*;
importjava.awt.*;
importjava.awt.event.*;//导入java.awt.event包
publicclassSimpleEventHandlingextendsJFrameimplementsActionListener{//实现接口
JTextFieldtext;//定义文本框text
JButtoncolorButton;//定义选颜色的按钮colorButton
Containercontainer;
publicSimpleEventHandling(){
super("一个简单示例");
container=getContentPane();
container.setLayout(newFlowLayout());
text=newJTextField("选择颜色的示例文字");图9-1例9.1的运行结果
colorButton=newJButton("选择颜色");
colorButton.addActionListener(this);//注册监听器
container.add(text);
container.add(colorButton);
pack();
setVisible(true);
}
publicvoidactionPerformed(ActionEvente){//实现接口ActionListener的方法actionPerformed()
if(e.getSource()==colorButton){//判断事件源是否是按钮
Colorcolorstyle=Color.black;//定义颜色对象,默认颜色为黑色
colorstyle=JColorChooser.showDialog(this,"选择颜色",colorstyle);//选择颜色
text.setForeground(colorstyle);//设置文本框的前景颜色为选择的颜色
colorButton.setForeground(colorstyle);//设置按钮的前景色为选择的颜色
}
}
publicstaticvoidmain(Stringargs[]){
SimpleEventHandlingseh=newSimpleEventHandling();
seh.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
从例9.1中可以看出,事件处理的过程是:
首先,导入事件处理的软件包java.awt.event,然后定义文本框组件和按钮组件;再将按钮组件注册相应的监听器对象。
由于这个例子是实现一个ActionListener接口,所以,注册按钮组件到实现该接口的实例对象。
为了让按钮动作发生时,能出现颜色的选择处理,对ActionListener接口的方法actionPerformed()进行定义,来实现颜色选择的动作。
9.1.2事件处理的方式
从9.1.1节中,已经了解到在实现事件处理的过程是利用监听器接口实现事件处理,其实就是在同一个类中实现一个事件的接口。
对该接口的方法进行定义,实现特定的功能。
一般形式如下:
publicclass事件发生类名implements事件监听器接口{
……
public事件发生类名(){
…
组件.addXXXListener(this);//注册到监听器对象,this表示当前对象。
…}
publicvoid监听器接口说明的方法1(){
……
}……
publicvoid监听器接口说明的方法n(){
……
}
}
这种方法的优点在于:
可以直接对监听器接口的方法进行处理和调用,并且应用简单方便。
但是,这种方式存在一个问题,由于实现接口的方法和定义类的方法处于平行定义,如果要求对多个组件有不同的处理,这种方法无疑会增加阅读程序的困难。
Java语言在具体应用中,还允许用其他三种方式来实现事件的处理:
利用独立监听器类实现事件处理;利用内部类实现事件处理;以及利用匿名内部类实现事件处理。
利用监听器类实现事件处理,就是通过扩展一个监听器接口,定义监听器类,然后对要求发生动作的组件在注册到这个监听器类的对象中。
这种方法的一般形式如下:
publicclass自定义监听类名extends事件适配器(或implements事件监听器){//定义监听器类
……
publicvoid监听器接口说明的方法1(){
……}……
publicvoid监听器接口说明的方法n(){
……}
}
publicclass事件发生类名{//定义事件发生的类
……
public自定义监听类名(){
…
组件.addXXXListener(new自定义监听类名());/注册组件到监听器对象
…
}….
}
为了说明问题,我们将例9.1用定义监听器类的方式来改写。
例9.2定义监听器类,实现一个文字框的文字颜色设置的程序。
importjavax.swing.*;//定义自定义的按钮
importjava.awt.*;
publicclassSimpleButtonextendsJButton{
JTextFieldtext;
Colorcolor;
publicSimpleButton(JTextFieldtext){
setText("选择颜色");//设置按钮的文本信息
this.text=text;//接受文本框对象
this.color=Color.black;
}
publicvoidsetTextColor(Colorc){//设置文本框的前景颜色
text.setForeground(c);
}
}
importjava.awt.event.*;//NewActionListener.java
importjavax.swing.*;
importjava.awt.*;
publicclassNewActionListenerimplementsActionListener{//定义一个实现ActionListener的事件类
Colorcolorstyle=Color.black;
publicvoidactionPerformed(ActionEvente){
SimpleButtonbutton=(SimpleButton)e.getSource();
if(e.getSource()instanceofJButton){//如果事件源是按钮
colorstyle=JColorChooser.showDialog(null,"选择颜色",colorstyle);
button.setTextColor(colorstyle);
}
}
}
importjavax.swing.*;//SimpleEventTest.java
importjava.awt.*;
publicclassSimpleEventTestextendsJFrame{//定义测试类
privateSimpleButtonbutton;
privateJTextFieldtext;
Containercontainer;
publicSimpleEventTest(){
super("一个简单示例");
container=getContentPane();
container.setLayout(newFlowLayout());
text=newJTextField("颜色选择的示例文字");//定义文本框对象
button=newSimpleButton(text);//定义自定义的按钮
button.addActionListener(newNewActionListener());//注册监听器
container.add(text);
container.add(button);
pack();
setVisible(true);
}
publicstaticvoidmain(Stringargs[]){
SimpleEventTestseh=newSimpleEventTest();
seh.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
观察例9.2,该例通过定义一个关于事件的具体处理的监听器类NewActionListener。
而在事件发生的类SimpleEventTest中,只需要创建一个监听器类的对象,将自定义SimpleButton组件对象button注册给监听器对象即可。
这种事件处理的方式优点在于,处理事件的方法清晰明了,可读性强。
另外,允许扩展事件适配器(具体内容见9.3节)来定义新的监听器的类,可以减少不需要的方法的处理。
但是,在事件发生的主类中,会增加事件发生对监听器对象的方法的额外调用。
为此,Java语言提供的第三种方式:
利用内部类实现事件处理。
这种方式无疑可以克服上述方法的缺点。
这种方法就是将独立的监听器类定义成事件发生类的内部类。
形式如下:
publicclass自定义监听类名{//定义事件发生的类
……
public自定义监听类名(){
…
组件.addXXXListener(new自定义监听类名());//注册组件到监听器对象
…}
….
class自定义监听类名extends事件适配器(或implements事件监听器){//定义内部监听器类
……
publicvoid监听器接口说明的方法1(){
……}
……
publicvoid监听器接口说明的方法n(){
……}
}//结束内部类
}
为了说明问题,用第三种方法来改写例9.1。
具体内容见例9.3。
例9.3定义监听内部类,实现一个文字框的文字颜色设置的程序。
importjavax.swing.*;
importjava.awt.*;
importjava.awt.event.*;
publicclassSimpleEventHandling2extendsJFrame{//定义事件发生的类
publicJTextFieldtext;
publicJButtoncolorButton;
Containercontainer;
publicSimpleEventHandling2(){
super("一个简单示例");
container=getContentPane();
container.setLayout(newFlowLayout());
text=newJTextField("选择颜色的示例文字");//定义文本框
colorButton=newJButton("选择颜色");//定义按钮
colorButton.addActionListener(newNewActionListener2());//注册监听器
container.add(text);
container.add(colorButton);
pack();
setVisible(true);
}
classNewActionListener2implementsActionListener{//定义内部类
publicvoidactionPerformed(ActionEvente){
if(e.getSource()==colorButton){
Colorcolorstyle=Color.black;
colorstyle=JColorChooser.showDialog(null,"选择颜色",colorstyle);
text.setForeground(colorstyle);
colorButton.setForeground(colorstyle);}
}
}//结束内部类
publicstaticvoidmain(Stringargs[]){
SimpleEventHandling2seh=newSimpleEventHandling2();
seh.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);}
}
利用内部类来实现事件处理,具有上述两种方法的优点。
但是随着发生事件的组件增多,程序会变得比较庞大,增加对程序的理解。
为了减少程序代码的长度,以及让发生事件的组件在具体处理的时候更有针对性,可以采用第四种方式:
利用匿名内部类实现事件处理。
不过,利用匿名内部类更会增加程序阅读的难度。
具体实现的情况见例9.4。
例9.4利用匿名内部类实现事件处理的示例。
importjavax.swing.*;
importjava.awt.*;
importjava.awt.event.*;
publicclassSimpleEventHandling3extendsJFrame{
publicJTextFieldtext;
publicJButtoncolorButton;
Containercontainer;
publicSimpleEventHandling3(){
super("一个简单示例");
container=getContentPane();
container.setLayout(newFlowLayout());
text=newJTextField("选择颜色的示例文字");
colorButton=newJButton("选择颜色");
colorButton.addActionListener(newActionListener(){//定义匿名内部类
publicvoidactionPerformed(ActionEvente){
Colorcolorstyle=Color.black;
if(e.getSource()==colorButton){
colorstyle=JColorChooser.showDialog(null,"颜色选择",colorstyle);
colorButton.setForeground(colorstyle);
text.setForeground(colorstyle);}
}
});//结束匿名类定义
container.add(text);container.add(colorButton);
pack();setVisible(true);}
publicstaticvoidmain(Stringargs[]){
SimpleEventHandling3seh=newSimpleEventHandling3();
seh.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
本节介绍的四种方法各有特点,在具体的应用中依据具体情况采用不同事件处理方式。
9.1.3事件处理类型
不同的GUI组件会产生不同的事件类型。
根据事件类型的不同,会导致需要监听器对事件处理方法的不同。
Java语言根据这些情况,针对不同GUI组件,有不同的事件处理类型。
在特定事件处理类型中,特定的事件类对应于特定的事件监听接口。
Java语言中提供事件处理的包主要有java.awt.event和javax.swing.event包。
其中,java.awt.event包提供了对awt包和swing包常见组件的支持,与事件处理相关常见的的事件类和事件监听器接口见表9-1。
至于swing包提供了对高级事件处理。
本节只对AWT包的事件处理详细介绍。
表9-1常见的事件类和事件监听接口
事件类
事件监听器接口
ActionEvent
ActionListener
ItemEvent
ItemListener
MouseEvent
MouseMotionListener
MouseListener
MouseWheelEvent
MouseWheelListener
KeyEvent
KeyListener
FocusEvent
FocusListener
AdjustmentEvent
AdjustmentLlistener
WindowEvent
WindowListener
WindowStateListener
WindowFocusListener
9.2常用的事件处理
9.2.1动作事件处理
动作事件处理上最简单和最常用的事件处理。
当用户点击按钮或在文本框中按回车键或选择菜单项或使用列表等组件时,都可以采用动作事件来处理这些组件引发的动作。
动作事件处理涉及到接口ActionListener与动作事件类ActionEvent。
通过接口ActionListener可以实现对组件发生动作事件ActionEvent对象的监听与处理。
其中,ActionEvent的主要方法见表9-2。
表9-2ActionEvent的主要方法
方法
功能
StringgetActionCommand()
获取动作命令字符串
intgetModifiers()
获取事件发生的期间的组合键
longgetWhen()
获取事件发生的时间戳
StringparamString()
获取标识此动作事件的参数字符串
实现动作事件,必须依赖于动作事件的监听器ActionListener接口。
动作的执行是通过调用监听器对象的方法来实现的。
ActionListner接口的主要方法见表9-3。
表9-3ActionListener的主要方法
方法
功能
publicvoidactionPerformed(ActionEvent)
动作发生时被调用
下面通过几个具体例子来说明如何应用动作事件处理具体问题。
例9.5设计一个程序,可以实现一个由文本框和文本区组成的简易聊天室界面,该程序允许用户启动聊天也可以禁止聊天。
importjavax.swing.*;
importjava.awt.*;
importjava.awt.event.*;
publicclassSimpleChatRoomextendsJFrameimplementsActionListener{
JPanelchatPanel;//定义聊天面板;
JTextAreadisplayArea;//定义聊天显示区;
JTextFieldinputText;//定义输入文本框;
JButtonstartButton,stopButton;//定义启用和禁止按钮
JLabelstatusLabel;//状态标签
publicSimpleChatRoom(){
setGUIComponent();
getContentPane().setLayout(newBorderLayout());
getContentPane().add(chatPanel,BorderLayout.CENTER);
getContentPane().add(statusLabel,BorderLayout.SOUTH);
pack();
setVisible(true);}
publicvoidsetGUIComponent(){//设置GUI组件
chatPanel=ne
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第9章 事件处理 事件 处理