- /*
- * @(#)Timer.java 1.32 00/02/02
- *
- * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved.
- *
- * This software is the proprietary information of Sun Microsystems, Inc.
- * Use is subject to license terms.
- *
- */
-
-
-
- package javax.swing;
-
-
-
- import java.util.*;
- import java.awt.*;
- import java.awt.event.*;
- import java.io.Serializable;
- import javax.swing.event.EventListenerList;
-
-
-
- /**
- * Causes an action to occur at a predefined rate. For
- * example, an animation object can use a Timer as the trigger for drawing its
- * next frame.
- * For documentation and examples of using timers, see
- * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/timer.html">How to Use Timers</a>
- * in <em>The Java Tutorial.</em>
- *
- * <p>
- * Each Timer has a list of ActionListeners and a delay
- * (the time between <b>actionPerformed()</b> calls). When
- * delay milliseconds have passed, a Timer sends the <b>actionPerformed()</b>
- * message to its listeners. This cycle repeats until
- * <b>stop()</b> is called, or halts immediately if the Timer is configured
- * to send its message just once.<p>
- * Using a Timer involves first creating it, then starting it using
- * the <b>start()</b> method.
- *
- * <p>
- * <strong>Warning:</strong>
- * Serialized objects of this class will not be compatible with
- * future Swing releases. The current serialization support is appropriate
- * for short term storage or RMI between applications running the same
- * version of Swing. A future release of Swing will provide support for
- * long term persistence.
- *
- * @version 1.32 02/02/00
- * @author Dave Moore
- */
- public class Timer implements Serializable
- {
- protected EventListenerList listenerList = new EventListenerList();
-
- boolean eventQueued = false;
- int initialDelay, delay;
- boolean repeats = true, coalesce = true;
-
- Runnable doPostEvent = null;
-
- private static boolean logTimers;
-
-
- // These fields are maintained by TimerQueue.
- // eventQueued can also be reset by the TimerQueue, but will only ever
- // happen in applet case when TimerQueues thread is destroyed.
- long expirationTime;
- Timer nextTimer;
- boolean running;
-
-
- /**
- * Creates a Timer that will notify its listeners every
- * <i>delay</i> milliseconds.
- * @param delay The number of milliseconds between listener notification
- * @param listener An initial listener
- * @see #setInitialDelay
- * @see #setRepeats
- */
- public Timer(int delay, ActionListener listener) {
- super();
- this.delay = delay;
- this.initialDelay = delay;
-
- doPostEvent = new DoPostEvent();
-
- if (listener != null) {
- addActionListener(listener);
- }
- }
-
-
- /**
- * DoPostEvent is a runnable class that fires actionEvents to
- * the listeners on the EventDispatchThread, via invokeLater.
- * @see #post
- */
- class DoPostEvent implements Runnable, Serializable
- {
- public void run() {
- if (logTimers) {
- System.out.println("Timer ringing: " + Timer.this);
- }
- if(eventQueued) {
- fireActionPerformed(new ActionEvent(Timer.this, 0, null));
- cancelEvent();
- }
- }
-
- Timer getTimer() {
- return Timer.this;
- }
- }
-
-
- /**
- * Adds an actionListener to the Timer
- */
- public void addActionListener(ActionListener listener) {
- listenerList.add(ActionListener.class, listener);
- }
-
-
- /**
- * Removes an ActionListener from the Timer.
- */
- public void removeActionListener(ActionListener listener) {
- listenerList.remove(ActionListener.class, listener);
- }
-
-
- /**
- * Notify all listeners that have registered interest for
- * notification on this event type. The event instance
- * is lazily created using the parameters passed into
- * the fire method.
- * @see EventListenerList
- */
- protected void fireActionPerformed(ActionEvent e) {
- // Guaranteed to return a non-null array
- Object[] listeners = listenerList.getListenerList();
-
- // Process the listeners last to first, notifying
- // those that are interested in this event
- for (int i=listeners.length-2; i>=0; i-=2) {
- if (listeners[i]==ActionListener.class) {
- ((ActionListener)listeners[i+1]).actionPerformed(e);
- }
- }
- }
-
- /**
- * Return an array of all the listeners of the given type that
- * were added to this timer.
- *
- * @returns all of the objects recieving <em>listenerType</em> notifications
- * from this timer
- *
- * @since 1.3
- */
- public EventListener[] getListeners(Class listenerType) {
- return listenerList.getListeners(listenerType);
- }
-
- /**
- * Returns the timer queue.
- */
- TimerQueue timerQueue() {
- return TimerQueue.sharedInstance();
- }
-
-
- /**
- * Enables or disables the timer log. When enabled, a message
- * is posted to System.out whenever the timer goes off.
- *
- * @param flag true to enable logging
- * @see #getLogTimers
- */
- public static void setLogTimers(boolean flag) {
- logTimers = flag;
- }
-
-
- /**
- * Returns true if logging is enabled.
- *
- * @return true if logging is enabled
- * @see #setLogTimers
- */
- public static boolean getLogTimers() {
- return logTimers;
- }
-
-
- /**
- * Sets the Timer's delay, the number of milliseconds between successive
- * <b>actionPerfomed()</b> messages to its listeners
- * @see #setInitialDelay
- */
- public void setDelay(int delay) {
- if (delay < 0) {
- throw new IllegalArgumentException("Invalid delay: " + delay);
- }
- else {
- this.delay = delay;
- }
- }
-
-
- /** Returns the Timer's delay.
- * @see #setDelay
- */
- public int getDelay() {
- return delay;
- }
-
-
- /**
- * Sets the Timer's initial delay. This will be used for the first
- * "ringing" of the Timer only. Subsequent ringings will be spaced
- * using the delay property.
- * @see #setDelay
- */
- public void setInitialDelay(int initialDelay) {
- if (initialDelay < 0) {
- throw new IllegalArgumentException("Invalid initial delay: " +
- initialDelay);
- }
- else {
- this.initialDelay = initialDelay;
- }
- }
-
-
- /**
- * Returns the Timer's initial delay.
- * @see #setDelay
- */
- public int getInitialDelay() {
- return initialDelay;
- }
-
-
- /**
- * If <b>flag</b> is <b>false</b>, instructs the Timer to send
- * <b>actionPerformed()</b> to its listeners only once, and then stop.
- */
- public void setRepeats(boolean flag) {
- repeats = flag;
- }
-
-
- /**
- * Returns <b>true</b> if the Timer will send a <b>actionPerformed()</b>
- * message to its listeners multiple times.
- * @see #setRepeats
- */
- public boolean isRepeats() {
- return repeats;
- }
-
-
- /**
- * Sets whether the Timer coalesces multiple pending ActionEvent firings.
- * A busy application may not be able
- * to keep up with a Timer's message generation, causing multiple
- * <b>actionPerformed()</b> message sends to be queued. When processed,
- * the application sends these messages one after the other, causing the
- * Timer's listeners to receive a sequence of <b>actionPerformed()</b>
- * messages with no delay between them. Coalescing avoids this situation
- * by reducing multiple pending messages to a single message send. Timers
- * coalesce their message sends by default.
- */
- public void setCoalesce(boolean flag) {
- coalesce = flag;
- }
-
-
- /**
- * Returns <b>true</b> if the Timer coalesces multiple pending
- * <b>performCommand()</b> messages.
- * @see #setCoalesce
- */
- public boolean isCoalesce() {
- return coalesce;
- }
-
-
- /**
- * Starts the Timer, causing it to send <b>actionPerformed()</b> messages
- * to its listeners.
- * @see #stop
- */
- public void start() {
- timerQueue().addTimer(this,
- System.currentTimeMillis() + getInitialDelay());
- }
-
-
- /**
- * Returns <b>true</b> if the Timer is running.
- * @see #start
- */
- public boolean isRunning() {
- return timerQueue().containsTimer(this);
- }
-
-
- /**
- * Stops a Timer, causing it to stop sending <b>actionPerformed()</b>
- * messages to its Target.
- * @see #start
- */
- public void stop() {
- timerQueue().removeTimer(this);
- cancelEvent();
- }
-
-
- /**
- * Restarts a Timer, canceling any pending firings, and causing
- * it to fire with its initial dely.
- */
- public void restart() {
- stop();
- start();
- }
-
-
- synchronized void cancelEvent() {
- eventQueued = false;
- }
-
-
- synchronized void post() {
- if (eventQueued == false) {
- eventQueued = true;
- SwingUtilities.invokeLater(doPostEvent);
- }
- }
- }