Exempel på händelsehantering: väckarklocka

Flash Player 9 och senare, Adobe AIR 1.0 och senare

Exemplet Alarm Clock består av en klocka som gör att användaren kan ange vilken tid larmet ska utlösas och att ett meddelande då ska visas. Exemplet Alarm Clock bygger på SimpleClock-programmet från Alarm Clock. Arbeta med datum och tidpunkter illustrerar flera aspekter av att arbeta med händelser i ActionScript 3.0, inklusive följande:

  • Lyssna efter och svara på en händelse

  • Meddela avlyssnare om en händelse

  • Skapa en anpassad händelsetyp

Information om hur du hämtar Flash Professional-programfilerna för det här exemplet finns i http://www.adobe.com/go/learn_programmingAS3samples_flash_se . Information om hur du hämtar Flex-programfilerna för det här exemplet finns i http://www.adobe.com/go/as3examples_se . Alarm Clock-programfilerna finns i mappen Samples/AlarmClock. Programmet innehåller följande filer:

Fil

Beskrivning

AlarmClockApp.mxml

eller

AlarmClockApp.fla

Huvudprogramfilen i Flash (FLA) eller Flex (MXML).

com/example/programmingas3/clock/AlarmClock.as

En klass som utökar klassen SimpleClock genom att lägga till larmfunktionalitet.

com/example/programmingas3/clock/AlarmEvent.as

En anpassad händelseklass (en underklass till flash.events.Event) som fungerar som händelseobjektet för klassen AlarmClocks alarm -händelse.

com/example/programmingas3/clock/AnalogClockFace.as

Ritar en rund urtavla med tim-, minut- och sekundvisare baserat på tiden (enligt beskrivningen i SimpleClock-exemplet).

com/example/programmingas3/clock/SimpleClock.as

En klockgränssnittskomponent med enkel tidangivningsfunktionalitet (enligt beskrivningen i SimpleClock-exemplet).

Översikt över Alarm Clock

Den primära funktionen hos klockan i det här exemplet, inklusive att följa upp tiden och visa urtavlan, återanvänder SimpleClock-programkoden som beskrivs i Exempel på datum och tid: enkel analog klocka . Klassen AlarmClock utökar klassen SimpleClock från det exemplet genom att lägga till larmfunktionalitet, inklusive inställning av väckningstid och meddelande om när klockan ”ringer”.

Att meddela när något händer är den uppgift som händelser är till för. Klassen AlarmClock visar Alarm-händelsen, som andra objekt kan lyssna efter för att kunna utföra önskade åtgärder. Klassen AlarmClock använder dessutom en instans av klassen Timer för att avgöra när larmet ska utlösas. Klassen Timer erbjuder liksom klassen AlarmClock en händelse för att meddela andra objekt (en AlarmClock-instans i det här fallet) när en viss tid har gått. Precis som med de flesta ActionScript-program utgör händelser en viktig del av funktionaliteten hos Alarm Clock-exempelprogrammet.

Utlösa larmet

Som tidigare nämnts är den enda funktionaliteten som klassen AlarmClock erbjuder den som rör inställning och utlösning av larmet. Den inbyggda klassen Timer (flash.utils.Timer) erbjuder ett annat sätt för programmerare att definiera kod som ska köras efter en viss tid. Klassen AlarmClock använder en Timer-instans för att bestämma när larmet ska utlösas.

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

Timer-instansen i klassen AlarmClock heter alarmTimer . initClock() -metoden, som utför nödvändiga inställningar för AlarmClock-instansen, gör två saker med alarmTimer -variabeln. Först skapas variabeln med parametrar som instruerar Timer-instansen att vänta 0 millisekunder och att bara utlösa timer-händelsen en gång. Efter att ha skapat alarmTimer anropar koden variabelns addEventListener() -metod för att ange att den vill lyssna på den variabelns timer -händelse. En Timer-instans fungerar så att den skickar sin timer -händelse efter att en viss tid har gått. Klassen AlarmClock behöver veta när timer -händelsen skickas för att kunna utlösa sitt eget larm. Genom att anropa addEventListener() registrerar AlarmClock-koden sig själv som avlyssnare med alarmTimer . De två parametrarna indikerar att klassen AlarmClock vill lyssna efter timer -händelsen (indikeras av konstanten TimerEvent.TIMER ) och att klassen AlarmClocks onAlarm() -metod anropas som svar på händelsen när den inträffar.

För att verkligen kunna ställa in larmet anropas klassen AlarmClocks setAlarm() -metod som i följande:

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

Den här metoden gör flera saker, som att lagra larmmeddelandet och att skapa ett datumobjekt ( alarmTime ) som representerar den verkliga tidpunkten när larmet ska utlösas. Det som är mest relevant här är metodens sista rader, som innebär att alarmTimer -variabelns timer ställs in och aktiveras. Först anropas dess reset() -metod, vilket stoppar timern och återställer den om den redan är igång. Sedan subtraheras den aktuella tiden (som representeras av now -variabeln) från alarmTime -variabelns värde för att bestämma hur många millisekunder som måste gå innan larmet utlöses. Klassen Timer utlöser inte sin timer -händelse som en absolut tid, så det är denna relativa tidsskillnad som tilldelas delay -egenskapen för alarmTimer . Slutligen anropas start() -metoden för att starta timern.

När den angivna tiden har gått, skickar alarmTimer timer -händelsen. Eftersom klassen AlarmClock registrerade sin onAlarm() -metod som avlyssnare för den händelsen, och timer -händelsen inträffar, anropas 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); 
    }

En metod som registreras som händelseavlyssnare måste definieras med lämplig signatur (d.v.s. parameteruppsättningen och metodens returtyp). För att vara avlyssnare för klassen Timers timer -händelse måste en metod definiera en parameter vars datatyp är TimerEvent (flash.events.TimerEvent), som är en underklass till klassen Event. När Timer-instansen anropar sina händelseavlyssnare, överför den en TimerEvent-instans som händelseobjekt.

Meddela andra om larmet

Klassen AlarmClock erbjuder liksom klassen Timer en händelse som gör att annan kod kan ta emot meddelanden när larmet utlöses. För att en klass ska använda det ramverk för händelsehantering som är inbyggt i ActionScript måste klassen implementera gränssnittet flash.events.IEventDispatcher. Detta görs normalt genom att utöka klassen flash.events.EventDispatcher, som erbjuder en standardimplementering av IEventDispatcher (eller genom att utöka en av underklasserna till EventDispatcher). Som tidigare har beskrivits utökar klassen AlarmClock klassen SimpleClock, som i sin tur (via en arvskedja) utökar klassen EventDispatcher. Allt detta innebär att klassen AlarmClock redan har inbyggd funktionalitet att erbjuda sina egna händelser.

Annan kod kan registreras så att den får meddelande om klassen AlarmClocks alarm -händelse genom att anropa addEventListener() -metoden som AlarmClock ärver från EventDispatcher. När en AlarmClock-instans är redo att meddela annan kod att dess alarm -händelse har utlösts, gör den det genom att anropa dispatchEvent() -metoden, som också ärvs från EventDispatcher.

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

Dessa rader kod är tagna från klassen AlarmClocks onAlarm() -metod (som redan har visats fullständigt tidigare i den här dokumentationen). AlarmClock-instansens dispatchEvent() -metod anropas, som i sin tur meddelar alla registrerade avlyssnare att AlarmClock-instansens alarm -händelse har utlösts. Parametern som överförs till dispatchEvent() är det händelseobjekt som kommer att överföras till avlyssnarmetoderna. I det här fallet är detta en instans av klassen AlarmEvent, som är en Event-underklass särskilt framtagen för det här exemplet.

Erbjuda en anpassad larmhändelse

Alla händelseavlyssnare får en händelseobjektparameter med information om den specifika händelse som utlöses. I många fall är händelseobjektet en instans av klassen Event. Ibland kan det dock vara användbart att erbjuda ytterligare information till händelseavlyssnare. Detta uppnås ofta genom att en ny klass definieras, en underklass till klassen Event, och därefter används en instans av den klassen som händelseobjekt. I det här exemplet används en AlarmEvent-instans som händelseobjekt när klassen AlarmClocks alarm -händelse skickas. Klassen AlarmEvent, som visas här, erbjuder ytterligare information om alarm -händelsen, nämligen larmmeddelandet:

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

Det bästa sättet att skapa en anpassad händelseobjektsklass på är att definiera en klass som utökar klassen Event, som i föregående exempel. För att komplettera den ärvda funktionaliteten definierar klassen AlarmEvent en message -egenskap som innehåller texten för larmmeddelandet som är kopplat till händelsen. Värdet för message anges som en parameter i AlarmEvent-konstruktorn. Klassen AlarmEvent definierar även konstanten ALARM , som kan användas för att referera till den specifika händelsen ( alarm ) vid anrop av klassen AlarmClocks addEventListener() -metod.

Förutom att lägga till anpassad funktionalitet måste varje Event-underklass åsidosätta den ärvda clone() -metoden som del av ramverket för ActionScript-händelsehantering. Event-underklasser kan även (valfritt) åsidosätta den ärvda toString() -metoden för att inkludera den anpassade händelsens egenskaper i värdet som returneras när toString() -metoden anropas.

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

Den åsidosatta clone() -metoden måste returnera en ny instans av den anpassade Event-underklassen med alla anpassade egenskaper inställda så att de överensstämmer med den aktuella instansen. I den åsidosatta toString() -metoden används verktygsmetoden formatToString() (ärvd från Event) för att ange en sträng med namnet på den anpassade typen samt namnen och värdena för alla dess egenskaper.