initial import
[iDMC.git] / src / java / org / tsho / dmc2 / managers / CowebManager.java
blob945b99f8709025df0e321665a88195db4e4690df
1 /*
2 * iDMC the interactive Dynamical Model Calculator simulates and performs
3 * graphical and numerical analysis of systems of differential and
4 * difference equations.
6 * Copyright (C) 2004 Marji Lines and Alfredo Medio.
8 * Written by Daniele Pizzoni <auouo@tin.it>.
9 * Extended by Alexei Grigoriev <alexei_grigoriev@libero.it>.
13 * The software program was developed within a research project financed
14 * by the Italian Ministry of Universities, the Universities of Udine and
15 * Ca'Foscari of Venice, the Friuli-Venezia Giulia Region.
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or any
20 * later version.
22 * This program is distributed in the hope that it will be useful, but
23 * WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 * General Public License for more details.
27 package org.tsho.dmc2.managers;
29 import java.awt.event.ComponentAdapter;
30 import java.awt.event.ComponentEvent;
32 import org.jfree.data.Range;
33 import org.tsho.dmc2.core.CoreStatusEvent;
34 import org.tsho.dmc2.core.CoreStatusListener;
35 import org.tsho.dmc2.core.ODEStepper;
36 import org.tsho.dmc2.core.Stepper;
37 import org.tsho.dmc2.core.VariableDoubles;
38 import org.tsho.dmc2.core.chart.CowebRenderer;
39 import org.tsho.dmc2.core.chart.DmcPlotRenderer;
40 import org.tsho.dmc2.core.dlua.Lua;
41 import org.tsho.dmc2.core.model.Model;
42 import org.tsho.dmc2.core.model.ODE;
43 import org.tsho.dmc2.core.model.SimpleMap;
44 import org.tsho.dmc2.ui.InvalidData;
45 import org.tsho.dmc2.ui.coweb.CowebControlForm2;
47 /**
49 * @author tsho
51 public class CowebManager extends AbstractManager
52 implements AbstractManager.GridLines,
53 AbstractManager.Crosshair,
54 AbstractManager.Transparency,
55 AbstractManager.ConnectDots,
56 AbstractManager.BigDots,
57 AbstractManager.AxesVisibility {
59 private Model model;
60 private CowebControlForm2 form;
62 private boolean gridlines;
63 private boolean crosshair;
64 private boolean bigDots;
65 private boolean connectDots;
67 private static final int REFRESH_SLEEP_TIME_NORMAL = 500;
68 private static final int REFRESH_SLEEP_TIME_FAST = 25;
69 private int refreshSleepTime = REFRESH_SLEEP_TIME_NORMAL;
71 public CowebManager(final Model model,
72 final CowebControlForm2 form,
73 final ManagerListener2 frame) {
75 super(frame);
77 this.model = model;
78 this.form = form;
80 /* defaults */
81 connectDots = true;
82 gridlines = true;
83 crosshair = false;
84 bigDots = false;
86 if (!(model instanceof SimpleMap) || model.getNVar() != 1) {
87 throw new Error("only unidimentional maps allowed");
90 plot.setForegroundAlpha(0.1F);
92 plot.setAntialias(true);
93 setCrosshair(crosshair);
94 chart.setTitle(model.getName());
96 plot.addCoreStatusListener( new CoreStatusListener() {
97 public void sendCoreStatus(final CoreStatusEvent event) {
98 if (event.getType() == CoreStatusEvent.REDRAW) {
99 // ((CowebRenderer) plot.getPlotRenderer()).setContinua(false);
100 launchThread(false);
102 else if (event.getType() == CoreStatusEvent.REPAINT) {
103 chartPanel.repaint();
108 // chart = new JFreeChart(model.getName(), plot);
110 // chartPanel = new DmcChartPanel(chart);
111 // chartPanel.setMouseZoomable(true, false);
112 // chartPanel.setPopupMenu(null);
114 // stop everything on resizing
115 // TODO fix
116 chartPanel.addComponentListener(new ComponentAdapter() {
117 public final void componentResized(final ComponentEvent e) {
118 CowebManager.this.stopRendering();
123 public final boolean doRendering(final boolean redraw) {
125 CowebRenderer renderer = null;
127 int type;
128 int power;
129 VariableDoubles initialVal = null;
130 VariableDoubles parameters;
131 double stepSize = 0;
132 int transients = 0;
133 Range xRange = null, yRange = null;
135 // collect user values
137 type = form.getPlotType();
139 try {
140 parameters = form.getParameterValues();
142 if (type == CowebControlForm2.TYPE_COWEB) {
143 initialVal = form.getInitialValues();
144 transients = form.getTransients();
147 power = form.getPower();
149 xRange = form.getXRange();
150 yRange = form.getYRange();
153 catch (InvalidData e) {
154 errorMessage = e.getMessage();
155 return false;
158 // create renderer
160 Stepper stepper = null;
161 if (model instanceof SimpleMap) {
162 stepper = Lua.newIterator2(model,
163 VariableDoubles.toArray(parameters),
164 new double[model.getNVar()]);
166 else if (model instanceof ODE) {
167 stepper = Lua.newODEStepper(model,
168 VariableDoubles.toArray(parameters),
169 new double[model.getNVar()],
170 stepSize, 4);
173 renderer = new CowebRenderer(plot, stepper);
174 plot.setPlotRenderer(renderer);
176 stepper.setAxes(0, 0);
177 stepper.initialize();
179 // set type-depending stuff
181 if (type == CowebControlForm2.TYPE_SHIFTED) {
182 renderer.setAnimate(false);
183 refreshSleepTime = REFRESH_SLEEP_TIME_NORMAL;
185 else if (type == CowebControlForm2.TYPE_COWEB) {
186 renderer.setAnimate(true);
187 refreshSleepTime = REFRESH_SLEEP_TIME_FAST;
189 else {
190 throw new Error("Wrong plot type");
193 // set ranges if not redrawing only
195 if (!redraw) {
196 xAxis.setLowerMargin(0);
197 xAxis.setUpperMargin(0);
198 yAxis.setLowerMargin(0);
199 yAxis.setUpperMargin(0);
200 plot.setDataRanges(xRange, yRange);
201 plot.zoom(0.0); // reset zoom
204 if (type == CowebControlForm2.TYPE_COWEB) {
205 renderer.setInitialValue(VariableDoubles.toArray(initialVal));
206 renderer.setTransients(transients);
208 else {
209 renderer.setInitialValue(null);
210 renderer.setTransients(0);
213 // labels
215 String xLabel, yLabel;
216 xLabel = model.getVarNames()[0];
217 yLabel = "f^" + power + "(" + xLabel + ")";
218 xAxis.setLabel(xLabel);
219 yAxis.setLabel(yLabel);
221 renderer.setPower(power);
222 renderer.setDelay(frame.getDelayValue());
223 renderer.setBigDots(bigDots);
224 renderer.setConnectWithLines(connectDots);
226 plot.setDrawGridLines(gridlines);
227 plot.setNoData(false);
229 launchThread(false);
231 return true;
234 // public final boolean continueRendering() {
235 // TrajectoryRenderer renderer = (CowebRenderer) plot.getPlotRenderer();
236 // try {
237 // renderer.setIterations(form.getIterations());
238 // }
239 // catch (InvalidData e) {
240 // errorMessage = e.getMessage();
241 // return false;
242 // }
244 // renderer.setContinua(true);
246 // launchThread(true);
248 // return true;
249 // }
251 class RefreshThread extends Thread {
253 int state = DmcPlotRenderer.STATE_NONE;
254 int ratio;
256 RefreshThread() {
257 super("DMCDUE - ScatterRefresh");
260 public void run() {
261 CowebRenderer renderer = (CowebRenderer) plot.getPlotRenderer();
262 while (true) {
263 int newState = renderer.getState();
265 if (newState != state) {
267 state = newState;
269 switch (newState) {
270 case DmcPlotRenderer.STATE_NONE:
271 ratio = 0;
272 break;
274 case DmcPlotRenderer.STATE_ERROR:
275 ratio = 0;
276 frame.progressString("error...");
277 return;
279 case DmcPlotRenderer.STATE_TRANSIENTS:
280 ratio = renderer.getTransients();
281 frame.progressString("calculating transients...");
282 break;
284 case DmcPlotRenderer.STATE_POINTS:
285 // ratio = renderer.getIterations();
286 frame.progressString("plotting...");
287 break;
289 case DmcPlotRenderer.STATE_FINISHED:
290 frame.progressString("ok. ");
291 report();
292 return;
294 case DmcPlotRenderer.STATE_STOPPED:
295 frame.progressString("stopped, ok.");
296 report();
298 return;
300 default:
301 ratio = 0;
305 if (((state & DmcPlotRenderer.STATE_RUNNING)
306 | (state & DmcPlotRenderer.STATE_POINTS)) != 0 ) {
308 report();
309 chartPanel.repaint();
312 try {
313 sleep(refreshSleepTime);
315 catch (InterruptedException e2) {}
319 private void report() {
320 CowebRenderer renderer = (CowebRenderer) plot.getPlotRenderer();
321 // frame.progressCount(renderer.getIndex());
322 if (ratio != 0) {
323 // frame.progressPercent((renderer.getIndex() * 100 / ratio));
328 private void launchThread(final boolean plotOnly) {
330 plot.getPlotRenderer().setState(DmcPlotRenderer.STATE_NONE);
332 Thread refreshJob = new RefreshThread();
333 refreshJob.start();
335 Thread plotJob = new PlotThread("DMCDUE - Trajectory plotter", plotOnly);
336 plotJob.setPriority(Thread.currentThread().getPriority() - 1);
337 plotJob.start();
341 // private void launch1Thread(final boolean plotOnly) {
343 // Thread job = new Thread("ScatterManager thread") {
344 // CowebRenderer renderer = (CowebRenderer) plot.getPlotRenderer();
345 // public final void run() {
347 // RefreshThread refresh = new RefreshThread("ScatterRefresh");
349 // renderer.setState(DmcPlotRenderer.STATE_NONE);
350 // refresh.start();
352 // try {
353 // frame.jobNotify(true);
355 // if (plotOnly) {
356 // chartPanel.drawPlot();
357 // }
358 // else {
359 // chartPanel.drawChart();
360 // }
361 // }
362 // catch (ModelException e) {
363 // renderer.setState(DmcPlotRenderer.STATE_ERROR);
364 // e.printStackTrace();
365 // if (e.getCause() != null) {
366 // e.getCause().printStackTrace();
367 // }
368 // if (e.getMessage() != null) {
369 // frame.showInvalidDataDialog(e.getMessage());
370 // }
371 // else {
372 // frame.showInvalidDataDialog("Model error.");
373 // }
375 // }
376 // catch (OutOfMemoryError e) {
377 // renderer.setState(DmcPlotRenderer.STATE_ERROR);
378 // e.printStackTrace();
379 // frame.showInvalidDataDialog("Out of Memory Error");
380 // }
381 // catch (Throwable e) {
382 // renderer.setState(DmcPlotRenderer.STATE_ERROR);
383 // e.printStackTrace();
384 // if (e.getMessage() != null) {
385 // frame.showInvalidDataDialog("Error - " + e.getMessage());
386 // }
387 // else {
388 // frame.showInvalidDataDialog("Undefined error.");
389 // }
390 // }
391 // finally {
392 // refresh.interrupt();
393 // frame.jobNotify(false);
394 // }
395 // }
396 // };
398 // // the GUI (er, the whole system...) gets unresponsive
399 // // without this on Windows
400 // job.setPriority(Thread.currentThread().getPriority() - 1);
401 // job.start();
402 // }
406 public void stopRendering() {
407 CowebRenderer renderer = (CowebRenderer) plot.getPlotRenderer();
409 if (renderer != null) {
410 renderer.stop();
414 public void clear() {
415 plot.setNoData(true);
416 plot.zoom(0.0);
417 launchThread(false);
420 public void setAlpha(final boolean flag) {
421 plot.setAlpha(flag);
424 public void setAlphaValue(final float f) {
425 plot.setForegroundAlpha(f);
428 public float getAlphaValue() {
429 return plot.getForegroundAlpha();
432 public void setCrosshair(final boolean flag) {
433 crosshair = flag;
434 chartPanel.setHorizontalAxisTrace(flag);
435 chartPanel.setVerticalAxisTrace(flag);
438 public boolean isCrosshair() {
439 return crosshair;
442 public boolean isGridlines() {
443 return gridlines;
446 public void setGridlines(final boolean b) {
447 gridlines = b;
450 public boolean isConnectDots() {
451 return connectDots;
454 public void setConnectDots(final boolean b) {
455 connectDots = b;
456 ((CowebRenderer) plot.getPlotRenderer()).setConnectWithLines(b);
459 public boolean isBigDots() {
460 return bigDots;
463 public void setBigDots(final boolean b) {
464 bigDots = b;
465 ((CowebRenderer) plot.getPlotRenderer()).setBigDots(b);
468 public void setDelay(final int delay) {
469 CowebRenderer renderer = (CowebRenderer) plot.getPlotRenderer();
471 if (renderer != null) {
472 ((CowebRenderer) plot.getPlotRenderer()).setDelay(delay);
475 if (delay > 0) {
476 refreshSleepTime = REFRESH_SLEEP_TIME_FAST;
478 else {
479 refreshSleepTime = REFRESH_SLEEP_TIME_NORMAL;
483 public void setVariation(final boolean flag) {