>> 11.5.2事件和事件监听器

来源:互联网 发布:淘宝外贸店推荐 编辑:程序博客网 时间:2024/06/06 07:41
>> 11.5.2事件和事件监听器 

在事件处理的过程中,主要涉及3类对象:
》Event Source(事件源):事件发生的场所,通常就是各个组件,例如按钮、窗口、菜单等。
》Event(事件):事件封装了GUI组件上发生的特定事情(通常就是一次用户操作)。如果程序需要获得GUI组件上所发生事件的相关信息,都通过Event对象来取得。
Event Listener(事件监听器):负责监听事件源所发生的事件,并对各种事件做出响应处理。
    从图11.20中可以看出:当外部动作在AWT组件上进行操作时,系统会自动生成事件对象,这个事件对象是EventObject子类的实例,该事件对象会自动触发注册到事件源上的事件监听器。
    AWT事件机制涉及到三个成员:事件源、事件事件监听器,其中事件源最容易创建,只要通过new来创建一个AWT组件,该组件就是事件源;事件的产生无须程序员关心,它是由系统自动产生的;所以,事件监听器是整个事件处理的心。
    事件监听器必须事件监听器接口,AWT提供了大量的事件监听器接口用于实现不同类型的事件监听器,用于监听不同类型的事件。AWT中提供丰富的事件类,用于封装不同组件上所发生的特定操作:AWT的事件类都是AWTEvent类的子类,它是EventObject类的子类。
AWT事件分为两大类:低级事件和高级事件。
低级事件
    低级事件是指基于特定动作的事件。如鼠标的进入、点击、拖放等动作的鼠标事件,当组件得到焦点、失去焦点时触发焦点事件。
    》ComponentEvent:组件事件,当组件尺寸发生变化、位置发生移动、显示/隐藏状态发生改变时候触发该事件。
    》ContainerEvent:容器事件,当容器里发生成添加组件、删除组件时触发该事件。
    》WindowEvent:窗口事件,当窗口状态发生改变(如打开、关闭、最大化、最小化)时触发。
    》FocusEvent:焦点事件,当组件得到焦点或失去焦点时触发该事件。
    》KeyEvent:键盘事件,当键进行按下、松开、单击时触发该事件。
    》Mouse Event:鼠标事件,当鼠标进行单击、按下、松开、移动等动作时触发该事件。
    》PaintEvent:组件绘制事件,该事件是一个特殊事件类型,当GUI组件调用update /paint方法来呈现自身时将触发该事件,该事件并非专用于事件处理模型。
  高级事件(语义事件)
    高级事件是基于语义的事件,它可以不和特定的动作相关联,而依赖于触发此事件的类。比如,在TextField中按Enter键会触发ActionEvent事件,滑动滚动条会触发AdjustmentEvent事件,选中项目列表的某一条就会触发ItemEvent事件。
ActionEvent:动作事件,当按钮、菜单项被单击,TextField中按Enter键时触发。
AdjustmentEvent:调节事件,在滑动条上移动滑块以调节数值时触发。
ItemEvent:选项事件,当用户选中某项,或取消选中某项时触发。
TextEvent:文本事件,当文本框、文本域里的文本发生改变时触发。
AWT中事件继承层次图如图11.21所示:
    图11.21中常用的AWT事件使用粗线框框出。对于系统没有用粗线框框出的事件,程序员很少使用它们,它们可能被作为事件基类或作为系统内部实现来使用。
    不同事件需要使用不同的监听器监听,不同的监听器需要实现不同的监听器接口,当指定事件发生后,事件监听器就会调用所包含的事件处理器(实例方法)来处理事件。表11.1显示了常用事件、监听器接口和处理器之间的对应关系。
    通过表11.1可以大致知道常用组件可能发生哪些事件,以及该事件对应的监听器接口,通过实现该监听器接口就可以实现对应的事件处理器。然后通过addXxxListener方法来将事件监听器注册给指定的组件(事件源)。当事件源组件上发生特定事件时,被注册到该组件的事件监听器里的对应方法(事件处理器)将被触发。
下面程序示范了一个监听器监听多个组件,一个组件被多个监听器监听的效果:
程序清单:codes/11/11-5/MultiListener.java
public class MultiListener {
private Frame f = new Frame("测试");
private TextArea ta = new TextArea(6,40);
private Button b1 = new Button("按钮一");
private Button b2 = new Button("按钮二");
public void init(){
//创建FirstListener监听器的实例
FirstListener f1 = new FirstListener();
//给b1按钮注册第一、第二,两个事件监听器
b1.addActionListener(f1);
b1.addActionListener(new SecondListener());
//将f1事件监听器注册给b2按钮
b2.addActionListener(f1);
f.add(ta);
Panel p = new Panel();
p.add(b1);
p.add(b2);
f.add(p, BorderLayout.SOUTH);
f.pack();
f.setVisible(true);
}
class FirstListener implements ActionListener{

@Override
public void actionPerformed(ActionEvent e) {
 ta.append("第一个事件监听器被触发,事件源是" + e.getActionCommand() + "\n");
}
}
class SecondListener implements ActionListener{
public void actionPerformed(ActionEvent e){
ta.append("单击了" +e.getActionCommand() + "按钮\n");
}
}
public static void main(String[] args){
new MultiListener().init();
}
}
  上面程序中b1按钮增加了两个事件监听器,当用户单击b1按钮时,两个监听器的actionPerform方法都会被触发;而且f1监听器同时监听b1, b2两个按钮,当b1, b2任意一个按钮被单击时,f1监听器的actionPerform方法都会被触发。
提示:上面程序中调用了 ActionEvent对象的getActionCommand方法,用于获取被单击按钮上的文本.
运行上面程序,分别单击“按钮一”、“按钮二”一次,将看到如图11.22所示的窗口效果:
    下面程序为窗口添加窗口监听器,从而示范窗口监听器的用法,并允许用户单击窗口右上角的"X"按钮来结束程序。
程序清单:codes/11/一1-5/TestWindowListener.java
public class TestWindowListener {
private Frame f = new Frame("测试");
private TextArea ta = new TextArea(6,50);
public void init(){
f.addWindowListener(new MyListener());
f.add(ta);
f.pack();
f.setVisible(true);
}
//实现一个窗口监听器类
class MyListener implements WindowListener{
public void windowActivated(WindowEvent e){
ta.append("窗口被激活 \n");
}
public void windowClosed(WindowEvent e) {
ta.append("窗口被成功关闭! \n");
}
public void windowClosing(WindowEvent e) {
ta.append("用户试图关闭窗口!\n"); 
System.exit(0);
}
public void windowDeactivated(WindowEvent e) {
ta.append("窗口失去焦点!\n");
}
public void windowDeiconified(WindowEvent e) {
ta.append("窗口被恢复\n");  
}
public void windowIconified(WindowEvent e) {
ta.append("窗口被最小化\n"); 
}
public void windowOpened(WindowEvent e) {
ta.append("窗口初次被打开\n");  
}
}
 
public static void main(String[] args) {
 new TestWindowListener().init();
}
}
运行如下:
    上面程序详细监听了窗口的每个动作,当用户单击窗口右上角的每个按钮时,程序都会做出对应响应,当用户单击窗口的“x”按钮时,程序将正常退出。
    大部分时候,程序无须监听窗口的每个动作,程序只需要为用户单击窗口的“x”按钮提供响应,无须为每个窗口事件提供响应—即程序只想重写windowClosingw事件处理器,但因为该监听器实现了WindowListener接口,实现该接口就不得不实现该接口里的每个抽象方法,这是非常烦琐的事情.为此,AWT提供了事件适配器





0 0