[转]Java监听器的原理与实现
监听器是一个专门用于对其他对象身上发生的事件或状态改变进行监听和相应处理的对象,当被监视的对象发生情况时,立即采取相应的行动。
监听器其实就是一个实现特定接口的普通java程序,这个程序专门用于监听另一个java对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法立即被执行。
我们是写监听器去监听其他对象,那么我们如果想设计一个对象,让这个对象可以被别的对象监听又该怎么做呢,
可以按照严格的事件处理模型来设计一个对象,这个对象就可以被别的对象监听,事件处理模型涉及到三个组件:事件源、事件对象、事件监听器。
模型图
监听器模型涉及以下三个对象,模型图如下:
(1)事件:用户对组件的一个操作,称之为一个事件
(2)事件源:发生事件的组件就是事件源
(3)事件监听器(处理器):监听并负责处理事件的方法
执行顺序如下
1、给事件源注册监听器
2、组件接受外部作用,也就是事件被触发
3、组件产生一个相应的事件对象,并把此对象传递给与之关联的事件处理器
4、事件处理器启动,并执行相关的代码来处理该事件。
监听器模式
事件源注册监听器之后,当事件源触发事件,监听器就可以回调事件对象的方法;更形象地说,监听者模式是基于:注册-回调的事件/消息通知处理模式,就是被监控者将消息通知给所有监控者。
1、注册监听器:事件源.setListener;
2、回调:事件源实现onListener。
下面,来看两个demo。
一、简化了上图所示的模型,仅仅包含事件源与监听器
1 /* 2 * 事件源:事件发生的地点 3 */ 4 public class EventSource { 5 private IEventListener mEventListener; 6 7 // 注册监听器 8 public void setEventListener(IEventListener arg) { 9 mEventListener = arg; 10 } 11 12 // 触发事件 13 public void EventHappened() { 14 mEventListener.onclickButton(); 15 } 16 17 }
1 /* 2 * 事件监听器,事件处理器 3 */ 4 public interface IEventListener { 5 void onclickButton(); 6 }
1 public class Test { 2 public static void main(String[] args) { 3 4 // 事件源(被监听的对象) 5 EventSource m1 = new EventSource(); 6 7 // 监听器 8 IEventListener mEventListener = new IEventListener() { 9 10 @Override 11 public void onclickButton() { 12 // TODO Auto-generated method stub 13 System.out.println("你点击了按钮"); 14 } 15 }; 16 17 // 注册监听器到事件源 18 m1.setEventListener(mEventListener); 19 m1.EventHappened(); 20 } 21 }
【实验结果】
你点击了按钮
完整模型的demo
1 /* 2 * 事件 3 */ 4 public interface IEvent { 5 6 void setEventListener(IEventListener arg); 7 8 boolean ClickButton(); 9 10 boolean MoveMouse(); 11 12 }
1 /* 2 * 事件监听器,调用事件处理器 3 */ 4 public interface IEventListener { 5 6 void doEvent(IEvent arg); 7 }
1 /* 2 * 事件源:事件发生的地点 3 */ 4 public class EventSource implements IEvent{ 5 private IEventListener mEventListener; 6 boolean button; 7 boolean mouse; 8 9 //注册监听器 10 @Override 11 public void setEventListener(IEventListener arg){ 12 mEventListener = arg; 13 } 14 15 //触发事件 16 public void mouseEventHappened(){ 17 mouse = true; 18 mEventListener.doEvent(this); 19 } 20 21 @Override 22 public boolean ClickButton() { 23 return button; 24 // TODO Auto-generated method stub 25 26 } 27 28 @Override 29 public boolean MoveMouse() { 30 // TODO Auto-generated method stub 31 return mouse; 32 } 33 34 }
1 public class EventSource2 implements IEvent { 2 private IEventListener ml; 3 boolean button; 4 boolean mouse; 5 6 @Override 7 public void setEventListener(IEventListener arg) { 8 ml = arg; 9 } 10 11 @Override 12 public boolean ClickButton() { 13 // TODO Auto-generated method stub 14 return button; 15 } 16 17 @Override 18 public boolean MoveMouse() { 19 // TODO Auto-generated method stub 20 return mouse; 21 } 22 23 // 触发事件 24 public void buttonEventHappened() { 25 button = true; 26 ml.doEvent(this); 27 } 28 29 }
1 public class Test { 2 public static void main(String[] args) { 3 4 // 事件源(被监听的对象) 5 EventSource m1 = new EventSource(); 6 EventSource2 m2 = new EventSource2(); 7 // 监听器 8 IEventListener mEventListener = new IEventListener() { 9 10 @Override 11 public void doEvent(IEvent arg) { 12 if (true == arg.ClickButton()) { 13 System.out.println("你点击了按钮"); 14 }else if(true == arg.MoveMouse()){ 15 System.out.println("你移动了鼠标"); 16 } 17 } 18 }; 19 20 // 注册监听器到事件源 21 m1.setEventListener(mEventListener); 22 m1.mouseEventHappened(); 23 24 // 注册监听器到事件源 25 m2.setEventListener(mEventListener); 26 m2.buttonEventHappened(); 27 } 28 }
【实验结果】
你移动了鼠标
你点击了按钮
合群是堕落的开始 优秀的开始是孤行