W przykładzie Alarm Clock przedstawiono zegar, który umożliwia określenie czasu, w którym zostanie uruchomiony alarm, a także zawiera komunikat, który będzie wyświetlany w przed uruchomieniem alarmu. W przykładzie Alarm Clock wykorzystano aplikację SimpleClock z sekcji
Praca z datami i czasem
. Przykład Alarm Clock ilustruje kilka aspektów pracy ze zdarzeniami w języku ActionScript 3.0, między innymi:
-
Wykrywanie zdarzeń i reagowanie na nie
-
Powiadamianie użytkowników o zdarzeniach
-
Tworzenie niestandardowych typów zdarzeń
Aby pobrać pliki tej przykładowej aplikacji w wersji dla programu Flash Professional, należy skorzystać ze strony
http://www.adobe.com/go/learn_programmingAS3samples_flash_pl
. Aby pobrać pliki tej przykładowej aplikacji w wersji dla środowiska Flex, należy skorzystać ze strony
http://www.adobe.com/go/as3examples_pl
. Pliki aplikacji Alarm Clock są dostępne w folderze Samples/AlarmClock. Aplikacja obejmuje następujące pliki:
File
|
Opis
|
AlarmClockApp.mxml
lub
AlarmClockApp.fla
|
Główny plik aplikacji w formacie Flash (FLA) lub Flex (MXML).
|
com/example/programmingas3/clock/AlarmClock.as
|
Klasa, która stanowi rozszerzenie klasy SimpleClock — dodaje funkcję alarmu.
|
com/example/programmingas3/clock/AlarmEvent.as
|
Niestandardowa klasa zdarzeń (podklasa klasy flash.events.Event), która jest wykorzystywana jako obiekt zdarzenia dla zdarzenia
alarm
klasy AlarmClock.
|
com/example/programmingas3/clock/AnalogClockFace.as
|
Rysuje okrągłą tarczę zegara, a także wskazówki: godzinową, minutową i sekundową (opisane w przykładzie SimpleClock).
|
com/example/programmingas3/clock/SimpleClock.as
|
Składnik interfejsu zegara z prostą funkcją kontroli czasu (opisane w przykładzie SimpleClock).
|
Alarm Clock — przegląd
Główna funkcja zegara w tym przykładzie, oprócz śledzenia czasu i wyświetlania tarczy zegara, korzysta ponownie z kodu aplikacji SimpleClock, która została opisana w rozdziale
Przykład z datą i godziną: prosty zegar analogowy
. Klasa AlarmClock stanowi rozszerzenie klasy SimpleClock z przykładu — dodaje funkcje wymagane dla budzika, między innymi: funkcję ustawiania czasu alarmu i powiadamiania o uruchomieniu alarmu.
Powiadomienie to najważniejsza funkcja zdarzeń. Klasa AlarmClock udostępnia zdarzenie Alarm, które może być wykrywane przez inne obiekty w celu wykonywania żądanych operacji. Ponadto klasa AlarmClock korzysta z instancji klasy Timer w celu określenia czasu wywoływania alarmu. Klasa Timer — podobnie, jak klasa AlarmClock — udostępnia zdarzenie, które powiadamia inne obiekty (w tym przypadku instancja AlarmClock) o upływie określonego czasu. Zdarzenia — podobnie jak w większości aplikacji ActionScript — stanowią istotną część funkcji przykładowej aplikacji Alarm Clock.
Uruchamianie alarmu
Jak wspomniano powyżej — jedyna funkcja, którą udostępnia aplikacja AlarmClock, odwołuje się do ustawiania i uruchamiania alarmu. Wbudowana klasa Timer (flash.utils.Timer) umożliwia programiście napisanie kodu, który zostanie wykonany po upływie określonego czasu. Klasa AlarmClock korzysta z instancji Timer w celu określenia czasu uruchomienia alarmu.
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);
}
Instancja Timer zdefiniowana w klasie AlarmClock ma nazwę
alarmTimer
. Metoda
initClock()
, która wykonuje niezbędne operacje ustawiania dla instancji AlarmClock, wykonuje dwie czynności ze zmienną
alarmTimer
. Po pierwsze: zmienna zostaje zainicjowana z parametrami, które stanowią dla instancji Timer instrukcję oczekiwania przez czas 0 milisekund oraz instrukcję uruchomienia zdarzenia Timer tylko jeden raz. Po wywołaniu
alarmTimer
kod wywołuje metodę
addEventListener()
zmiennej, co oznacza, że chce wykryć zdarzenie
timer
zmiennej. Instancja Timer działa poprzez wywoływanie jej zdarzenia
timer
nawet po upływie określonego czasu. Klasa AlarmClock musi wiedzieć o wywołaniu zdarzenia
timer
w celu uruchomienia własnego alarmu. Wywołując metodę
addEventListener()
kod aplikacji AlarmClock rejestruje się jako detektor w
alarmTimer
. Te dwa parametry oznaczają, że klasa AlarmClock chce wykrywać zdarzenie
timer
(na co wskazuje zmienna
TimerEvent.TIMER
), oraz że w odpowiedzi na zdarzenie powinna zostać wywołana metoda
onAlarm()
klasy AlarmClock.
W celu ustawienia alarmu wywoływana jest metoda
setAlarm()
klasy AlarmClock:
/**
* 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;
}
Ta metoda wykonuje kilka operacji, między innymi: zapisuje komunikat alarmu i tworzy obiekt Date (
alarmTime
), który reprezentuje rzeczywisty moment, w którym nastąpi uruchomienie alarmu. Najważniejsze w tym opisie jest to, że w kilku ostatnich liniach metody następuje ustawienie i aktywacja zmiennej
alarmTimer
licznika czasu. Najpierw następuje wywołanie metody
reset()
, która zatrzymuje licznik czasu, jeśli licznik działa. Następnie bieżący czas (reprezentowany przez zmienną
now
) jest odejmowany od wartości zmiennej
alarmTime
w celu określenia liczby milisekund, jaka upłynie przed uruchomieniem alarmu. Klasa Timer nie wywołuje jej zdarzenia
timer
w czasie bezwzględnym, więc do właściwości
delay
zmiennej
alarmTimer
zostaje przypisana względna różnica czasu. Ostatecznie wywoływana jest metoda
start()
, która uruchamia licznik czasu.
Po upływie określonego czasu zmienna
alarmTimer
wywołuje zdarzenie
timer
. Klasa AlarmClock zarejestrowała metodę
onAlarm()
jako detektor dla tego zdarzenia, dlatego po zdarzeniu
timer
wywoływana jest metoda
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);
}
Metoda, która została zarejestrowana jako detektor zdarzenia, musi zostać zdefiniowana z odpowiednim podpisem (tj. z zestawem parametrów i typem powrotu metody). Aby metoda była detektorem zdarzenia
timer
klasy Timer, metoda musi definiować jeden parametr, który zawiera dane typu TimerEvent (flash.events.TimerEvent) — jest to podklasa klasy Event. Gdy instancja Timer wywoła swoje detektory zdarzeń, przekaże instancję TimerEvent jako obiekt zdarzenia.
Powiadamianie innych o alarmie
Klasa AlarmClock — podobnie jak klasa Timer — udostępnia zdarzenie, dzięki któremu inny kod może otrzymać powiadomienie o uruchomieniu alarmu. Aby klasa mogła korzystać ze struktury obsługi zdarzeń wbudowanej do języka ActionScript, klasa musi implementować interfejs flash.events.IEventDispatcher. Jest to możliwe, gdy klasa flash.events.EventDispatcher zostanie rozszerzona — w wyniku rozszerzenia następuje udostępnienie standardowej implementacji IEventDispatcher (lub poprzez rozszerzenie jednej z podklas klasy EventDispatcher). Jak już wcześniej wspomniano, klasa AlarmClock rozszerza klasę SimpleClock, która (poprzez łańcuch dziedziczenia) rozszerza klasę EventDispatcher. Oznacza to, że klasa AlarmClock zawiera wbudowane funkcje, dzięki którym może udostępniać swoje własne zdarzenia.
Inny kod może być powiadamiany o zdarzeniu
alarm
klasy AlarmClock, gdy wywoła metodę
addEventListener()
, którą klasa AlarmClock dziedziczy z klasy EventDispatcher. Gdy instancja AlarmClock jest gotowa do powiadomienia innego kodu o wystąpieniu zdarzenia
alarm
, powiadamia poprzez wywołanie metody
dispatchEvent()
, która również jest dziedziczona z klasy EventDispatcher.
var alarm:AlarmEvent = new AlarmEvent(this.alarmMessage);
this.dispatchEvent(alarm);
Te wiersze klasy pochodzą z metody
onAlarm()
klasy AlarmClock (poprzednio zaprezentowano całą metodę). Następuje wywołanie metody
dispatchEvent()
klasy AlarmClock, która powiadamia wszystkie zarejestrowane detektory o wywołaniu zdarzenia
alarm
instancji AlarmClock. Parametr przekazany do
dispatchEvent()
jest obiektem zdarzenia, który zostanie przekazany również do metod detektora. W takim przypadku jest on instancją klasy AlarmEvent, która jest podklasą klasy Event utworzoną specjalnie w tym przykładzie.
Udostępnianie niestandardowego zdarzenia alarmu
Wszystkie detektory zdarzeń odbierają parametr obiektu zdarzenia z informacją o wywołaniu konkretnego zdarzenia. W wielu przypadkach obiekt zdarzenia jest instancją klasy Event. Jednak w niektórych przypadkach lepszym rozwiązaniem jest udostępnienie dodatkowych informacji do detektorów zdarzeń. Często stosowanym sposobem osiągnięcia tego celu jest zdefiniowanie nowej klasy, podklasy klasy Event, a następnie użycie instancji tej klasy jako obiektu zdarzenia. W tym przykładzie instancja AlarmEvent jest używana jako obiekt zdarzenia przy wywołaniu zdarzenia
alarm
klasy AlarmClock. Przedstawiona klasa AlarmEvent udostępnia dodatkowe informacje o zdarzeniu
alarm
, przede wszystkim komunikat alarmu:
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;
}
...
}
Najlepszym sposobem na utworzenie niestandardowego obiektu zdarzenia jest zdefiniowanie klasy, która rozszerzy klasę Event, co przedstawiono w poprzednim przykładzie. W celu uzupełnienia odziedziczonej funkcji w klasie AlarmEvent zdefiniowano właściwość
message
, która zawiera tekst komunikatu alarmu skojarzony z danym zdarzeniem; wartość
message
jest przekazywana jako parametr do konstruktora AlarmEvent. Klasa AlarmEvent definiuje również stałą
ALARM
, która może służyć jako odwołanie do określonego zdarzenia (
alarm
) podczas wywołania metody
addEventListener()
klasy AlarmClock.
Oprócz dodawania funkcji niestandardowych każda podklasa Event musi zastępować odziedziczoną metodę
clone()
jako część ActionScript event-handling framework. Podklasy klasy Event mogą również opcjonalnie zastępować odziedziczoną metodę
toString()
w celu uwzględniania niestandardowych właściwości zdarzenia w wartości zwracanej po wywołaniu metody
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");
}
Zastąpiona metoda
clone()
musi zwracać nową instancję niestandardowej podklasy Event z wszystkimi niestandardowymi właściwościami ustawionymi w taki sposób, aby były zgodne z bieżącą instancją. W zastąpionej metodzie
toString()
metoda narzędziowa
formatToString()
(odziedziczona z Event) udostępnia ciąg z nazwą niestandardowego typu, a także nazwy i wartości wszystkich jego właściwości.
|
|
|