在使用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
至此,我们已经会使用自定义事件监听,可以适用很多场合,例如我自己写的线程抛出异常后自动重启
文章在:
其实也可以使用事件监听来实现,因为事件监听原理也是使用观察者模式,希望对你有帮助!