이벤트 처리 예제: 알람 시계

Flash Player 9 이상, Adobe AIR 1.0 이상

알람 시계 예제는 사용자가 알람이 울리는 시간 및 알람이 울릴 때 표시되는 메시지를 지정하는 데 사용할 수 있는 시계로 구성됩니다. 알람 시계 예제는 날짜 및 시간을 사용한 작업 의 SimpleClock 응용 프로그램을 기초로 구성되며, 다음을 포함하여 ActionScript 3.0에서 이벤트를 사용하는 몇 가지 작업을 보여 줍니다.

  • 이벤트 수신 및 응답

  • 리스너에 이벤트 알림

  • 사용자 정의 이벤트 유형 만들기

이 샘플에 대한 Flash Professional 응용 프로그램 파일을 가져오려면 http://www.adobe.com/go/learn_programmingAS3samples_flash_kr 을 참조하십시오. 이 샘플에 대한 Flex 응용 프로그램 파일을 가져오려면 http://www.adobe.com/go/as3examples_kr 을 참조하십시오. Alarm Clock 응용 프로그램 파일은 Samples/AlarmClock 폴더에 있으며 이 응용 프로그램은 다음과 같은 파일을 포함합니다.

파일

설명

AlarmClockApp.mxml

또는

AlarmClockApp.fla

Flash(FLA) 또는 Flex(MXML) 형식의 기본 응용 프로그램 파일입니다.

com/example/programmingas3/clock/AlarmClock.as

알람 시계 기능을 추가하여 SimpleClock 클래스를 확장하는 클래스입니다.

com/example/programmingas3/clock/AlarmEvent.as

AlarmClock 클래스의 alarm 이벤트에 대한 이벤트 객체로 사용되는 사용자 정의 이벤트 클래스(flash.events.Event의 하위 클래스)입니다.

com/example/programmingas3/clock/AnalogClockFace.as

현재 시간을 기준으로 시계의 둥근 문자판과 시침, 분침, 초침을 그립니다(SimpleClock 예제의 설명 참조).

com/example/programmingas3/clock/SimpleClock.as

간단한 시간 계측 기능을 포함하는 시계 인터페이스 구성 요소입니다(SimpleClock 예제의 설명 참조).

알람 시계 개요

이 예제에 나오는 시계의 주요 기능(예: 시간 추적 및 시계 문자판 표시)은 날짜 및 시간 예제: 간단한 아날로그 시계 에서 설명하는 SimpleClock 응용 프로그램 코드를 다시 사용합니다. AlarmClock 클래스는 SimpleClock 예제에서 알람 시간 설정, 알람이 "울릴" 때 알림 제공 등 알람 시계에 필요한 기능을 추가하여 SimpleClock 클래스를 확장합니다.

특정 동작이 발생할 때 알림을 제공하는 것은 이벤트의 역할입니다. AlarmClock 클래스는 원하는 액션을 실행하기 위해 다른 객체에서 수신할 수 있는 Alarm 이벤트를 노출합니다. 또한 AlarmClock 클래스는 Timer 클래스의 인스턴스를 사용하여 알람 트리거 시기를 결정할 수 있습니다. Timer 클래스는 AlarmClock 클래스와 같이 지정된 시간이 경과하면 다른 객체(이 예제의 경우 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밀리초 동안 대기한 후 타이머 이벤트를 한 번 트리거하도록 지시하는 매개 변수를 사용하여 변수가 인스턴스화되고, 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 이벤트에 대한 리스너로 등록할 메서드는 데이터 유형이 Event 클래스의 하위 클래스인 TimerEvent(flash.events.TimerEvent)로 설정된 하나의 매개 변수를 정의해야 합니다. 그러면 Timer 인스턴스에서 이벤트 리스너를 호출하는 경우 TimerEvent 인스턴스가 이벤트 객체로 전달됩니다.

다른 코드에 알람 알림

AlarmClock 클래스는 Timer 클래스와 마찬가지로 알람이 울릴 때 다른 코드에서 알림을 받을 수 있도록 이벤트를 제공합니다. 클래스에서 ActionScript에 내장된 이벤트 처리 프레임워크를 사용하려면 해당 클래스에서 flash.events.IEventDispatcher 인터페이스를 구현해야 합니다. 일반적으로 이 작업을 수행하려면 flash.events.EventDispatcher 클래스를 확장하여 IEventDispatcher를 구현하거나, EventDispatcher의 하위 클래스 중 하나를 확장합니다. 앞에서 설명했듯이 AlarmClock 클래스는 SimpleClock 클래스를 확장하고 결국 상속 체인을 통해 EventDispatcher 클래스를 확장합니다. 즉, AlarmClock 클래스에는 고유한 이벤트를 제공하는 기능이 이미 포함되어 있습니다.

EventDispatcher에서 AlarmClock에 상속되는 addEventListener() 메서드를 호출하면 다른 코드에 AlarmClock 클래스의 alarm 이벤트를 알리도록 등록할 수 있습니다. AlarmClock 인스턴스에서 alarm 이벤트가 발생했음을 다른 코드에 알릴 준비가 되면 EventDispatcher에서 상속되는 dispatchEvent() 메서드를 호출합니다.

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

이러한 코드 행은 AlarmClock 클래스의 onAlarm() 메서드에서 가져온 것입니다(전체 코드는 앞에 있음). AlarmClock 인스턴스의 dispatchEvent() 메서드가 호출되면 등록된 모든 리스너에 AlarmClock 인스턴스의 alarm 이벤트가 트리거되었음을 알립니다. dispatchEvent() 에 전달되는 매개 변수는 리스너 메서드에 전달될 이벤트 객체이며, 여기에서는 AlarmEvent 클래스의 인스턴스입니다. 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 클래스는 AlarmClock 클래스의 addEventListener() 메서드를 호출할 때 특정 이벤트( alarm )를 참조하는 데 사용할 수 있는 ALARM 상수도 정의합니다.

모든 Event 하위 클래스는 사용자 정의 기능을 추가해야 할 뿐만 아니라 ActionScript 이벤트 처리 프레임워크의 일부로 상속 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에서 상속됨)은 사용자 정의 유형의 이름 및 모든 속성의 이름과 값으로 이루어진 문자열을 제공하는 데 사용됩니다.