package sale; /** * A timer that has the functionality of the {@link StepTimer StepTimer} and additionally * can increase the time automatically. * * @author Stephan Gambke * @version 2.0 11/06/1999 * @since v2.0 */ public class AutoTimer extends StepTimer { /** * Communications channel used for controlling the internal processing loop. */ private transient Object m_oTimer; /** * Return the communications channel used for controlling the internal processing loop. */ private Object getTimer() { if (m_oTimer == null) { m_oTimer = new Object(); } return m_oTimer; } /** * Is the timer running ? * * @serial */ private boolean m_fOnTheRun; /** * Delay between increases. * * @serial */ private long m_lDelay = 1; /** * Create a new AutoTimer with a {@link Step Step} as time object and a delay of 10 seconds. * The timer is initially not running. */ public AutoTimer () { this (new Step(), 10000); } /** * Create a new AutoTimer with the given time object and a delay of 10 seconds. The timer is initially not * running. * * @param tTime the time object to be used */ public AutoTimer (Time tTime) { this (tTime, 10000); } /** * Create a new AutoTimer with the given time object and delay. The timer is initially not running. * * @param tTime the time object to use * @param lDelay the delay in milliseconds between the increasing steps */ public AutoTimer (Time tTime, long lDelay) { super (tTime); m_fOnTheRun = false; setDelay (lDelay); } /** * Internal method that just calls <code>super.goAhead()</code> * * @override Never */ private void doGoAhead() throws IllegalArgumentException { super.goAhead(); } /** * Increase the time by the current interval. * * <p>If no interval has yet been set, the interval given by the {@link Time#getDefaultInterval()} method * of the time object is used.</p> * * <p>If the AutoTimer is running, the time is increased and the delay restartet.</p> * * @override Never * * @exception IllegalArgumentException if the interval does not meet the time object's class or format * requirements. */ public void goAhead () throws IllegalArgumentException { if (m_fOnTheRun) synchronized (getTimer()) {getTimer().notifyAll();} else doGoAhead(); } /** * Set the timer running. If the timer is already running, nothing happens. * * <p>The first timer tick occurs at once.</p> * * @override Never */ public void start() throws IllegalArgumentException { synchronized (getTimer()) { if (m_fOnTheRun) { return; } m_fOnTheRun = true; new Thread() { public void run() { synchronized (getTimer()) { while (m_fOnTheRun) { try { doGoAhead(); getTimer().wait (m_lDelay); } catch (InterruptedException iexc) {} catch (Throwable t) { m_fOnTheRun = false; System.err.println ("Error in AutoTimer: " + t); t.printStackTrace(); } } } } }.start(); } } /** * Stop the timer. * * @override Never */ public void stop() { m_fOnTheRun = false; } /** * Set the delay between timer ticks. * * <p>If the AutoTimer is currently running, the new delay takes effect after the next tick.</p> * * @override Never * * @param lMilliSecs the delay in milliseconds. Must be > 0. */ public void setDelay (long lMilliSecs) { if (lMilliSecs > 0) { m_lDelay = lMilliSecs; } } /** * Get the current delay between timer ticks in milliseconds. * * @return a long value representing the delay */ public long getDelay () { return m_lDelay; } }