Commit b1079a61 by Michael Koch Committed by Michael Koch

Timer.java: Reordered all fields and methods, Added more javadocs.

2005-04-28  Michael Koch  <konqueror@gmx.de>

	* javax/swing/Timer.java: Reordered all fields and methods,
	Added more javadocs.

From-SVN: r98936
parent 0ffcc9e7
2005-04-28 Michael Koch <konqueror@gmx.de> 2005-04-28 Michael Koch <konqueror@gmx.de>
* javax/swing/Timer.java: Reordered all fields and methods,
Added more javadocs.
2005-04-28 Michael Koch <konqueror@gmx.de>
* javax/swing/Timer.java: Javadocs merged * javax/swing/Timer.java: Javadocs merged
from GNU classpath. from GNU classpath.
......
...@@ -54,29 +54,58 @@ import javax.swing.event.EventListenerList; ...@@ -54,29 +54,58 @@ import javax.swing.event.EventListenerList;
public class Timer public class Timer
implements Serializable implements Serializable
{ {
/** DOCUMENT ME! */ /**
private static final long serialVersionUID = -1116180831621385484L; * The timer thread
*/
/** DOCUMENT ME! */ private class Waker
protected EventListenerList listenerList = new EventListenerList(); extends Thread
{
// This object manages a "queue" of virtual actionEvents, maintained as a /**
// simple long counter. When the timer expires, a new event is queued, * Fires events, pausing for required intervals.
// and a dispatcher object is pushed into the system event queue. When */
// the system thread runs the dispatcher, it will fire as many public void run()
// ActionEvents as have been queued, unless the timer is set to {
// coalescing mode, in which case it will fire only one ActionEvent. running = true;
try
/** DOCUMENT ME! */ {
private long queue; sleep(initialDelay);
/** DOCUMENT ME! */ while (running)
private Object queueLock = new Object(); {
try
{
sleep(delay);
}
catch (InterruptedException e)
{
return;
}
queueEvent();
if (logTimers)
System.out.println("javax.swing.Timer -> clocktick");
if ( ! repeats)
break;
}
running = false;
}
catch (Exception e)
{
}
}
}
/** DOCUMENT ME! */ /**
private Waker waker; * Use serialVersionUID for interoperability.
*/
private static final long serialVersionUID = -1116180831621385484L;
private Runnable drainer = new Runnable() /**
* The encloding class, used with {@link SwingUtilities#invokeLater}
* to invoke the {@link #drainEvents()}.
*/
private Runnable drainer = new Runnable()
{ {
public void run() public void run()
{ {
...@@ -85,45 +114,15 @@ public class Timer ...@@ -85,45 +114,15 @@ public class Timer
}; };
/** /**
* DOCUMENT ME! * If <code>true</code>, the timer prints a message to
* Package-private to avoid an accessor method. * {@link System#out} when firing each event.
*/ */
private void queueEvent() static boolean logTimers;
{
synchronized (queueLock)
{
queue++;
if (queue == 1)
SwingUtilities.invokeLater(drainer);
}
}
/** /**
* DOCUMENT ME! * A field to store all listeners who are listening to this timer.
* This is package-private to avoid an accessor method.
*/ */
void drainEvents() protected EventListenerList listenerList = new EventListenerList();
{
synchronized (queueLock)
{
if (isCoalesce())
{
if (queue > 0)
fireActionPerformed();
}
else
{
while (queue > 0)
{
fireActionPerformed();
queue--;
}
}
queue = 0;
}
}
static boolean logTimers;
/** /**
* <code>true</code> if the timer coalesces events. * <code>true</code> if the timer coalesces events.
...@@ -141,9 +140,6 @@ public class Timer ...@@ -141,9 +140,6 @@ public class Timer
*/ */
boolean running; boolean running;
/** DOCUMENT ME! */
int ticks;
/** /**
* The delay between subsequent repetetive events. * The delay between subsequent repetetive events.
*/ */
...@@ -155,46 +151,33 @@ public class Timer ...@@ -155,46 +151,33 @@ public class Timer
int initialDelay; int initialDelay;
/** /**
* DOCUMENT ME! * The number of events that have been already fired by this timer.
* This is used as a numeric identifier for the next event that would
* be fired.
*/ */
private class Waker extends Thread int ticks;
{
/** /**
* DOCUMENT ME! * Stores the thread that posts events to the queue at required time
*/ * intervals.
public void run() */
{ private Waker waker;
running = true;
try /**
{ * This object manages a "queue" of virtual actionEvents, maintained as a
sleep(initialDelay); * simple long counter. When the timer expires, a new event is queued,
* and a dispatcher object is pushed into the system event queue. When
while (running) * the system thread runs the dispatcher, it will fire as many
{ * ActionEvents as have been queued, unless the timer is set to
try * coalescing mode, in which case it will fire only one ActionEvent.
{ */
sleep(delay); private long queue;
}
catch (InterruptedException e) /**
{ * <code>synchronized(queueLock)</code> replaces
return; * <code>synchronized(queue)</code> that is not supported by this language.
} */
queueEvent(); private Object queueLock = new Object();
if (logTimers)
System.out.println("javax.swing.Timer -> clocktick");
if (! repeats)
break;
}
running = false;
}
catch (Exception e)
{
// System.out.println("swing.Timer::" + e);
}
}
}
/** /**
* Creates a new Timer object. * Creates a new Timer object.
...@@ -212,43 +195,44 @@ public class Timer ...@@ -212,43 +195,44 @@ public class Timer
} }
/** /**
* DOCUMENT ME! * Get the array of action listeners.
* *
* @param c DOCUMENT ME! * @return the array of action listeners that are listening for the events,
*/ * fired by this timer
public void setCoalesce(boolean c)
{
coalesce = c;
}
/**
* DOCUMENT ME!
* *
* @return DOCUMENT ME! * @since 1.4
*/ */
public boolean isCoalesce() public ActionListener[] getActionListeners()
{ {
return coalesce; return (ActionListener[]) listenerList.getListeners(ActionListener.class);
} }
/** /**
* DOCUMENT ME! * Sets whether the Timer coalesces multiple pending event firings.
* If the coalescing is enabled, the multiple events that have not been
* fired on time are replaced by the single event. The events may not
* be fired on time if the application is busy.
* *
* @param listener DOCUMENT ME! * @param c <code>true</code> (default) to enable the event coalescing,
* <code>false</code> otherwise
*/ */
public void addActionListener(ActionListener listener) public void setCoalesce(boolean c)
{ {
listenerList.add(ActionListener.class, listener); coalesce = c;
} }
/** /**
* DOCUMENT ME! * Checks if the Timer coalesces multiple pending event firings.
* If the coalescing is enabled, the multiple events that have not been
* fired on time are replaced by the single event. The events may not
* be fired on time if the application is busy.
* *
* @param listener DOCUMENT ME! * @return <code>true</code> if the coalescing is enabled,
* <code>false</code> otherwise
*/ */
public void removeActionListener(ActionListener listener) public boolean isCoalesce()
{ {
listenerList.remove(ActionListener.class, listener); return coalesce;
} }
/** /**
...@@ -267,39 +251,6 @@ public class Timer ...@@ -267,39 +251,6 @@ public class Timer
} }
/** /**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*
* @since 1.4
*/
public ActionListener[] getActionListeners()
{
return (ActionListener[]) listenerList.getListeners(ActionListener.class);
}
/**
* DOCUMENT ME!
*
* @param event DOCUMENT ME!
*/
protected void fireActionPerformed(ActionEvent event)
{
ActionListener[] listeners = getActionListeners();
for (int i = 0; i < listeners.length; i++)
listeners[i].actionPerformed(event);
}
/**
* DOCUMENT ME!
*/
void fireActionPerformed()
{
fireActionPerformed(new ActionEvent(this, ticks++, "Timer"));
}
/**
* Set the timer logging state. If it is set to <code>true</code>, the * Set the timer logging state. If it is set to <code>true</code>, the
* timer prints a message to {@link System#out} when firing each * timer prints a message to {@link System#out} when firing each
* action event. * action event.
...@@ -408,18 +359,28 @@ public class Timer ...@@ -408,18 +359,28 @@ public class Timer
} }
/** /**
* DOCUMENT ME! * Add the action listener
*
* @param listener the action listener to add
*/ */
public void start() public void addActionListener(ActionListener listener)
{ {
if (isRunning()) listenerList.add(ActionListener.class, listener);
return; }
waker = new Waker();
waker.start(); /**
* Remove the action listener.
*
* @param listener the action listener to remove
*/
public void removeActionListener(ActionListener listener)
{
listenerList.remove(ActionListener.class, listener);
} }
/** /**
* DOCUMENT ME! * Cancel all pending tasks and fire the first event after the initial
* delay.
*/ */
public void restart() public void restart()
{ {
...@@ -428,7 +389,18 @@ public class Timer ...@@ -428,7 +389,18 @@ public class Timer
} }
/** /**
* DOCUMENT ME! * Start firing the action events.
*/
public void start()
{
if (isRunning())
return;
waker = new Waker();
waker.start();
}
/**
* Stop firing the action events.
*/ */
public void stop() public void stop()
{ {
...@@ -440,4 +412,69 @@ public class Timer ...@@ -440,4 +412,69 @@ public class Timer
queue = 0; queue = 0;
} }
} }
/**
* Fire the given action event to the action listeners.
*
* @param event the event to fire
*/
protected void fireActionPerformed(ActionEvent event)
{
ActionListener[] listeners = getActionListeners();
for (int i = 0; i < listeners.length; i++)
listeners [ i ].actionPerformed(event);
}
/**
* Fire the action event, named "Timer" and having the numeric
* identifier, equal to the numer of events that have been
* already fired before.
*/
void fireActionPerformed()
{
fireActionPerformed(new ActionEvent(this, ticks++, "Timer"));
}
/**
* Fire the queued action events.
* In the coalescing mode, a single event is fired as a replacement
* for all queued events. In non coalescing mode, a series of
* all queued events is fired.
* This is package-private to avoid an accessor method.
*/
void drainEvents()
{
synchronized (queueLock)
{
if (isCoalesce())
{
if (queue > 0)
fireActionPerformed();
}
else
{
while (queue > 0)
{
fireActionPerformed();
queue--;
}
}
queue = 0;
}
}
/**
* Post a scheduled event to the event queue.
* Package-private to avoid an accessor method.
*/
private void queueEvent()
{
synchronized (queueLock)
{
queue++;
if (queue == 1)
SwingUtilities.invokeLater(drainer);
}
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment