您好,欢迎访问三七文档
1第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);对于同一个事件源而言,允许有多个事件监听器;但是同一个监听器只能被同一个事件源注2册一次。第4步,根据监听得到事件的类型,实现事件监听器接口的对应方法。例9.1利用Swing包的类JColorChooser,设计一个文字框的文字颜色设置的程序。importjavax.swing.*;importjava.awt.*;importjava.awt.event.*;//导入java.awt.event包publicclassSimpleEventHandlingextendsJFrameimplementsActionListener{//实现接口JTextFieldtext;//定义文本框textJButtoncolorButton;//定义选颜色的按钮colorButtonContainercontainer;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(){3……}……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.javaimportjavax.swing.*;importjava.awt.*;publicclassNewActionListenerimplementsActionListener{//定义一个实现ActionListener的事件类Colorcolorstyle=Color.black;publicvoidactionPerformed(ActionEvente){SimpleButtonbutton=(SimpleButton)e.getSource();if(e.getSource()instanceofJButton){//如果事件源是按钮4colorstyle=JColorChooser.showDialog(null,选择颜色,colorstyle);button.setTextColor(colorstyle);}}}importjavax.swing.*;//SimpleEventTest.javaimportjava.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事件适配
本文标题:第9章 事件处理
链接地址:https://www.777doc.com/doc-5477463 .html