如先前內容所提及,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 實體做為事件物件。