Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: echopoint/Timer.java


1   package echopoint;
2   
3   /* 
4    * This file is part of the Echo Point Project.  This project is a collection
5    * of Components that have extended the Echo Web Application Framework.
6    *
7    * EchoPoint is free software; you can redistribute it and/or modify
8    * it under the terms of the GNU Lesser General Public License as published by
9    * the Free Software Foundation; either version 2 of the License, or
10   * (at your option) any later version.
11   *
12   * EchoPoint is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   * GNU Lesser General Public License for more details.
16   *
17   * You should have received a copy of the GNU Lesser General Public License
18   * along with Echo Point; if not, write to the Free Software
19   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20   */
21  
22  import java.util.EventListener;
23  
24  import nextapp.echo.Component;
25  import nextapp.echo.event.ActionEvent;
26  import nextapp.echo.event.ActionListener;
27  
28  import echopoint.util.reflect.ReflectionSetter;
29  
30  /**
31   *
32   * The <code>Timer</code> class is a <code>Component</code>
33   * that causes an action to occur at a predefined rate.
34   * <br>
35   * Each <code>Timer</code> has a list of <code>ActionListeners</code> and a 
36   * delay ( the time between <code>actionPerfomed()</code> calls). 
37   * <br>
38   * When delay milliseconds have passed, a <code>Timer</code> sends the 
39   * <code>actionPerformed()</code> message to its listeners. 
40   * <br>
41   * This cycle repeats until <code>stop()</code> is called, or 
42   * halts immediately if the Timer is configured to 
43   * send its message just once.
44   * <br>
45   * Note that this is a very coarse timer.  The timer is run on the 
46   * client and the timeout must travel back to the server before any 
47   * other code can be notified of this event.  Therefore the granuality 
48   * of the timer cannot be gaurunteed, as it depends on the client speed and 
49   * the network speed between the client and server.
50   * <br>
51   * This class is mostly useful for causing the client to update without having
52   * to have the user click on anything.
53   * <br>
54   * You can only have one effective Timer on a <code>Window</code> at a time.  
55   * This is because once the lowest delay timer has popped, any screen updates 
56   * will cause all Timers on that <code>Window</code> to be reset to their
57   * respective starting delays, regardless of how much time has passed since the 
58   * last event happened on a given timer.
59   * <br>
60   * The reason the Timer is fired on the client rather than via a thread on the server,
61   * is to help support many clients (thousands).  Each client is running their 
62   * own timers, using their own processing power.  If a single thread was created for 
63   * all Timers (or worse one per client) then the system would eventually grind to a halt.
64   * <br>
65   * @author Brad Baker 
66   */
67  
68  public class Timer extends Component implements ReflectionSetter {
69    
70    public static final String TIMER_CHANGED_PROPERTY = "timer";
71  
72    private String actionCommand = "";
73    private int delay = -1;
74    private boolean hasFired = false;
75    private int initialDelay = -1;
76    private boolean repeats = true;
77    private boolean running = false;
78  
79    /**
80     * Creates a <code>Timer</code> that will notify its 
81     * listeners every <code>1000</code> milliseconds. 
82     */
83    public Timer() {
84      this(1000, null);
85    }
86    
87    /**
88     * Creates a <code>Timer</code> that will notify its 
89     * listeners every <code>delay</code> milliseconds. 
90     */
91    public Timer(int delay) {
92      this(delay, null);
93    }
94    /**
95    * Creates a <code>Timer</code> that will notify its 
96    * listeners every <code>delay</code> milliseconds. 
97    */
98    public Timer(int delay, ActionListener actionListener) {
99      super();
100     hasFired = false;
101 
102     setRepeats(true);
103     setDelay(delay);
104     setInitialDelay(delay);
105     if(actionListener != null) 
106       addActionListener(actionListener);
107   }
108   /**
109    * Adds an <code>ActionListener</code> to the Timer.
110    *
111    * @param l The <code>ActionListener</code> to be added.
112    */
113   public void addActionListener(ActionListener l) {
114     listenerList.addListener(ActionListener.class, l);
115   }
116   /**
117    * Notifies all listeners that have registered for this event type.
118    *
119    * @param e The <code>ActionEvent</code> to send.
120    */
121   public void fireActionPerformed(ActionEvent e) {
122     hasFired = true;
123 
124     EventListener[] listeners = listenerList.getListeners(ActionListener.class);
125     for (int index = 0; index < listeners.length; ++index) {
126       ((ActionListener) listeners[index]).actionPerformed(e);
127     }
128   }
129   /**
130    * @return the action command for the Timer
131    *
132    */
133   public String getActionCommand() {
134     return actionCommand;
135   }
136   /**
137    * @return The delay in milliseconds of the <code>Timer</code>.
138    */
139   public int getDelay() {
140     return delay;
141   }
142   /**
143    * @return The initial delay in milliseconds of the <code>Timer</code>.
144    */
145   public int getInitialDelay() {
146     return initialDelay;
147   }
148   /**
149    * @return true if the <code>Timer</code> has fired before
150    */
151   public boolean hasFired() {
152     return hasFired;
153   }
154   /**
155    * Returns true if the <code>Timer</code> will send a 
156    * <code>actionPerformed()</code> message to its listeners 
157    * multiple times. 
158    */
159   public boolean isRepeats() {
160     return repeats;
161   }
162   /**
163    * @return true of the <code>Timer</code> is running.
164    */
165   public boolean isRunning() {
166     return running;
167   }
168   /**
169    * Removes an <code>ActionListener</code> from the Timer.
170    *
171    * @param l The <code>ActionListener</code> to be removed.
172    */
173   public void removeActionListener(ActionListener l) {
174     listenerList.removeListener(ActionListener.class, l);
175   }
176   /**
177    * Restarts a <code>Timer</code>, canceling any pending firings, and causing
178    * it to fire with its initial dely.
179    */
180   public void restart() {
181     stop();
182     start();
183   }
184   /**
185    * Sets the Timer's action command.
186    *
187    * @param newValue The new action command for this timer.
188    */
189   public void setActionCommand(String newValue) {
190     String oldValue = actionCommand;
191 
192     actionCommand = newValue;
193 
194     firePropertyChange(TIMER_CHANGED_PROPERTY, oldValue, newValue);
195   }
196   /**
197    * Sets the <code>Timer's</code> delay, the number of 
198    * milliseconds between successive <code>actionPerfomed()</code> 
199    * messages to its listeners 
200    * <br>
201    * This methods fires a <code>PropertyChangeEvent</code> with a
202    * <code>getPropertyName()</code> value of 
203    * <code>Timer.TIMER_CHANGED_PROPERTY</code>
204    *
205    */
206   public void setDelay(int newValue) {
207     newValue = Math.abs(newValue);    
208     int oldValue = delay;
209     delay = newValue;
210     firePropertyChange(TIMER_CHANGED_PROPERTY, oldValue, newValue);
211   }
212   /**
213    * Sets the <code>Timer's</code> initial delay. This will be 
214    * used for the first "ringing" of the Timer only. Subsequent 
215    * ringings will be spaced using the delay property. 
216    * <br>
217    * This methods fires a <code>PropertyChangeEvent</code> with a
218    * <code>getPropertyName()</code> value of 
219    * <code>Timer.TIMER_CHANGED_PROPERTY</code>
220    *
221    */
222   public void setInitialDelay(int newValue) {
223     newValue = Math.abs(newValue);    
224     int oldValue = initialDelay;
225     initialDelay = newValue;
226     firePropertyChange(TIMER_CHANGED_PROPERTY, oldValue, newValue);
227   }
228   /**
229    * Instructs the <code>Timer</code> to send <code>actionPerformed()</code>
230    * to its listeners only once, and then stop. 
231    * <br>
232    * This methods fires a <code>PropertyChangeEvent</code> with a
233    * <code>getPropertyName()</code> value of 
234    * <code>Timer.TIMER_CHANGED_PROPERTY</code>
235    *
236    */
237   public void setRepeats(boolean newValue) {
238     boolean oldValue = repeats;
239     repeats = newValue;
240     firePropertyChange(TIMER_CHANGED_PROPERTY, oldValue, newValue);
241   }
242   /**
243    * Starts the <code>Timer</code>, causing it to send <code>actionPerformed()</code>
244    * messages to its listeners. 
245    */
246   public void start() {
247     boolean oldValue = running;
248     running = true;
249     firePropertyChange(TIMER_CHANGED_PROPERTY, oldValue, running);
250   }
251   /**
252    * Stops the <code>Timer</code>, causing it to stop sending <code>actionPerformed()</code>
253    * messages to its listeners. 
254    */
255   public void stop() {
256     boolean oldValue = running;
257     running = false;
258     firePropertyChange(TIMER_CHANGED_PROPERTY, oldValue, running);
259   }
260 
261   
262   /** @see echopoint.util.ReflectionSetter#set(Field, Object) */  
263   public Object set(java.lang.reflect.Field field, Object newValue) throws Exception {
264     Object oldValue = field.get(this); field.set(this,newValue); return oldValue;
265   }
266   
267 }