java中的事件机制的参与者有3种角色:
1.event object:就是事件产生时具体的“事件”,用于listener的相应的方法之中,作为参数,一般存在与listerner的方法之中
2.event source:具体的接受事件的实体,比如说,你点击一个button,那么button就是event source,这样你必须使button对某些事件进行相应,你就需要注册特定的listener,比如说MouseEvent之中的MouseClicked方法,这是他就必须有了add方法
3.event listener:具体的对监听的事件类,当有其对应的event object产生的时候,它就调用相应的方法,进行处理。在windows程序设计里边这种相应使用callback机制来实现的
先看看jdk提供的event包:
public interface EventListener:所有事件侦听器接口必须扩展的标记接口。
public class EventObject extends Object implements Serializable所有事件状态对象都将从其派生的根类。 所有 Event 在构造时都引用了对象 "source",在逻辑上认为该对象是最初发生有关 Event 的对象。
在Java2处理事件时,没有采用dispatchEvent()-postEvent()-handleEvent()方式,采用了监听器类,每个事件类都有相关联的监听器接口。事件从事件源到监听者的传递是通过对目标监听者对象的Java方法调用进行的。 对每个明确的事件的发生,都相应地定义一个明确的Java方法。这些方法都集中定义在事件监听者(EventListener)接口中,这个接口要继承 java.util.EventListener。
实现了事件监听者接口中一些或全部方法的类就是事件监听者。 伴随着事件的发生,相应的状态通常都封装在事件状态对象中,该对象必须继承自java.util.EventObject。事件状态对象作为单参传递给应响应该事件的监听者方法中。发出某种特定事件的事件源的标识是:遵从规定的设计格式为事件监听者定义注册方法,并接受对指定事件监听者接口实例的引用。 开始之前首先问个问题:您熟悉java.util.EventObject 和java.util.EventListener两个类以及他们已有的子类吗?
如果你已经能够熟练使用jdk为我们提供的事件监听器,并且很熟悉MouseEvent, KeyEvent, WindowEvent等等这些jdk为我们准备好的事件,那么想必你对java的事件机制已经有所理解。但是也许你还是觉得虽然用起来没什么问题,但是原理还是有些糊涂,那么下面我们再进一步自己实现这些事件和监听器,我们把这个取名为自定义事件。 其实自定义事件在java中很有用处,我们有的时候想让自己的程序产生一个事件,但有不希望(或者不可能)用鼠标,键盘之类的输入设备进行操作,比如你写一个应用程序,在这个程序中一旦收到邮件就对邮件进行相关处理,对于“收到邮件”这个事件,jdk中就没有定义。对于这样的事件,以及对于这样的事件的监听器,我们只能自己动手完成了。
其实呢,java事件处理机制就是观察者模式,我这里详细的整理一下,在并发编程中,动不动就给某一个主题注册一个监听,然后当主题状态发生变化的时候,监听就会被触发。好了,废话不多说了,我贴出几篇代码好了。
第一步:
/** * */ package test; /** * @author LinkinPark * @date 2015年8月31日 下午3:07:34 * @Description: * 前面我已经整理了观察者模式,这里对照这个设计模式来整理下java事件 * 这里先写个最简单的模拟 */ public class Util { public static void main(String[] args) { // 首先初始化一个被观察者,然后在初始化一个观察者 // 然后将观察者绑定到被观察者上面,然后使用被观察者看看观察者里面的事件有没有被触发 Observable observable = new Observable(); Observer observer = new Observer(); observable.setObserver(observer); observable.test();//事件被成功的触发了 } } //这个模拟被观察者 class Observable { //绑定到被观察者上面的观察者 private Observer observer; //被观察者对外面提供的操作 public void test() { observer.test(); } public Observer getObserver() { return observer; } public void setObserver(Observer observer) { this.observer = observer; } } // 这个模拟观察者 class Observer { // 这个模拟事件 public void test() { System.out.println("这里就是事件。。。"); } }
第二步:
/** * */ package test; import java.util.ArrayList; import java.util.List; /** * @author LinkinPark * @date 2015年8月31日 下午3:07:34 * @Description: * 现在在原来的基础上稍微复杂一点,现在不在被观察者身上只绑一个观察者了。 * 现在绑定多个观察者。 */ public class Util { public static void main(String[] args) { // 首先初始化一个被观察者,然后在初始化2个观察者 // 然后将观察者绑定到被观察者上面,然后使用被观察者看看观察者里面的事件有没有被触发 Observable observable = new Observable(); Observer observer1 = new Observer(); Observer observer2 = new Observer(); observable.registObserver(observer1); observable.registObserver(observer2); //调用外部事件,看看观察者里面的事件执行了没有 observable.notifyObserver("被观察者触发了操作了呢"); } } // 这个模拟被观察者 class Observable { // 绑定到被观察者上面的观察者 private List<Observer> observers = new ArrayList<Observer>(); // 添加一个观察者到被观察者身上 public void registObserver(Observer observer) { observers.add(observer); } // 从绑定的观察者集合中去掉当前这个 public void removeObserver(Observer observer) { observers.remove(observer); } // 定义外部执行 public void notifyObserver(String str) { for (Observer observer : observers) { observer.test(str); } } } // 这个模拟观察者 class Observer { // 这个模拟事件 public void test(String str) { System.out.println("这里就是事件-->" + str); } }
第三步:
/** * */ package test; import java.util.ArrayList; import java.util.List; /** * @author LinkinPark * @date 2015年8月31日 下午3:07:34 * @Description: * 现在在原来的基础上稍微复杂一点,现在不在被观察者身上只绑一个观察者了。 * 现在绑定多个观察者。现在在稍微复杂一点,观察者和被观察者都面向接口编程,里面提供多个实现 */ public class Util { public static void main(String[] args) { // 首先初始化一个被观察者,然后在初始化2个观察者 // 然后将观察者绑定到被观察者上面,然后使用被观察者看看观察者里面的事件有没有被触发 Iobservable observable = new Observable(); Iobserver observer = new Observer(); Iobserver observer1 = new Observer1(); observable.registObserver(observer); observable.registObserver(observer1); // 调用被观察者的外部事件,看看观察者里面的事件执行了没有 observable.notifyObserver("被观察者触发了操作了呢"); } } // 被观察者对外提供的接口,其实这里定义成抽象类,也就是模板好一点。 interface Iobservable { // 绑定到被观察者上面的观察者 public List<Iobserver> observers = new ArrayList<Iobserver>(); // 添加一个观察者到被观察者身上 void registObserver(Iobserver observer); // 从绑定的观察者集合中去掉当前这个 void removeObserver(Iobserver observer); // 定义外部执行 public void notifyObserver(String str); } // 观察者对外提供的接口。 interface Iobserver { // 这个模拟事件 public void test(String str); } // 这个模拟被观察者 class Observable implements Iobservable { public void registObserver(Iobserver observer) { observers.add(observer); System.out.println("这里添加一个被观察者-->" + observer.getClass()); } public void removeObserver(Iobserver observer) { observers.remove(observer); System.out.println("这里溢出一个被观察者-->" + observer.getClass()); } public void notifyObserver(String str) { for (Iobserver observer : observers) { observer.test(str); } } } // 这个模拟观察者0 class Observer implements Iobserver { public void test(String str) { System.out.println("这里就是Observer事件-->" + str); } } // 这个模拟观察者1 class Observer1 implements Iobserver { public void test(String str) { System.out.println("这里就是Observer1事件-->" + str); } }
第四步:
/** * */ package test; import java.util.ArrayList; import java.util.List; /** * @author LinkinPark * @date 2015年8月31日 下午3:07:34 * @Description: * 现在在原来的基础上稍微复杂一点,现在不在被观察者身上只绑一个观察者了。 * 现在绑定多个观察者。现在在稍微复杂一点,观察者和被观察者都面向接口编程,里面提供多个实现。 * 最后现在提供一个最完美的观察者模式,其实和我前面那篇博客写的差不多 */ public class Util { public static void main(String[] args) { // 首先初始化一个被观察者,然后在初始化2个观察者 // 然后将观察者绑定到被观察者上面,然后使用被观察者看看观察者里面的事件有没有被触发 Iobservable observable = new Observable(); Iobserver observer = new Observer(); Iobserver observer1 = new Observer1(); observable.registObserver(observer); observable.registObserver(observer1); // 调用被观察者的外部事件,看看观察者里面的事件执行了没有 System.out.println("===========华丽丽的分割线============="); observable.notifyObserver("LinkinPark..."); } } // 被观察者对外提供的接口,其实这里定义成抽象类,也就是模板好一点。 abstract class Iobservable { // 绑定到被观察者上面的观察者 public List<Iobserver> observers = new ArrayList<Iobserver>(); // 添加一个观察者到被观察者身上 abstract void registObserver(Iobserver observer); // 从绑定的观察者集合中去掉当前这个 abstract void removeObserver(Iobserver observer); // 通知给观察者,让其开始做相关处理 public void notifyObserver(String str) { for (Iobserver observer : observers) { observer.test(str); } } } // 观察者对外提供的接口。 interface Iobserver { // 这个模拟事件 public void test(String str); } // 这个模拟被观察者 class Observable extends Iobservable { private String name; public String getName() { return name; } // 在给这个被观察者重新设值name的时候,也就说现在观察者状态发生改变了,那么就要通知给观察者,让他也来做相关的处理 public void setName(String name) { this.name = name; notifyObserver(name); } public void registObserver(Iobserver observer) { observers.add(observer); System.out.println("这里添加一个被观察者-->" + observer.getClass()); } public void removeObserver(Iobserver observer) { observers.remove(observer); System.out.println("这里移除一个被观察者-->" + observer.getClass()); } } // 这个模拟观察者0 class Observer implements Iobserver { public Observer() { System.out.println("Observer:观察者原来的name-->" + getName()); } private String name = "Observer"; public String getName() { return name; } public void setName(String name) { this.name = name; } public void test(String str) { System.out.println("Observer:原来的name-->" + getName()); setName(str); System.out.println("被观察者状态改变后本地的同步name-->" + getName()); } } // 这个模拟观察者1 class Observer1 implements Iobserver { public Observer1() { System.out.println("Observer1:观察者原来的name-->" + getName()); } private String name = "Observer1"; public String getName() { return name; } public void setName(String name) { this.name = name; } public void test(String str) { System.out.println("Observer1:原来的name-->" + getName()); setName(str); System.out.println("被观察者状态改变后本地的同步name-->" + getName()); } }
最后一步:java事件监听了呢。
package test; import java.util.ArrayList; import java.util.EventListener; import java.util.EventObject; import java.util.Iterator; import java.util.List; /** * @author LinkinPark * @date 2015年9月1日 下午1:46:52 * @Description: java事件监听机制 */ public class Linkin { // 初始化主题-->被观察者 DemoSource source = new DemoSource(); // 初始化监听-->观察者 DemoListener Listener1 = new Listener1(); DemoListener Listener2 = new Listener2(); public Linkin() { source.addDemoListener(Listener1).addDemoListener(Listener2).addDemoListener(new DemoListener() { @Override public void demoEvent(DemoEvent demoEvent) { System.out.println("匿名内部类收到主题推送-->" + demoEvent.getSource().getClass()); } }); System.out.println("主题原来的状态-->" + name); } private String name = "nameOld"; /** * @return the name */ public String getName() { return name; } /** * @param name the name to set */ public void setName(String name) { this.name = name; System.out.println("主题现在的状态-->" + name); source.notifyDemoEvent(); } public static void main(String[] args) { new Linkin().setName("nameNew"); } } // 就是事件产生时具体的“事件”,用于listener的相应的方法之中,作为参数,一般存在与listerner的方法之中 class DemoEvent extends EventObject { private static final long serialVersionUID = 1L; Object obj; public DemoEvent(Object source) { super(source); obj = source; } public Object getSource() { return obj; } } // 具体的对监听的事件类,当有其对应的event object产生的时候,它就调用相应的方法,进行处理。 interface DemoListener extends EventListener { void demoEvent(DemoEvent demoEvent); } // 这个相当于观察者 class Listener1 implements DemoListener { @Override public void demoEvent(DemoEvent demoEvent) { System.out.println("Listener1监听收到了主题的推送消息" + demoEvent.getSource()); } } // 这个相当于观察者 class Listener2 implements DemoListener { @Override public void demoEvent(DemoEvent demoEvent) { System.out.println("Listener2监听收到了主题的推送消息" + demoEvent.getSource()); } } // 具体的接受事件的实体,也就是观察者模式中的被观察者。比如说,你点击一个button,那么button就是event source, // 这样你必须使button对某些事件进行相应,你就需要注册特定的listener,比如说MouseEvent之中的MouseClicked方法,这是他就必须有了add方法 class DemoSource { private List<Object> repository = new ArrayList<Object>(); DemoListener dl; public DemoSource() { } // 添加监听 public DemoSource addDemoListener(DemoListener dl) { repository.add(dl); return this; } // 状态改变被触发 public void notifyDemoEvent() { Iterator<Object> it = repository.iterator(); while (it.hasNext()) { dl = (DemoListener) it.next(); dl.demoEvent(new DemoEvent(this)); } } }