1 /* 2 Copyright aswing.org, see the LICENCE.txt. 3 */ 4 5 import org.aswing.*; 6 7 /** 8 * Fires one or more action events after a specified delay. 9 * For example, an animation object can use a <code>Timer</code> 10 * as the trigger for drawing its frames. 11 * 12 *<p> 13 * Setting up a timer 14 * involves creating a <code>Timer</code> object, 15 * registering one or more action listeners on it, 16 * and starting the timer using 17 * the <code>start</code> method. 18 * For example, 19 * the following code creates and starts a timer 20 * that fires an action event once per second 21 * (as specified by the first argument to the <code>Timer</code> constructor). 22 * The second argument to the <code>Timer</code> constructor 23 * specifies a listener to receive the timer's action events. 24 * 25 *<pre> 26 * var delay:Number = 1000; //milliseconds 27 * var listener:Object = new Object(); 28 * listener.taskPerformer = function() { 29 * <em>//...Perform a task...</em> 30 * } 31 * var timer:Timer = new Timer(delay); 32 * timer.addActionListener(listener.taskPerformer, listener); 33 * timer.start(); 34 * </pre> 35 * 36 * <p> 37 * @author iiley 38 */ 39 class org.aswing.utils.Timer extends EventDispatcher{ 40 41 private var delay:Number; 42 private var initialDelay:Number; 43 private var repeats:Boolean; 44 private var intervalID:Number; 45 private var isInitalFire:Boolean; 46 47 /** 48 * Construct Timer. 49 * @see #setDelay() 50 * @throws Error when init delay <= 0 or delay == null 51 */ 52 public function Timer(delay:Number){ 53 if(delay == undefined || delay <=0){ 54 trace("delay must > 0! when create a Timer"); 55 throw new Error("delay must > 0! when create a Timer"); 56 } 57 this.delay = delay; 58 this.initialDelay = undefined; 59 this.repeats = true; 60 this.isInitalFire = true; 61 this.intervalID = null; 62 } 63 64 /** 65 * Adds an action listener to the <code>Timer</code>. 66 * 67 * @param func the listener function 68 * @param obj the listener obj 69 * 70 * @see org.aswing.EventDispatcher#addEventListener() 71 * @see org.aswing.EventDispatcher#ON_ACT 72 * @return the listener just added. 73 */ 74 public function addActionListener(func:Function, obj:Object):Object{ 75 return addEventListener(ON_ACT, func, obj); 76 } 77 78 /** 79 * Sets the <code>Timer</code>'s delay, the number of milliseconds 80 * between successive events. 81 * 82 * @param delay the delay in milliseconds 83 * @see #setInitialDelay() 84 * @throws Error when set delay <= 0 or delay == null 85 */ 86 public function setDelay(delay:Number):Void{ 87 if(delay == undefined || delay <= 0){ 88 trace("Timer should be specified delay>0! Error delay = " + delay); 89 throw new Error("Timer should be specified delay>0! Error delay = " + delay); 90 } 91 this.delay = delay; 92 } 93 94 /** 95 * Returns the delay, in milliseconds, 96 * between firings of events. 97 * 98 * @see #setDelay() 99 * @see #getInitialDelay() 100 */ 101 public function getDelay():Number{ 102 return delay; 103 } 104 105 /** 106 * Sets the <code>Timer</code>'s initial delay, 107 * which by default is the same as the between-event delay. 108 * This is used only for the first action event. 109 * Subsequent events are spaced 110 * using the delay property. 111 * 112 * @param initialDelay the delay, in milliseconds, 113 * between the invocation of the <code>start</code> 114 * method and the first event 115 * fired by this timer 116 * 117 * @see #setDelay() 118 * @throws Error when set initialDelay <= 0 or initialDelay == null 119 */ 120 public function setInitialDelay(initialDelay:Number):Void{ 121 if(initialDelay == undefined || initialDelay <= 0){ 122 trace("Timer should be specified initialDelay>0! Error initialDelay = " + initialDelay); 123 throw new Error("Timer should be specified initialDelay>0! Error initialDelay = " + initialDelay); 124 } 125 this.initialDelay = initialDelay; 126 } 127 128 /** 129 * Returns the <code>Timer</code>'s initial delay. 130 * 131 * @see #setInitialDelay() 132 * @see #setDelay() 133 */ 134 public function getInitialDelay():Number{ 135 if(initialDelay == undefined){ 136 return delay; 137 }else{ 138 return initialDelay; 139 } 140 } 141 142 /** 143 * If <code>flag</code> is <code>false</code>, 144 * instructs the <code>Timer</code> to send only once 145 * action event to its listeners after a start. 146 * 147 * @param flag specify <code>false</code> to make the timer 148 * stop after sending its first action event. 149 * Default value is true. 150 */ 151 public function setRepeats(flag:Boolean):Void{ 152 repeats = flag; 153 } 154 155 /** 156 * Returns <code>true</code> (the default) 157 * if the <code>Timer</code> will send 158 * an action event 159 * to its listeners multiple times. 160 * 161 * @see #setRepeats() 162 */ 163 public function isRepeats():Boolean{ 164 return repeats; 165 } 166 167 /** 168 * Starts the <code>Timer</code>, 169 * causing it to start sending action events 170 * to its listeners. 171 * 172 * @see #stop() 173 */ 174 public function start():Void{ 175 isInitalFire = true; 176 clearInterval(intervalID); 177 intervalID = setInterval(this, "fireActionPerformed", getInitialDelay()); 178 } 179 180 /** 181 * Returns <code>true</code> if the <code>Timer</code> is running. 182 * 183 * @see #start() 184 */ 185 public function isRunning():Boolean{ 186 return intervalID != null; 187 } 188 189 /** 190 * Stops the <code>Timer</code>, 191 * causing it to stop sending action events 192 * to its listeners. 193 * 194 * @see #start() 195 */ 196 public function stop():Void{ 197 clearInterval(intervalID); 198 intervalID = null; 199 } 200 201 /** 202 * Restarts the <code>Timer</code>, 203 * canceling any pending firings and causing 204 * it to fire with its initial delay. 205 */ 206 public function restart():Void{ 207 stop(); 208 start(); 209 } 210 211 private function fireActionPerformed():Void{ 212 dispatchEvent(ON_ACT, createEventObj(ON_ACT)); 213 if(isInitalFire){ 214 isInitalFire = false; 215 if(repeats){ 216 clearInterval(intervalID); 217 intervalID = setInterval(this, "fireActionPerformed", getDelay()); 218 }else{ 219 stop(); 220 } 221 } 222 } 223 } 224