事件处理示例:闹钟Flash Player 9 和更高版本,Adobe AIR 1.0 和更高版本 Alarm Clock 示例包含一个时钟,供用户指定闹铃响起的时间,还包含一个在该时间显示的消息。Alarm Clock 示例是在使用日期和时间中的 SimpleClock 应用程序的基础上构建的。Alarm Clock 说明了在 ActionScript 3.0 中使用事件的几个方面,其中包括:
若要获取此范例的 Flash Professional 应用程序文件,请参阅 http://www.adobe.com/go/learn_programmingAS3samples_flash_cn。若要获取此范例的 Flex 应用程序文件,请参阅 http://www.adobe.com/go/as3examples_cn。可以在 Samples/AlarmClock 文件夹中找到 Alarm Clock 应用程序文件。该应用程序包括以下文件:
Alarm Clock 概述在此示例中,时钟的主要功能(包括跟踪时间和显示时钟形状)重复使用 SimpleClock 应用程序代码,相关介绍请参阅日期和时间示例:简单模拟时钟。AlarmClock 类添加了闹钟所需的功能(包括设置闹铃时间和在闹铃“响起”时显示通知),从而扩展了该示例中的 SimpleClock 类。 在发生事情时提供通知,是创建事件的目的。AlarmClock 类公开 Alarm 事件,其他对象可侦听该事件以执行所需操作。此外,AlarmClock 类使用 Timer 类的实例来确定何时触发闹铃。和 AlarmClock 类一样,Timer 类提供一个事件,用于在经过特定时间时通知其他对象(在本例中为 AlarmClock 实例)。就像大多数 ActionScript 应用程序一样,事件构成了 Alarm Clock 范例应用程序功能的重要部分。 触发闹铃如前所述,AlarmClock 类实际提供的唯一功能与设置和触发闹铃有关。内置的 Timer 类 (flash.utils.Timer) 为开发人员提供了定义要在指定时间之后执行的代码的方法。AlarmClock 类使用 Timer 实例来确定何时触发闹铃。 import flash.events.TimerEvent; import flash.utils.Timer; /** * The Timer that will be used for the alarm. */ public var alarmTimer:Timer; ... /** * Instantiates a new AlarmClock of a given size. */ public override function initClock(faceSize:Number = 200):void { super.initClock(faceSize); alarmTimer = new Timer(0, 1); alarmTimer.addEventListener(TimerEvent.TIMER, onAlarm); } AlarmClock 类中定义的 Timer 实例被命名为 alarmTimer。initClock() 方法执行 AlarmClock 实例的所需设置操作,使用 alarmTimer 变量执行两个任务。首先,使用指示 Timer 实例等待 0 毫秒且仅触发其 timer 事件一次的参数实例化变量。实例化 alarmTimer 后,代码调用变量的 addEventListener() 方法,指示它要监听该变量的 timer 事件。Timer 实例的工作方式是:在经过指定时间后调度其 timer 事件。AlarmClock 类需要了解何时调度 timer 事件,以便触发自己的闹铃。通过调用 addEventListener(),AlarmClock 代码将自身作为侦听器在 alarmTimer 中进行注册。两个参数指示 AlarmClock 类要侦听 timer 事件(由常量 TimerEvent.TIMER 指示),并且当事件发生时,应调用 AlarmClock 类的 onAlarm() 方法以响应事件。 为了实际设置闹铃,代码调用了 AlarmClock 类的 setAlarm() 方法,如下所示: /** * Sets the time at which the alarm should go off. * @param hour The hour portion of the alarm time. * @param minutes The minutes portion of the alarm time. * @param message The message to display when the alarm goes off. * @return The time at which the alarm will go off. */ public function setAlarm(hour:Number = 0, minutes:Number = 0, message:String = "Alarm!"):Date { this.alarmMessage = message; var now:Date = new Date(); // Create this time on today's date. alarmTime = new Date(now.fullYear, now.month, now.date, hour, minutes); // Determine if the specified time has already passed today. if (alarmTime <= now) { alarmTime.setTime(alarmTime.time + MILLISECONDS_PER_DAY); } // Stop the alarm timer if it's currently set. alarmTimer.reset(); // Calculate how many milliseconds should pass before the alarm should // go off (the difference between the alarm time and now) and set that // value as the delay for the alarm timer. alarmTimer.delay = Math.max(1000, alarmTime.time - now.time); alarmTimer.start(); return alarmTime; } 此方法执行了几项操作,包括存储闹铃消息和创建一个 Date 对象 (alarmTime),该对象表示触发闹铃的实际时间。在该方法的最后几行中,与当前讨论最相关的操作是设置和激活了 alarmTimer 变量的计时器。首先,调用其 reset() 方法,如果计时器已运行,则将其停止并进行重置。接下来,从 alarmTime 变量值中减去当前时间(由 now 变量表示),以确定需要经过多少毫秒后才会触发闹铃。Timer 类并不会在某个绝对时间触发其 timer 事件,因此,分配给 alarmTimer 的 delay 属性的是该相对时间差。最后,调用 start() 方法以实际启动计时器。 一旦经过指定时间,alarmTimer 将调度 timer 事件。由于 AlarmClock 类已将其 onAlarm() 方法注册为该事件的侦听器,因此发生 timer 事件时,将调用 onAlarm()。 /** * Called when the timer event is dispatched. */ public function onAlarm(event:TimerEvent):void { trace("Alarm!"); var alarm:AlarmEvent = new AlarmEvent(this.alarmMessage); this.dispatchEvent(alarm); } 注册为事件侦听器的方法必须使用适当的签名(即,方法的参数集和返回类型)来定义。若要侦听 Timer 类的 timer 事件,方法必须定义一个数据类型为 TimerEvent (flash.events.TimerEvent) 的参数,该参数是 Event 类的子类。当 Timer 实例调用其事件侦听器时,会传递一个 TimerEvent 实例作为事件对象。 向其他代码通知闹铃和 Timer 类一样,AlarmClock 类提供了一个事件,以允许其他代码在闹铃响起时收到通知。对于类而言,要使用内置于 ActionScript 中的事件处理框架,必须实现 flash.events.IEventDispatcher 接口。通常,这是通过扩展 flash.events.EventDispatcher 类(提供 IEventDispatcher 的标准实现)或 EventDispatcher 的某个子类来完成的。如前所述,AlarmClock 类扩展了 SimpleClock 类,SimpleClock 类(通过继承链)扩展了 EventDispatcher 类。 所有这些意味着 AlarmClock 类已经具有内置功能以提供自己的事件。 其他代码可通过调用 AlarmClock 从 EventDispatcher 继承的 addEventListener() 方法进行注册,以获得 AlarmClock 类的 alarm 事件的通知。当 AlarmClock 实例准备通知其他代码已引发其 alarm 事件时,它会调用 dispatchEvent() 方法进行通知,该方法同样是从 EventDispatcher 继承的。 var alarm:AlarmEvent = new AlarmEvent(this.alarmMessage); this.dispatchEvent(alarm); 这些代码行摘自 AlarmClock 类的 onAlarm() 方法(前面完整介绍过)。调用 AlarmClock 实例的 dispatchEvent() 方法,该方法接下来通知所有注册的侦听器:已触发 AlarmClock 实例的 alarm 事件。传递给 dispatchEvent() 的参数是要一直传递到侦听器方法的事件对象。在本例中,它是 AlarmEvent 类的实例,即为本示例专门创建的 Event 子类。 提供自定义 Alarm 事件所有事件侦听器都接收一个事件对象参数,该参数提供有关要触发的特定事件的信息。在许多情况下,事件对象是 Event 类的实例。但在某些情况下,向事件侦听器提供其他信息很有用。实现该目的的一个常用方法是定义一个新类(Event 类的子类),并将该类的实例用作事件对象。在本示例中,当调度 AlarmClock 类的 alarm 事件时,会将一个 AlarmEvent 实例用作事件对象。在此介绍的 AlarmEvent 类提供有关 alarm 事件的其他信息,具体来说是闹铃消息: import flash.events.Event; /** * This custom Event class adds a message property to a basic Event. */ public class AlarmEvent extends Event { /** * The name of the new AlarmEvent type. */ public static const ALARM:String = "alarm"; /** * A text message that can be passed to an event handler * with this event object. */ public var message:String; /** *Constructor. *@param message The text to display when the alarm goes off. */ public function AlarmEvent(message:String = "ALARM!") { super(ALARM); this.message = message; } ... } 要创建自定义事件对象类,最好的方法是定义一个扩展 Event 类的类,如前面的示例中所示。为了补充继承的功能,AlarmEvent 类定义一个属性 message,该属性包含与事件关联的闹铃消息的文本;message 是作为 AlarmEvent 构造函数中的参数传入的。AlarmEvent 类还定义常量 ALARM,当调用 AlarmClock 类的 addEventListener() 方法时,该常量可用于引用特定事件 (alarm)。 除了添加自定义功能外,作为 ActionScript 事件处理框架的一部分,每个 Event 子类还必须覆盖继承的 clone() 方法。Event 子类还可以选择性地覆盖继承的 toString() 方法,以便在调用 toString() 方法时返回的值中包括自定义事件的属性。 /** * Creates and returns a copy of the current instance. * @return A copy of the current instance. */ public override function clone():Event { return new AlarmEvent(message); } /** * Returns a String containing all the properties of the current * instance. * @return A string representation of the current instance. */ public override function toString():String { return formatToString("AlarmEvent", "type", "bubbles", "cancelable", "eventPhase", "message"); } 被覆盖的 clone() 方法需要返回自定义 Event 子类的新实例,并且设置了所有自定义属性以匹配当前实例。在被覆盖的 toString() 方法中,实用程序方法 formatToString()(从 Event 继承)用于提供一个字符串,包括自定义类型的名称以及所有属性的名称和值。 |
|