AWT的事件处理机制是一种委派式事件处理方式:普通组件(事件源)将整个事件处理委托给特定的对象(事件监听器);当该事件源发生指定的事件时,就通知所委托的事件监听器,由事件监听器来处理这个事件。
每个组件均可以针对特定的事件指定一个或多个事件监听对象,每个事件监听器也可以监听一个或多个事件源。因为同一个事件源上可能发生多个事件源。因为同一个事件源上可能发生多种事件,委派式事件处理方式可以把事件源上所有可能发生的事件分别授权给不同的事件监听器来处理;同时也可以让一类事件都使用同一个事件监听器来处理。
上图常用的AWT事件使用粗线框框出,对于系统没有用粗线框框出的事件,程序员很少使用它们,它们可能被作为事件基类或作为系统内部实现来使用。
不同事件需要使用不同的监听器监听,不同的监听器需要实现不同的监听器接口,当指定事件发生后,事件监听器就会调用所包含的事件处理器(实例方法)来处理事件。下表显示了常用事件、监听器接口和处理器之间的关系。
AWT事件分为两大类:低级事件和高级事件。
(1)低级事件:低级事件是指基于特定动作的事件。比如进入、点击、拖放等动作的鼠标事件,当组件得到焦点、失去焦点时触发焦点事件。
ComponentEvent:组件事件,当组件尺寸发生变化、位置发生移动、显示/隐藏状态发生时触发该事件。
ContainerEvent:容器事件,当容器里发生添加组件、删除组件时触发该事件。
WindowEvent:窗口事件,当窗口状态发生改变(如打开、关闭、最大化、最小化)时触发该事件。
FocusEvent:焦点事件,当组件得到焦点或处理失去焦点时触发该事件。
KeyEvent:键盘时间,当按键被按下、松开、单击时触发该事件。
MouseEvent:鼠标事件,当进行单击、按下、松开、移动鼠标等动作时触发该事件。
PaintEvent:组件绘制时间,该事件是一个特殊的事件类型,当GUI组件调用update/paint方法来呈现自身时触发该事件,该事件并非专用于事件处理模型。
(2)高级事件(语义事件):高级事件是基于语义的事件,它可以不和特定的动作相关联,而依赖于触发此事件的类。比如,在TextField中按Enter键会触发ActionEvent事件,在滑动条上移动滑块会触发AdjustmentEvent事件,选中项目列表的某一项就会触发ItemEvent事件。
ActionEvent:动作事件,事件当按钮、菜单项被点击,在TextField中按Enter键时触发该事件。
AdjustmentEvent:调节事件,在滑动条上移动滑块以调节数值时触发该事件。
ItemEvent:选项事件,当用户选中某项,或取消选中某项时触发该事件。
TextEvent:文本事件,当文本框、文本域里的文本发生改变时触发该事件。
/**
* 程序示范了一个监听器监听多个组件,一个组件被多个监听器监听的效果
*/
package codes11;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Frame;
import java.awt.Panel;
import java.awt.TextArea;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class MultiListener {
private Frame f = new Frame("测试");
private TextArea textArea = 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(textArea);
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) {
textArea.append("第一个事件监听器被触发,事件源是:" + e.getActionCommand() + "\n");
}
}
//自定义监听器
class SecondListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
textArea.append("单击了“" + e.getActionCommand() + "” 按钮" + "\n");
}
}
//运行程序
public static void main(String[] args) {
new MultiListener().init();
}
}
/**
* 下面程序为窗口监听器,从而示范窗口监听器的用法,并允许用户单击窗口右上角的“x”按钮来结束程序
*/
package codes11;
import java.awt.Frame;
import java.awt.TextArea;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
public class WindowListenerTest {
private Frame f = new Frame("测试");
private TextArea textArea = new TextArea(6, 40);
//窗体初始化方法
public void init() {
// 为窗口添加窗口事件监听器
f.addWindowListener(new MyListener());
f.add(textArea);
f.pack();
f.setVisible(true);
}
class MyListener implements WindowListener {
@Override
public void windowActivated(WindowEvent e) {
textArea.append("窗口被激活!\n");
}
@Override
public void windowClosed(WindowEvent e) {
textArea.append("窗口被成功关闭!\n");
}
@Override
public void windowClosing(WindowEvent e) {
textArea.append("用户关闭窗口!\n");
System.exit(0);
}
@Override
public void windowDeactivated(WindowEvent e) {
textArea.append("窗口失去焦点!\n");
}
@Override
public void windowDeiconified(WindowEvent e) {
textArea.append("窗口被恢复!\n");
}
@Override
public void windowIconified(WindowEvent e) {
textArea.append("窗口被最小化!\n");
}
@Override
public void windowOpened(WindowEvent e) {
textArea.append("窗口初次被打开!\n");
}
}
public static void main(String[] args) {
new WindowListenerTest().init();
}
}