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.unit.Unit;
22 import net.sf.openrocket.unit.UnitGroup;
23 import net.sf.openrocket.util.GUIUtil;
24 import net.sf.openrocket.util.Prefs;
26 public class PreferencesDialog extends JDialog {
28 private final List<DefaultUnitSelector> unitSelectors = new ArrayList<DefaultUnitSelector>();
30 private PreferencesDialog() {
31 super((JFrame)null, "Preferences", true);
33 JPanel panel = new JPanel(new MigLayout("fill, gap unrel","[grow]","[grow][]"));
35 JTabbedPane tabbedPane = new JTabbedPane();
36 panel.add(tabbedPane,"grow, wrap");
39 tabbedPane.addTab("Units", null, unitsPane(), "Default units");
40 tabbedPane.addTab("Confirmation", null, confirmationPane(), "Confirmation dialog settings");
44 JButton close = new JButton("Close");
45 close.addActionListener(new ActionListener() {
47 public void actionPerformed(ActionEvent arg0) {
48 PreferencesDialog.this.setVisible(false);
49 PreferencesDialog.this.dispose();
52 panel.add(close,"span, right, tag close");
54 this.setContentPane(panel);
57 this.setLocationRelativeTo(null);
59 this.addWindowListener(new WindowAdapter() {
61 public void windowClosed(WindowEvent e) {
62 Prefs.storeDefaultUnits();
66 GUIUtil.setDefaultButton(close);
67 GUIUtil.installEscapeCloseOperation(this);
71 private JPanel confirmationPane() {
72 JPanel panel = new JPanel(new MigLayout("fill"));
74 panel.add(new JLabel("Position to insert new body components:"));
75 panel.add(new JComboBox(new PrefChoiseSelector(Prefs.BODY_COMPONENT_INSERT_POSITION_KEY,
76 "Always ask", "Insert in middle", "Add to end")), "wrap para, sg combos");
78 panel.add(new JLabel("Confirm deletion of simulations:"));
79 panel.add(new JComboBox(new PrefBooleanSelector(Prefs.CONFIRM_DELETE_SIMULATION,
80 "Delete", "Confirm", true)), "wrap para, sg combos");
85 private JPanel unitsPane() {
86 JPanel panel = new JPanel(new MigLayout("", "[][]40lp[][]"));
89 panel.add(new JLabel("Select your preferred units:"), "span, wrap paragraph");
92 public static final UnitGroup UNITS_LENGTH;
93 public static final UnitGroup UNITS_MOTOR_DIMENSIONS;
94 public static final UnitGroup UNITS_DISTANCE;
96 public static final UnitGroup UNITS_VELOCITY;
97 public static final UnitGroup UNITS_ACCELERATION;
98 public static final UnitGroup UNITS_MASS;
99 public static final UnitGroup UNITS_FORCE;
100 public static final UnitGroup UNITS_IMPULSE;
102 public static final UnitGroup UNITS_STABILITY;
103 public static final UnitGroup UNITS_FLIGHT_TIME;
104 public static final UnitGroup UNITS_ROLL;
106 public static final UnitGroup UNITS_AREA;
107 public static final UnitGroup UNITS_DENSITY_LINE;
108 public static final UnitGroup UNITS_DENSITY_SURFACE;
109 public static final UnitGroup UNITS_DENSITY_BULK;
110 public static final UnitGroup UNITS_ROUGHNESS;
112 public static final UnitGroup UNITS_TEMPERATURE;
113 public static final UnitGroup UNITS_PRESSURE;
114 public static final UnitGroup UNITS_ANGLE;
117 panel.add(new JLabel("Rocket dimensions:"));
118 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_LENGTH));
119 panel.add(combo, "sizegroup boxes");
121 panel.add(new JLabel("Line density:"));
122 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_DENSITY_LINE));
123 panel.add(combo, "sizegroup boxes, wrap");
127 panel.add(new JLabel("Motor dimensions:"));
128 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_MOTOR_DIMENSIONS));
129 panel.add(combo, "sizegroup boxes");
131 panel.add(new JLabel("Surface density:"));
132 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_DENSITY_SURFACE));
133 panel.add(combo, "sizegroup boxes, wrap");
137 panel.add(new JLabel("Distance:"));
138 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_DISTANCE));
139 panel.add(combo, "sizegroup boxes");
141 panel.add(new JLabel("Bulk density::"));
142 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_DENSITY_BULK));
143 panel.add(combo, "sizegroup boxes, wrap");
147 panel.add(new JLabel("Velocity:"));
148 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_VELOCITY));
149 panel.add(combo, "sizegroup boxes");
151 panel.add(new JLabel("Surface roughness:"));
152 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_ROUGHNESS));
153 panel.add(combo, "sizegroup boxes, wrap");
157 panel.add(new JLabel("Acceleration:"));
158 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_ACCELERATION));
159 panel.add(combo, "sizegroup boxes");
161 panel.add(new JLabel("Area:"));
162 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_AREA));
163 panel.add(combo, "sizegroup boxes, wrap");
167 panel.add(new JLabel("Mass:"));
168 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_MASS));
169 panel.add(combo, "sizegroup boxes");
171 panel.add(new JLabel("Angle:"));
172 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_ANGLE));
173 panel.add(combo, "sizegroup boxes, wrap");
177 panel.add(new JLabel("Force:"));
178 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_FORCE));
179 panel.add(combo, "sizegroup boxes");
181 panel.add(new JLabel("Roll rate:"));
182 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_ROLL));
183 panel.add(combo, "sizegroup boxes, wrap");
187 panel.add(new JLabel("Total impulse:"));
188 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_IMPULSE));
189 panel.add(combo, "sizegroup boxes");
191 panel.add(new JLabel("Temperature:"));
192 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_TEMPERATURE));
193 panel.add(combo, "sizegroup boxes, wrap");
197 panel.add(new JLabel("Stability:"));
198 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_STABILITY));
199 panel.add(combo, "sizegroup boxes");
201 panel.add(new JLabel("Pressure:"));
202 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_PRESSURE));
203 panel.add(combo, "sizegroup boxes, wrap para");
207 JButton button = new JButton("Default metric");
208 button.addActionListener(new ActionListener() {
210 public void actionPerformed(ActionEvent e) {
211 UnitGroup.setDefaultMetricUnits();
212 for (DefaultUnitSelector s: unitSelectors)
216 panel.add(button, "spanx, split 2, grow");
218 button = new JButton("Default imperial");
219 button.addActionListener(new ActionListener() {
221 public void actionPerformed(ActionEvent e) {
222 UnitGroup.setDefaultImperialUnits();
223 for (DefaultUnitSelector s: unitSelectors)
227 panel.add(button, "grow, wrap para");
230 panel.add(new ResizeLabel("The effects will take place the next time you open a window.",-2),
240 private class DefaultUnitSelector extends AbstractListModel implements ComboBoxModel {
242 private final UnitGroup group;
243 public DefaultUnitSelector(UnitGroup group) {
245 unitSelectors.add(this);
249 public Object getSelectedItem() {
250 return group.getDefaultUnit();
253 public void setSelectedItem(Object item) {
254 if (!(item instanceof Unit)) {
255 throw new IllegalArgumentException("Illegal argument "+item);
257 group.setDefaultUnit(group.getUnitIndex((Unit)item));
260 public Object getElementAt(int index) {
261 return group.getUnit(index);
264 public int getSize() {
265 return group.getUnitCount();
269 public void fireChange() {
270 this.fireContentsChanged(this, 0, this.getSize());
276 private class PrefChoiseSelector extends AbstractListModel implements ComboBoxModel {
277 private final String preference;
278 private final String[] descriptions;
280 public PrefChoiseSelector(String preference, String ... descriptions) {
281 this.preference = preference;
282 this.descriptions = descriptions;
286 public Object getSelectedItem() {
287 return descriptions[Prefs.getChoise(preference, descriptions.length, 0)];
291 public void setSelectedItem(Object item) {
292 if (!(item instanceof String)) {
293 throw new IllegalArgumentException("Illegal argument "+item);
296 for (index = 0; index < descriptions.length; index++) {
297 if (((String)item).equalsIgnoreCase(descriptions[index]))
300 if (index >= descriptions.length) {
301 throw new IllegalArgumentException("Illegal argument "+item);
304 Prefs.putChoise(preference, index);
308 public Object getElementAt(int index) {
309 return descriptions[index];
312 public int getSize() {
313 return descriptions.length;
318 private class PrefBooleanSelector extends AbstractListModel implements ComboBoxModel {
319 private final String preference;
320 private final String trueDesc, falseDesc;
321 private final boolean def;
323 public PrefBooleanSelector(String preference, String falseDescription,
324 String trueDescription, boolean defaultState) {
325 this.preference = preference;
326 this.trueDesc = trueDescription;
327 this.falseDesc = falseDescription;
328 this.def = defaultState;
332 public Object getSelectedItem() {
333 if (Prefs.NODE.getBoolean(preference, def)) {
341 public void setSelectedItem(Object item) {
342 if (!(item instanceof String)) {
343 throw new IllegalArgumentException("Illegal argument "+item);
346 if (trueDesc.equals(item)) {
347 Prefs.NODE.putBoolean(preference, true);
348 } else if (falseDesc.equals(item)) {
349 Prefs.NODE.putBoolean(preference, false);
351 throw new IllegalArgumentException("Illegal argument "+item);
356 public Object getElementAt(int index) {
359 return def ? trueDesc : falseDesc;
362 return def ? falseDesc: trueDesc;
365 throw new IndexOutOfBoundsException("Boolean asked for index="+index);
369 public int getSize() {
376 //////// Singleton implementation ////////
378 private static PreferencesDialog dialog = null;
380 public static void showPreferences() {
381 if (dialog != null) {
384 dialog = new PreferencesDialog();
385 dialog.setVisible(true);