观察者模式 java 事件_观察者模式-Java自定义事件

package wintys.event;

import javax.swing.event.EventListenerList;

import java.util.Date;

import java.text.DateFormat;

import java.text.SimpleDateFormat;

/**

* Java的事件机制/自定义事件.

运行结果:

do something interesting in source here.

listener detects [event]:wintys.event.MyEvent[source=wintys.event.MySource@18158

59] [occur at]:2009-10-11 16:27:49

listener detects [event]:wintys.event.MyEvent[source=wintys.event.MySource@18158

59] [occur at]:2009-10-11 16:27:49

* @version 2009-10-11

* @author 天堂露珠 (wintys@gmail.com)

*/

class MyEventTest{

public static void main(String[] args){

MySource source = new MySource();

MyListener myListener = new MyListener(){

public void doMyAction(MyEvent e){

System.out.println("listener detects " + e);

}

};

source.addMyListener(myListener);

source.addMyListener(myListener);

source.addMyListener(myListener);

source.removeMyListener(myListener);

source.doSomething();

}

}

/**

* 自定义的事件.

* @version 2009-10-11

* @author 天堂露珠(wintys@gmail.com)

*/

class MyEvent extends java.util.EventObject{

private Date date;//记录事件发生的时间

public MyEvent(Object source , Date date){

super(source);

this.date = date;

}

public String toString(){

DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

String dt = df.format(date);

return "[event]:" + super.toString() + " [occur at]:" + dt;

}

}

/**

* 自定义事件监听器接口.

* @version 2009-10-11

* @author 天堂露珠(wintys@gmail.com)

*/

interface MyListener extends java.util.EventListener{

void doMyAction(MyEvent e);

}

/**

* 自定义事件源.

* @version 2009-10-11

* @author 天堂露珠(wintys@gmail.com)

*/

class MySource{

/**

* 保存注册的监听器列表.

* 子类可以使用它保存自己的事件监听器(非MyListener监听器)列表.

*/

protected EventListenerList listenerList = new EventListenerList();

private MyEvent myEvent = null;//fireDoMyAction()使用此变量

/**

* 没有做任何事

*/

public MySource(){

}

/**

* 添加一个MyListener监听器

*/

public void addMyListener(MyListener listener){

listenerList.add(MyListener.class , listener);

}

/**

* 移除一个已注册的MyListener监听器.

* 如果监听器列表中已有相同的监听器listener1、listener2,

* 并且listener1==listener2,

* 那么只移除最近注册的一个监听器。

*/

public void removeMyListener(MyListener listener){

listenerList.remove(MyListener.class , listener);

}

/**

* @return 在此对象上监听的所有MyListener类型的监听器

*/

public MyListener[] getMyListeners(){

return (MyListener[])listenerList.getListeners(MyListener.class);

}

//Winty:Copy directly from javax.swing.event.EventListenerList

/*Notify all listeners that have registered interest for

notification on this event type.  The event instance

is lazily created using the parameters passed into

the fire method.

*/

protected void fireDoMyAction() {

// getListenerList() Guaranteed to return a non-null array

Object[] listeners = listenerList.getListenerList();

// Process the listeners last to first, notifying

// those that are interested in this event

for (int i = listeners.length-2; i>=0; i-=2) {

if (listeners[i]==MyListener.class) {

// Lazily create the event:

if (myEvent == null)

myEvent = new MyEvent(this , new Date());

((MyListener)listeners[i+1]).doMyAction(myEvent);

}

}

}

/**

* 做一些事件源应该做的有意义的事,然后通知监听器.

* 这里只是一个示例方法.

* 例如:MySource如果是一个按钮,则doSomething()就可以命名为click(),

* 当用户点击按钮时调用click()方法.

*/

public void doSomething() {

System.out.println("do something interesting here.");

fireDoMyAction();//通知监听器

}

}

EventListenerList是特别需要说明的,它内部使用一个Object数组存放监听器。但是它并不是直接存放,而是先存监听器的class类型,然后再存监听器本身。即存放(MyListener.class

,

myListener)。一个Object数组可以存放多种类型的Listener,如果还有一种监听器AnotherListener,那么(AnotherListener.class

,

anotherListener)也可以存放。无论增删都是两个对象一同被添加或删除。上述代码中的listenerList.add(MyListener.class

, listener)或listenerList.remove(MyListener.class ,

listener),以及fireDoMyAction()中的"i-=2",就是这样操作的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值