KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > info > monitorenter > gui > chart > io > ADataCollector


1 /*
2  * AbstractDataCollector.java jchart2d Copyright (C) Achim Westermann, created
3  * on 10.12.2004, 14:48:09
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18  *
19  * If you modify or optimize the code in a useful way please let me know.
20  * Achim.Westermann@gmx.de
21  */

22 package info.monitorenter.gui.chart.io;
23
24 import info.monitorenter.gui.chart.ITrace2D;
25 import info.monitorenter.gui.chart.TracePoint2D;
26
27
28 /**
29  * A simple Runnable that contiuously collects data every latency time period
30  * and adds it to the internal ITrace2D instance.
31  * <p>
32  * Extend from this class and override the method {@link #collectData()}.
33  * <p>
34  * Set it up with code like:
35  *
36  * <pre>
37  * Chart2D chart = new Chart2D();
38  * ITrace2D trace = &lt;initializatioin&gt;
39  * chart.addTrace(trace);
40  * // Put the chart in your UI...
41  * // ...
42  * AbstractDataCollector collector = new &lt;subtypename&gt;(200,trace);
43  * collector.start();
44  * </pre>
45  * <p>
46  *
47  * <h3>Caution</h3>
48  * Calling <code>new Thread(collector).start()</code> is disallowed and will
49  * throw an exception as it would allow several Threads to run a collector. Use
50  * the {@link #start()} instead.
51  * <p>
52  * rabbel rabbel.
53  * <p>
54  *
55  * @author <a HREF="mailto:Achim.Westermann@gmx.de">Achim Westermann </a>
56  * @version $Revision: 1.1 $
57  */

58 public abstract class ADataCollector implements Runnable JavaDoc {
59
60   /** Flag to check wether the collector is running. */
61   private boolean m_isRunning = false;
62
63   /** The interval for data collection of a single point. */
64   private long m_latency = 400;
65
66   /** This flag controls stopping / starting the thread that is used. */
67   private boolean m_stop = true;
68
69   /**
70    * The thread that is created in {@link #start()}.
71    * <p>
72    * If someone tries to: <code>new Thread(collector).start()</code> instead
73    * of <code>collector.start()</code> an exception will be thrown.
74    */

75   private Thread JavaDoc m_thread;
76
77   /** The trace to add collected data to. */
78   private ITrace2D m_trace;
79
80   /**
81    * Creates an instance that will collect every latency ms a point and add it
82    * to the trace.
83    * <p>
84    *
85    * @param trace
86    * the trace to add collected points to.
87    * @param latency
88    * the interval in ms for collecting points.
89    */

90   public ADataCollector(final ITrace2D trace, final long latency) {
91     super();
92     this.m_latency = latency;
93     this.m_trace = trace;
94   }
95
96   /**
97    * <p>
98    * Override this method. It will be invoked in intervals of the configured
99    * latency time. The TracePoint2D that is returned will be added to the
100    * constructor given ITrace2D.
101    * </p>
102    * <p>
103    * Keep your implementation fast. If the computations performed here take
104    * longer than the latency time that desired refresh rate will not be reached.
105    * </p>
106    *
107    * @return the colleted point.
108    */

109   public abstract TracePoint2D collectData();
110
111   /**
112    * @see java.lang.Object#finalize()
113    */

114   public void finalize() throws Throwable JavaDoc {
115     super.finalize();
116     this.stop();
117   }
118
119   /**
120    * Returns the interval in ms a point is collected.
121    * <p>
122    *
123    * @return the interval in ms a point is collected.
124    */

125   public long getLatency() {
126     return this.m_latency;
127   }
128
129   /**
130    * Returns the trace that is filled by this collector.
131    * <p>
132    *
133    * @return Returns the trace.
134    */

135   public ITrace2D getTrace() {
136     return this.m_trace;
137   }
138
139   /**
140    * Returns true if this datacollector currently is running.
141    * <p>
142    *
143    * @return true if this datacollector currently is running.
144    */

145   public boolean isRunning() {
146     return this.m_isRunning;
147   }
148
149   /**
150    * @see java.lang.Runnable#run()
151    */

152   public void run() {
153     if (Thread.currentThread() != this.m_thread) {
154       throw new IllegalStateException JavaDoc(
155           "You cannot start an own thread for data collectors. Use collector.start()!");
156     }
157     this.m_isRunning = true;
158     long lasttime;
159     this.m_stop = false;
160     TracePoint2D point;
161     while (!this.m_stop) {
162       lasttime = System.currentTimeMillis();
163       point = this.collectData();
164       this.m_trace.addPoint(point);
165       try {
166         Thread.sleep(Math.max(this.m_latency - System.currentTimeMillis() + lasttime, 0));
167       } catch (InterruptedException JavaDoc e) {
168         this.stop();
169       }
170       if (Thread.interrupted()) {
171         this.stop();
172       }
173     }
174     this.m_isRunning = false;
175   }
176
177   /**
178    * Sets the interval for collecting points in ms.
179    * <p>
180    *
181    * @param latency
182    * the interval for collecting points in ms.
183    */

184   public void setLatency(final long latency) {
185     this.m_latency = latency;
186   }
187
188   /**
189    * <p>
190    * Starts a Thread using this {@link Runnable}.
191    * </p>
192    * <p>
193    * This method will not start a new Thread if the current one is still
194    * running. If you prefer to use your own Threads (e.g. from a ThreadPool)
195    * prefer:
196    *
197    * <pre>
198    * AbstractDataCollector collector = new &lt;subtypename&gt;(200,trace);
199    * new Thread(collector).start();
200    * </pre>
201    *
202    * or more abstract (as proposed for Thread improvement reasons:
203    *
204    * <pre>
205    * AbstractDataCollector collector = new &lt;subtypename&gt;(200,trace);
206    * &lt;getSomeThreadInstance&gt;(collector).start();
207    * </pre>
208    *
209    * </p>
210    */

211   public void start() {
212     if (this.m_stop) {
213       this.m_thread = new Thread JavaDoc(this);
214       this.m_thread.start();
215     }
216   }
217
218   /**
219    * <p>
220    * Stops this Thread. Data collection will end when finished the current loop.
221    * </p>
222    * <p>
223    * Note that your application may
224    * <ol>
225    * <li>run into deadlocks (blocking IO,...)
226    * <li>face memory problems
227    * </ol>
228    * if the AbstractDataCollector implementation fetches and removes data from
229    * 1) a limited buffer or a 2) unlimited buffer. This behaviour will of course
230    * not appear if the data is not read from a queue where it has to be removed
231    * from.
232    * </p>
233    */

234   public void stop() {
235     this.m_stop = true;
236   }
237
238 }
239
Popular Tags