Beispiel für die Ereignisverarbeitung: Alarm Clock

Flash Player 9 und höher, Adobe AIR 1.0 und höher

Die Beispielanwendung „Alarm Clock“ besteht aus einer Uhr, für die Benutzer eine Weckzeit sowie eine Meldung angeben können, die zur Weckzeit angezeigt werden soll. Die Beispielanwendung „Alarm Clock“ basiert auf der Anwendung „SimpleClock“ aus Arbeiten mit Datum und Zeit . Dieses Beispiel veranschaulicht mehrere Aspekte der Verwendung von Ereignissen in ActionScript 3.0:

  • Warten und Reagieren auf Ereignisse

  • Benachrichtigen von Listenern über Ereignisse

  • Erstellen benutzerdefinierter Ereignistypen

Die Flash Professional-Anwendungsdateien für dieses Beispiel finden Sie unter http://www.adobe.com/go/learn_programmingAS3samples_flash_de . Die Flex-Anwendungsdateien für dieses Beispiel finden Sie unter http://www.adobe.com/go/as3examples_de . Die Dateien der Anwendung „Alarm Clock“ befinden sich im Ordner „Samples/AlarmClock“. Zur Anwendung gehören folgende Dateien:

Datei

Beschreibung

AlarmClockApp.mxml

oder

AlarmClockApp.fla

Die Hauptanwendungsdatei im Flash-Format (FLA) oder Flex-Format (MXML).

com/example/programmingas3/clock/AlarmClock.as

Eine Klasse, die die SimpleClock-Klasse um Weckfunktionen erweitert.

com/example/programmingas3/clock/AlarmEvent.as

Eine benutzerdefinierte Event-Klasse (eine Unterklasse von flash.events.Event), die als Ereignisobjekt für das alarm -Ereignis der AlarmClock-Klasse dient.

com/example/programmingas3/clock/AnalogClockFace.as

Zeichnet ein rundes Zifferblatt sowie Stunden-, Minuten- und Sekundenzeiger anhand der aktuellen Zeit (siehe Beschreibung im SimpleClock-Beispiel).

com/example/programmingas3/clock/SimpleClock.as

Eine Uhrenschnittstellenkomponente mit einfacher Zeitmessungsfunktionalität (siehe Beschreibung im SimpleClock-Beispiel).

Überblick über die Beispielanwendung „Alarm Clock“

Für die primäre Funktionalität der Uhr in diesem Beispiel (einschließlich der Zeitmessung und der Zifferblattanzeige) wird die unter Beispiel für Datum und Uhrzeit: Einfache Analoguhr beschriebene Anwendung „SimpleClock“ verwendet. Die AlarmClock-Klasse erweitert die SimpleClock-Klasse aus diesem Beispiel um die für einen Wecker benötigten Funktionen. Dazu gehören das Festlegen einer Weckzeit und das Ausgeben einer Benachrichtigung, wenn der Wecker klingelt.

Ereignisse werden zur Bereitstellung von Benachrichtigungen beim Eintreten bestimmter Bedingungen eingesetzt. Die AlarmClock-Klasse stellt das Alarm-Ereignis bereit, auf das andere Objekte warten können, um dann die gewünschten Aktionen auszuführen. Zusätzlich wird mit der AlarmClock-Klasse eine Instanz der Timer-Klasse verwendet, um zu ermitteln, zu welchem Zeitpunkt der Weckalarm ausgelöst werden muss. Wie die AlarmClock-Klasse stellt auch die Timer-Klasse ein Ereignis bereit, um andere Objekte (in diesem Fall eine AlarmClock-Instanz) zu benachrichtigen, wenn eine bestimmte Zeit vergangen ist. Wie bei den meisten ActionScript-Anwendungen bilden Ereignisse einen wichtigen Teil der Funktionalität der Beispielanwendung „Alarm Clock“.

Auslösen des Weckalarms

Wie bereits erwähnt, bezieht sich die einzige tatsächlich mit der AlarmClock-Klasse bereitgestellte Funktionalität auf das Festlegen der Weckzeit und das Auslösen des Weckalarms. Die integrierte Timer-Klasse (flash.utils.Timer) ermöglicht es Entwicklern, Programmcode festzulegen, der nach Ablauf einer bestimmten Zeit ausgeführt wird. Die AlarmClock-Klasse verwendet eine Timer-Instanz, um zu ermitteln, zu welchem Zeitpunkt der Weckalarm ausgelöst werden muss.

    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); 
    }

Die in der AlarmClock-Klasse definierte Timer-Instanz trägt die Bezeichnung alarmTimer . Mit der initClock() -Methode, durch die die erforderlichen Initialisierungsvorgänge der AlarmClock-Instanz vorgenommen werden, wird die Variable alarmTimer in zwei Schritten vorbereitet. Zunächst wird die Variable mit Parametern instanziiert, durch die in der Timer-Instanz festgelegt wird, dass 0 Millisekunden gewartet und das Timer-Ereignis nur einmal ausgelöst wird. Nach dem Instanziieren von alarmTimer wird die addEventListener() -Methode dieser Variablen aufgerufen, um anzugeben, dass auf das timer -Ereignis dieser Variablen gewartet werden soll. Timer-Instanzen senden das entsprechende timer -Ereignis, nachdem eine festgelegte Zeit vergangen ist. Die AlarmClock-Klasse benötigt eine Benachrichtigung, zu welchem Zeitpunkt das timer -Ereignis ausgelöst wird, um den Weckalarm auszulösen. Durch Aufrufen von addEventListener() wird AlarmClock als Listener bei alarmTimer registriert. Die beiden Parameter geben an, dass die AlarmClock-Klasse auf das timer -Ereignis warten soll (mithilfe der Konstanten TimerEvent.TIMER ) und dass beim Eintreten des Ereignisses als Reaktion die onAlarm() -Methode der AlarmClock-Klasse aufgerufen werden soll.

Um den Weckalarm festzulegen, wird die setAlarm() -Methode der AlarmClock-Klasse wie folgt aufgerufen:

    /** 
     * 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; 
    }

Mit dieser Methode werden mehrere Vorgänge durchgeführt, darunter Speichern der Meldung für den Weckalarm und Erstellen eines Date-Objekts ( alarmTime ), das den genauen Zeitpunkt angibt, an dem der Weckalarm ausgelöst werden soll. Von größter Bedeutung sind die Festlegung und Aktivierung des Timers der Variablen alarmTimer , die in den letzten Programmzeilen der Methode erfolgen. Zuerst wird die reset() -Methode der Variablen aufgerufen, um den Timer anzuhalten und zurückzusetzen, falls er bereits aktiviert ist. Anschließend wird die aktuelle Uhrzeit (angegeben durch die Variable now ) vom Wert der Variablen alarmTime subtrahiert, um zu ermitteln, wie viele Millisekunden vergehen sollen, bevor der Weckalarm ausgelöst wird. Das timer -Ereignis der Timer-Klasse wird nicht zu einem absoluten Zeitpunkt ausgelöst. Deshalb wird der delay -Eigenschaft von alarmTimer diese relative Zeitdifferenz zugewiesen. Schließlich wird die start() -Methode aufgerufen, um den Timer zu starten.

Nachdem die angegebene Zeit vergangen ist, löst alarmTimer das timer -Ereignis aus. Da die onAlarm() -Methode der AlarmClock-Klasse als Listener für dieses Ereignis registriert ist, wird beim Eintreten des timer -Ereignisses onAlarm() aufgerufen.

    /** 
     * 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); 
    }

Eine als Ereignis-Listener registrierte Methode muss mit der richtigen Signatur (Anzahl und Typ der Parameter sowie Rückgabetyp der Methode) definiert werden. Als Listener für das timer -Ereignis der Timer-Klasse muss für eine Methode ein Parameter des Datentyps „TimerEvent“ (flash.events.TimerEvent) definiert sein, einer Unterklasse der Event-Klasse. Wenn die Timer-Instanz die zugehörigen Ereignis-Listener aufruft, wird als Ereignisobjekt eine TimerEvent-Instanz übergeben.

Weckalarmbenachrichtigungen

Wie die Timer-Klasse stellt die AlarmClock-Klasse ein Ereignis bereit, mit dessen Hilfe Benachrichtigungen über das Auslösen des Weckalarms empfangen werden können. Damit eine Klasse das Framework zur Ereignisverarbeitung von ActionScript verwenden kann, muss sie die flash.events.IEventDispatcher-Schnittstelle implementieren. Dies wird am häufigsten durch Erweitern der flash.events.EventDispatcher-Klasse (oder einer ihrer Unterklassen) erreicht. Diese stellt eine Standardimplementierung von IEventDispatcher bereit. Wie bereits beschrieben, erweitert die AlarmClock-Klasse die SimpleClock-Klasse, die ihrerseits (über eine Vererbungskette) die EventDispatcher-Klasse erweitert. Das bedeutet, dass in der AlarmClock-Klasse bereits die Funktionalität integriert ist, die zum Bereitstellen von Ereignissen benötigt wird.

Anderer Programmcode kann für Benachrichtigungen über das alarm -Ereignis der AlarmClock-Klasse durch Aufrufen der addEventListener() -Methode registriert werden, die AlarmClock von EventDispatcher erbt. Wenn eine AlarmClock-Instanz anderen Programmcode über das Auslösen des alarm -Ereignisses benachrichtigt, erfolgt dies durch Aufrufen der dispatchEvent() -Methode, die ebenfalls von EventDispatcher übernommen wurde.

        var alarm:AlarmEvent = new AlarmEvent(this.alarmMessage); 
        this.dispatchEvent(alarm);

Diese Codezeilen stammen aus der onAlarm() -Methode der AlarmClock-Klasse (die bereits an anderer Stelle vollständig aufgeführt wurde). Die dispatchEvent() -Methode der AlarmClock-Instanz wird aufgerufen, die wiederum alle registrierten Listener darüber benachrichtigt, dass das alarm -Ereignis der AlarmClock-Instanz ausgelöst wurde. Bei dem an dispatchEvent() übergebenen Parameter handelt es sich um das Ereignisobjekt, das an die Listener-Methoden weitergeleitet wird. Im vorliegenden Fall ist es eine Instanz der AlarmEvent-Klasse, einer Event-Unterklasse, die speziell für dieses Beispiel erstellt wurde.

Bereitstellen benutzerdefinierter Alarmereignisse

Alle Ereignis-Listener empfangen einen Ereignisobjektparameter mit Informationen über das jeweils ausgelöste Ereignis. In vielen Fällen ist das Ereignisobjekt eine Instanz der Event-Klasse. Gelegentlich ist es jedoch hilfreich, Ereignis-Listenern zusätzliche Informationen zur Verfügung zu stellen. Dies wird üblicherweise durch die Definition einer neuen Klasse (einer Unterklasse der Event-Klasse) erreicht, deren Instanz dann als Ereignisobjekt verwendet wird. In diesem Beispiel wird als Ereignisobjekt eine AlarmEvent-Instanz verwendet, wenn das alarm -Ereignis der AlarmClock-Klasse ausgelöst wird. Die hier dargestellte AlarmEvent-Klasse stellt zusätzliche Informationen über das alarm -Ereignis bereit, d. h. die Meldung für den Weckalarm:

    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; 
        } 
        ... 
    }

Die beste Möglichkeit zum Erstellen einer benutzerdefinierten Ereignisobjektklasse ist das Definieren einer Klasse, die die Event-Klasse erweitert, wie dies im vorangegangenen Beispiel dargestellt ist. Zur Ergänzung der geerbten Funktionalität definiert die AlarmEvent-Klasse die message -Eigenschaft, die den Text der dem Ereignis zugeordneten Meldung für den Weckalarm enthält. Der Wert von message wird als Parameter an den AlarmEvent-Konstruktor übergeben. Die AlarmEvent-Klasse definiert auch die Konstante ALARM , mit der beim Aufrufen der addEventListener() -Methode der AlarmClock-Klasse auf dieses bestimmte Ereignis ( alarm ) Bezug genommen werden kann.

Zusätzlich zum Hinzufügen benutzerdefinierter Funktionalität muss jede Unterklasse der Event-Klasse die als Bestandteil des ActionScript-Frameworks zur Ereignisverarbeitung geerbte clone() -Methode überschreiben. Event-Unterklassen können auch optional die übernommene toString() -Methode überschreiben, um in den Rückgabewert der toString() -Methode auch die benutzerdefinierten Ereigniseigenschaften aufzunehmen.

    /** 
     * 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"); 
    }

Die überschriebene clone() -Methode muss eine neue Instanz der benutzerdefinierten Event-Unterklasse zurückgeben, bei der alle benutzerdefinierten Eigenschaften mit der aktuellen Instanz übereinstimmen. In der überschriebenen toString() -Methode kommt die Dienstprogrammmethode formatToString() (von Event geerbt) zum Einsatz, um einen String mit dem Namen des benutzerdefinierten Typs sowie den Namen und Werten aller Eigenschaften bereitzustellen.