javaGUI学习19:AWT-授权事件模型3

本文介绍了Java AWT中的事件处理机制,包括事件适配器在事件源和监听者间的中介作用,类型安全的多路处理适配器及其优缺点。此外,详细阐述了如何从自定义构件激发AWT事件和自定义事件,以及调度事件和AWT事件队列的使用。最后讨论了事件处理设计的不同方法,如监听自己、单独的事件处理类以及使用内部类的优缺点。
摘要由CSDN通过智能技术生成
1、事件适配器

事件适配器是位于事件源和事件监听者之间的对象。适配器实现一个事件监听者接口,并将一个或多个事件源从一个或多个事件监听者中分离出来。
通过实现适当的监听者接口,适配器类可以作为某个事件的监听者。当适配器接收到事件后,把它传给监听者。适配器可以处理事件,然后将事件传给监听者,也可以以后再传递。例如,一些适配器可以将未传送的事件排队,但另一些适配器可能会过滤要传给监听者的事件。

1.1 处理没有适配器的多点事件源事件

事件监听者向多个事件源注册同一类型的事件是很常见的。既然监听者实现一个给定的监听者接口一次,那么监听者必须确定事件源并采取适当的动作。

1.2 类型安全的多路处理适配器

如果没有适配器,监听者有责任根据事件源的标识调用一个适当的方法。

1.3 一般的多路处理适配器
  • 在调用每个的监听者方法中,适配器需要一个对应的适配器类,这可能导致大量的适配器类。
  • 另一方面,对于每个监听者类,一般适配器需要有一个对应的适配器类,这可以导致适配器类的数量减少,这种减少是有损失的,一般适配器类不是类型安全的。一般适配器在运行时使用Java反射API调用对象中的一个方法。可以在任何时候、任何地方使用一般适配器去调用任何监听者中的任何方法曰。
  • 一般适配器的缺点是,使用它们要求取消编译时的检查一类型检查完全在运行时处理——在像Java这样强类型的语言中这是个不小的超越。
  • 如果其他情形都相同,那么在编译时检查代码要比推迟到运行时检查好得多。更何况,所有的其余事情也不会完全等同。总之,开发者可以在大量类型安全的适配器或相对较少的非类型安全的一般适配器中自由选择。
1.4 AWT技巧:推荐类型安全

问题不在于编译时检查是否就比运行时检查好。一些面向对象的语言(例如SmallTalk ),在编译检查时不进行很多类型检查,然而其他的一些语言,如C++和Java却会这样做。问题在于:在Java中是否值得取消类型安全?大部分时候,答案是否定的。Java是一种强类型语言,取消类型系统除了与Java的类型系统的目标相冲突还会导致许多手工错误检查。

2、从自定义构件中激发AWT事件

大部分AWT构件可以激发某种语义事件。同样的,许多自定义构件执行的是一个或多个可被解释为语义事件的动作。配置激发语义事件的自定义构件是一个相当普通而又简单的任务,像下面列举的那样:

1)如果适当,构件实现监听者接口。

2)在类中添加适当的监听者成员。

  1. 实现addXXXListener ()和removeXXXListener ()。

4)实现 processXXXEvent ()。

3、从自定义构件中激发自定义事件

自行查询《java2图形设计卷1:AWT》相关章节

4、调度事件和AWT事件队列
  • 很多时候,我们希望产生一个事件,并将该事件传给指定的构件进行处理。例如,有些应用程序可以希望记录一个事件队列,并可以在以后重新排队。
  • 基本上有两种方法可以把一个事件发送给一个构件:调用 Component .dispatchEvent()或使用事件队列。

java.awt.EventQueue方法:

SecondaryLoop createSecondaryLoop() //创建与此事件队列关联的新 secondary loop 。  
protected void dispatchEvent(AWTEvent event) //派遣活动。  
static AWTEvent getCurrentEvent() //返回与调用线程关联的 EventQueue当前正在调度的事件。  
static long getMostRecentEventTime() //返回具有时间戳的最新事件的时间戳,该时间戳是从与调用线程关联的 EventQueue调度的。  
AWTEvent getNextEvent() //从 EventQueue删除事件并将其返回。  
static void invokeAndWait(Runnable runnable) //导致 runnable在 dispatch thread of the system EventQueue中调用其 run方法。  
static void invokeLater(Runnable runnable) //导致 runnable在 dispatch thread的 the system EventQueue中调用其 run方法。  
static boolean isDispatchThread() //如果调用线程是 the current AWT EventQueue的调度线程,则返回true。  
AWTEvent peekEvent() //返回 EventQueue上的第一个事件而不删除它。  
AWTEvent peekEvent(int id) //返回具有指定标识的第一个事件(如果有)。  
protected void pop() //使用此 EventQueue停止分派事件。  
void postEvent(AWTEvent theEvent) //将一个1.1风格的活动发布到 EventQueue 。  
void push(EventQueue newEventQueue) //用指定的替换现有的 EventQueue 。  

任何时候,都只存在一个可以通过调用Toolkit . getSystemEventQueue ()方法进行访问的系统事件队列。此外,事件还可以记入到本地事件队列中。

5、有效事件
  • 在AWT2以前,为了可以调度事件,记入到事件队列的事件必须以指定的Component或MenuComponent 作为事件源。当事件队列调度事件时,根据事件源的类型调用事件源中的Component . dispatchEvent ()方法或MenuComponent . dispatchEvent())方法。
  • 在 AWT 2中,引入了一个新的事件类型——有效事件(active event)。有效事件由java.awt.ActiveEvent接口表示,该接口只定义了一个方法 void dispatch ()。代替调用由事件源提供的方法,调用事件的 dispatch ()方法可以调度有效事件。结果,通过把事件记人到事件队列中,有效事件允许非构件安排某个行为在不同的线程上发生。
6、事件处理设计

虽然新的事件模型在旧的模型的基础上有很大改进,但旧模型的简单性自然有吸引力。在旧模型里处理事件时,基本上只有一个选择,即扩展构件并把事件处理代码嵌入到扩展部分。具有内部类的新事件模型与旧的事件模型相比,具有更多的灵活性。例如,在基于授权的事件模型下处理事件时可以:

  • 使用旧的事件模型。
  • 使用新模型提供的基于继承的机制。
  • 构件可以监听自己。
  • 在单独的监听者类中封装事件处理代码。
  • 在处理事件时还可以使用内部类。

尽管在执行事件处理时会面临多种选择,但决定使用哪种方法实际上比它看起来容易。很快就会发现,几乎在所有的情况下,后两种方法都是最好的方法,很少推荐前面两种。

6.1 使用基于继承的事件模型
  • 是可行的,因为新的事件模型支持旧的模型。但在以后将逐渐取消支持旧的模型,因此早些修改事件处理代码是个好主意。使用旧的事件处理将会做双份工作,因为最终还是要修改代码。因此,不推荐使用旧的事件模型。
  • 几乎在各种情况下,监听自己或授权给一个单独的事件处理类比使用基于继承的机制更可取,因为新的事件模型中的基于继承的机制具有和旧模型同样的缺点
6.2 监听自己

当构件处理事件时,把构件作为监听者注册是一个有效的、经常推荐使用的方法。
当无论使用何种方式扩展构件而其处理基本事件的方法都不改变时,通过让构件监听自己,把事件处理嵌入到构件中是最理想的。通过实现一个特定的监听者接口(或扩展一个适配器类)构件可以监听自己,然后把自己作为一个监听者加入:

public class demo extends Canvas implements MouseAdapter{}

当然,监听自己也存在缺点。

  • 首先,几乎必须实现空操作事件处理方法,因为其不能扩展适配器类(构件已经扩展了Component 或Component的扩展)。
  • 监听自己的另一个缺点是,它在激发事件的构件中包含硬编码的事件处理。
6.3 单独一个类中封装事件处理代码

这个方法的缺点是必须实现一个单独的类,并以某种方式使事件处理类和激发适当事件的构件联系起来。但是对于可能需要应付变化的事件处理,它的缺点只需付出很少的代价。
通常,当要处理的构件的事件处理可能发生变化时,特别是当默认事件处理将子类化时,在单独的类中封装事件处理代码是一个好主意。

6.4 使用内部类
  • 当监听自己时,使用内部类的决定通常最恰当。
  • 只要内部类的使用不需要采用不适合给定环境的方法,就推荐使用内部类。
  • 例如,如果十分肯定对于给定的构件来讲,某些事件处理功能可能会改变,那么使用内部类把事件处理合并到构件类中而不提供机制修改要处理的事件处理,将是一个相当不明智的设计决策。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值