zoukankan      html  css  js  c++  java
  • Java事件机制---自定义事件

    自定义事件在Java中很有用;有时想让程序产生一个事件,但这些事件又不是用户事件,也不是系统事件;比如:一个程序一旦收到邮件就对邮件进行相关处理,对于"收到邮件"这个事件,JDK中没有定义;对于这样的事件,以及对于这样的事件监听器,只能自己实现;再比如,Socket通讯中,链接成功、数据到达、数据发送、出错、断开链接,等等,这些事件,都需要自己实现;
    要实现自定义的事件以及事件处理程序,就必须要实现Java中的事件机制涉及到的三个元素:事件对象、事件源、事件监听器;
    Java提供了
    统一的事件对象类基类:java.util.EventObject;它的定义如下:
    public class EventObject extends Object implements Serializable;
    所有的事件状态对象类都要继承这个基类;
    Java提供了统一的事件监听器接口:java.util.EventListener;它的定义如下:
    public interface EventListener;
    所有的事件监听器对象类都要实现这个接口;
    伴随着事件的发生,对应的状态通常都封装在事件状态对象中,该对象必须继承java.util.EventObject类;事件状态对象作为单一的参数传递给对应的事件监听器对象的事件处理函数;
    首先,使用类EventObject作为父类来定义自己的事件类;然后,使用接口EventListener来实现自己的事件监听器类;最后就是注册这些事件以及事件监听器对象;
    以"开门"和"关门"为例,为对象"门"实现自定义的事件处理;
    STEP1:定义事件类DoorEvent,它继承EventObject类;
    import java.util.EventObject;
    public class DoorEvent extends EventObject
    {
      private String doorState = ""; //表示门的状态,取值"开"和"关";
      public DoorEvent(Object source, String doorState)
      {
        super(source);
        this.doorState = doorState;
      }
      public void setDoorState(String doorState)
      {
        this.doorState = doorState;
      }
      public String getDoorState()
      {
        return this.doorState;
      }
    }
    STEP2:定义事件监听器接口DoorListener,它继承接口EventListener;
    import java.util.EventListener;
    public interface DoorListener extends EventListener
    {
      public void doorEvent(DoorEvent event);
    }
    STEP3:定义事件监听器类DoorListener1和DoorListener2,它们两都分别实现接口DoorListener;
    public class DoorListener1 implements DoorListener
    {
      public void doorEvent(DoorEvent event)
      {
        if(event.getDoorState() != null && event.getDoorState().equals("open"))
        {
          System.out.println("门1打开");
        }
        else
        {
          System.out.println("门1关闭");
        }
      }
    }
    public class DoorListener2 implements DoorListener
    {
      public void doorEvent(DoorEvent event)
      {
        if(event.getDoorState() != null && event.getDoorState().equals("open"))
        {
          System.out.println("门2打开,同时打开走廊里面的灯");
        }
        else
        {
          System.out.println("门2关闭,同时关闭走廊里面的灯");
        }
      }
    }
    STEP4:模拟实现事件源类DoorManager,用于触发事件和广播通知事件;它使用一个Collection类型的对象类存储所有注册进来的事件监听器对象;
    import java.util.*;
    public class DoorManager
    {
      private Collection listeners; //存储所有注册进来的事件监听器对象;
      public void addDoorListener(DoorListener listener) //把一个事件监听器对象注册进来;
      {
        if(this.listeners == null)
        {
          this.listeners = new HashSet();
        }
        this.listeners.add(listener);
      }
      public void removeDoorListener(DoorListener listener) //移除一个已经注册的事件监听器对象;
      {
        if(this.listeners != null)
        {
          this.listeners.remove(listener);
        }
      }
      protected void fireDoorOpened()  //触发开门事件
      {
        if(this.listeners != null)
        {
          DoorEvent event = new DoorEvent(this, "open");
          notifyListeners(event);
        }
      }
      protected void fireDoorClose()  //触发关门事件
      {
        if(this.listeners != null)
        {
          DoorEvent event = new DoorEvent(this, "close");
          notifyListeners(event);
        }
      }
      private void notifyListeners(DoorEvent event)
      {
        Iterator iter = this.listeners.iterator();
        while(iter.hasNext())
        {
          DoorListener listener = (DoorListener)iter.next();
          listener.doorEvent(event);
        }
      }
    }
    至此,事件处理模型中涉及到的事件对象类、事件监听器类、事件源类,这三个参与者都已经实现;很明显,这是Observer(观察者)模式的一个具体应用;最后就是应用,只写个测试程序即可:
    public class DoorTest
    {
      public static void main(String []args)
      {
        DoorManager manager = new DoorManager();
        manager.addDoorListener(new DoorListener1()); //给"门1"增加事件监听器;
        manager.addDoorListener(new DoorListener2()); //给"门2"增加事件监听器;
        manager.fireDoorOpened(); //开门;
        System.out.println("我已经进来了");
        manager.fireDoorClose();  //关门;
      }
    }

  • 相关阅读:
    [redis] redis在线系统热迁移的方案与记录
    [golang] go get无法安装官方软件包
    我有关编程语言的一点理解
    [nginx] nginx源码分析--健康检查模块锁分析
    [nginx] nginx的hash与bucket size分析
    [daily][linux] dmesg格式里的时间为什么不准
    [daily] 查看linux程序或操作的kernel内核调用栈
    [go] 像gdb一样使用dlv debug golang程序
    [tls][https][nginx] https的client session cache与session ticket机制分析
    [性能优化] CPU电源管理pstate cstate
  • 原文地址:https://www.cnblogs.com/wcss/p/13019478.html
Copyright © 2011-2022 走看看