OSDN Git Service

2005-04-19 Roman Kennke <roman@kennke.org>
[pf3gnuchains/gcc-fork.git] / libjava / javax / swing / Timer.java
1 /* Timer.java --
2    Copyright (C) 2002, 2004  Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
20
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37
38
39 package javax.swing;
40
41 import java.awt.event.ActionEvent;
42 import java.awt.event.ActionListener;
43 import java.io.Serializable;
44 import java.util.EventListener;
45
46 import javax.swing.event.EventListenerList;
47
48 /**
49  * DOCUMENT ME!
50  */
51 public class Timer implements Serializable
52 {
53   /** DOCUMENT ME! */
54   private static final long serialVersionUID = -1116180831621385484L;
55
56   /** DOCUMENT ME! */
57   protected EventListenerList listenerList = new EventListenerList();
58
59   // This object manages a "queue" of virtual actionEvents, maintained as a
60   // simple long counter. When the timer expires, a new event is queued,
61   // and a dispatcher object is pushed into the system event queue. When
62   // the system thread runs the dispatcher, it will fire as many
63   // ActionEvents as have been queued, unless the timer is set to
64   // coalescing mode, in which case it will fire only one ActionEvent.
65
66   /** DOCUMENT ME! */
67   private long queue;
68
69   /** DOCUMENT ME! */
70   private Object queueLock = new Object();
71
72   /** DOCUMENT ME! */
73   private Waker waker;
74
75   private Runnable drainer = new Runnable() 
76     {
77       public void run()
78       {
79         drainEvents();
80       }
81     };
82
83   /**
84    * DOCUMENT ME!
85    */
86   private void queueEvent()
87   {
88     synchronized (queueLock)
89       {
90         queue++;
91         if (queue == 1)
92           SwingUtilities.invokeLater(drainer);
93       }
94   }
95
96   /**
97    * DOCUMENT ME!
98    */
99   private void drainEvents()
100   {
101     synchronized (queueLock)
102       {
103         if (isCoalesce())
104           {
105             if (queue > 0)
106               fireActionPerformed();
107           }
108         else
109           {
110             while (queue > 0)
111               {
112                 fireActionPerformed();
113                 queue--;
114               }
115           }
116         queue = 0;
117       }
118   }
119
120   static boolean logTimers;
121
122   /** DOCUMENT ME! */
123   boolean coalesce = true;
124
125   /** DOCUMENT ME! */
126   boolean repeats = true;
127
128   /** DOCUMENT ME! */
129   boolean running;
130
131   /** DOCUMENT ME! */
132   int ticks;
133
134   /** DOCUMENT ME! */
135   int delay;
136
137   /** DOCUMENT ME! */
138   int initialDelay;
139
140   /**
141    * DOCUMENT ME!
142    */
143   private class Waker extends Thread
144   {
145     /**
146      * DOCUMENT ME!
147      */
148     public void run()
149     {
150       running = true;
151       try
152         {
153           sleep(initialDelay);
154
155           while (running)
156             {
157               try
158                 {
159                   sleep(delay);
160                 }
161               catch (InterruptedException e)
162                 {
163                   return;
164                 }
165               queueEvent();
166
167               if (logTimers)
168                 System.out.println("javax.swing.Timer -> clocktick");
169
170               if (! repeats)
171                 break;
172             }
173           running = false;
174         }
175       catch (Exception e)
176         {
177 //        System.out.println("swing.Timer::" + e);
178         }
179     }
180   }
181
182   /**
183    * Creates a new Timer object.
184    *
185    * @param d DOCUMENT ME!
186    * @param listener DOCUMENT ME!
187    */
188   public Timer(int d, ActionListener listener)
189   {
190     delay = d;
191
192     if (listener != null)
193       addActionListener(listener);
194   }
195
196   /**
197    * DOCUMENT ME!
198    *
199    * @param c DOCUMENT ME!
200    */
201   public void setCoalesce(boolean c)
202   {
203     coalesce = c;
204   }
205
206   /**
207    * DOCUMENT ME!
208    *
209    * @return DOCUMENT ME!
210    */
211   public boolean isCoalesce()
212   {
213     return coalesce;
214   }
215
216   /**
217    * DOCUMENT ME!
218    *
219    * @param listener DOCUMENT ME!
220    */
221   public void addActionListener(ActionListener listener)
222   {
223     listenerList.add(ActionListener.class, listener);
224   }
225
226   /**
227    * DOCUMENT ME!
228    *
229    * @param listener DOCUMENT ME!
230    */
231   public void removeActionListener(ActionListener listener)
232   {
233     listenerList.remove(ActionListener.class, listener);
234   }
235
236   /**
237    * DOCUMENT ME!
238    *
239    * @param listenerType DOCUMENT ME!
240    *
241    * @return DOCUMENT ME!
242    *
243    * @since 1.3
244    */
245   public EventListener[] getListeners(Class listenerType)
246   {
247     return listenerList.getListeners(listenerType);
248   }
249
250   /**
251    * DOCUMENT ME!
252    *
253    * @return DOCUMENT ME!
254    *
255    * @since 1.4
256    */
257   public ActionListener[] getActionListeners()
258   {
259     return (ActionListener[]) listenerList.getListeners(ActionListener.class);
260   }
261
262   /**
263    * DOCUMENT ME!
264    *
265    * @param event DOCUMENT ME!
266    */
267   protected void fireActionPerformed(ActionEvent event)
268   {
269     ActionListener[] listeners = getActionListeners();
270
271     for (int i = 0; i < listeners.length; i++)
272       listeners[i].actionPerformed(event);
273   }
274
275   /**
276    * DOCUMENT ME!
277    */
278   void fireActionPerformed()
279   {
280     fireActionPerformed(new ActionEvent(this, ticks++, "Timer"));
281   }
282
283   /**
284    * DOCUMENT ME!
285    *
286    * @param lt DOCUMENT ME!
287    */
288   public static void setLogTimers(boolean lt)
289   {
290     logTimers = lt;
291   }
292
293   /**
294    * DOCUMENT ME!
295    *
296    * @return DOCUMENT ME!
297    */
298   public static boolean getLogTimers()
299   {
300     return logTimers;
301   }
302
303   /**
304    * DOCUMENT ME!
305    *
306    * @param d DOCUMENT ME!
307    */
308   public void setDelay(int d)
309   {
310     delay = d;
311   }
312
313   /**
314    * DOCUMENT ME!
315    *
316    * @return DOCUMENT ME!
317    */
318   public int getDelay()
319   {
320     return delay;
321   }
322
323   /**
324    * DOCUMENT ME!
325    *
326    * @param i DOCUMENT ME!
327    */
328   public void setInitialDelay(int i)
329   {
330     initialDelay = i;
331   }
332
333   /**
334    * DOCUMENT ME!
335    *
336    * @return DOCUMENT ME!
337    */
338   public int getInitialDelay()
339   {
340     return initialDelay;
341   }
342
343   /**
344    * DOCUMENT ME!
345    *
346    * @param r DOCUMENT ME!
347    */
348   public void setRepeats(boolean r)
349   {
350     repeats = r;
351   }
352
353   /**
354    * DOCUMENT ME!
355    *
356    * @return DOCUMENT ME!
357    */
358   public boolean isRepeats()
359   {
360     return repeats;
361   }
362
363   /**
364    * DOCUMENT ME!
365    *
366    * @return DOCUMENT ME!
367    */
368   public boolean isRunning()
369   {
370     return running;
371   }
372
373   /**
374    * DOCUMENT ME!
375    */
376   public void start()
377   {
378     if (isRunning())
379       return;
380     waker = new Waker();
381     waker.start();
382   }
383
384   /**
385    * DOCUMENT ME!
386    */
387   public void restart()
388   {
389     stop();
390     start();
391   }
392
393   /**
394    * DOCUMENT ME!
395    */
396   public void stop()
397   {
398     running = false;
399     if (waker != null)
400       waker.interrupt();
401     synchronized (queueLock)
402       {
403         queue = 0;
404       }
405   }
406 }