--- /dev/null
+package net.sf.openrocket.gui.preset;
+
+import javax.swing.*;
+import javax.swing.plaf.basic.BasicComboBoxRenderer;
+import java.awt.*;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * A combo box that allows for items to be deselected.
+ */
+public class DeselectableComboBox extends JComboBox {
+
+ public DeselectableComboBox() {
+ super();
+ super.setRenderer(new DeselectedtemsRenderer());
+ }
+
+ private Set disabled_items = new HashSet();
+
+ public void addItem(Object anObject, boolean disabled) {
+ super.addItem(anObject);
+ if (disabled) {
+ disabled_items.add(getItemCount() - 1);
+ }
+ }
+
+ @Override
+ public void removeAllItems() {
+ super.removeAllItems();
+ disabled_items = new HashSet();
+ }
+
+ @Override
+ public void removeItemAt(final int anIndex) {
+ super.removeItemAt(anIndex);
+ disabled_items.remove(anIndex);
+ }
+
+ @Override
+ public void removeItem(final Object anObject) {
+ for (int i = 0; i < getItemCount(); i++) {
+ if (getItemAt(i) == anObject) {
+ disabled_items.remove(i);
+ }
+ }
+ super.removeItem(anObject);
+ }
+
+ @Override
+ public void setSelectedIndex(int index) {
+ if (!disabled_items.contains(index)) {
+ super.setSelectedIndex(index);
+ }
+ }
+
+ private class DeselectedtemsRenderer extends BasicComboBoxRenderer {
+
+ @Override
+ public Component getListCellRendererComponent(JList list,
+ Object value,
+ int index,
+ boolean isSelected,
+ boolean cellHasFocus) {
+
+ if (isSelected) {
+ setBackground(list.getSelectionBackground());
+ setForeground(list.getSelectionForeground());
+ }
+ else {
+ setBackground(list.getBackground());
+ setForeground(list.getForeground());
+ }
+ if (disabled_items.contains(index)) {
+ setBackground(list.getBackground());
+ setForeground(UIManager.getColor("Label.disabledForeground"));
+ }
+ setFont(list.getFont());
+ setText((value == null) ? "" : value.toString());
+ return this;
+ }
+ }
+}
import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.gui.print.PrintUnit;
-import net.sf.openrocket.gui.util.SwingPreferences;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.logging.LogHelper;
import net.sf.openrocket.material.Material;
new PresetInputVerifier(Pattern.compile(NON_NEGATIVE_DECIMAL_FIELD));
private final JPanel contentPanel = new JPanel();
- private JComboBox typeCombo;
+ private DeselectableComboBox typeCombo;
private JTextField mfgTextField;
private JComboBox materialChooser;
private JComboBox massUnitCombo;
lengthMap.put("ft", PrintUnit.FOOT);
}
- /**
- * Launch the application.
- */
- public static void main(String[] args) {
- try {
- Application.setPreferences(new SwingPreferences());
- PresetEditorDialog dialog = new PresetEditorDialog();
- dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
- dialog.setVisible(true);
- }
- catch (Exception e) {
- e.printStackTrace();
- }
- }
-
/**
* Create the dialog.
+ *
+ * @param theCallback the listener that gets the results of editing the presets
*/
- public PresetEditorDialog() {
- this(new PresetResultListener() {
- @Override
- public void notifyResult(final ComponentPreset preset) {
- }
- });
- }
-
public PresetEditorDialog(PresetResultListener theCallback) {
this(theCallback, null);
- typeCombo.setEditable(true);
}
+ /**
+ * Create the dialog.
+ *
+ * @param theCallback the listener that gets the results of editing the presets
+ * @param toEdit the ComponentPreset to be edited; or null if a new one is being added
+ */
public PresetEditorDialog(PresetResultListener theCallback, ComponentPreset toEdit) {
resultListener = theCallback;
getContentPane().setMinimumSize(new Dimension(200, 200));
JLabel typeLabel = new JLabel("Type:");
contentPanel.add(typeLabel, "cell 2 1,alignx left,aligny center");
- typeCombo = new JComboBox();
+ componentOverlayPanel = new JPanel();
+ contentPanel.add(componentOverlayPanel, "cell 1 3 5 2,grow");
+ componentOverlayPanel.setLayout(new CardLayout(0, 0));
+
+ typeCombo = new DeselectableComboBox();
typeCombo.addItemListener(this);
- typeCombo.setModel(new DefaultComboBoxModel(new String[]{
- trans.get(NOSE_CONE_KEY), trans.get(BODY_TUBE_KEY), trans.get(TUBE_COUPLER_KEY), trans.get(TRANSITION_KEY),
- trans.get(CR_KEY), trans.get(BULKHEAD_KEY), trans.get(EB_KEY)}));
+ typeCombo.setModel(new DefaultComboBoxModel());
+ setItems(typeCombo, toEdit);
contentPanel.add(typeCombo, "cell 3 1,growx");
JLabel massUnitLabel = new JLabel("Mass Unit:");
materialChooser = new JComboBox(new MaterialModel(this, Material.Type.BULK));
contentPanel.add(materialChooser, "cell 3 2,growx");
- componentOverlayPanel = new JPanel();
- contentPanel.add(componentOverlayPanel, "cell 1 3 5 2,grow");
- componentOverlayPanel.setLayout(new CardLayout(0, 0));
-
{
JPanel ncPanel = new JPanel();
componentOverlayPanel.add(ncPanel, "NOSECONE");
if (toEdit != null) {
fillEditor(toEdit);
- typeCombo.setEditable(false);
- }
- else {
- typeCombo.setEditable(true);
}
}
+ /**
+ * When an existing preset is edited, we want to disable the other types of presets. If the user wants a different
+ * type of component, then they should delete this one and add a new one.
+ *
+ * @param cb
+ * @param preset
+ */
+ private void setItems(DeselectableComboBox cb, ComponentPreset preset) {
+ cb.addItem(trans.get(NOSE_CONE_KEY), preset == null ? false : !preset.get(ComponentPreset.TYPE).equals(ComponentPreset.Type.NOSE_CONE));
+ cb.addItem(trans.get(BODY_TUBE_KEY), preset == null ? false : !preset.get(ComponentPreset.TYPE).equals(ComponentPreset.Type.BODY_TUBE));
+ cb.addItem(trans.get(TUBE_COUPLER_KEY), preset == null ? false : !preset.get(ComponentPreset.TYPE).equals(ComponentPreset.Type.TUBE_COUPLER));
+ cb.addItem(trans.get(TRANSITION_KEY), preset == null ? false : !preset.get(ComponentPreset.TYPE).equals(ComponentPreset.Type.TRANSITION));
+ cb.addItem(trans.get(CR_KEY), preset == null ? false : !preset.get(ComponentPreset.TYPE).equals(ComponentPreset.Type.CENTERING_RING));
+ cb.addItem(trans.get(BULKHEAD_KEY), preset == null ? false : !preset.get(ComponentPreset.TYPE).equals(ComponentPreset.Type.BULK_HEAD));
+ cb.addItem(trans.get(EB_KEY), preset == null ? false : !preset.get(ComponentPreset.TYPE).equals(ComponentPreset.Type.ENGINE_BLOCK));
+ }
+
+ /**
+ * Create an image chooser. Currently png and jpg are supported.
+ *
+ * @return
+ */
private JFileChooser createImageChooser() {
final JFileChooser chooser = new JFileChooser();
ImagePreviewPanel preview = new ImagePreviewPanel();
* Convert an image to a byte array in png format.
*
* @param originalImage
+ *
* @return
*/
private byte[] imageToByteArray(Image originalImage) {
*/
public boolean verify(JComponent aComponent) {
JTextComponent textComponent = (JTextComponent) aComponent;
- matcher.reset(textComponent.getText());
+ String text = textComponent.getText();
+ boolean munged = false;
+ //Make sure there's a leading number
+ if (text.startsWith(".")) {
+ text = "0" + text;
+ munged = true;
+ }
+ //Make sure there's a trailing number
+ if (text.endsWith(".")) {
+ text = text + "0";
+ munged = true;
+ }
+ //Make sure if it's a decimal format
+ else if (text.length() > 0 && !text.contains(".")) {
+ text = text + ".0";
+ munged = true;
+ }
+
+ if (munged) {
+ textComponent.setInputVerifier(null);
+ textComponent.setText(text);
+ textComponent.setInputVerifier(this);
+ }
+ matcher.reset(text);
return matcher.matches();
}