|
事件最初由事件源产生,事件源可以是GUI组件Java Bean或由生成事件能力的对象,在GUI组件情况下,事件源或者是组件的同位体(对于Abstract Window Toolkit[awt]GUI组件来说)或组件本身(对于Swing组件来说)。事件生成后放在系统事件队列内部。现在事件处于事件分发线程的控制下。事件在队列中等待处理,然后事件从事件队列中选出,送到dispatchEvent()方法,dispatchEvent()方法调用processEvent()方法并将事件的一个引用传递给processEvent()方法。此刻,系统会查看是否有送出事件的位置,如果没有这种事件类型相应的已经注册的监听器,或者如果没有任何组件受到激活来接收事件类型,事件就被抛弃。当然上图显示的是AWTEvent类的子类的生命周期。dispatchEvent()方法和processEvent()方法把AWTEvent作为一个参数。但对,javax.swing.event并不是AWTEvent子类,而是从EventObject直接继承过来,生成这些事件的对象也会定义fireEvent()方法,此方法将事件送到包含在对象监听器列表内的那种类型的任何监听器。
3.2 Java事件捕获
从上面的分析我们知道,任何事件产生到dispatchEvent()方法分发方法前,所有的事件都是存放在系统事件的队列中,而且所有的事件都由dispatchEvent()方法来分派。所以只要能重载dispatchEvent()方法就可以获取系统的所有事件,包括用户输入事件。一般来说,系统事件队列的操作对用户来说是可以控制。它在后台自动完成所要完成的事情,使用EventQueue类可以查看甚至操纵系统事件队列。
Java提供了EventQueue类来访问甚至操纵系统事件队列。EventQueue类中封装了对系统事件队列的各种操作,除dispatchEvent()方法外,其中最关键的是提供了push()方法,允许用特定的EventQueue来代替当前的EventQueue.只要从EventQueue类中派生一个新类,然后通过push()方法用派生类来代替当前的EventQueue类即可。这样,所有的系统事件都会转发到派生EventQueue类。然后,再在派生类中重载dispatchEvent()方法就可以截获所有的系统事件,包括用户输入事件。下面一段代码给出一个操纵EventQueue的实例:
import java.awt.*;
import java.awt.event.*;
public class GenerateEventQueue extends Frame implements ActionListener{
Button button1 = new Button();
TextField textField1 = new TextField();
public GenerateEventQueue() {
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
GenerateEventQueue generateEventQueue = new GenerateEventQueue();
}
private void jbInit() throws Exception {
button1.setLabel("button1");
button1.addActionListener(this) ;
textField1.setText("textField1");
this.add(button1, BorderLayout.SOUTH);
this.add(textField1, BorderLayout.CENTER);
EventQueue eq=getToolkit().getSystemEventQueue() ;
eq.postEvent(new ActionEvent(button1,ActionEvent.ACTION_PERFORMED,"test" )) ;
addWindowListener(new WinListener());
setBounds(100,100,300,200);
setVisible(true);
}
public void actionPerformed(ActionEvent e) {
textField1.setText("event is :"+e.getActionCommand()) ;
}
}
class WinListener extends WindowAdapter{
public void windowClosing(WindowEvent we){
System.exit(0) ;
}
}
|
运行结果如下图所示:

在文本域中首先出现的是"event is :test",这是因为首先得到处理的是EventQueue对象发送到系统事件队列上的ActionEvent。
上一页 [1] [2] [3] [4] [5] [6] 下一页
 【责编:Youping】 |