Java基础教程之事件和监听器


  • 本文介绍了事件监听器的设计方法。事件监听器是经常可以遇到的一种设计模 式,即:当模块的一部分A在完成后需要通知其他的软件模块B,而等待通知的模块B在事先不需要采用轮询的方式来查看另一个模块A是否通知自己。

事件监听器是经常可以遇到的一种设计模式,一般用在这样一种场景下:当模块的一部分A在完成后需要通知其他的软件模块B,而等待通 知的模块B在事先不需要采用轮询的方式来查看另一个模块A是否通知自己。即,当某事件发生,则监听器立刻就知道了该事件。这种模式大量的应用在GUI设计 中,比如按钮的点击,状态栏上状态的改变等等。

 

笔记: 某个类实现监听器就是获得一个listener的引用(把实现了监听器接口的监听器对象set进类的属性里--注册监听器),在适当时机通过listener调用监听器里的方法。

 

接口的设计

我们需要一个对事件(event)的抽象,同样需要一个对监听器(listener)的抽象。我们可以把接口抽的很简单:

这个是事件源的接口,只需要提供一个可以获取事件类型的方法即可:

 
 
  1. package


     listenerdemo.framework;  

  2.  

  3. /**
     

  4.  * @author juntao.qiu

     

  5.  */

     

  6. public


     
    interface


     EventListener {  

  7.     
    /**
     

  8.      * handle the event when it raise

     

  9.      * @param event

     

  10.      */

     

  11.     
    public


     
    void


     handleEvent(EventSource event);  

  12. }  

  13.    


监听器接口,提供一个当事件发生后的处理方法即可:

 
 
  1. package


     listenerdemo.framework;  

  2.  

  3. public


     
    interface


     EventSource {  

  4.     
    public


     
    final


     
    int


     EVENT_TIMEOUT = 
    1

    ;  

  5.     
    public


     
    final


     
    int


     EVENT_OVERFLOW = 
    2

    ;  

  6.  

  7.     
    /**
     

  8.      * get an integer to identify a special event

     

  9.      * @return

     

  10.      */

     

  11.     
    public


     
    int


     getEventType();  

  12. }  


实例化事件

我们举一个实现了事件源接口(EventSource)的类TimeoutEvent 来说明如何使用事件监听器模型:

 
 
  1. package


     listenerdemo;  

  2.  

  3. import


     listenerdemo.framework.*;  

  4.  

  5. public


     
    class


     TimeOutEvent 
    implements


     EventSource{  

  6.     
    private


     
    int


     type;  

  7.  

  8.     
    public


     TimeOutEvent(){  

  9.         
    this


    .type = EventSource.EVENT_TIMEOUT;;  

  10.     }  

  11.       

  12.     
    public


     
    int


     getEventType() {  

  13.         
    return


     
    this


    .type;  

  14.     }  

  15.  

  16. }  


这个事件的类型为EVENT_TIMEOUT, 当操作超时时触发该事件,我们假设这样一个场景:一个定时器T, 先设置这个定时器的时间为t,当t到时后,则触发一个超时事件,当然,事件是需要监听器来监听才有意义的。我们看看这个定时器的实现:

 
 
  1. package


     listenerdemo;  

  2.  

  3. import


     listenerdemo.framework.*;  

  4.  

  5. /**
     

  6.  * @author juntao.qiu

     

  7.  */

     

  8. public


     
    class


     Timer 
    extends


     Thread{  

  9.     
    private


     EventListener listener;  

  10.     
    private


     
    int


     sleepSeconds;  

  11.  

  12.     
    public


     Timer(
    int


     seconds){  

  13.         
    this


    .sleepSeconds = seconds;  

  14.     }  

  15.  

  16.     
    public


     
    void


     setEventListener(EventListener listener){  

  17.         
    this


    .listener = listener;  

  18.     }  

  19.       

  20.     
    public


     
    void


     run(){  

  21.         
    for


    (
    int


     i = sleepSeconds;i>
    0

    ;i--){  

  22.             
    try


     {  

  23.                 Thread.sleep(
    1000

    );  

  24.             } 
    catch


     (InterruptedException ex) {  

  25.                 System.err.println(ex.getMessage());  

  26.             }  

  27.         }  

  28.           

  29.         raiseTimeoutEvent();
    //raise一个TimeOut事件给监听器

     

  30.     }  

  31.  

  32.     
    private


     
    void


     raiseTimeoutEvent(){  

  33.         
    this


    .listener.handleEvent(
    new


     TimeOutEvent());  

  34.     }  

  35. }  


使用事件及其监听器

在类Tester的execute()方法中,我们先设置一个定时器,这个定时器初始化为3秒,设置好定时器后,程序进入一个 while(true)循环中,当定时器到时后,它会发送一个timeout事件给当前线程Tester,此时我们可以设置execute中的while 条件为false,退出死循环。流程很清晰了,我们来看看代码:

 
 
  1. package


     listenerdemo;  

  2.  

  3. import


     listenerdemo.framework.*;  

  4.  

  5. /**
     

  6.  * @author juntao.qiu

     

  7.  */

     

  8. public


     
    class


     EventListenerTester 
    implements


     EventListener{  

  9.     
    private


     
    boolean


     loop = 
    true


    ;  

  10.  

  11.     
    public


     
    void


     execute(){  

  12.         Timer timer = 
    new


     Timer(
    3

    );
    //初始化一个定时器

     

  13.         timer.setEventListener(
    this


    );
    //设置本类为监听器

     

  14.         timer.start();  

  15.           

  16.         
    while


    (loop){  

  17.             
    try


    {  

  18.                 Thread.sleep(
    1000

    );  

  19.                 System.out.println(
    "still in while(true) loop"

    );  

  20.             }
    catch


    (Exception e){  

  21.                 System.err.println(e.getMessage());  

  22.             }  

  23.         }  

  24.  

  25.         System.out.println(
    "interupted by time out event"

    );  

  26.     }  

  27.  

  28.  

  29. //实现了EventListener接口

     

  30.     
    public


     
    void


     handleEvent(EventSource event) {  

  31.         
    int


     eType = event.getEventType();  

  32.         
    switch


    (eType){
    //判断事件类型,我们可以有很多种的事件

     

  33.             
    case


     EventSource.EVENT_TIMEOUT:  

  34.                 
    this


    .loop = 
    false


    ;  

  35.                 
    break


    ;  

  36.             
    case


     EventSource.EVENT_OVERFLOW:  

  37.                 
    break


    ;  

  38.             
    default


    :  

  39.                 
    this


    .loop = 
    true


    ;  

  40.                 
    break


    ;  

  41.         }  

  42.     }  

  43.  

  44.     
    public


     
    static


     
    void


     main(String[] args){  

  45.         EventListenerTester tester = 
    new


     EventListenerTester();  

  46.         tester.execute();  

  47.     }  

  48.  

  49. }  


运行结果如下:
run:
still in while(true) loop
still in while(true) loop
still in while(true) loop
interupted by time out event
程序正 是按照预期的方式运行了,当然,为了说明主要问题,我们的事件,对事件的处理,监听器的接口都尽可能的保持简单。如果想要完成更复杂的功能,可以参考文章 中的方法自行扩充,但是大概流程文中都已经说到。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值