1 package net.sf.openrocket.gui;
3 import java.awt.event.ActionEvent;
4 import java.awt.event.ActionListener;
5 import java.awt.event.WindowAdapter;
6 import java.awt.event.WindowEvent;
7 import java.util.ArrayList;
10 import javax.swing.AbstractListModel;
11 import javax.swing.ComboBoxModel;
12 import javax.swing.JButton;
13 import javax.swing.JComboBox;
14 import javax.swing.JDialog;
15 import javax.swing.JFrame;
16 import javax.swing.JLabel;
17 import javax.swing.JPanel;
18 import javax.swing.JTabbedPane;
20 import net.miginfocom.swing.MigLayout;
21 import net.sf.openrocket.gui.components.ResizeLabel;
22 import net.sf.openrocket.unit.Unit;
23 import net.sf.openrocket.unit.UnitGroup;
24 import net.sf.openrocket.util.GUIUtil;
25 import net.sf.openrocket.util.Prefs;
27 public class PreferencesDialog extends JDialog {
29 private final List<DefaultUnitSelector> unitSelectors = new ArrayList<DefaultUnitSelector>();
31 private PreferencesDialog() {
32 super((JFrame)null, "Preferences", true);
34 JPanel panel = new JPanel(new MigLayout("fill, gap unrel","[grow]","[grow][]"));
36 JTabbedPane tabbedPane = new JTabbedPane();
37 panel.add(tabbedPane,"grow, wrap");
40 tabbedPane.addTab("Units", null, unitsPane(), "Default units");
41 tabbedPane.addTab("Confirmation", null, confirmationPane(), "Confirmation dialog settings");
45 JButton close = new JButton("Close");
46 close.addActionListener(new ActionListener() {
48 public void actionPerformed(ActionEvent arg0) {
49 PreferencesDialog.this.setVisible(false);
50 PreferencesDialog.this.dispose();
53 panel.add(close,"span, right, tag close");
55 this.setContentPane(panel);
58 this.setLocationRelativeTo(null);
60 this.addWindowListener(new WindowAdapter() {
62 public void windowClosed(WindowEvent e) {
63 Prefs.storeDefaultUnits();
67 GUIUtil.setDefaultButton(close);
68 GUIUtil.installEscapeCloseOperation(this);
72 private JPanel confirmationPane() {
73 JPanel panel = new JPanel(new MigLayout("fill"));
75 panel.add(new JLabel("Position to insert new body components:"));
76 panel.add(new JComboBox(new PrefChoiseSelector(Prefs.BODY_COMPONENT_INSERT_POSITION_KEY,
77 "Always ask", "Insert in middle", "Add to end")), "wrap para, sg combos");
79 panel.add(new JLabel("Confirm deletion of simulations:"));
80 panel.add(new JComboBox(new PrefBooleanSelector(Prefs.CONFIRM_DELETE_SIMULATION,
81 "Delete", "Confirm", true)), "wrap para, sg combos");
86 private JPanel unitsPane() {
87 JPanel panel = new JPanel(new MigLayout("", "[][]40lp[][]"));
90 panel.add(new JLabel("Select your preferred units:"), "span, wrap paragraph");
93 public static final UnitGroup UNITS_LENGTH;
94 public static final UnitGroup UNITS_MOTOR_DIMENSIONS;
95 public static final UnitGroup UNITS_DISTANCE;
97 public static final UnitGroup UNITS_VELOCITY;
98 public static final UnitGroup UNITS_ACCELERATION;
99 public static final UnitGroup UNITS_MASS;
100 public static final UnitGroup UNITS_FORCE;
101 public static final UnitGroup UNITS_IMPULSE;
103 public static final UnitGroup UNITS_STABILITY;
104 public static final UnitGroup UNITS_FLIGHT_TIME;
105 public static final UnitGroup UNITS_ROLL;
107 public static final UnitGroup UNITS_AREA;
108 public static final UnitGroup UNITS_DENSITY_LINE;
109 public static final UnitGroup UNITS_DENSITY_SURFACE;
110 public static final UnitGroup UNITS_DENSITY_BULK;
111 public static final UnitGroup UNITS_ROUGHNESS;
113 public static final UnitGroup UNITS_TEMPERATURE;
114 public static final UnitGroup UNITS_PRESSURE;
115 public static final UnitGroup UNITS_ANGLE;
118 panel.add(new JLabel("Rocket dimensions:"));
119 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_LENGTH));
120 panel.add(combo, "sizegroup boxes");
122 panel.add(new JLabel("Line density:"));
123 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_DENSITY_LINE));
124 panel.add(combo, "sizegroup boxes, wrap");
128 panel.add(new JLabel("Motor dimensions:"));
129 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_MOTOR_DIMENSIONS));
130 panel.add(combo, "sizegroup boxes");
132 panel.add(new JLabel("Surface density:"));
133 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_DENSITY_SURFACE));
134 panel.add(combo, "sizegroup boxes, wrap");
138 panel.add(new JLabel("Distance:"));
139 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_DISTANCE));
140 panel.add(combo, "sizegroup boxes");
142 panel.add(new JLabel("Bulk density::"));
143 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_DENSITY_BULK));
144 panel.add(combo, "sizegroup boxes, wrap");
148 panel.add(new JLabel("Velocity:"));
149 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_VELOCITY));
150 panel.add(combo, "sizegroup boxes");
152 panel.add(new JLabel("Surface roughness:"));
153 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_ROUGHNESS));
154 panel.add(combo, "sizegroup boxes, wrap");
158 panel.add(new JLabel("Acceleration:"));
159 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_ACCELERATION));
160 panel.add(combo, "sizegroup boxes");
162 panel.add(new JLabel("Area:"));
163 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_AREA));
164 panel.add(combo, "sizegroup boxes, wrap");
168 panel.add(new JLabel("Mass:"));
169 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_MASS));
170 panel.add(combo, "sizegroup boxes");
172 panel.add(new JLabel("Angle:"));
173 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_ANGLE));
174 panel.add(combo, "sizegroup boxes, wrap");
178 panel.add(new JLabel("Force:"));
179 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_FORCE));
180 panel.add(combo, "sizegroup boxes");
182 panel.add(new JLabel("Roll rate:"));
183 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_ROLL));
184 panel.add(combo, "sizegroup boxes, wrap");
188 panel.add(new JLabel("Total impulse:"));
189 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_IMPULSE));
190 panel.add(combo, "sizegroup boxes");
192 panel.add(new JLabel("Temperature:"));
193 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_TEMPERATURE));
194 panel.add(combo, "sizegroup boxes, wrap");
198 panel.add(new JLabel("Stability:"));
199 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_STABILITY));
200 panel.add(combo, "sizegroup boxes");
202 panel.add(new JLabel("Pressure:"));
203 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_PRESSURE));
204 panel.add(combo, "sizegroup boxes, wrap para");
208 JButton button = new JButton("Default metric");
209 button.addActionListener(new ActionListener() {
211 public void actionPerformed(ActionEvent e) {
212 UnitGroup.setDefaultMetricUnits();
213 for (DefaultUnitSelector s: unitSelectors)
217 panel.add(button, "spanx, split 2, grow");
219 button = new JButton("Default imperial");
220 button.addActionListener(new ActionListener() {
222 public void actionPerformed(ActionEvent e) {
223 UnitGroup.setDefaultImperialUnits();
224 for (DefaultUnitSelector s: unitSelectors)
228 panel.add(button, "grow, wrap para");
231 panel.add(new ResizeLabel("The effects will take place the next time you open a window.",-2),
241 private class DefaultUnitSelector extends AbstractListModel implements ComboBoxModel {
243 private final UnitGroup group;
244 public DefaultUnitSelector(UnitGroup group) {
246 unitSelectors.add(this);
250 public Object getSelectedItem() {
251 return group.getDefaultUnit();
254 public void setSelectedItem(Object item) {
255 if (!(item instanceof Unit)) {
256 throw new IllegalArgumentException("Illegal argument "+item);
258 group.setDefaultUnit(group.getUnitIndex((Unit)item));
261 public Object getElementAt(int index) {
262 return group.getUnit(index);
265 public int getSize() {
266 return group.getUnitCount();
270 public void fireChange() {
271 this.fireContentsChanged(this, 0, this.getSize());
277 private class PrefChoiseSelector extends AbstractListModel implements ComboBoxModel {
278 private final String preference;
279 private final String[] descriptions;
281 public PrefChoiseSelector(String preference, String ... descriptions) {
282 this.preference = preference;
283 this.descriptions = descriptions;
287 public Object getSelectedItem() {
288 return descriptions[Prefs.getChoise(preference, descriptions.length, 0)];
292 public void setSelectedItem(Object item) {
293 if (!(item instanceof String)) {
294 throw new IllegalArgumentException("Illegal argument "+item);
297 for (index = 0; index < descriptions.length; index++) {
298 if (((String)item).equalsIgnoreCase(descriptions[index]))
301 if (index >= descriptions.length) {
302 throw new IllegalArgumentException("Illegal argument "+item);
305 Prefs.putChoise(preference, index);
309 public Object getElementAt(int index) {
310 return descriptions[index];
313 public int getSize() {
314 return descriptions.length;
319 private class PrefBooleanSelector extends AbstractListModel implements ComboBoxModel {
320 private final String preference;
321 private final String trueDesc, falseDesc;
322 private final boolean def;
324 public PrefBooleanSelector(String preference, String falseDescription,
325 String trueDescription, boolean defaultState) {
326 this.preference = preference;
327 this.trueDesc = trueDescription;
328 this.falseDesc = falseDescription;
329 this.def = defaultState;
333 public Object getSelectedItem() {
334 if (Prefs.NODE.getBoolean(preference, def)) {
342 public void setSelectedItem(Object item) {
343 if (!(item instanceof String)) {
344 throw new IllegalArgumentException("Illegal argument "+item);
347 if (trueDesc.equals(item)) {
348 Prefs.NODE.putBoolean(preference, true);
349 } else if (falseDesc.equals(item)) {
350 Prefs.NODE.putBoolean(preference, false);
352 throw new IllegalArgumentException("Illegal argument "+item);
357 public Object getElementAt(int index) {
360 return def ? trueDesc : falseDesc;
363 return def ? falseDesc: trueDesc;
366 throw new IndexOutOfBoundsException("Boolean asked for index="+index);
370 public int getSize() {
377 //////// Singleton implementation ////////
379 private static PreferencesDialog dialog = null;
381 public static void showPreferences() {
382 if (dialog != null) {
385 dialog = new PreferencesDialog();
386 dialog.setVisible(true);