removed *broken* option in 'ODE step function' menu in trajectory plot
[iDMC.git] / src / java / org / tsho / dmc2 / ui / trajectory / TrajectoryComponent.java
blob11e00b3b2ad779fa67d2de66cb4863b9a97a2100
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.ui.trajectory;
29 import java.awt.event.ActionEvent;
30 import java.awt.event.ActionListener;
31 import java.awt.event.KeyEvent;
33 import javax.swing.Action;
34 import javax.swing.ButtonGroup;
35 import javax.swing.JButton;
36 import javax.swing.JCheckBoxMenuItem;
37 import javax.swing.JMenu;
38 import javax.swing.JMenuItem;
39 import javax.swing.JRadioButtonMenuItem;
40 import javax.swing.JSlider;
41 import javax.swing.JToolBar;
42 import javax.swing.event.ChangeEvent;
43 import javax.swing.event.ChangeListener;
45 import org.jfree.data.Range;
46 import org.tsho.dmc2.ModelDefaults;
47 import org.tsho.dmc2.core.VariableDoubles;
48 import org.tsho.dmc2.core.VariableItems;
49 import org.tsho.dmc2.core.dlua.Lua;
50 import org.tsho.dmc2.core.model.Model;
51 import org.tsho.dmc2.core.model.ODE;
52 import org.tsho.dmc2.core.model.SimpleMap;
53 import org.tsho.dmc2.core.util.Dataset;
54 import org.tsho.dmc2.managers.ManagerListener2;
55 import org.tsho.dmc2.managers.TrajectoryManager;
56 import org.tsho.dmc2.sm.Input;
57 import org.tsho.dmc2.ui.AbstractPlotComponent;
58 import org.tsho.dmc2.ui.MainFrame;
59 import org.tsho.dmc2.ui.components.DmcAction;
60 import org.tsho.dmc2.ui.components.DmcButton;
61 import org.tsho.dmc2.ui.components.DmcMenuItem;
64 /**
66 * @author Daniele Pizzoni <auouo@tin.it>
68 public final class TrajectoryComponent extends AbstractPlotComponent
69 implements ManagerListener2,
70 TrajectorySMItf {
72 private final TrajectoryControlForm2 privateControlForm;
74 JSlider slider;
76 // TODO make a custom action that changes the visibilty
77 // via properties
79 * These are here because the machine needs to change
80 * their visibility.
83 private JMenuItem autoBoundsMenuItem;
84 private JMenuItem manualBoundsMenuItem;
85 private JMenuItem normalPlotMenuItem;
86 private JMenuItem timePlotMenuItem;
87 private JMenuItem variationMenuItem;
89 /* actions */
90 private final Action startAction = new StartAction();
91 private final Action stopAction = new StopAction();
92 private final DmcAction continueAction = new ContinueAction();
93 private final DmcAction redrawAction = new RedrawAction();
94 private final Action clearAction = new ClearAction();
95 private final DmcAction resetAction = new ResetAction();
97 /* defaults */
98 boolean autoBoundsDefault = true;
99 int plotTypeDefault;
103 public TrajectoryComponent(final Model model, MainFrame mainFrame) {
104 super(model,mainFrame,new Dataset(model.getVarNames()));
105 defaultsSection = ModelDefaults.SCATTER_SECTION;
107 controlForm = privateControlForm = new TrajectoryControlForm2(model,this);
109 init(new TrajectoryManager(this, privateControlForm),
110 new TrajectorySM(this), controlForm, "Trajectory");
112 stateMachine.addSensibleItem(autoBoundsMenuItem);
113 stateMachine.addSensibleItem(manualBoundsMenuItem);
114 stateMachine.addSensibleItem(variationMenuItem);
116 stateMachine.addNoRunItem(clearAction);
118 stateMachine.addNoRunItem(getTransparencyAction());
119 stateMachine.addNoRunItem(getConnectDotsMenuItem());
120 stateMachine.addNoRunItem(getBigDotsMenuItem());
121 stateMachine.addNoRunItem(getGridLinesMenuItem());
123 variationMenuItem.setSelected(false);
125 if (model instanceof SimpleMap) {
126 getConnectDotsMenuItem().setSelected(false);
128 else if (model instanceof ODE) {
129 getConnectDotsMenuItem().setSelected(true);
132 stateMachine.parseInput(Input.go);
133 finishInit(controlForm);
136 protected JMenu createCommandMenu() {
137 JMenu menu;
139 menu = new JMenu("Command");
140 menu.setMnemonic(KeyEvent.VK_C);
142 menu.add(new JMenuItem(startAction));
143 menu.add(new JMenuItem(stopAction));
145 menu.addSeparator();
147 menu.add(new DmcMenuItem(continueAction));
148 menu.add(new DmcMenuItem(redrawAction));
149 menu.add(new DmcMenuItem(resetAction));
150 menu.add(new JMenuItem(clearAction));
152 return menu;
155 protected JMenu createPlotMenu() {
156 JMenu menu;
157 JMenuItem menuItem;
159 menu = new JMenu("Plot");
161 ButtonGroup group;
163 group = new ButtonGroup();
164 menuItem = new JRadioButtonMenuItem("State space plot");
165 menuItem.setMnemonic(KeyEvent.VK_N);
166 group.add(menuItem);
167 menu.add(menuItem);
168 menuItem.addActionListener(new ActionListener() {
169 public void actionPerformed(final ActionEvent e) {
170 stateMachine.parseInput(UserMenuInput.normalMode);
171 controlForm.updateSamplesMenu();
172 getSaveDataAction().setEnabled(true);
175 normalPlotMenuItem = menuItem;
177 menuItem = new JRadioButtonMenuItem("Time plot");
178 menuItem.setMnemonic(KeyEvent.VK_T);
179 group.add(menuItem);
180 menu.add(menuItem);
181 menuItem.addActionListener(new ActionListener() {
182 public void actionPerformed(final ActionEvent e) {
183 stateMachine.parseInput(UserMenuInput.timeMode);
184 controlForm.updateSamplesMenu();
185 getSaveDataAction().setEnabled(true);
188 timePlotMenuItem = menuItem;
190 menu.addSeparator();
192 menuItem = new JCheckBoxMenuItem("Variation");
193 menuItem.setMnemonic(KeyEvent.VK_T);
194 menu.add(menuItem);
195 menuItem.addActionListener(new ActionListener() {
196 public void actionPerformed(final ActionEvent e) {
197 boolean state;
198 state = ((JCheckBoxMenuItem) e.getSource()).isSelected();
199 privateControlForm.setVariation(state);
200 privateControlForm.updateSamplesMenu();
201 getSaveDataAction().setEnabled(false);
204 variationMenuItem = menuItem;
206 menu.addSeparator();
208 group = new ButtonGroup();
209 menuItem = new JRadioButtonMenuItem("Automatic bounds");
210 menuItem.setMnemonic(KeyEvent.VK_A);
211 group.add(menuItem);
212 menu.add(menuItem);
213 menuItem.addActionListener(new ActionListener() {
214 public void actionPerformed(final ActionEvent e) {
215 privateControlForm.setAutoRanges(true);
216 privateControlForm.updateSamplesMenu();
219 autoBoundsMenuItem = menuItem;
221 menuItem = new JRadioButtonMenuItem("Manual bounds");
222 menuItem.setMnemonic(KeyEvent.VK_M);
223 group.add(menuItem);
224 menu.add(menuItem);
225 menuItem.addActionListener(new ActionListener() {
226 public void actionPerformed(final ActionEvent e) {
227 privateControlForm.setAutoRanges(false);
228 controlForm.updateSamplesMenu();
231 manualBoundsMenuItem = menuItem;
232 setAutomaticBounds(autoBoundsDefault);
234 /* Step Function */
236 class SetStepFunctionPerform implements ActionListener {
237 private int i;
239 SetStepFunctionPerform(final int i) {
240 this.i = i;
243 public void actionPerformed(final ActionEvent e) {
244 ((TrajectoryManager) manager).setOdeStepFunction(i);
248 if (model instanceof ODE) {
250 menu.addSeparator();
252 JMenu stepFuctionMenu = new JMenu("Step function");
253 stepFuctionMenu.setMnemonic(KeyEvent.VK_S);
255 group = new ButtonGroup();
257 int i = 0;
258 do {
259 String name = Lua.getStepFunctionName(i);
260 if (name == null) break;
262 menuItem = new JRadioButtonMenuItem(name);
263 group.add(menuItem);
264 stepFuctionMenu.add(menuItem);
266 menuItem.setToolTipText(Lua.getStepFunctionDescription(i));
268 if (name.equals("rkf45")) {
269 menuItem.setSelected(true);
271 menuItem.addActionListener(new SetStepFunctionPerform(i));
272 i++;
274 } while (true);
275 menu.add(stepFuctionMenu);
276 stateMachine.addNoRunItem(stepFuctionMenu);
279 return menu;
283 protected JToolBar createToolBar() {
284 JToolBar toolBar = new JToolBar();
285 JButton button;
287 button = new JButton(startAction);
288 toolBar.add(button);
290 button = new JButton(stopAction);
291 toolBar.add(button);
293 toolBar.addSeparator();
295 button = new DmcButton(continueAction);
296 toolBar.add(button);
298 button = new DmcButton(redrawAction);
299 toolBar.add(button);
301 toolBar.addSeparator();
303 button = new DmcButton(resetAction);
305 toolBar.add(button);
307 toolBar.addSeparator();
308 toolBar.addSeparator();
310 slider = new JSlider(0, 50, 10);
311 slider.setMajorTickSpacing(10);
312 slider.setMinorTickSpacing(1);
313 slider.setSnapToTicks(true);
314 slider.setPaintTicks(true);
316 slider.addChangeListener(new ChangeListener() {
318 public void stateChanged(final ChangeEvent e) {
319 JSlider s = (JSlider) e.getSource();
320 ((TrajectoryManager) getManager()).setDelay(s.getValue());
323 toolBar.add(slider);
324 slider.setValue(0);
326 return toolBar;
331 * Defaults
333 protected void fillDefaults(final int index) {
334 VariableItems items;
335 VariableItems.Iterator ii;
336 VariableDoubles doubles;
337 VariableDoubles.Iterator di;
339 /* initialization is important: if a key is not present use
340 * the default */
341 double hMin = 1, hMax = -1, vMin = 1, vMax = -1;
342 boolean autoBoundsState = autoBoundsDefault;
344 items = Lua.loadDefaults(model, defaultsSection, index);
346 /* parameters */
347 doubles = new VariableDoubles(model.getParNames());
348 di = doubles.iterator();
349 while (di.hasNext()) {
350 if (items.containsLabel(di.nextLabel())) {
351 double value = Double.parseDouble((String)items.get(di.label()));
352 doubles.put(di.label(), value);
355 privateControlForm.setParameterValues(doubles);
357 /* variables */
358 doubles = new VariableDoubles(model.getVarNames());
359 di = doubles.iterator();
360 while (di.hasNext()) {
361 if (items.containsLabel(di.nextLabel())) {
362 double value =
363 Double.parseDouble((String) items.get(di.label()));
364 doubles.put(di.label(), value);
367 privateControlForm.setInitialValues(doubles);
369 /* other values */
370 ii = items.iterator();
371 while (ii.hasNext()) {
372 String key = ii.nextLabel();
373 String value = (String) items.get(ii.label());
374 double doubleValue;
376 System.out.println("key: " + key + ", value: " + value);
378 if (key.equals(ModelDefaults.ITERATIONS_KEY)) {
379 doubleValue = Double.parseDouble(value);
380 privateControlForm.setIterations((int) doubleValue);
383 else if (key.equals(ModelDefaults.TRANSIENTS_KEY)) {
384 doubleValue = Double.parseDouble(value);
385 privateControlForm.setTransients((int) doubleValue);
388 else if (key.equals(ModelDefaults.SCATTER_AUTOBOUNDS_ITERATIONS_KEY)) {
389 doubleValue = Double.parseDouble(value);
390 privateControlForm.setRangeIterations((int) doubleValue);
393 /* manual bounds */
394 else if (key.equals(ModelDefaults.SCATTER_BOUNDS_KEY)) {
395 if (value.equals(ModelDefaults.SCATTER_BOUNDS_AUTO_VALUE)) {
396 autoBoundsState = true;
398 else if (value.equals(ModelDefaults.SCATTER_BOUNDS_MANUAL_VALUE)) {
399 autoBoundsState = false;
402 else if (key.equals(ModelDefaults.SCATTER_AUTO_BOUNDS_HMIN_KEY)) {
403 hMin = Double.parseDouble(value);
405 else if (key.equals(ModelDefaults.SCATTER_AUTO_BOUNDS_HMAX_KEY)) {
406 hMax = Double.parseDouble(value);
408 else if (key.equals(ModelDefaults.SCATTER_AUTO_BOUNDS_VMIN_KEY)) {
409 vMin = Double.parseDouble(value);
411 else if (key.equals(ModelDefaults.SCATTER_AUTO_BOUNDS_VMAX_KEY)) {
412 vMax = Double.parseDouble(value);
417 /* post processing */
418 setAutomaticBounds(autoBoundsState);
420 Range range = null;
421 try {
422 range = new Range(hMin, hMax);
423 } catch (IllegalArgumentException e) {
424 range = null;
425 } finally {
426 if (range != null) {
427 privateControlForm.setXRange(range);
431 range = null;
432 try {
433 range = new Range(vMin, vMax);
434 } catch (IllegalArgumentException e) {
435 range = null;
436 } finally {
437 if (range != null) {
438 privateControlForm.setYRange(range);
444 // helper
445 private void setAutomaticBounds(final boolean flag) {
446 autoBoundsMenuItem.setSelected(flag);
447 manualBoundsMenuItem.setSelected(!flag);
448 privateControlForm.setAutoRanges(flag);
452 * @return Returns the normalPlotMenuItem.
454 public JMenuItem getNormalPlotMenuItem() {
455 return normalPlotMenuItem;
459 * @return Returns the timePlotMenuItem.
461 public JMenuItem getTimePlotMenuItem() {
462 return timePlotMenuItem;
466 * @return
468 public DmcAction getContinueAction() {
469 return continueAction;
473 * @return
475 public DmcAction getRedrawAction() {
476 return redrawAction;
480 * @return
482 public DmcAction getResetAction() {
483 return resetAction;
487 * @return
489 public Action getStartAction() {
490 return startAction;
494 * @return
496 public Action getStopAction() {
497 return stopAction;
501 * @return
503 public int getDelayValue() {
504 return slider.getValue();
507 public JSlider getSlider() {
508 return slider;
511 public Model getModel() {
512 return model;
515 public void callUponStart() {