图形用户界面通过事件机制响应用户和程序的交互,产生事件的组件称事件源,例如当用户单击某个按钮时就会产生动作事件,该按钮就是事件源。要处理产生的事件,需要在特定的方法中编写处理事件的程序。这样,当产生某种事件时就会调用处理这种事件的方法,从而实现用户与程序的交互,这就是图形用户界面事件处理的基本原理。
现在处理事件的方法是基于授权事件模型(Delegation Event Model)的,这种模型定义了标准一致的机制去产生和处理事件。它的概念十分简单:一个源(Source)产生一个事件(Event),并把它送到一个或多个监听器(Listeners)。在这种方案中,监听器简单地等待,直到它收到一个事件。一旦事件被接受,监听器将处理这些事件,然后返回。这种设计的优点是:处理事件的应用程序可以明确地和用来产生事件的用户接口程序分开。一个用户接口程序可以授权一段特定的代码处理一个事件。
在授权事件模型中,监听器为了接受一个事件通知而必须注册。这样有一个重要的好处:通知只被发送给那些想接受它们的监听器。这是一种比JDK 1.0版本设计的方法更有效的处理事件的方法。以前,一个事件按照封装的层次被传递,直到它被一个组件处理。这需要组件接受那些它们不处理的事件,所以浪费了宝贵的时间;而授权事件模型则避免了这个开销。
Java事件处理机制的核心是这些代表事件的类。因而,从浏览事件类开始,学习事件处理。
在java.util包中被封装的EventObject类是Java事件类层次结构的根结点。它是所有事件类的父类。它的一个构造函数如下所示。
EventObject(Object src)
这里,src是一个可以产生事件的对象。
EventObject类包括两个方法:getSource( )和toString( )。getSource( )方法返回的是事件源。它通常的形式如下所示。
Object getSource()
这里,返回的是等价于事件的一个字符串。
在java.awt包中被定义的AWTEvent类是EventObject类的子类。同时作为所有基于awt的事件的父类(不论直接还是间接),它在授权事件模型中被使用。它的getID( )方法可以被用来决定事件的类型。这个方法的形式如下所示。
int getID()
注意:EventObject是所有事件类的父类。
AWTEvent是所有在授权事件模型中处理的AWT事件类的父类。
java.awt.event这个包定义了一些能被各种用户接口单元产生的事件类型。在表10-2中列举了这个包中的主要事件类,并对它们的产生条件进行了简要的描述。
表10-2 java.awt.event中的主要事件类
事 件 类 |
描 述 |
ActionEvent |
通常在单击一个按钮,选择一个列表项或者一个菜单项时发生 |
AdjustmentEvent |
当操作一个滚动条时发生 |
ComponentEvent |
当一个组件隐藏、移动、改变大小或成为可见时发生 |
ContainerEvent |
当一个组件从容器中加入或删除时发生 |
FocusEvent |
当一个组件获得或失去键盘焦点时发生 |
InputEvent |
所有组件的输入事件的抽象超类 |
ItemEvent |
当一个复选框或列表项被单击时发生;当一个列表框或一个可选择菜单的项被选择或取消时发生 |
KeyEvent |
当输入从键盘获得时发生 |
MouseEvent |
当鼠标被拖动、移动、点击、按下、释放时发生;或者在鼠标进入或退出一个组件时发生 |
TextEvent |
当文本区和文本框的文本改变时发生 |
WindowEvent |
当一个窗口激活、关闭、失效、恢复、最小化、打开或退出时发生 |
为了进行事件处理,需要创建实现Listener接口的类;而按Java的规定,在实现该接口的类中,必须同时实现接口中所定义的全部方法。在具体的程序设计过程中,有可能只用到接口中的一个或几个方法,为了方便,Java为那些声明了多个方法的Listener接口提供了对应的事件监听器接口和事件适配器类。
事件监听器是一个在事件发生时被通知的对象。它有两个要求:第一,为了可以接受到特殊类型事件的通知,它必须在事件源中已经被注册。第二,它必须实现接受和处理通知的方法。
用于接受和处理事件的方法在java.awt.event包中被定义为一系列的接口。例如,MouseMotionListener接口定义了两个在鼠标被拖动时接受通知的方法。
表10-3列出了通常用到的监听器接口,同时还简要地说明了它们所定义的方法。接下来将解释每一个接口所包含的一些特殊方法。
表10-3 通常使用的监听器接口
接 口 |
描 述 |
ActionListener |
定义了一个接受动作事件的方法 |
AdjustmentListener |
定义了一个接受调整事件的方法 |
ComponentListener |
定义了4个方法来识别何时隐藏、移动、改变大小和显示组件 |
ContainerListener |
定义了两个方法来识别何时从容器中加入或删除组件 |
FocusListener |
定义了两个方法来识别何时组件获得或失去焦点 |
ItemListener |
定义了一个方法来识别何时项目状态改变 |
KeyListener |
定义了3个方法来识别何时键按下、释放和输入字符事件 |
MouseListener |
定义了5个方法来识别何时鼠标单击、进入组件、离开组件、按下和释放事件 |
MouseMotionListener |
定义了两个方法来识别何时鼠标拖动和移动 |
TextListener |
定义了一个方法来识别何时文本值改变 |
WindowListener |
定义了7个方法来识别何时窗口激活、关闭、失效、最小化、还原、打开和退出 |
(1)ActionListener接口。
在这个接口中定义了actionPerformed( )方法,当一个动作事件发生时,它将被调用。一般形式如下所示。
void actionPerformed (ActionEvent ae )
(2)AdjustmentListener接口。
在这个接口中定义了adjustmentValueChanged( )方法,当一个调整事件发生时,它将被调用。其一般形式如下所示。
void adjustmentValueChanged (AdjustmentEvent ae )
(3)ComponentListener接口。
在这个接口中定义了4个方法,当一个组件被改变大小、移动、显示或隐藏时,它们将被调用。其一般形式如下所示。
void componentResized ( ComponentEvent ce )
void componentMoved ( ComponentEvent ce )
void componentShown ( ComponentEvent ce )
void componentHidden ( ComponentEvent ce )
注意:AWT处理改变大小和移动事件。componentResized( )和componentMoved( )方法只用来提供通知。
(4)ContainerListener接口。
在这个接口中定义了两个方法,当一个组件被加入到一个容器中时,componentAdded( )方法将被调用;当一个组件从一个容器中删除时,componentRemoved( )方法将被调用。这两个方法的一般形式如下所示。
void componentAdded(ContainerEvent ce )
void componentRemoved (ContainerEvent ce )
(5)FocusListener接口。
在这个接口中定义了两个方法,当一个组件获得键盘焦点时,focusGained( )方法将被调用;当一个组件失去键盘焦点时,focusLost()方法将被调用。这两个方法的一般形式如下所示。
void focusGainde (FocusEvent fe )
void focusLost (FocusEvent fe )
(6)ItemListener接口。
在这个接口中定义了itemStateChanged( )方法,当一个选项的状态发生变化时,它将被调用。这个方法的原型如下所示。
Void itemStateChanged (ItemEvent ie )
(7)KeyListener接口。
在这个接口中定义了3个方法,当一个键被按下和释放时,相应的KeyPressed( )方法和KeyReleased( )方法将被调用;当一个字符已经被输入时,KeyTyped( )方法将被调用。
(8)MouseListener接口。
在这个接口中定义了5个方法,当鼠标在同一点被按下和释放时,mouseClicked( )方法将被调用;当鼠标进入一个组件时,mouseEntered( )方法将被调用;当鼠标离开组件时,mouseExited()方法将被调用;当鼠标被按下和释放时,相应的mousePressed()方法和mouseReleased( )方法将被调用。
这些方法的一般形式如下所示。
void mouseClicked (MouseEvent me)
void mouseClicked (MouseEvent me)
void mouseEntered (MouseEvent me)
void mouseExited (MouseEvent me)
void mousePressed (MouseEvent me)
void mouseReleased (MouseEvent me)
(9)MouseMotionListener接口。
在这个接口中定义了两个方法,当鼠标被拖动时,mouseDragged( )方法将被调用多次;当鼠标被移动时,mouseMoved( )方法将被调用多次。这些方法的一般形式如下所示。
void mouseDragged (MouseEvent me )
void mouseMoved (MouseEvent me )
(10)TextListener接口。
在这个接口中定义了textChanged( )方法,当文本区或文本框发生变化时,它将被调用。这个方法的一般形式如下所示。
void textChanged (TextEvent te )
(11)WindowListener接口。
在这个接口中定义了7个方法,当一个窗口被激活或禁止时,windowActivated( )方法或windowDeactivated( )方法将相应地被调用;如果一个窗口被最小化,windowIconified( )方法将被调用;如果一个窗口被打开或关闭时,windowOpened( )方法或windowClosed( )方法将相应地被调用。
这些方法的一般形式如下所示。
void windowActivated (WindowEvent we )
void windowCloseed (WindowEvent we )
void windowClosing (WindowEvent we )
void windowDeactivated (WindowEvent we )
void windowDeiconified (WindowEvent we )
void windowIconified (WindowEvent we )
void windowOpened (WindowEvent we )
Java提供了一个适配器类(Adapter Class),它可以使一些情况下的事件处理变得简单。一个适配器类实现并提供了一个事件监听器接口中所有的方法,但这些方法都是空方法。当只想接受和处理特定的事件监听器接口对应的一部分事件时,适配器类将十分有用。可以定义一个扩展了相应适配器类的新类来作为事件监听器,然后只实现那些感兴趣的事件处理方法。
例如,MouseMotionAdapter类有两个方法:mouseDragged()方法和mouseMoved( )方法。这些空方法的声明被定义在MouseMotionListener接口中。如果只对鼠标的拖动事件感兴趣,可以简单地继承MouseMotionAdapter类并实现mouseDragged( )方法。MouseMotion Adapter类中实现mouseMoved( )方法的空方法将处理鼠标移动事件。
表10-4列出了在java.awt.event包中定义的适配器类,并且注明了它们所实现的接口。
表10-4 适配器类实现的监听器接口
适配器类 |
监听器接口 |
适配器类 |
监听器接口 |
ComponentAdapter |
ComponentListener |
MouseAdapter |
MouseListener |
ContainerAdapter |
ContainerListener |
MouseMotionAdapter |
MouseListener |
FocusAdapter |
FocusListener |
WindowAdapter |
WindowListener |
KeyAdapter |
KeyListener |
|
|