您的位置:首页 > 其它

一个简单的Listener,可以自己动手实现

2014-06-04 14:50 676 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/shuaididi/article/details/84603992 Java事件由事件类和监听接口组成,自定义一个事件前,必须提供一个事件的监听接口以及一个事件类。事件监听是观察者模式的一种实现。
我们一起来看看这到底是怎么一回事。

1、首先定义一个Event类 存放事件中存在的属性和方法

public class MyEvent {

private int value ;
public void setValue(int value){
this.value = value;
}
public int getValue(){
return this.value;
}
}

2、然后定义一个Listener接口,用于监听Event事件

public interface Listener {
void valueChanged(MyEvent e);
}

3、最后再来一个Source类,这是是我们要监听的对象

import java.util.ArrayList;
import java.util.List;

public class MySource {

private int value ;
private List<Listener> listeners = new ArrayList<Listener>();

// public Methods

public void setValue(int value){
this.value = value;
notifyAllListener();
}

public void addListener(Listener listener){
listeners.add(listener);
}

public void removeListener(Listener listener){
listeners.remove(listener);
}

// private Methods

private void notifyAllListener() {
MyEvent e = new MyEvent();
e.setValue( value);
for(int i = 0; i < listeners.size(); i++){
Listener l = listeners.get(i);
l.valueChanged(e);
}
}
}

一切准备就绪,现在我们可以来看看有什么效果了。

public class Main {

public static void main(String[] args) {
MySource source = new MySource();
System. out.println("----------------- Before Add Listener ---------------");
System. out.println("changing value..." );
source.setValue(5);
System. out.println("----------------- After Add Listener ----------------");
Listener myListener = new Listener() {
public void valueChanged(MyEvent e) {
System. out.println("MySource value changed to:" + e.getValue());
}
};
source.addListener(myListener);
System. out.println("changing value..." );
source.setValue(10);
System. out.println("----------------- After Remove Listener -------------");
source.removeListener(myListener);
System. out.println("changing value..." );
source.setValue(1000);
}
}

结果:
----------------- Before Add Listener ---------------
changing value...
----------------- After Add Listener ----------------
changing value...
MySource value changed to:10
----------------- After Remove Listener -------------
changing value...

从结果可以看出,我们已经实现了事件监听效果。
不过,这只是一个定制版的监听器,我们只能根据被监听的对象来定制事件中所包含的属性。
如果要实现通用版的Listener,我们又该怎么做呢。那就要使用Java为我们提供的监听接口(继承java.util.EventListener)和事件类(继承java.util.EventObject)。

接下来我们就实现这个需求。

1、相同的,首先我们还是需要一个Event

import java.util.EventObject;

public class MyEvent extends EventObject {

// 这里我们添加了2个自定义属性
private String changedPropertyName ;
private Object changedValue ;

public Object getChangedValue() {
return changedValue ;
}

public void setChangedValue(Object changedValue) {
this .changedValue = changedValue;
}

public String getChangedPropertyName() {
return changedPropertyName ;
}

public void setChangedPropertyName(String changedPropertyName) {
this .changedPropertyName = changedPropertyName;
}

public MyEvent(Object source) {
super (source);
}

public Object getSource() {
return super .getSource();
}

}

2、然后是Listener

import java.util.EventListener;

public interface Listener extends EventListener{

public void changed(MyEvent e);
}

3、最后是我们的监听对象

import java.util.ArrayList;
import java.util.List;

public class MySource {

private int value ;
private String name ;
private List<Listener> listeners = new ArrayList<Listener>();

public MySource(){

}

public MySource(String name, int value){
this .name = name;
this .value = value;
}

public int getValue() {
return value ;
}

public void setValue( int value) {
this .value = value;
notifyAllListener( "value" ,value);
}

public String getName() {
return name ;
}

public void setName(String name) {
this .name = name;
notifyAllListener( "name" ,name);
}

public void addListener(Listener listener){
listeners .add(listener);
}

public void removeListener(Listener listener){
listeners .remove(listener);
}

public void notifyAllListener(String changedPropertyName,Object changedValue){
MyEvent e = new MyEvent( this);
e.setChangedPropertyName(changedPropertyName);
e.setChangedValue(changedValue);
for (int i=0; i < listeners.size(); i++){
Listener listener = listeners .get(i);
listener.changed(e);
}
}
}


最后测试一下

public class Main {

public static void main(String[] args) {
MySource source = new MySource("I dont have a name" ,0);
print(source);
System. out .println("------------------- Before Add Listener ----------------");
System. out .println("changing name..." );
source.setName( "Test Listener" );
print(source);
System. out .println("changing value..." );
source.setValue(5);
print(source);

System. out .println("------------------- After Add Listener -----------------");
Listener myListener = new Listener() {

public void changed(MyEvent e) {
System. out .println("Mysource属性" + e.getChangedPropertyName() + "的值发生了变化,值为:" + e.getChangedValue() +"." );
MySource source = (MySource) e.getSource();
print(source);
}
};
source.addListener(myListener);
System. out .println("changing name..." );
source.setName( "My Listener" );
System. out .println("changing value..." );
source.setValue(10);

System. out .println("------------------ After Remove Listener ---------------");
source.removeListener(myListener); 3ff7
System. out .println("changing name..." );
source.setName( "No Listener" );
print(source);
System. out .println("changing value..." );
source.setValue(100);
print(source);
}

public static void print(MySource source){
System. out .println("Name:" + source.getName());
System. out .println("Value:" + source.getValue());
System. out .println();
}
}

测试结果:
Name:I dont have a name
Value:0

------------------- Before Add Listener ----------------
changing name...
Name:Test Listener
Value:0

changing value...
Name:Test Listener
Value:5

------------------- After Add Listener -----------------
changing name...
Mysource属性name的值发生了变化,值为:My Listener.
Name:My Listener
Value:5

changing value...
Mysource属性value的值发生了变化,值为:10.
Name:My Listener
Value:10

------------------ After Remove Listener ---------------
changing name...
Name:No Listener
Value:10

changing value...
Name:No Listener
Value:100

好了,结果还是和我们想象的一样。

最后说一句,如果我们想获取到变化之前的值和变化之后的值,那么我们就要加入备忘录模式了,这些就留给你们自己去实现了。
Thanks for reading!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: