<p>本文主要内容:事件处理的基础概念,基本流程,还有一个简单的按钮事件例子(《Core Java》书中例子)。</p><p>1.事件处理基础知识</p><p> JDK 1.1开始,Java的事件处理采用事件委托(代理)模型(event delegation)。</p><p> 在这个模型中,比较重要的几个概念如下:</p><p> (也可以看完第二部分的事件处理过程之后再来看这些概念,或许思路明朗一些)。</p><p> 1.事件源(event source)</p><p> 事件源是一个能够注册监听器对象并发送事件对象的对象。例如按钮或者滚动条就是事件源。</p><p> 2.事件,事件类型和事件对象</p><p> 事件一般是用户在界面上的一个操作,当一个事件发生时,该事件用一个事件对象来表示,事件对象有对应的事件类。</p><p> 不同的事件类描述不同类型的用户动作,不同的事件源可以产生不同类别的事件。例如,按钮可以发送ActionEvent对象,而窗口可以发送WindowEvent对象。</p><p> 在Java中,所有的事件对象都最终派生于java.util.EventObject类。</p><p> 3.事件监听器(event listener)</p><p> 监听器对象是一个实现了特定监听器接口(listener interface)的类的实例。</p><p> 事件监听器类(监听器对象所属的类)必须实现事件监听器接口或继承事件监听器适配器类。</p><p> 事件监听器接口定义了处理事件必须实现的方法。</p><p> 事件监听器适配器类是对事件监听器接口的简单实现。目的是为了减少编程的工作量。</p><p> 处理事件的方法被称为事件处理器,即事件监听器接口定义,并在事件监听器类中实现的方法。</p><p> 4.注册事件监听器</p><p> 为了能够让事件监听器检查某个组件(事件源)是否发生了某些事件,并且在发生时激活事件处理器进行相应的处理,必须在事件源上注册事件监听器。</p><p> 这是通过使用事件源组件的以下方法来完成的:</p><p> addXxxListener(事件监听器对象)</p><p> Xxx对应相应的事件类。</p><p> 5.再论事件和监听器</p><p> 每一类事件有一个相应的事件监听器接口,该接口定义了接收和处理事件的抽象方法。实现该接口的类,就是监听器类。其对象可作为监听器对象向相应的组件注册。</p><p> 事件的类名通常为:XxxEvent</p><p> 对应的事件监听器接口名通常为:XxxListener</p><p> 一个监听器接口定义了一种以上的抽象事件处理方法(事件处理器)。</p><p> 事件监听器类实现事件监听器接口,其类名可以由我们自己取。事件监听器类需要我们自己编写。</p><p>2.事件处理过程</p><p> 在这个event delegation模型中,事件源产生事件对象,然后将其发送给所有注册的的事件监听器对象,监听器对象利用事件对象中的信息决定如何对事件做出响应。</p><p> 从网上找的ppt中的一个图:</p><p><img src="/up_pic/201812/120420513573.png" title="120420513573.png" alt="1.png"/></p><p> 2012-9-8 星期六 10-35-17</p><p>3.实例:处理按钮点击事件</p><p> 为了加深理解,以一个简单的例子来说明(《Core Java》书中例子)。</p><p> 这个例子中:在一个面板中放置三个按钮,添加三个监听器对象用来作为按钮的动作监听器。</p><p> 在这个情况下,只要用户点击面板上的任何一个按钮,相关的监听器对象就会接收到一个ActionEvent对象,它表示有个按钮被点击了。在示例程序中,监听器对象将改变面板的背景颜色。</p><p> 具体流程如下:</p><p> 1.创建按钮JButton,将按钮添加到面板中(在面板中调用add方法);</p><p> 2.需要一个实现了ActionListerner接口的类(事件监听器类),它应该包含一个actionPerformed方法,其签名为:</p><p>public void actionPerformed(ActionEvent event);</p><p></p><p> 当按钮被点击时,我们希望将面板的背景颜色设置为指定的颜色。该颜色存储在监听器类中。</p><p> 3.为每种颜色构造一个监听器对象,将这些对象设置为按钮监听器,即,调用按钮的addActionListener方法注册监听器。</p><p> 代码如下:</p><pre class="brush:java;toolbar:false">/**
@version1.322004-05-04
@authorCayHorstmann
*/
importjava.awt.*;
importjava.awt.event.*;
importjavax.swing.*;
publicclassButtonTest
{
publicstaticvoidmain(String[]args)
{
ButtonFrameframe=newButtonFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
/**
Aframewithabuttonpanel
*/
classButtonFrameextendsJFrame
{
publicButtonFrame()
{
setTitle("ButtonTest");
setSize(DEFAULT_WIDTH,DEFAULT_HEIGHT);
//addpaneltoframe
ButtonPanelpanel=newButtonPanel();
add(panel);
}
publicstaticfinalintDEFAULT_WIDTH=300;
publicstaticfinalintDEFAULT_HEIGHT=200;
}
/**
Apanelwiththreebuttons.
*/
classButtonPanelextendsJPanel
{
publicButtonPanel()
{
//createbuttons
JButtonyellowButton=newJButton("Yellow");
JButtonblueButton=newJButton("Blue");
JButtonredButton=newJButton("Red");
//addbuttonstopanel
add(yellowButton);
add(blueButton);
add(redButton);
//createbuttonactions
ColorActionyellowAction=newColorAction(Color.YELLOW);
ColorActionblueAction=newColorAction(Color.BLUE);
ColorActionredAction=newColorAction(Color.RED);
//associateactionswithbuttons
yellowButton.addActionListener(yellowAction);
blueButton.addActionListener(blueAction);
redButton.addActionListener(redAction);
}
/**
Anactionlistenerthatsetsthepanel'sbackgroundcolor.
*/
privateclassColorActionimplementsActionListener
{
publicColorAction(Colorc)
{
backgroundColor=c;
}
publicvoidactionPerformed(ActionEventevent)
{
setBackground(backgroundColor);
}
privateColorbackgroundColor;
}
}</pre><p></p><p> 例如,如果有一个用户在标有"Yellow"的按钮上点击了一下,那么yellowAction对象的actionPerformed方法就会被调用。这个对象的backgroudColor实例域设置为Color.YELLOW,然后就将面板的颜色设置为黄色了。</p><p> 有一个需要考虑的问题,是ColorAction对象(监听器对象)没有权限访问panel变量。可以采用两种方式解决这个问题:</p><p> 1.将面板存储在ColorAction对象中,并在ColorAction构造器中设置它;</p><p> 2.将ColorAction作为ButtonPanel类的内部类。这样一来,ColorAction就自动地拥有访问外部类的权限了。</p><p> 这里使用的就是第二种方法,ColorAction类中调用过了外部类ButtonPanel中的setBackground方法。这种情形十分常见,事件监听器对象通常需要执行一些对其他对象可能产生影响的操作,可以策略性地将监听器类放置在需要修改状态的那个类中。</p>