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 }