在使用swing编程的时候经常都会用到JButton这个组件,使用Button组件的时候经常都有这样的代码:
JButton btn = new JButton();
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
//此处做事件处理
}
});
老师上课的时候都会教到,说按钮一点击,就会执行actionPerformed方法里面的代码,没错,就是会执行actionPerformed里面的代码,现在的问题是,为啥它会执行actionPerformed方法里面的代码呢?带着这个问题,我们先来了解一下什么叫事件监听。
事件监听:打个比喻就是“守株待兔”,在某个地方等着某个东西,当等到某个东西之后就去做某件事("守株待兔"里面农夫要是等到兔子来了,那肯定得是抓回去煮着吃了)。
在Java中,有一种事件监听机制,其实就是sun封装了一些类,这些类有他们自己的监听思想,我们如果要使用,就继承或拓展他们这些类,从而实现使用事件监听机制的行为。
Java中的事件机制中有3种角色
1,event object:就是具体的事件(事件)
2,event source:就是事件产生的地方(事件源)
3,event listener:就是对事件产生之后应该干什么(监听者)
打个比喻,我们描述一个事情,如果发生xxx事情,就去干xxx事情,守株待兔的故事就是农夫要是等到兔子,就拿回去煮着吃了。
在事件监听中,我们可以这样描述如果发生event object事件,就去干event listener方法里面的事情这里会加上事件产生的地方event source,就是只定在哪或者在什么情况下出现事件才去干某件事情,比如说要是山洞中出现兔子,兔子又没撞树桩,那农夫肯定不能拿着兔子回去煮着吃了。唯一能够让农夫拿回去煮着吃的前提是那兔子自己撞树桩了。
在JDK中,sun提供的event包,位置在java.util.EventListener, 所有的事件监听器都拓展了这个接口,例如ActionListener
public interface ActionListener extends EventListener {
/**
* Invoked when an action occurs.
*/
public void actionPerformed(ActionEvent e);
}
其实EventListener也只是一个标志接口而已
/**
* A tagging interface that all event listener interfaces must extend.
* @since JDK1.1
*/
public interface EventListener {
}
每个时间类都有相关联的监听器接口,事件从事件源到监听者的传递是通过对目标监听者对象的Java方法调用来进行的。
且先不说JButton的ActionLister怎么实现,我们先来一个自定义事件监听,具体需求描述是:
让自己的程序产生一个事件,但不是用鼠标,键盘之类的输入设备进行(也就是JDK中没有实现的事件监听)。例如写一个程序,这个程序是一旦受到邮件,就对邮件进行相关处理,对于“收到邮件”,这个事件,JDK是没有定义的,我们可以自己去定义它,这就是我们的自定义事件。下面的问题就是:如何自定义事件?
我们上面说到事件的参与者有3个(事件,事件源,事件监听者),所以我们要做的就是定义这3个角色。
1,定义事件,必要条件,必须继承java.util.EventObject
import java.util.EventObject;
public class MailEvent extends EventObject{
Object obj;
public MailEvent(Object source) {
super(source);
obj = source;
}
/**
*
*/
private static final long serialVersionUID = -5529585059881850545L;
@Override
public Object getSource() {
return obj;
}
}
2,定义监听接口
import java.util.EventListener;
public interface MailListener extends EventListener{
//此方法定义接收到MailEvent事件之后应该怎么办
public void doEvent(MailEvent event);
}
3,定义事件源
import java.util.Enumeration;
import java.util.Vector;
public class MailSource {
private Vector ve = new Vector();
MailListener mailListener;
public void addMailListener(MailListener listener){
ve.addElement(listener);
}
public void notifyMailEvent(){
Enumeration en = ve.elements();
while(en.hasMoreElements()){
mailListener = (MailListener)en.nextElement();
mailListener.doEvent(new MailEvent(this));
}
}
}
4,测试
public class TestListener {
public static void main(String[] args) {
MailSource ms = new MailSource();
ms.addMailListener(new MailListener() {
@Override
public void doEvent(MailEvent event) {
System.out.println("doEvent");
}
});
ms.notifyMailEvent();
}
}
输出:
doEvent
至此,我们已经会使用自定义事件监听,可以适用很多场合,例如我自己写的线程抛出异常后自动重启
文章在:
http://sziitjiang.iteye.com/blog/1697053
其实也可以使用事件监听来实现,因为事件监听原理也是使用观察者模式,希望对你有帮助!