Java事件处理机制(自定义事件)实例详解

Java事件处理机制

java中的事件机制的参与者有3种角色:

1.event object:事件状态对象,用于listener的相应的方法之中,作为参数,一般存在与listerner的方法之中

2.event source:具体的事件源,比如说,你点击一个button,那么button就是event source,要想使button对某些事件进行响应,你就需要注册特定的listener。

3.event listener:对每个明确的事件的发生,都相应地定义一个明确的Java方法。这些方法都集中定义在事件监听者(EventListener)接口中,这个接口要继承 java.util.EventListener。 实现了事件监听者接口中一些或全部方法的类就是事件监听者。

  伴随着事件的发生,相应的状态通常都封装在事件状态对象中,该对象必须继承自java.util.EventObject。事件状态对象作为单参传递给应响应该事件的监听者方法中。发出某种特定事件的事件源的标识是:遵从规定的设计格式为事件监听者定义注册方法,并接受对指定事件监听者接口实例的引用。

具体的对监听的事件类,当它监听到event object产生的时候,它就调用相应的方法,进行处理。

先看看jdk提供的event包:

public interface EventListener:所有事件侦听器接口必须扩展的标记接口。

public class EventObject extends Object implements Serializable

所有事件状态对象都将从其派生的根类。 所有 Event 在构造时都引用了对象 "source",在逻辑上认为该对象是最初发生有关 Event 的对象。

(1)通过DoorEvent.java文件创建DoorEvent类,这个类继承EventObject。

/**
* 定义事件对象,必须继承EventObject
*/
public class DoorEvent extends EventObject {

 private static final long serialVersionUID = 6496098798146410884L;

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

}

(2)定义新的事件监听接口,该接口继承自EventListener;该接口包含对doorEvent事件的处理程序:

/**
* 定义监听接口,负责监听DoorEvent事件
*/

public interface DoorListener extends EventListener {
  public void doorEvent(DoorEvent event);
}

通过上面的接口我们再定义事件监听类,这些类具体实现了监听功能和事件处理功能。

/**
* 该类为 门1监听接口的实现,做具体的开门,关门动作
*/

public class DoorListener1 implements DoorListener {
 @Override
 public void doorEvent(DoorEvent event) {
  // TODO Auto-generated method stub
  if (event.getDoorState() != null && event.getDoorState().equals("open")) {
   System.out.println("门1打开");
  } else {
   System.out.println("门1关闭");
  }
 }

}

/**

* 该类为 门2监听接口的实现,做具体的开门,关门,以及开灯,关灯动作
*/

public class DoorListener2 implements DoorListener {

 @Override
 public void doorEvent(DoorEvent event) {
  // TODO Auto-generated method stub
  if (event.getDoorState() != null && event.getDoorState().equals("open")) {
   System.out.println("门2打开,同时打开走廊的灯");
  } else {
   System.out.println("门2关闭,同时关闭走廊的灯");
  }
 }

}

(3)通过DoorManager.java创造一个事件源类,它用一个Collection listeners对象来存储所有的事件监听器对象,存储方式是通过addDoorListener(..)这样的方法。notifyListeners(..)是触发事件的方法,用来通知系统:事件发生了,你调用相应的处理函数吧。

/**
* 事件源对象,在这里你可以把它想象成一个控制开门关门的遥控器,
* (如果是在swing中,就类似一个button)
*/

public class DoorManager {
 private Collection listeners;

 /**
  * 添加事件
  *
  * @param listener
  *   DoorListener
  */
 public void addDoorListener(DoorListener listener) {
  if (listeners == null) {
   listeners = new HashSet();
  }
  listeners.add(listener);
 }

 /**
  * 移除事件
  *
  * @param listener
  *   DoorListener
  */
 public void removeDoorListener(DoorListener listener) {
  if (listeners == null)
   return;
  listeners.remove(listener);
 }

 /**
  * 触发开门事件
  */
 protected void fireWorkspaceOpened() {
  if (listeners == null)
   return;
  DoorEvent event = new DoorEvent(this, "open");
  notifyListeners(event);
 }

 /**
  * 触发关门事件
  */
 protected void fireWorkspaceClosed() {
  if (listeners == null)
   return;
  DoorEvent event = new DoorEvent(this, "close");
  notifyListeners(event);
 }

 /**
  * 通知所有的DoorListener
  */
 private void notifyListeners(DoorEvent event) {
  Iterator iter = listeners.iterator();
  while (iter.hasNext()) {
   DoorListener listener = (DoorListener) iter.next();
   listener.doorEvent(event);
  }
 }
}

(4)好了,最后写一个测试程序测试一下我们自定义的事件吧,这段程序应该不难理解吧:)

/**
* 主程序,就想象成要开门的哪个人
*/

public class DoorMain {
 public static void main(String[] args) {
  DoorManager manager = new DoorManager();
  manager.addDoorListener(new DoorListener1());// 给门1增加监听器
  manager.addDoorListener(new DoorListener2());// 给门2增加监听器
  // 开门
  manager.fireWorkspaceOpened();
  System.out.println("我已经进来了");
  // 关门
  manager.fireWorkspaceClosed();
 }
}

运行DoorMain

门1打开
门2打开,同时打开走廊的灯

我已经进来了

门1关闭
门2关闭,同时关闭走廊的灯

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

时间: 2016-12-23

浅谈用java实现事件驱动机制

由于项目需求,需要为Java提供一套支持事件驱动机制的类库,可以实现类似于C#中的event和delegate机制.众所周知,Java语言本身以及其标准库中并没有提供事件驱动机制的相关接口,虽然Swing(我且认为其不属于标准库,因为一般没人用:)中存在相关的类支持该机制以实现组件的事件处理,但它毕竟是与GUI相耦合的,而在其它类型的应用程序中使用起来显得就有些别扭,缺乏通用性.因此有必要实现一套通用的Java事件驱动机制类库,然后将其应用于通用的Java应用程序当中,虽然这并不是什么难事:)

浅谈从Java中的栈和堆,进而衍生到值传递

简述Java中的栈和堆,变量和对象的地址存放和绑定机制 初学java的小白,很多人都搞不清楚java中堆和栈的概念,我们都知道计算机只能识别二进制字节码文件,如果分不清楚对象和变量在内存的地址分配,也就是堆和栈的问题,很多问题比如绑定机制.静态方法.实例方法.局部变量的作用域就会搞不清楚. 首先记住结论: 基本数据类型.局部变量.String类型的直接赋值都是存放在栈内存中的,用完就消失. new创建的实例化对象.String类型的构造方法new出来的对象及数组,是存放在堆内存中的,用完之后靠垃

浅谈在JAVA项目中LOG4J的使用

一.直接使用: //输出到项目文件夹下output1.txt文件中 ////////////////////////////// // DEBUG - Here is some DEBUG // INFO - Here is some INFO // WARN - Here is some WARN // ERROR - Here is some ERROR // FATAL - Here is some FATAL ////////////////////////////// package

浅谈在Java中使用Callable、Future进行并行编程

使用Callable.Future进行并行编程 在Java中进行并行编程最常用的方式是继承Thread类或者实现Runnable接口.这两种方式的缺点是在任务完成后无法直接获取执行结果,必须通过共享变量或线程间通信,使用起来很不方便. 从Java1.5开始提供了Callable和Future两个接口,通过使用它们可以在任务执行完毕后得到执行结果. 下面我们来学习下如何使用Callable.Future和FutureTask. Callable接口 Callable接口位于java.util.co

浅谈对Java双冒号::的理解

本文为个人理解,不保证完全正确. 官方文档中将双冒号的用法分为4类,按照我的个人理解可以分成2类来使用. 官方文档 官方文档中将双冒号的用法分为了以下4类: 用法 举例 引用静态方法 ContainingClass::staticMethodName 引用特定对象的实例方法 containingObject::instanceMethodName 引用特定类型的任意对象的实例方法 ContainingType::methodName 引用构造函数 ClassName::new 以下是我的理解 个

浅谈为什么Java中1000==1000为false而100==100为true

这是一个挺有意思的讨论话题. 如果你运行下面的代码 Integer a = 1000, b = 1000; System.out.println(a == b);//1 Integer c = 100, d = 100; System.out.println(c == d);//2 你会得到 false true 基本知识:我们知道,如果两个引用指向同一个对象,用==表示它们是相等的.如果两个引用指向不同的对象,用==表示它们是不相等的,即使它们的内容相同. 因此,后面一条语句也应该是false

浅谈使用Java Web获取客户端真实IP的方法示例详解

Java-Web获取客户端真实IP: 发生的场景:服务器端接收客户端请求的时候,一般需要进行签名验证,客户端IP限定等情况,在进行客户端IP限定的时候,需要首先获取该真实的IP. 一般分为两种情况: 方式一.客户端未经过代理,直接访问服务器端(nginx,squid,haproxy): 方式二.客户端通过多级代理,最终到达服务器端(nginx,squid,haproxy): 客户端请求信息都包含在HttpServletRequest中,可以通过方法getRemoteAddr()获得该客户端IP.

浅谈关于Java的GC垃圾回收器的一些基本概念

一.基本回收算法 1. 引用计数(Reference Counting) 比较古老的回收算法.原理是此对象有一个引用,即增加一个计数,删除一个引用则减少一个计数.垃圾回收时,只用收集计数为0的对象.此算法最致命的是无法处理循环引用的问题. 2. 标记-清除(Mark-Sweep) 此算法执行分两阶段.第一阶段从引用根节点开始标记所有被引用的对象,第二阶段遍历整个堆,把未标记的对象清除.此算法需要暂停整个应用,同时,会产生内存碎片. 3. 复制(Copying) 此算法把内存空间划为两个相等的区域

浅谈对java中锁的理解

在并发编程中,经常遇到多个线程访问同一个 共享资源 ,这时候作为开发者必须考虑如何维护数据一致性,在java中synchronized关键字被常用于维护数据一致性.synchronized机制是给共享资源上锁,只有拿到锁的线程才可以访问共享资源,这样就可以强制使得对共享资源的访问都是顺序的,因为对于共享资源属性访问是必要也是必须的,下文会有具体示例演示. 一.java中的锁 一般在java中所说的锁就是指的内置锁,每个java对象都可以作为一个实现同步的锁,虽然说在java中一切皆对象, 但是锁

浅谈Node异步编程的机制

本文介绍了Node异步编程,分享给大家,具体如下: 目前的异步编程主要解决方案有: 事件发布/订阅模式 Promise/Deferred模式 流程控制库 事件发布/订阅模式 Node自身提供了events模块,可以轻松实现事件的发布/订阅 //订阅 emmiter.on("event1",function(message){ console.log(message); }) //发布 emmiter.emit("event1","I am mesaage!