在java中,事件的处理非常重要,如响应键盘的输入,鼠标的点击,窗口的移动等等。java事由事件类和监听接口组成,算定义一个事件前,必须提供一个事件的监听接口以及一个事件类。java中监听接口是继承自java.util.EventListener的,事件类继承自java.util.EventObject。很多基本的事件系统已经为我们定义好了,我们只要学会调用即可,但是为了更加灵活地满足特定的要求,我们有时候需要自定义事件。
java事件监听器即一组动作接口。如键盘事件KeyEvent对应的接口是:
public interface KeyListener extends EventListener {
public void keyPressed(KeyEvent ev);
public void keyReleased(KeyEvent ev);
public void keyTyped(KeyEvent ev);
}
这个监听器定义了三个动作,键盘按下去调用KeyPressed方法,键盘抬起来调用KeyReleased,键盘被敲击一次调用KeyTyped。
事件监听器是需要注册才能使用的,注册方法如下:
public void add<LitenerType>(<ListenerType>listener);
事件监听器也可以注销,注销方法如下:
public void remove<ListenerType>(<ListenerType>listener);
事件监听器机制是观察者模式的一种,通过把事件源和事件处理流程以监听器的方法隔离开来,减少了主流程与被触发事件的执行流程间的耦合,便于代码的维护和事件处理流程的扩展。
在事件监听机制中,涉及三个角色:事件、发布者和监听器
事件:在事件源和事件监听器之间传递信息的对象实体。
发布者:在事件发生后,负责把事件发布到监听者的对象。
监听者:监听事件,并进行处理或转发的对象。
java中提供了事件监听器实现的框架,使用java事件中的事件监听器,需要熟悉以下几个类或接口:
1.EventObject:事件的基类,在java中自定义事件时需要继承的基类,其定义了事件源---Object类型的属性,可以把发生事件所在的类实例的引用传递过来,以便于在事件处理流程中使用(如果有使用要求的话)。在自定义的事件中,还可以定义自己应用所需的其他属性。
2.EventListener:自定义事件监听器必须实现的接口,没有具体方法,只起到标识作用。
AWT事件及其相应的监听器接口(1)
下表列出了所有AWT事件及其相应的监听器接口,一共10类事件,11个接口。下面这张表应能牢牢记住。
事件类别 | 描述信息 | 接口名 | 方法 |
ActionEvent | 激活组件 | ActionListener | actionPerformed(ActionEvent) |
ItemEvent | 选择了某些项目 | ItemListener | itemStateChanged(ItemEvent) |
MouseEvent | 鼠标移动 | MouseMotionListener | mouseDragged(MouseEvent) mouseMoved(MouseEvent) |
鼠标点击等 | MouseListener | mousePressed(MouseEvent) mouseReleased(MouseEvent) mouseEntered(MouseEvent) mouseExited(MouseEvent) mouseClicked(MouseEvent) |
|
KeyEvent | 键盘输入 | KeyListener | keyPressed(KeyEvent) keyReleased(KeyEvent) keyTyped(KeyEvent) |
FocusEvent | 组件收到或失去焦点 | FocusListener | focusGained(FocusEvent) focusLost(FocusEvent) |
AdjustmentEvent | 移动了滚动条等组件 | AdjustmentListener | adjustmentValueChanged(AdjustmentEvent) |
ComponentEvent | 对象移动缩放显示隐藏等 | ComponentListener | componentMoved(ComponentEvent) componentHidden(ComponentEvent) componentResized(ComponentEvent) componentShown(ComponentEvent) |
WindowEvent | 窗口收到窗口级事件 | WindowListener | windowClosing(WindowEvent) windowOpened(WindowEvent) windowIconified(WindowEvent) windowDeiconified(WindowEvent) windowClosed(WindowEvent) windowActivated(WindowEvent) windowDeactivated(WindowEvent) |
ContainerEvent | 容器中增加删除了组件 | ContainerListener | componentAdded(ContainerEvent) componentRemoved(ContainerEvent) |
TextEvent | 文本字段或文本区发生改变 | TextListener | textValueChanged(TextEvent) |
AWT事件及其相应的监听器接口(2)
下例说明事件处理模型的应用。
import java.awt.*;
import java.awt.event.*;
public class ThreeListener implements MouseMotionListener,MouseListener,WindowListener {
//实现了三个接口
private Frame f;
private TextField tf;
public static void main(String args[])
{
ThreeListener two = new ThreeListener();
two.go(); }
public void go() {
f = new Frame("Three listeners example");
f.add(new Label("Click and drag the mouse"),"North");
tf = new TextField(30);
f.add(tf,"South"); //使用缺省的布局管理器
f.addMouseMotionListener(this); //注册监听器MouseMotionListener
f.addMouseListener(this); //注册监听器MouseListener
f.addWindowListener(this); //注册监听器WindowListener
f.setSize(300,200);
f.setVisible(true);
}
public void mouseDragged (MouseEvent e) {
//实现mouseDragged方法
String s = "Mouse dragging : X="+e.getX()+"Y = "+e.getY();
tf.setText(s);
}
public void mouseMoved(MouseEvent e){}
//对其不感兴趣的方法可以方法体为空
public void mouseClicked(MouseEvent e){}
public void mouseEntered(MouseEvent e){
String s = "The mouse entered";
tf.setText(s);
}
public void mouseExited(MouseEvent e){
String s = "The mouse has left the building";
tf.setText(s);
}
public void mousePressed(MouseEvent e){}
public void mouseReleased(MouseEvent e){ }
public void windowClosing(WindowEvent e) {
//为了使窗口能正常关闭,程序正常退出,需要实现windowClosing方法
System.exit(1);
}
public void windowOpened(WindowEvent e) {}
//对其不感兴趣的方法可以方法体为空
public void windowIconified(WindowEvent e) {}
public void windowDeiconified(WindowEvent e) {}
public void windowClosed(WindowEvent e) {}
public void windowActivated(WindowEvent e) { }
public void windowDeactivated(WindowEvent e) {}
}
上例中有如下几个特点:
1.可以声明多个接口,接口之间用逗号隔开。
……implements MouseMotionListener, MouseListener, WindowListener;
2.可以由同一个对象监听一个事件源上发生的多种事件:
f.addMouseMotionListener(this);
f.addMouseListener(this);
f.addWindowListener(this);
则对象f 上发生的多个事件都将被同一个监听器接收和处理。
3.事件处理者和事件源处在同一个类中。本例中事件源是Frame f,事件处理者是类ThreeListener,其中事件源Frame f是类ThreeListener的成员变量。
4.可以通过事件对象获得详细资料,比如本例中就通过事件对象获得了鼠标发生时的坐标值。
public void mouseDragged(MouseEvent e) {
String s="Mouse dragging :X="+e.getX()+"Y="+e.getY();
tf.setText(s);
}
Java语言类的层次非常分明,因而只支持单继承,为了实现多重继承的能力,Java用接口来实现,一个类可以实现多个接口,这种机制比多重继承具有更简单、灵活、更强的功能。在AWT中就经常用到声明和实现多个接口。记住无论实现了几个接口,接口中已定义的方法必须一一实现,如果对某事件不感兴趣,可以不具体实现其方法,而用空的方法体来代替。但却必须所有方法都要写上。
关于java的监听器的一些题:
(1) 下列有关事件监听器的描述正确的是(C)。
A、一个监听器只能接受一个组件产生的事件
B、只有一个监听器可以被附加到一个组件上
C、多个监听器可以被附加到一个组件
D、以上描述都不对