KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > info > monitorenter > gui > chart > demos > MultiTracing


1 /*
2  * MultiTracing, a demo testing the thread- safetiness of the Chart2D.
3  * Copyright (C) 2002 Achim Westermann, Achim.Westermann@gmx.de
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.demos;
23
24 import info.monitorenter.gui.chart.Chart2D;
25 import info.monitorenter.gui.chart.ITrace2D;
26 import info.monitorenter.gui.chart.layout.ChartPanel;
27 import info.monitorenter.gui.chart.rangepolicies.RangePolicyMinimumViewport;
28 import info.monitorenter.gui.chart.traces.Trace2DSimple;
29 import info.monitorenter.util.Range;
30
31 import java.awt.BorderLayout JavaDoc;
32 import java.awt.Color JavaDoc;
33 import java.awt.Container JavaDoc;
34 import java.awt.event.WindowAdapter JavaDoc;
35 import java.awt.event.WindowEvent JavaDoc;
36
37 import javax.swing.JFrame JavaDoc;
38
39
40 /**
41  * <p>
42  * An example that tests the ability of multithreaded use of a single
43  * <code>Chart2D</code>. Six different Threads are painting subsequently a
44  * single point to the chart and go to a sleep. After having painted the whole
45  * trace, each Thread sleeps for a random time, removes it's trace, sleeps for
46  * another random time and starts again. <br>
47  * To be true: the data for the <code>TracePoint</code> instances is computed
48  * a single time at startup.
49  * </p>
50  * <p>
51  * This test may blow your CPU. I am currently working on an AMD Athlon 1200,
52  * 512 MB RAM so I did not get these problems.
53  * </p>
54  *
55  * @version $Revision: 1.1 $
56  *
57  * @author <a HREF='mailto:Achim.Westermann@gmx.de'>Achim Westermann </a>
58  */

59
60 public final class MultiTracing extends JFrame JavaDoc {
61   /**
62    * Thread that adds a trace to a chart, paints the points with configurable
63    * sleep breaks and then removes it. It then goes to sleep and starts this
64    * cycle anew.
65    * <p>
66    *
67    * @author <a HREF="mailto:Achim.Westermann@gmx.de">Achim Westermann </a>
68    *
69    *
70    * @version $Revision: 1.1 $
71    */

72   static final class AddPaintRemoveThread extends Thread JavaDoc {
73
74     /** The y values to paint. */
75     private double[] m_data;
76
77     /** the chart to use. */
78     private Chart2D m_innnerChart;
79
80     /** The break the Thread takes between painting two points. */
81     private long m_sleep;
82
83     /** The trace to paint to. */
84     private ITrace2D m_trace;
85
86     /**
87      * Creates an instance that paints data to the trace that is added to the
88      * chart.
89      * <p>
90      *
91      * @param chart
92      * the chart to use.
93      *
94      * @param trace
95      * the trace to add points to.
96      *
97      * @param data
98      * the y values of the points to add.
99      *
100      * @param sleep
101      * the length of the sleep break between painting points in ms.
102      */

103     public AddPaintRemoveThread(final Chart2D chart, final ITrace2D trace, final double[] data,
104         final long sleep) {
105       this.m_innnerChart = chart;
106       this.m_trace = trace;
107       this.m_trace.setName(this.getName());
108       this.m_data = data;
109       this.m_sleep = sleep;
110     }
111
112     /**
113      * @see java.lang.Runnable#run()
114      */

115     public void run() {
116
117       while (true) {
118
119         this.m_innnerChart.addTrace(this.m_trace);
120         for (int i = 0; i < this.m_data.length; i++) {
121           if (DEBUG) {
122             System.out.println(this.getName() + " adding point to " + this.m_trace.getName());
123           }
124           this.m_trace.addPoint(i, this.m_data[i]);
125           try {
126             Thread.sleep(this.m_sleep);
127           } catch (InterruptedException JavaDoc e) {
128             e.printStackTrace(System.err);
129           }
130
131         }
132         try {
133           Thread.sleep((long) (Math.random() * this.m_sleep));
134         } catch (InterruptedException JavaDoc e) {
135           e.printStackTrace(System.err);
136         }
137         if (DEBUG) {
138           System.out.println(this.getName() + " removing trace.");
139         }
140         this.m_innnerChart.removeTrace(this.m_trace);
141         this.m_trace.removeAllPoints();
142
143         try {
144           Thread.sleep((long) (Math.random() * this.m_sleep));
145         } catch (InterruptedException JavaDoc e) {
146           e.printStackTrace(System.err);
147         }
148       }
149     }
150   }
151
152   /** Debugging switch. */
153   private static final boolean DEBUG = false;
154
155   /**
156    * Generated <code>serialVersionUID</code>.
157    */

158   private static final long serialVersionUID = 3256722879394820657L;
159
160   /** Sleep break time between adding two points. */
161   private static final int SLEEP = 100;
162
163   /**
164    * Helper method that generates random data for display.
165    * <p>
166    *
167    * @param data
168    * will be filled with random y and ascending x values.
169    *
170    * @return the range of the generated data.
171    */

172   private static Range getRange(final double[][] data) {
173     double min = Double.MAX_VALUE;
174     double max = Double.MIN_VALUE;
175     double tmp;
176     for (int i = data.length - 1; i >= 0; i--) {
177       for (int j = data[i].length - 1; j >= 0; j--) {
178         tmp = data[i][j];
179         if (tmp > max) {
180           max = tmp;
181         }
182         if (tmp < min) {
183           min = tmp;
184         }
185       }
186     }
187
188     return new Range(min, max);
189   }
190
191   /**
192    * Main entry.
193    * <p>
194    *
195    * @param args
196    * ignored.
197    */

198   public static void main(final String JavaDoc[] args) {
199     /*
200      * [[xa 1,..,xa n],..,[xf 1,...,xf n]]
201      */

202     final double[][] data = new double[6][200];
203     final java.util.Random JavaDoc rand = new java.util.Random JavaDoc();
204     // first traces data
205
// recursive entry:
206
data[0][0] = rand.nextDouble() * 5;
207     for (int i = 1; i < data[0].length; i++) {
208       data[0][i] = (rand.nextDouble() < 0.5) ? data[0][i - 1] + rand.nextDouble() * 5
209           : data[0][i - 1] - rand.nextDouble() * 5;
210     }
211     // second trace
212
double tmp;
213     for (int i = 0; i < data[0].length; i++) {
214       tmp = Math.pow(Math.E, ((double) i) / 40) + (Math.random() < 0.5 ? data[0][i] : -data[0][i]);
215       data[1][i] = tmp;
216     }
217     // third trace
218
for (int i = 0; i < data[0].length; i++) {
219       data[2][i] = Math.pow(Math.cos(((double) i) / 10) * 5, 2);
220     }
221     // fourth trace: numerical integration of fist trace's previous entries.
222
// recursive entry:
223
data[3][0] = data[0][0];
224     tmp = 0;
225     for (int i = 1; i < data[0].length; i++) {
226       for (int j = Math.max(0, i - 10); j <= i; j++) {
227         tmp += data[0][j];
228       }
229       data[3][i] = tmp / (((double) i) + 1);
230       tmp = 0;
231     }
232     // fifth trace addition of second trace and third trace
233
for (int i = 0; i < data[0].length; i++) {
234       data[4][i] = data[1][i] + data[2][i] * (0.1 * -data[0][i]);
235     }
236     // sixth trace: addition of first and second trace
237
for (int i = 0; i < data[0].length; i++) {
238       data[5][i] = data[0][i] + data[2][i];
239     }
240
241     final MultiTracing wnd = new MultiTracing();
242     wnd.setForceXRange(new Range(0, data[0].length + 10));
243     wnd.setForceYRange(getRange(data));
244     wnd.setLocation(100, 300);
245     wnd.setSize(800, 300);
246     wnd.setResizable(true);
247     wnd.setVisible(true);
248
249     ITrace2D trace;
250     // first Thread:
251
trace = new Trace2DSimple();
252     trace.setColor(Color.red);
253     new AddPaintRemoveThread(wnd.m_chart, trace, data[0], MultiTracing.SLEEP).start();
254     // second Thread:
255
trace = new Trace2DSimple();
256     trace.setColor(Color.green);
257     new AddPaintRemoveThread(wnd.m_chart, trace, data[1], (long) (MultiTracing.SLEEP * 1.5))
258         .start();
259     // third Thread:
260
trace = new Trace2DSimple();
261     trace.setColor(Color.blue);
262     new AddPaintRemoveThread(wnd.m_chart, trace, data[2], (long) (MultiTracing.SLEEP * 2)).start();
263
264     // fourth Thread:
265
trace = new Trace2DSimple();
266     trace.setColor(Color.cyan);
267     new AddPaintRemoveThread(wnd.m_chart, trace, data[3], (long) (MultiTracing.SLEEP * 2.5))
268         .start();
269     // fifth Thread:
270
trace = new Trace2DSimple();
271     trace.setColor(Color.black);
272     new AddPaintRemoveThread(wnd.m_chart, trace, data[4], (long) (MultiTracing.SLEEP * 3)).start();
273     // sixth Thread:
274
trace = new Trace2DSimple();
275     trace.setColor(Color.white);
276     new AddPaintRemoveThread(wnd.m_chart, trace, data[5], (long) (MultiTracing.SLEEP * 3.5))
277         .start();
278
279   }
280
281   /** The chart to fill. */
282   protected Chart2D m_chart = null;
283
284   /** Defcon. */
285   public MultiTracing() {
286     super("MultiTracing");
287     this.m_chart = new Chart2D();
288     this.m_chart.getAxisX().setPaintGrid(true);
289     this.m_chart.getAxisY().setPaintGrid(true);
290     this.m_chart.setBackground(Color.lightGray);
291     this.m_chart.setGridColor(new Color JavaDoc(0xDD, 0xDD, 0xDD));
292     // add WindowListener
293
addWindowListener(new WindowAdapter JavaDoc() {
294       public void windowClosing(final WindowEvent JavaDoc e) {
295         System.exit(0);
296       }
297     });
298     Container JavaDoc contentPane = getContentPane();
299     contentPane.setLayout(new BorderLayout JavaDoc());
300     contentPane.add(new ChartPanel(this.m_chart), BorderLayout.CENTER);
301   }
302
303   /**
304    * Enforces to display a certain visible x range that will be expanded if
305    * traces in the chart have higher or lower values.
306    * <p>
307    *
308    * @param forceXRange
309    * the range that at least has to be kept visible.
310    */

311   public void setForceXRange(final Range forceXRange) {
312     this.m_chart.getAxisX().setRangePolicy(new RangePolicyMinimumViewport(forceXRange));
313   }
314
315   /**
316    * Enforces to display a certain visible x range that will be expanded if
317    * traces in the chart have higher or lower values.
318    * <p>
319    *
320    * @param forceYRange
321    * the range that at least has to be kept visible.
322    */

323   public void setForceYRange(final Range forceYRange) {
324     this.m_chart.getAxisY().setRangePolicy(new RangePolicyMinimumViewport(forceYRange));
325   }
326 }
327
Popular Tags