Finished simulation preferences panel.

This commit is contained in:
Craig Earls 2014-12-24 17:23:32 -08:00
parent 5cc403368e
commit ff2f68962c
4 changed files with 408 additions and 177 deletions

View File

@ -18,60 +18,58 @@ public class DesignPreferencesPanel extends PreferencesPanel {
public DesignPreferencesPanel() { public DesignPreferencesPanel() {
super(new MigLayout("fillx, ins 30lp n n n")); super(new MigLayout("fillx, ins 30lp n n n"));
//// Position to insert new body components:
this.add(new JLabel(trans.get("pref.dlg.lbl.Positiontoinsert")), "gapright para");
this.add(new JComboBox<Object>(new PrefChoiceSelector(Preferences.BODY_COMPONENT_INSERT_POSITION_KEY,
//// Always ask
//// Insert in middle
//// Add to end
trans.get("pref.dlg.PrefChoiseSelector1"),
trans.get("pref.dlg.PrefChoiseSelector2"),
trans.get("pref.dlg.PrefChoiseSelector3"))), "wrap para, growx, sg combos");
//// Font size of information in panel window
this.add(new JLabel(trans.get("pref.dlg.lbl.Rocketinfofontsize")), "gapright para");
this.add(new JComboBox<Object>(new PrefChoiceSelector(Preferences.ROCKET_INFO_FONT_SIZE, // // Position to insert new body components:
//// Small this.add(new JLabel(trans.get("pref.dlg.lbl.Positiontoinsert")),
//// Medium "gapright para");
//// Large this.add(
trans.get("pref.dlg.PrefFontSmall"), new JComboBox<Object>(new PrefChoiceSelector(
trans.get("pref.dlg.PrefFontMedium"), Preferences.BODY_COMPONENT_INSERT_POSITION_KEY,
trans.get("pref.dlg.PrefFontLarge"))), "wrap para, growx, sg combos"); // // Always ask
// // Insert in middle
//// Default Mach number // // Add to end
trans.get("pref.dlg.PrefChoiseSelector1"), trans
.get("pref.dlg.PrefChoiseSelector2"), trans
.get("pref.dlg.PrefChoiseSelector3"))),
"wrap para, growx, sg combos");
// // Default Mach number
JLabel dfn = new JLabel(trans.get("pref.dlg.lbl.DefaultMach")); JLabel dfn = new JLabel(trans.get("pref.dlg.lbl.DefaultMach"));
this.add(dfn, "gapright para"); this.add(dfn, "gapright para");
dfn.setToolTipText(trans.get("pref.dlg.ttip.DefaultMach1")+ dfn.setToolTipText(trans.get("pref.dlg.ttip.DefaultMach1")
trans.get("pref.dlg.ttip.DefaultMach2")); + trans.get("pref.dlg.ttip.DefaultMach2"));
DoubleModel m = new DoubleModel(preferences, "DefaultMach", 1.0,
UnitGroup.UNITS_COEFFICIENT, 0.1, 0.9);
DoubleModel m = new DoubleModel(preferences, "DefaultMach", 1.0, UnitGroup.UNITS_COEFFICIENT, 0.1, 0.9);
JSpinner spin = new JSpinner(m.getSpinnerModel()); JSpinner spin = new JSpinner(m.getSpinnerModel());
spin.setEditor(new SpinnerEditor(spin)); spin.setEditor(new SpinnerEditor(spin));
spin.setToolTipText(trans.get("pref.dlg.ttip.DefaultMach1")+ spin.setToolTipText(trans.get("pref.dlg.ttip.DefaultMach1")
trans.get("pref.dlg.ttip.DefaultMach2")); + trans.get("pref.dlg.ttip.DefaultMach2"));
this.add(spin, "wrap"); this.add(spin, "wrap");
final JCheckBox autoOpenDesignFile = new JCheckBox(trans.get("pref.dlg.but.openlast")); final JCheckBox autoOpenDesignFile = new JCheckBox(
autoOpenDesignFile.setSelected(preferences.isAutoOpenLastDesignOnStartupEnabled()); trans.get("pref.dlg.but.openlast"));
autoOpenDesignFile.setSelected(preferences
.isAutoOpenLastDesignOnStartupEnabled());
autoOpenDesignFile.addActionListener(new ActionListener() { autoOpenDesignFile.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
preferences.setAutoOpenLastDesignOnStartup(autoOpenDesignFile.isSelected()); preferences.setAutoOpenLastDesignOnStartup(autoOpenDesignFile
.isSelected());
} }
}); });
this.add(autoOpenDesignFile, "wrap, growx, span 2"); this.add(autoOpenDesignFile, "wrap, growx, span 2");
//// Update flight estimates in the design window // // Update flight estimates in the design window
final JCheckBox updateEstimates = final JCheckBox updateEstimates = new JCheckBox(
new JCheckBox(trans.get("pref.dlg.checkbox.Updateestimates")); trans.get("pref.dlg.checkbox.Updateestimates"));
updateEstimates.setSelected(preferences.computeFlightInBackground()); updateEstimates.setSelected(preferences.computeFlightInBackground());
updateEstimates.addActionListener(new ActionListener() { updateEstimates.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
preferences.setComputeFlightInBackground(updateEstimates.isSelected()); preferences.setComputeFlightInBackground(updateEstimates
.isSelected());
} }
}); });
this.add(updateEstimates, "wrap, growx, sg combos "); this.add(updateEstimates, "wrap, growx, sg combos ");

View File

@ -3,16 +3,33 @@
*/ */
package net.sf.openrocket.gui.dialogs.preferences; package net.sf.openrocket.gui.dialogs.preferences;
import javax.swing.JPanel; import javax.swing.JComboBox;
import javax.swing.JLabel;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.startup.Preferences;
/** /**
* @author cpearls * @author cpearls
* *
*/ */
public class DisplayPreferencesPanel extends PreferencesPanel { public class DisplayPreferencesPanel extends PreferencesPanel {
public DisplayPreferencesPanel(){ public DisplayPreferencesPanel() {
super(new MigLayout("fillx")); super(new MigLayout("fillx"));
// // Font size of information in panel window
this.add(new JLabel(trans.get("pref.dlg.lbl.Rocketinfofontsize")),
"gapright para");
this.add(
new JComboBox<Object>(new PrefChoiceSelector(
Preferences.ROCKET_INFO_FONT_SIZE,
// // Small
// // Medium
// // Large
trans.get("pref.dlg.PrefFontSmall"), trans
.get("pref.dlg.PrefFontMedium"), trans
.get("pref.dlg.PrefFontLarge"))),
"wrap para, growx, sg combos");
} }
} }

View File

@ -1,28 +1,36 @@
package net.sf.openrocket.gui.dialogs.preferences; package net.sf.openrocket.gui.dialogs.preferences;
import java.awt.Component;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox; import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.ListCellRenderer;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.gui.SpinnerEditor;
import net.sf.openrocket.gui.adaptors.DoubleModel;
import net.sf.openrocket.gui.adaptors.EnumModel;
import net.sf.openrocket.gui.components.BasicSlider;
import net.sf.openrocket.gui.components.UnitSelector;
import net.sf.openrocket.gui.util.Icons;
import net.sf.openrocket.simulation.RK4SimulationStepper;
import net.sf.openrocket.simulation.listeners.SimulationListener;
import net.sf.openrocket.unit.UnitGroup;
import net.sf.openrocket.util.GeodeticComputationStrategy;
public class SimulationPreferencesPanel extends PreferencesPanel { public class SimulationPreferencesPanel extends PreferencesPanel {
/* /*
* private double launchRodLength = 1; * private GeodeticComputationStrategy geodeticComputation =
* * GeodeticComputationStrategy.SPHERICAL;
* private boolean launchIntoWind = true; private double launchRodAngle = 0;
*
* private double windDirection = Math.PI / 2; private double
* launchRodDirection = 0;
*
*
* private double windAverage = 2.0; private double windTurbulence = 0.1;
*
* private double launchAltitude = 0; private double launchLatitude = 45;
* private double launchLongitude = 0; private GeodeticComputationStrategy
* geodeticComputation = GeodeticComputationStrategy.SPHERICAL;
*/ */
public SimulationPreferencesPanel() { public SimulationPreferencesPanel() {
@ -54,32 +62,233 @@ public class SimulationPreferencesPanel extends PreferencesPanel {
}); });
this.add(automaticallyRunSimsBox, "wrap, growx, sg combos "); this.add(automaticallyRunSimsBox, "wrap, growx, sg combos ");
// private double launchRodLength = 1; GeodeticComputationStrategy geodeticComputation = GeodeticComputationStrategy.SPHERICAL;
// Keep launch rod aligned with the wind JPanel sub, subsub;
final JCheckBox launchIntoWind = new JCheckBox( String tip;
trans.get("simedtdlg.checkbox.Intowind")); JLabel label;
launchIntoWind.setSelected(preferences.getLaunchIntoWind()); DoubleModel m;
launchIntoWind.addActionListener(new ActionListener() { JSpinner spin;
UnitSelector unit;
BasicSlider slider;
// // Simulation options
sub = new JPanel(new MigLayout("fill, gap rel unrel",
"[grow][65lp!][30lp!][75lp!]", ""));
// // Simulator options
sub.setBorder(BorderFactory.createTitledBorder(trans
.get("simedtdlg.border.Simopt")));
this.add(sub, "growx, growy, aligny 0");
// Separate panel for computation methods, as they use a different
// layout
subsub = new JPanel(new MigLayout("insets 0, fill"));
// // Calculation method:
tip = trans.get("simedtdlg.lbl.ttip.Calcmethod");
label = new JLabel(trans.get("simedtdlg.lbl.Calcmethod"));
label.setToolTipText(tip);
subsub.add(label, "gapright para");
// // Extended Barrowman
label = new JLabel(trans.get("simedtdlg.lbl.ExtBarrowman"));
label.setToolTipText(tip);
subsub.add(label, "growx, wrap para");
// Simulation method
tip = trans.get("simedtdlg.lbl.ttip.Simmethod1")
+ trans.get("simedtdlg.lbl.ttip.Simmethod2");
label = new JLabel(trans.get("simedtdlg.lbl.Simmethod"));
label.setToolTipText(tip);
subsub.add(label, "gapright para");
label = new JLabel("6-DOF Runge-Kutta 4");
label.setToolTipText(tip);
subsub.add(label, "growx, wrap para");
// // Geodetic calculation method:
label = new JLabel(trans.get("simedtdlg.lbl.GeodeticMethod"));
label.setToolTipText(trans.get("simedtdlg.lbl.ttip.GeodeticMethodTip"));
subsub.add(label, "gapright para");
EnumModel<GeodeticComputationStrategy> gcsModel = new EnumModel<GeodeticComputationStrategy>(
preferences, "GeodeticComputation");
final JComboBox gcsCombo = new JComboBox(gcsModel);
ActionListener gcsTTipListener = new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
preferences.setLaunchIntoWind(launchIntoWind.isSelected()); GeodeticComputationStrategy gcs = (GeodeticComputationStrategy) gcsCombo
.getSelectedItem();
gcsCombo.setToolTipText(gcs.getDescription());
}
};
gcsCombo.addActionListener(gcsTTipListener);
gcsTTipListener.actionPerformed(null);
subsub.add(gcsCombo, "growx, wrap para");
sub.add(subsub, "spanx, wrap para");
// // Time step:
label = new JLabel(trans.get("simedtdlg.lbl.Timestep"));
tip = trans.get("simedtdlg.lbl.ttip.Timestep1")
+ trans.get("simedtdlg.lbl.ttip.Timestep2")
+ " "
+ UnitGroup.UNITS_TIME_STEP
.toStringUnit(RK4SimulationStepper.RECOMMENDED_TIME_STEP)
+ ".";
label.setToolTipText(tip);
sub.add(label);
m = new DoubleModel(preferences, "TimeStep", UnitGroup.UNITS_TIME_STEP,
0, 1);
spin = new JSpinner(m.getSpinnerModel());
spin.setEditor(new SpinnerEditor(spin));
spin.setToolTipText(tip);
sub.add(spin, "w 65lp!");
// sub.add(spin, "nogrid");
unit = new UnitSelector(m);
unit.setToolTipText(tip);
sub.add(unit, "w 25");
// sub.add(unit, "nogrid");
slider = new BasicSlider(m.getSliderModel(0, 0.2));
slider.setToolTipText(tip);
sub.add(slider, "w 75lp, wrap");
// sub.add(slider,"wrap");
// // Reset to default button
JButton button = new JButton(trans.get("simedtdlg.but.resettodefault"));
// // Reset the time step to its default value (
button.setToolTipText(trans.get("simedtdlg.but.ttip.resettodefault")
+ UnitGroup.UNITS_SHORT_TIME
.toStringUnit(RK4SimulationStepper.RECOMMENDED_TIME_STEP)
+ ").");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
preferences
.setTimeStep(RK4SimulationStepper.RECOMMENDED_TIME_STEP);
preferences
.setGeodeticComputation(GeodeticComputationStrategy.SPHERICAL);
} }
}); });
this.add(launchIntoWind, "wrap, growx, sg combos ");
// private double launchRodAngle = 0; sub.add(button, "align left");
// launchRodDirection = 0;
// private double windDirection = Math.PI / 2; private double
// private double windAverage = 2.0;
// private double windTurbulence = 0.1;
// private double launchAltitude = 0;
// private double launchLatitude = 45;
// private double launchLongitude = 0;
// private GeodeticComputationStrategy
// geodeticComputation = GeodeticComputationStrategy.SPHERICAL;
/*
* // // Simulation listeners sub = new JPanel(new
* MigLayout("fill, gap 0 0")); // // Simulator listeners
* sub.setBorder(BorderFactory.createTitledBorder(trans
* .get("simedtdlg.border.Simlist"))); this.add(sub, "growx, growy");
*
* DescriptionArea desc = new DescriptionArea(5); // //
* <html><i>Simulation listeners</i> is an advanced feature that //
* allows user-written code to listen to and interact with the //
* simulation. // // For details on writing simulation listeners, see
* the OpenRocket // technical documentation.
* desc.setText(trans.get("simedtdlg.txt.longA1") +
* trans.get("simedtdlg.txt.longA2")); sub.add(desc,
* "aligny 0, growx, wrap para");
*
* // // Current listeners: label = new
* JLabel(trans.get("simedtdlg.lbl.Curlist")); sub.add(label,
* "spanx, wrap rel");
*
* final ListenerListModel listenerModel = new ListenerListModel();
* final JList list = new JList(listenerModel); list.setCellRenderer(new
* ListenerCellRenderer()); JScrollPane scroll = new JScrollPane(list);
* // scroll.setPreferredSize(new Dimension(1,1)); sub.add(scroll,
* "height 1px, grow, wrap rel");
*
* // // Add button button = new
* JButton(trans.get("simedtdlg.but.add")); button.addActionListener(new
* ActionListener() {
*
* @Override public void actionPerformed(ActionEvent e) { String
* previous = Application.getPreferences().getString(
* "previousListenerName", ""); String input = (String)
* JOptionPane.showInputDialog(
* SwingUtilities.getRoot(SimulationPreferencesPanel.this), new Object[]
* { // // Type the full Java class name of the // simulation listener,
* for example:
* "Type the full Java class name of the simulation listener, for example:"
* , "<html><tt>" + CSVSaveListener.class.getName() + "</tt>" }, // //
* Add simulation listener trans.get("simedtdlg.lbl.Addsimlist"),
* JOptionPane.QUESTION_MESSAGE, null, null, previous); if (input ==
* null || input.equals("")) return;
*
* Application.getPreferences().putString("previousListenerName",
* input); // preferences.getSimulationListeners().add(input);
* listenerModel.fireContentsChanged(); } }); sub.add(button,
* "split 2, sizegroup buttons, alignx 50%, gapright para");
*
* // // Remove button button = new
* JButton(trans.get("simedtdlg.but.remove"));
* button.addActionListener(new ActionListener() {
*
* @Override public void actionPerformed(ActionEvent e) { int[] selected
* = list.getSelectedIndices(); Arrays.sort(selected); for (int i =
* selected.length - 1; i >= 0; i--) { //
* simulation.getSimulationListeners().remove(selected[i]); }
* listenerModel.fireContentsChanged(); } }); sub.add(button,
* "sizegroup buttons, alignx 50%");
*/
} }
private class ListenerCellRenderer extends JLabel implements
ListCellRenderer {
@Override
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {
String s = value.toString();
setText(s);
// Attempt instantiating, catch any exceptions
Exception ex = null;
try {
Class<?> c = Class.forName(s);
@SuppressWarnings("unused")
SimulationListener l = (SimulationListener) c.newInstance();
} catch (Exception e) {
ex = e;
}
if (ex == null) {
setIcon(Icons.SIMULATION_LISTENER_OK);
// // Listener instantiated successfully.
setToolTipText("Listener instantiated successfully.");
} else {
setIcon(Icons.SIMULATION_LISTENER_ERROR);
// // <html>Unable to instantiate listener due to exception:<br>
setToolTipText("<html>Unable to instantiate listener due to exception:<br>"
+ ex.toString());
}
if (isSelected) {
setBackground(list.getSelectionBackground());
setForeground(list.getSelectionForeground());
} else {
setBackground(list.getBackground());
setForeground(list.getForeground());
}
setOpaque(true);
return this;
}
}
/*
* private class ListenerListModel extends AbstractListModel {
*
* @Override public String getElementAt(int index) { if (index < 0 || index
* >= getSize()) return null; return
* simulation.getSimulationListeners().get(index); }
*
* @Override public int getSize() { return
* simulation.getSimulationListeners().size(); }
*
* public void fireContentsChanged() { super.fireContentsChanged(this, 0,
* getSize()); } }
*/
} }

View File

@ -33,21 +33,22 @@ import net.sf.openrocket.simulation.SimulationOptions;
import net.sf.openrocket.simulation.listeners.SimulationListener; import net.sf.openrocket.simulation.listeners.SimulationListener;
import net.sf.openrocket.simulation.listeners.example.CSVSaveListener; import net.sf.openrocket.simulation.listeners.example.CSVSaveListener;
import net.sf.openrocket.startup.Application; import net.sf.openrocket.startup.Application;
import net.sf.openrocket.startup.Preferences;
import net.sf.openrocket.unit.UnitGroup; import net.sf.openrocket.unit.UnitGroup;
import net.sf.openrocket.util.GeodeticComputationStrategy; import net.sf.openrocket.util.GeodeticComputationStrategy;
class SimulationOptionsPanel extends JPanel { class SimulationOptionsPanel extends JPanel {
private static final Translator trans = Application.getTranslator(); private static final Translator trans = Application.getTranslator();
final Simulation simulation; final Simulation simulation;
SimulationOptionsPanel(final Simulation simulation) { SimulationOptionsPanel(final Simulation simulation) {
super(new MigLayout("fill")); super(new MigLayout("fill"));
this.simulation = simulation; this.simulation = simulation;
final SimulationOptions conditions = simulation.getOptions(); final SimulationOptions conditions = simulation.getOptions();
JPanel sub, subsub; JPanel sub, subsub;
String tip; String tip;
JLabel label; JLabel label;
@ -55,166 +56,172 @@ class SimulationOptionsPanel extends JPanel {
JSpinner spin; JSpinner spin;
UnitSelector unit; UnitSelector unit;
BasicSlider slider; BasicSlider slider;
// // Simulation options
//// Simulation options
sub = new JPanel(new MigLayout("fill, gap rel unrel", sub = new JPanel(new MigLayout("fill, gap rel unrel",
"[grow][65lp!][30lp!][75lp!]", "")); "[grow][65lp!][30lp!][75lp!]", ""));
//// Simulator options // // Simulator options
sub.setBorder(BorderFactory.createTitledBorder(trans.get("simedtdlg.border.Simopt"))); sub.setBorder(BorderFactory.createTitledBorder(trans
.get("simedtdlg.border.Simopt")));
this.add(sub, "growx, growy, aligny 0"); this.add(sub, "growx, growy, aligny 0");
// Separate panel for computation methods, as they use a different
// Separate panel for computation methods, as they use a different layout // layout
subsub = new JPanel(new MigLayout("insets 0, fill")); subsub = new JPanel(new MigLayout("insets 0, fill"));
// // Calculation method:
//// Calculation method:
tip = trans.get("simedtdlg.lbl.ttip.Calcmethod"); tip = trans.get("simedtdlg.lbl.ttip.Calcmethod");
label = new JLabel(trans.get("simedtdlg.lbl.Calcmethod")); label = new JLabel(trans.get("simedtdlg.lbl.Calcmethod"));
label.setToolTipText(tip); label.setToolTipText(tip);
subsub.add(label, "gapright para"); subsub.add(label, "gapright para");
//// Extended Barrowman // // Extended Barrowman
label = new JLabel(trans.get("simedtdlg.lbl.ExtBarrowman")); label = new JLabel(trans.get("simedtdlg.lbl.ExtBarrowman"));
label.setToolTipText(tip); label.setToolTipText(tip);
subsub.add(label, "growx, wrap para"); subsub.add(label, "growx, wrap para");
// Simulation method
// Simulation method tip = trans.get("simedtdlg.lbl.ttip.Simmethod1")
tip = trans.get("simedtdlg.lbl.ttip.Simmethod1") + + trans.get("simedtdlg.lbl.ttip.Simmethod2");
trans.get("simedtdlg.lbl.ttip.Simmethod2");
label = new JLabel(trans.get("simedtdlg.lbl.Simmethod")); label = new JLabel(trans.get("simedtdlg.lbl.Simmethod"));
label.setToolTipText(tip); label.setToolTipText(tip);
subsub.add(label, "gapright para"); subsub.add(label, "gapright para");
label = new JLabel("6-DOF Runge-Kutta 4"); label = new JLabel("6-DOF Runge-Kutta 4");
label.setToolTipText(tip); label.setToolTipText(tip);
subsub.add(label, "growx, wrap para"); subsub.add(label, "growx, wrap para");
// // Geodetic calculation method:
//// Geodetic calculation method:
label = new JLabel(trans.get("simedtdlg.lbl.GeodeticMethod")); label = new JLabel(trans.get("simedtdlg.lbl.GeodeticMethod"));
label.setToolTipText(trans.get("simedtdlg.lbl.ttip.GeodeticMethodTip")); label.setToolTipText(trans.get("simedtdlg.lbl.ttip.GeodeticMethodTip"));
subsub.add(label, "gapright para"); subsub.add(label, "gapright para");
EnumModel<GeodeticComputationStrategy> gcsModel = new EnumModel<GeodeticComputationStrategy>(conditions, "GeodeticComputation"); EnumModel<GeodeticComputationStrategy> gcsModel = new EnumModel<GeodeticComputationStrategy>(
conditions, "GeodeticComputation");
final JComboBox gcsCombo = new JComboBox(gcsModel); final JComboBox gcsCombo = new JComboBox(gcsModel);
ActionListener gcsTTipListener = new ActionListener() { ActionListener gcsTTipListener = new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
GeodeticComputationStrategy gcs = (GeodeticComputationStrategy) gcsCombo.getSelectedItem(); GeodeticComputationStrategy gcs = (GeodeticComputationStrategy) gcsCombo
.getSelectedItem();
gcsCombo.setToolTipText(gcs.getDescription()); gcsCombo.setToolTipText(gcs.getDescription());
} }
}; };
gcsCombo.addActionListener(gcsTTipListener); gcsCombo.addActionListener(gcsTTipListener);
gcsTTipListener.actionPerformed(null); gcsTTipListener.actionPerformed(null);
subsub.add(gcsCombo, "growx, wrap para"); subsub.add(gcsCombo, "growx, wrap para");
sub.add(subsub, "spanx, wrap para"); sub.add(subsub, "spanx, wrap para");
// // Time step:
//// Time step:
label = new JLabel(trans.get("simedtdlg.lbl.Timestep")); label = new JLabel(trans.get("simedtdlg.lbl.Timestep"));
tip = trans.get("simedtdlg.lbl.ttip.Timestep1") + tip = trans.get("simedtdlg.lbl.ttip.Timestep1")
trans.get("simedtdlg.lbl.ttip.Timestep2") + " " + + trans.get("simedtdlg.lbl.ttip.Timestep2")
UnitGroup.UNITS_TIME_STEP.toStringUnit(RK4SimulationStepper.RECOMMENDED_TIME_STEP) + + " "
"."; + UnitGroup.UNITS_TIME_STEP
.toStringUnit(RK4SimulationStepper.RECOMMENDED_TIME_STEP)
+ ".";
label.setToolTipText(tip); label.setToolTipText(tip);
sub.add(label); sub.add(label);
m = new DoubleModel(conditions, "TimeStep", UnitGroup.UNITS_TIME_STEP, 0, 1); m = new DoubleModel(conditions, "TimeStep", UnitGroup.UNITS_TIME_STEP,
0, 1);
spin = new JSpinner(m.getSpinnerModel()); spin = new JSpinner(m.getSpinnerModel());
spin.setEditor(new SpinnerEditor(spin)); spin.setEditor(new SpinnerEditor(spin));
spin.setToolTipText(tip); spin.setToolTipText(tip);
sub.add(spin, "w 65lp!"); sub.add(spin, "w 65lp!");
//sub.add(spin, "nogrid"); // sub.add(spin, "nogrid");
unit = new UnitSelector(m); unit = new UnitSelector(m);
unit.setToolTipText(tip); unit.setToolTipText(tip);
sub.add(unit, "w 25"); sub.add(unit, "w 25");
//sub.add(unit, "nogrid"); // sub.add(unit, "nogrid");
slider = new BasicSlider(m.getSliderModel(0, 0.2)); slider = new BasicSlider(m.getSliderModel(0, 0.2));
slider.setToolTipText(tip); slider.setToolTipText(tip);
sub.add(slider, "w 75lp, wrap"); sub.add(slider, "w 75lp, wrap");
//sub.add(slider,"wrap"); // sub.add(slider,"wrap");
// // Reset to default button
//// Reset to default button
JButton button = new JButton(trans.get("simedtdlg.but.resettodefault")); JButton button = new JButton(trans.get("simedtdlg.but.resettodefault"));
//// Reset the time step to its default value ( // // Reset the time step to its default value (
button.setToolTipText(trans.get("simedtdlg.but.ttip.resettodefault") + button.setToolTipText(trans.get("simedtdlg.but.ttip.resettodefault")
UnitGroup.UNITS_SHORT_TIME.toStringUnit(RK4SimulationStepper.RECOMMENDED_TIME_STEP) + + UnitGroup.UNITS_SHORT_TIME
")."); .toStringUnit(RK4SimulationStepper.RECOMMENDED_TIME_STEP)
+ ").");
button.addActionListener(new ActionListener() { button.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
conditions.setTimeStep(RK4SimulationStepper.RECOMMENDED_TIME_STEP); Preferences preferences = Application.getPreferences();
conditions.setGeodeticComputation(GeodeticComputationStrategy.SPHERICAL); conditions.setTimeStep(preferences.getDouble(
Preferences.SIMULATION_TIME_STEP,
RK4SimulationStepper.RECOMMENDED_TIME_STEP));
conditions.setGeodeticComputation(preferences.getEnum(
Preferences.GEODETIC_COMPUTATION,
GeodeticComputationStrategy.SPHERICAL));
} }
}); });
sub.add(button, "align left"); sub.add(button, "align left");
// // Simulation listeners
//// Simulation listeners
sub = new JPanel(new MigLayout("fill, gap 0 0")); sub = new JPanel(new MigLayout("fill, gap 0 0"));
//// Simulator listeners // // Simulator listeners
sub.setBorder(BorderFactory.createTitledBorder(trans.get("simedtdlg.border.Simlist"))); sub.setBorder(BorderFactory.createTitledBorder(trans
.get("simedtdlg.border.Simlist")));
this.add(sub, "growx, growy"); this.add(sub, "growx, growy");
DescriptionArea desc = new DescriptionArea(5); DescriptionArea desc = new DescriptionArea(5);
//// <html><i>Simulation listeners</i> is an advanced feature that allows user-written code to listen to and interact with the simulation. // // <html><i>Simulation listeners</i> is an advanced feature that
//// For details on writing simulation listeners, see the OpenRocket technical documentation. // allows user-written code to listen to and interact with the
desc.setText(trans.get("simedtdlg.txt.longA1") + // simulation.
trans.get("simedtdlg.txt.longA2")); // // For details on writing simulation listeners, see the OpenRocket
// technical documentation.
desc.setText(trans.get("simedtdlg.txt.longA1")
+ trans.get("simedtdlg.txt.longA2"));
sub.add(desc, "aligny 0, growx, wrap para"); sub.add(desc, "aligny 0, growx, wrap para");
//// Current listeners: // // Current listeners:
label = new JLabel(trans.get("simedtdlg.lbl.Curlist")); label = new JLabel(trans.get("simedtdlg.lbl.Curlist"));
sub.add(label, "spanx, wrap rel"); sub.add(label, "spanx, wrap rel");
final ListenerListModel listenerModel = new ListenerListModel(); final ListenerListModel listenerModel = new ListenerListModel();
final JList list = new JList(listenerModel); final JList list = new JList(listenerModel);
list.setCellRenderer(new ListenerCellRenderer()); list.setCellRenderer(new ListenerCellRenderer());
JScrollPane scroll = new JScrollPane(list); JScrollPane scroll = new JScrollPane(list);
// scroll.setPreferredSize(new Dimension(1,1)); // scroll.setPreferredSize(new Dimension(1,1));
sub.add(scroll, "height 1px, grow, wrap rel"); sub.add(scroll, "height 1px, grow, wrap rel");
//// Add button // // Add button
button = new JButton(trans.get("simedtdlg.but.add")); button = new JButton(trans.get("simedtdlg.but.add"));
button.addActionListener(new ActionListener() { button.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
String previous = Application.getPreferences().getString("previousListenerName", ""); String previous = Application.getPreferences().getString(
String input = (String) JOptionPane.showInputDialog(SwingUtilities.getRoot(SimulationOptionsPanel.this), "previousListenerName", "");
String input = (String) JOptionPane.showInputDialog(
SwingUtilities.getRoot(SimulationOptionsPanel.this),
new Object[] { new Object[] {
//// Type the full Java class name of the simulation listener, for example: // // Type the full Java class name of the
// simulation listener, for example:
"Type the full Java class name of the simulation listener, for example:", "Type the full Java class name of the simulation listener, for example:",
"<html><tt>" + CSVSaveListener.class.getName() + "</tt>" }, "<html><tt>" + CSVSaveListener.class.getName()
//// Add simulation listener + "</tt>" },
// // Add simulation listener
trans.get("simedtdlg.lbl.Addsimlist"), trans.get("simedtdlg.lbl.Addsimlist"),
JOptionPane.QUESTION_MESSAGE, JOptionPane.QUESTION_MESSAGE, null, null, previous);
null, null,
previous
);
if (input == null || input.equals("")) if (input == null || input.equals(""))
return; return;
Application.getPreferences().putString("previousListenerName", input); Application.getPreferences().putString("previousListenerName",
input);
simulation.getSimulationListeners().add(input); simulation.getSimulationListeners().add(input);
listenerModel.fireContentsChanged(); listenerModel.fireContentsChanged();
} }
}); });
sub.add(button, "split 2, sizegroup buttons, alignx 50%, gapright para"); sub.add(button, "split 2, sizegroup buttons, alignx 50%, gapright para");
//// Remove button // // Remove button
button = new JButton(trans.get("simedtdlg.but.remove")); button = new JButton(trans.get("simedtdlg.but.remove"));
button.addActionListener(new ActionListener() { button.addActionListener(new ActionListener() {
@Override @Override
@ -228,18 +235,18 @@ class SimulationOptionsPanel extends JPanel {
} }
}); });
sub.add(button, "sizegroup buttons, alignx 50%"); sub.add(button, "sizegroup buttons, alignx 50%");
} }
private class ListenerCellRenderer extends JLabel implements ListCellRenderer { private class ListenerCellRenderer extends JLabel implements
ListCellRenderer {
@Override @Override
public Component getListCellRendererComponent(JList list, Object value, public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus) { int index, boolean isSelected, boolean cellHasFocus) {
String s = value.toString(); String s = value.toString();
setText(s); setText(s);
// Attempt instantiating, catch any exceptions // Attempt instantiating, catch any exceptions
Exception ex = null; Exception ex = null;
try { try {
@ -249,18 +256,18 @@ class SimulationOptionsPanel extends JPanel {
} catch (Exception e) { } catch (Exception e) {
ex = e; ex = e;
} }
if (ex == null) { if (ex == null) {
setIcon(Icons.SIMULATION_LISTENER_OK); setIcon(Icons.SIMULATION_LISTENER_OK);
//// Listener instantiated successfully. // // Listener instantiated successfully.
setToolTipText("Listener instantiated successfully."); setToolTipText("Listener instantiated successfully.");
} else { } else {
setIcon(Icons.SIMULATION_LISTENER_ERROR); setIcon(Icons.SIMULATION_LISTENER_ERROR);
//// <html>Unable to instantiate listener due to exception:<br> // // <html>Unable to instantiate listener due to exception:<br>
setToolTipText("<html>Unable to instantiate listener due to exception:<br>" + setToolTipText("<html>Unable to instantiate listener due to exception:<br>"
ex.toString()); + ex.toString());
} }
if (isSelected) { if (isSelected) {
setBackground(list.getSelectionBackground()); setBackground(list.getSelectionBackground());
setForeground(list.getSelectionForeground()); setForeground(list.getSelectionForeground());
@ -272,7 +279,7 @@ class SimulationOptionsPanel extends JPanel {
return this; return this;
} }
} }
private class ListenerListModel extends AbstractListModel { private class ListenerListModel extends AbstractListModel {
@Override @Override
public String getElementAt(int index) { public String getElementAt(int index) {
@ -280,15 +287,15 @@ class SimulationOptionsPanel extends JPanel {
return null; return null;
return simulation.getSimulationListeners().get(index); return simulation.getSimulationListeners().get(index);
} }
@Override @Override
public int getSize() { public int getSize() {
return simulation.getSimulationListeners().size(); return simulation.getSimulationListeners().size();
} }
public void fireContentsChanged() { public void fireContentsChanged() {
super.fireContentsChanged(this, 0, getSize()); super.fireContentsChanged(this, 0, getSize());
} }
} }
} }