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
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
;
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
{
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
) {
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);
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
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;
129 VariableDoubles initialVal
= null;
130 VariableDoubles parameters
;
133 Range xRange
= null, yRange
= null;
135 // collect user values
137 type
= form
.getPlotType();
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();
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()],
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
;
190 throw new Error("Wrong plot type");
193 // set ranges if not redrawing only
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
);
209 renderer
.setInitialValue(null);
210 renderer
.setTransients(0);
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);
234 // public final boolean continueRendering() {
235 // TrajectoryRenderer renderer = (CowebRenderer) plot.getPlotRenderer();
237 // renderer.setIterations(form.getIterations());
239 // catch (InvalidData e) {
240 // errorMessage = e.getMessage();
244 // renderer.setContinua(true);
246 // launchThread(true);
251 class RefreshThread
extends Thread
{
253 int state
= DmcPlotRenderer
.STATE_NONE
;
257 super("DMCDUE - ScatterRefresh");
261 CowebRenderer renderer
= (CowebRenderer
) plot
.getPlotRenderer();
263 int newState
= renderer
.getState();
265 if (newState
!= state
) {
270 case DmcPlotRenderer
.STATE_NONE
:
274 case DmcPlotRenderer
.STATE_ERROR
:
276 frame
.progressString("error...");
279 case DmcPlotRenderer
.STATE_TRANSIENTS
:
280 ratio
= renderer
.getTransients();
281 frame
.progressString("calculating transients...");
284 case DmcPlotRenderer
.STATE_POINTS
:
285 // ratio = renderer.getIterations();
286 frame
.progressString("plotting...");
289 case DmcPlotRenderer
.STATE_FINISHED
:
290 frame
.progressString("ok. ");
294 case DmcPlotRenderer
.STATE_STOPPED
:
295 frame
.progressString("stopped, ok.");
305 if (((state
& DmcPlotRenderer
.STATE_RUNNING
)
306 | (state
& DmcPlotRenderer
.STATE_POINTS
)) != 0 ) {
309 chartPanel
.repaint();
313 sleep(refreshSleepTime
);
315 catch (InterruptedException e2
) {}
319 private void report() {
320 CowebRenderer renderer
= (CowebRenderer
) plot
.getPlotRenderer();
321 // frame.progressCount(renderer.getIndex());
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();
335 Thread plotJob
= new PlotThread("DMCDUE - Trajectory plotter", plotOnly
);
336 plotJob
.setPriority(Thread
.currentThread().getPriority() - 1);
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);
353 // frame.jobNotify(true);
356 // chartPanel.drawPlot();
359 // chartPanel.drawChart();
362 // catch (ModelException e) {
363 // renderer.setState(DmcPlotRenderer.STATE_ERROR);
364 // e.printStackTrace();
365 // if (e.getCause() != null) {
366 // e.getCause().printStackTrace();
368 // if (e.getMessage() != null) {
369 // frame.showInvalidDataDialog(e.getMessage());
372 // frame.showInvalidDataDialog("Model error.");
376 // catch (OutOfMemoryError e) {
377 // renderer.setState(DmcPlotRenderer.STATE_ERROR);
378 // e.printStackTrace();
379 // frame.showInvalidDataDialog("Out of Memory Error");
381 // catch (Throwable e) {
382 // renderer.setState(DmcPlotRenderer.STATE_ERROR);
383 // e.printStackTrace();
384 // if (e.getMessage() != null) {
385 // frame.showInvalidDataDialog("Error - " + e.getMessage());
388 // frame.showInvalidDataDialog("Undefined error.");
392 // refresh.interrupt();
393 // frame.jobNotify(false);
398 // // the GUI (er, the whole system...) gets unresponsive
399 // // without this on Windows
400 // job.setPriority(Thread.currentThread().getPriority() - 1);
406 public void stopRendering() {
407 CowebRenderer renderer
= (CowebRenderer
) plot
.getPlotRenderer();
409 if (renderer
!= null) {
414 public void clear() {
415 plot
.setNoData(true);
420 public void setAlpha(final boolean 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
) {
434 chartPanel
.setHorizontalAxisTrace(flag
);
435 chartPanel
.setVerticalAxisTrace(flag
);
438 public boolean isCrosshair() {
442 public boolean isGridlines() {
446 public void setGridlines(final boolean b
) {
450 public boolean isConnectDots() {
454 public void setConnectDots(final boolean b
) {
456 ((CowebRenderer
) plot
.getPlotRenderer()).setConnectWithLines(b
);
459 public boolean isBigDots() {
463 public void setBigDots(final boolean 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
);
476 refreshSleepTime
= REFRESH_SLEEP_TIME_FAST
;
479 refreshSleepTime
= REFRESH_SLEEP_TIME_NORMAL
;
483 public void setVariation(final boolean flag
) {