zoukankan      html  css  js  c++  java
  • java事件处理机制

    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));
    		}
    	}
    }
    



  • 相关阅读:
    使用 DataAdapter 执行批量更新 [摘自MSDN]
    深入浅出net泛型编程
    模版页中引用文件路径的问题
    查询SQLSERVER某个表所占用空间大小的SQL语句
    如何获取SQL Server数据库里表的占用容量大小的存储过程
    确定计算机是否可以运行 Windows Vista? 操作系统
    SQL语句 [转]
    SQLServer中如何将一个字段的多个记录值合在一行显示
    ASP.net在页面所有内容生成后、输出内容前对页面内容进行操作
    oracle 删除用于及其表空间
  • 原文地址:https://www.cnblogs.com/LinkinPark/p/5232994.html
Copyright © 2011-2022 走看看