KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > wings > util > Timer


1 /*
2  * $Id: Timer.java,v 1.4 2005/02/25 14:36:13 blueshift Exp $
3  * Copyright 2000,2005 wingS development team.
4  *
5  * This file is part of wingS (http://www.j-wings.org).
6  *
7  * wingS is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU Lesser General Public License
9  * as published by the Free Software Foundation; either version 2.1
10  * of the License, or (at your option) any later version.
11  *
12  * Please see COPYING for the complete licence.
13  */

14 package org.wings.util;
15
16 import org.apache.commons.logging.Log;
17 import org.apache.commons.logging.LogFactory;
18
19 import java.awt.event.ActionEvent JavaDoc;
20 import java.awt.event.ActionListener JavaDoc;
21 import java.io.Serializable JavaDoc;
22 import java.util.Vector JavaDoc;
23
24 /*
25  * Die Klasse ist praktisch von der Swing Implementierung
26  * abgeleitet. Leider brauch ich einen Timer, der auch innerhalb des
27  * Swing Event Threads Impulse gibt. Deshalb angepasst. Ich hoffe das
28  * gibt keine Problemen mit dem Swing Team.
29  */

30
31 /**
32  * @author <a HREF="mailto:haaf@mercatis.de">Armin Haaf</a>
33  * @version $Revision: 1.4 $
34  */

35 public final class Timer
36         implements Serializable JavaDoc {
37     private final static Log log = LogFactory.getLog(Timer.class);
38
39     /*
40      * Die Verzoegerung, bis das erste mal ein Impuls (ActionEvent)
41      * kommt.
42      */

43     private long initialDelay;
44
45     /*
46      * Die Dauer zwischen 2 Impulsen (ActionEvent)
47      */

48     private long delay;
49
50     /*
51      * Einmaliger Impuls, oder andauernder.
52      */

53     private boolean repeats = true;
54
55     /*
56      * Sollen Impulse, die zur gleichen Zeit auflaufen (etwa weil der
57      * {@link TimerQueue} so lange geschlafen hat, bis mehrere Impulse vom
58      * gleichen Timer aufgelaufen sind) sind zusammengefasst und nur einer
59      * geschickt werden ?
60      */

61     private boolean coalesce = true;
62
63     /*
64      * Alle ActionListener, die zu benachrichtigen sind.
65      */

66     private final Vector JavaDoc listenerList = new Vector JavaDoc();
67
68     boolean eventQueued = false;
69
70     /**
71      * Command used when action is fired.
72      */

73     private String JavaDoc actionCommand = null;
74
75     /*
76      * Sollen Impulse geloggt werden.
77      */

78     private static boolean logTimers;
79
80     // These fields are maintained by TimerQueue.
81
// eventQueued can also be reset by the TimerQueue, but will only ever
82
// happen in applet case when TimerQueues thread is destroyed.
83
long expirationTime;
84     Timer nextTimer;
85     boolean running;
86
87     /**
88      * Creates a Timer that will notify its listeners every
89      * <i>delay</i> milliseconds.
90      *
91      * @param delay The number of milliseconds between listener notification
92      * @param listener An initial listener
93      * @see #setInitialDelay
94      * @see #setRepeats
95      */

96     public Timer(long delay, ActionListener JavaDoc listener) {
97         super();
98         this.delay = delay;
99         this.initialDelay = delay;
100
101         addActionListener(listener);
102     }
103
104     /**
105      * Adds an actionListener to the Timer
106      */

107     public void addActionListener(ActionListener JavaDoc listener) {
108         listenerList.addElement(listener);
109     }
110
111     /**
112      * Removes an ActionListener from the Timer.
113      */

114     public void removeActionListener(ActionListener JavaDoc listener) {
115         listenerList.removeElement(listener);
116     }
117
118     /**
119      * Sets action command for this timer.
120      */

121     public void setActionCommand(String JavaDoc command) {
122         actionCommand = command;
123     }
124
125     /**
126      * Notify all listeners that have registered interest for
127      * notification on this event type. The event instance
128      * is lazily created using the parameters passed into
129      * the fire method.
130      */

131     protected void fireActionPerformed(ActionEvent JavaDoc e) {
132         // Process the listeners last to first, notifying
133
// those that are interested in this event
134
for (int i = listenerList.size() - 1; i >= 0; i--) {
135             ((ActionListener JavaDoc) listenerList.elementAt(i)).actionPerformed(e);
136         }
137     }
138
139     /**
140      * Returns the timer queue.
141      */

142     TimerQueue timerQueue() {
143         return TimerQueue.sharedInstance();
144     }
145
146     /**
147      * Enables or disables the timer log. When enabled, a message
148      * is posted to System.out whenever the timer goes off.
149      *
150      * @param flag true to enable logging
151      * @see #getLogTimers
152      */

153     public static void setLogTimers(boolean flag) {
154         logTimers = flag;
155     }
156
157     /**
158      * Returns true if logging is enabled.
159      *
160      * @return true if logging is enabled
161      * @see #setLogTimers
162      */

163     public static boolean getLogTimers() {
164         return logTimers;
165     }
166
167     /**
168      * Sets the Timer's delay, the number of milliseconds between successive
169      * <b>actionPerfomed()</b> messages to its listeners
170      *
171      * @see #setInitialDelay
172      */

173     public void setDelay(long delay) {
174         TimerQueue queue;
175
176         if (delay < 0) {
177             throw new RuntimeException JavaDoc("Invalid initial delay: " + delay);
178         }
179         this.delay = delay;
180
181         if (isRunning()) {
182             queue = timerQueue();
183             queue.removeTimer(this);
184             cancelEvent();
185             queue.addTimer(this, System.currentTimeMillis() + delay);
186         }
187     }
188
189     /**
190      * Returns the Timer's delay.
191      *
192      * @see #setDelay
193      */

194     public long getDelay() {
195         return delay;
196     }
197
198     /**
199      * Sets the Timer's initial delay. This will be used for the first
200      * "ringing" of the Timer only. Subsequent ringings will be spaced
201      * using the delay property.
202      *
203      * @see #setDelay
204      */

205     public void setInitialDelay(int initialDelay) {
206         if (initialDelay < 0) {
207             throw new RuntimeException JavaDoc("Invalid initial delay: " +
208                     initialDelay);
209         }
210         this.initialDelay = initialDelay;
211     }
212
213     /**
214      * Returns the Timer's initial delay.
215      *
216      * @see #setDelay
217      */

218     public long getInitialDelay() {
219         return initialDelay;
220     }
221
222     /**
223      * If <b>flag</b> is <b>false</b>, instructs the Timer to send
224      * <b>actionPerformed()</b> to its listeners only once, and then stop.
225      */

226     public void setRepeats(boolean flag) {
227         repeats = flag;
228     }
229
230     /**
231      * Returns <b>true</b> if the Timer will send a <b>actionPerformed()</b>
232      * message to its listeners multiple times.
233      *
234      * @see #setRepeats
235      */

236     public boolean isRepeats() {
237         return repeats;
238     }
239
240     /**
241      * Sets whether the Timer coalesces multiple pending ActionEvent firings.
242      * A busy application may not be able
243      * to keep up with a Timer's message generation, causing multiple
244      * <b>actionPerformed()</b> message sends to be queued. When processed,
245      * the application sends these messages one after the other, causing the
246      * Timer's listeners to receive a sequence of <b>actionPerformed()</b>
247      * messages with no delay between them. Coalescing avoids this situation
248      * by reducing multiple pending messages to a single message send. Timers
249      * coalesce their message sends by default.
250      */

251     public void setCoalesce(boolean flag) {
252         coalesce = flag;
253     }
254
255     /**
256      * Returns <b>true</b> if the Timer coalesces multiple pending
257      * <b>performCommand()</b> messages.
258      *
259      * @see #setCoalesce
260      */

261     public boolean isCoalesce() {
262         return coalesce;
263     }
264
265     /**
266      * Starts the Timer, causing it to send <b>actionPerformed()</b> messages
267      * to its listeners.
268      *
269      * @see #stop
270      */

271     public void start() {
272         timerQueue().addTimer(this, System.currentTimeMillis() + getInitialDelay());
273     }
274
275     /**
276      * Returns <b>true</b> if the Timer is running.
277      *
278      * @see #start
279      */

280     public boolean isRunning() {
281         return timerQueue().containsTimer(this);
282     }
283
284     /**
285      * Stops a Timer, causing it to stop sending <b>actionPerformed()</b>
286      * messages to its Target.
287      *
288      * @see #start
289      */

290     public void stop() {
291         timerQueue().removeTimer(this);
292         cancelEvent();
293     }
294
295     /**
296      * Restarts a Timer, canceling any pending firings, and causing
297      * it to fire with its initial dely.
298      */

299     public void restart() {
300         stop();
301         start();
302     }
303
304     synchronized void cancelEvent() {
305         eventQueued = false;
306     }
307
308     synchronized void post() {
309         if (eventQueued == false) {
310             eventQueued = true;
311             if (logTimers) {
312                 log.debug("Timer ringing: " + Timer.this);
313             }
314             if (eventQueued) {
315                 fireActionPerformed(new ActionEvent JavaDoc(Timer.this, 0, this.actionCommand));
316                 cancelEvent();
317             }
318         }
319     }
320 }
321
322
323
Popular Tags