package net.sf.openrocket.gui.dialogs.preferences;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
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.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 {
/*
* private GeodeticComputationStrategy geodeticComputation =
* GeodeticComputationStrategy.SPHERICAL;
*/
public SimulationPreferencesPanel() {
super(new MigLayout("fill"));
// Confirm deletion of simulations:
final JCheckBox confirmDelete = new JCheckBox(
trans.get("pref.dlg.lbl.Confirmdeletion"));
confirmDelete.setSelected(preferences.getConfirmSimDeletion());
confirmDelete.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
preferences.setAutoRunSimulations(confirmDelete.isSelected());
}
});
this.add(confirmDelete, "wrap, growx, sg combos ");
// Automatically run all simulation out-dated by design changes.
final JCheckBox automaticallyRunSimsBox = new JCheckBox(
trans.get("pref.dlg.checkbox.Runsimulations"));
automaticallyRunSimsBox
.setSelected(preferences.getAutoRunSimulations());
automaticallyRunSimsBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
preferences.setAutoRunSimulations(automaticallyRunSimsBox
.isSelected());
}
});
this.add(automaticallyRunSimsBox, "wrap, growx, sg combos ");
GeodeticComputationStrategy geodeticComputation = GeodeticComputationStrategy.SPHERICAL;
JPanel sub, subsub;
String tip;
JLabel label;
DoubleModel m;
JSpinner spin;
UnitSelector unit;
BasicSlider slider;
// // Simulation options
sub = new JPanel(new MigLayout("fill"));
// // 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", "[grow][min!][min!][]"));
// // 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, span 3, wrap");
// 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, span 3, wrap");
// // 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
public void actionPerformed(ActionEvent e) {
GeodeticComputationStrategy gcs = (GeodeticComputationStrategy) gcsCombo
.getSelectedItem();
gcsCombo.setToolTipText(gcs.getDescription());
}
};
gcsCombo.addActionListener(gcsTTipListener);
gcsTTipListener.actionPerformed(null);
subsub.add(gcsCombo, "span 3, wrap");
// // 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);
subsub.add(label, "gapright para");
m = new DoubleModel(preferences, "TimeStep", UnitGroup.UNITS_TIME_STEP,
0, 1);
spin = new JSpinner(m.getSpinnerModel());
spin.setEditor(new SpinnerEditor(spin));
spin.setToolTipText(tip);
subsub.add(spin, "");
unit = new UnitSelector(m);
unit.setToolTipText(tip);
subsub.add(unit, "");
slider = new BasicSlider(m.getSliderModel(0, 0.2));
slider.setToolTipText(tip);
subsub.add(slider, "w 100");
sub.add(subsub, "spanx, wrap para");
// 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);
}
});
sub.add(button, "align left");
/*
* // // 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()); } }
*/
}