OSDN Git Service

2004-11-30 Thomas Fitzsimmons <fitzsim@redhat.com>
[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   /**
76    * DOCUMENT ME!
77    */
78   private void queueEvent()
79   {
80     synchronized (queueLock)
81       {
82         queue++;
83         if (queue == 1)
84           SwingUtilities.invokeLater(new Runnable()
85               {
86                 public void run()
87                 {
88                   drainEvents();
89                 }
90               });
91
92       }
93   }
94
95   /**
96    * DOCUMENT ME!
97    */
98   private void drainEvents()
99   {
100     synchronized (queueLock)
101       {
102         if (isCoalesce())
103           {
104             if (queue > 0)
105               fireActionPerformed();
106           }
107         else
108           {
109             while (queue > 0)
110               {
111                 fireActionPerformed();
112                 queue--;
113               }
114           }
115         queue = 0;
116       }
117   }
118
119   static boolean logTimers;
120
121   /** DOCUMENT ME! */
122   boolean coalesce = true;
123
124   /** DOCUMENT ME! */
125   boolean repeats = true;
126
127   /** DOCUMENT ME! */
128   boolean running;
129
130   /** DOCUMENT ME! */
131   int ticks;
132
133   /** DOCUMENT ME! */
134   int delay;
135
136   /** DOCUMENT ME! */
137   int initialDelay;
138
139   /**
140    * DOCUMENT ME!
141    */
142   private class Waker extends Thread
143   {
144     /**
145      * DOCUMENT ME!
146      */
147     public void run()
148     {
149       running = true;
150       try
151         {
152           sleep(initialDelay);
153
154           while (running)
155             {
156               try
157                 {
158                   sleep(delay);
159                 }
160               catch (InterruptedException e)
161                 {
162                   return;
163                 }
164               queueEvent();
165
166               if (logTimers)
167                 System.out.println("javax.swing.Timer -> clocktick");
168
169               if (! repeats)
170                 break;
171             }
172           running = false;
173         }
174       catch (Exception e)
175         {
176 //        System.out.println("swing.Timer::" + e);
177         }
178     }
179   }
180
181   /**
182    * Creates a new Timer object.
183    *
184    * @param d DOCUMENT ME!
185    * @param listener DOCUMENT ME!
186    */
187   public Timer(int d, ActionListener listener)
188   {
189     delay = d;
190
191     if (listener != null)
192       addActionListener(listener);
193   }
194
195   /**
196    * DOCUMENT ME!
197    *
198    * @param c DOCUMENT ME!
199    */
200   public void setCoalesce(boolean c)
201   {
202     coalesce = c;
203   }
204
205   /**
206    * DOCUMENT ME!
207    *
208    * @return DOCUMENT ME!
209    */
210   public boolean isCoalesce()
211   {
212     return coalesce;
213   }
214
215   /**
216    * DOCUMENT ME!
217    *
218    * @param listener DOCUMENT ME!
219    */
220   public void addActionListener(ActionListener listener)
221   {
222     listenerList.add(ActionListener.class, listener);
223   }
224
225   /**
226    * DOCUMENT ME!
227    *
228    * @param listener DOCUMENT ME!
229    */
230   public void removeActionListener(ActionListener listener)
231   {
232     listenerList.remove(ActionListener.class, listener);
233   }
234
235   /**
236    * DOCUMENT ME!
237    *
238    * @param listenerType DOCUMENT ME!
239    *
240    * @return DOCUMENT ME!
241    *
242    * @since 1.3
243    */
244   public EventListener[] getListeners(Class listenerType)
245   {
246     return listenerList.getListeners(listenerType);
247   }
248
249   /**
250    * DOCUMENT ME!
251    *
252    * @return DOCUMENT ME!
253    *
254    * @since 1.4
255    */
256   public ActionListener[] getActionListeners()
257   {
258     return (ActionListener[]) listenerList.getListeners(ActionListener.class);
259   }
260
261   /**
262    * DOCUMENT ME!
263    *
264    * @param event DOCUMENT ME!
265    */
266   protected void fireActionPerformed(ActionEvent event)
267   {
268     ActionListener[] listeners = getActionListeners();
269
270     for (int i = 0; i < listeners.length; i++)
271       listeners[i].actionPerformed(event);
272   }
273
274   /**
275    * DOCUMENT ME!
276    */
277   void fireActionPerformed()
278   {
279     fireActionPerformed(new ActionEvent(this, ticks++, "Timer"));
280   }
281
282   /**
283    * DOCUMENT ME!
284    *
285    * @param lt DOCUMENT ME!
286    */
287   public static void setLogTimers(boolean lt)
288   {
289     logTimers = lt;
290   }
291
292   /**
293    * DOCUMENT ME!
294    *
295    * @return DOCUMENT ME!
296    */
297   public static boolean getLogTimers()
298   {
299     return logTimers;
300   }
301
302   /**
303    * DOCUMENT ME!
304    *
305    * @param d DOCUMENT ME!
306    */
307   public void setDelay(int d)
308   {
309     delay = d;
310   }
311
312   /**
313    * DOCUMENT ME!
314    *
315    * @return DOCUMENT ME!
316    */
317   public int getDelay()
318   {
319     return delay;
320   }
321
322   /**
323    * DOCUMENT ME!
324    *
325    * @param i DOCUMENT ME!
326    */
327   public void setInitialDelay(int i)
328   {
329     initialDelay = i;
330   }
331
332   /**
333    * DOCUMENT ME!
334    *
335    * @return DOCUMENT ME!
336    */
337   public int getInitialDelay()
338   {
339     return initialDelay;
340   }
341
342   /**
343    * DOCUMENT ME!
344    *
345    * @param r DOCUMENT ME!
346    */
347   public void setRepeats(boolean r)
348   {
349     repeats = r;
350   }
351
352   /**
353    * DOCUMENT ME!
354    *
355    * @return DOCUMENT ME!
356    */
357   public boolean isRepeats()
358   {
359     return repeats;
360   }
361
362   /**
363    * DOCUMENT ME!
364    *
365    * @return DOCUMENT ME!
366    */
367   public boolean isRunning()
368   {
369     return running;
370   }
371
372   /**
373    * DOCUMENT ME!
374    */
375   public void start()
376   {
377     if (isRunning())
378       return;
379     waker = new Waker();
380     waker.start();
381   }
382
383   /**
384    * DOCUMENT ME!
385    */
386   public void restart()
387   {
388     stop();
389     start();
390   }
391
392   /**
393    * DOCUMENT ME!
394    */
395   public void stop()
396   {
397     running = false;
398     if (waker != null)
399       waker.interrupt();
400     synchronized (queueLock)
401       {
402         queue = 0;
403       }
404   }
405 }