001 package sale;
002
003 /**
004 * A timer that has the functionality of the {@link StepTimer StepTimer} and additionally
005 * can increase the time automatically.
006 *
007 * @author Stephan Gambke
008 * @version 2.0 11/06/1999
009 * @since v2.0
010 */
011 public class AutoTimer extends StepTimer {
012
013 /**
014 * Communications channel used for controlling the internal processing loop.
015 */
016 private transient Object m_oTimer;
017 /**
018 * Return the communications channel used for controlling the internal processing loop.
019 */
020 private Object getTimer() {
021 if (m_oTimer == null) {
022 m_oTimer = new Object();
023 }
024
025 return m_oTimer;
026 }
027
028 /**
029 * Is the timer running ?
030 *
031 * @serial
032 */
033 private boolean m_fOnTheRun;
034
035 /**
036 * Delay between increases.
037 *
038 * @serial
039 */
040 private long m_lDelay = 1;
041
042 /**
043 * Create a new AutoTimer with a {@link Step Step} as time object and a delay of 10 seconds.
044 * The timer is initially not running.
045 */
046 public AutoTimer() {
047 this(new Step(), 10000);
048 }
049
050 /**
051 * Create a new AutoTimer with the given time object and a delay of 10 seconds. The timer is initially not
052 * running.
053 *
054 * @param tTime the time object to be used
055 */
056 public AutoTimer(Time tTime) {
057 this(tTime, 10000);
058 }
059
060 /**
061 * Create a new AutoTimer with the given time object and delay. The timer is initially not running.
062 *
063 * @param tTime the time object to use
064 * @param lDelay the delay in milliseconds between the increasing steps
065 */
066 public AutoTimer(Time tTime, long lDelay) {
067 super(tTime);
068 m_fOnTheRun = false;
069 setDelay(lDelay);
070 }
071
072 /**
073 * Internal method that just calls <code>super.goAhead()</code>
074 *
075 * @override Never
076 */
077 private void doGoAhead() throws IllegalArgumentException {
078 super.goAhead();
079 }
080
081 /**
082 * Increase the time by the current interval.
083 *
084 * <p>If no interval has yet been set, the interval given by the {@link Time#getDefaultInterval()} method
085 * of the time object is used.</p>
086 *
087 * <p>If the AutoTimer is running, the time is increased and the delay restartet.</p>
088 *
089 * @override Never
090 *
091 * @exception IllegalArgumentException if the interval does not meet the time object's class or format
092 * requirements.
093 */
094 public void goAhead() throws IllegalArgumentException {
095 if (m_fOnTheRun) {
096 synchronized (getTimer()) {
097 getTimer().notifyAll();
098 }
099 } else {
100 doGoAhead();
101 }
102 }
103
104 /**
105 * Set the timer running. If the timer is already running, nothing happens.
106 *
107 * <p>The first timer tick occurs at once.</p>
108 *
109 * @override Never
110 */
111 public void start() throws IllegalArgumentException {
112 synchronized (getTimer()) {
113 if (m_fOnTheRun) {
114 return;
115 }
116
117 m_fOnTheRun = true;
118
119 new Thread() {
120 public void run() {
121 synchronized (getTimer()) {
122 while (m_fOnTheRun) {
123 try {
124 doGoAhead();
125 getTimer().wait(m_lDelay);
126 }
127 catch (InterruptedException iexc) {}
128 catch (Throwable t) {
129 m_fOnTheRun = false;
130
131 System.err.println("Error in AutoTimer: " + t);
132 t.printStackTrace();
133 }
134 }
135 }
136 }
137 }
138
139 .start();
140 }
141 }
142
143 /**
144 * Stop the timer.
145 *
146 * @override Never
147 */
148 public void stop() {
149 m_fOnTheRun = false;
150 }
151
152 /**
153 * Set the delay between timer ticks.
154 *
155 * <p>If the AutoTimer is currently running, the new delay takes effect after the next tick.</p>
156 *
157 * @override Never
158 *
159 * @param lMilliSecs the delay in milliseconds. Must be > 0.
160 */
161 public void setDelay(long lMilliSecs) {
162 if (lMilliSecs > 0) {
163 m_lDelay = lMilliSecs;
164 }
165 }
166
167 /**
168 * Get the current delay between timer ticks in milliseconds.
169 *
170 * @return a long value representing the delay
171 */
172 public long getDelay() {
173 return m_lDelay;
174 }
175 }