From 232b36371296951cd3da8a6081578cb03e4f95f0 Mon Sep 17 00:00:00 2001 From: Billy Olsen Date: Sun, 1 Mar 2020 18:21:33 -0700 Subject: [PATCH 1/4] Fix large rail button default size. The default values assigned to RailButton sizes were configured with a 1.0 meter outer diameter and 0.8 meter internal diameter (for 1010 rail buttons) which resulted in overly large rail buttons when added using the default values. Presuming that 1010 rail buttons are the common and an acceptable default, change the default button sizes to align with the 1010 size. Additionally, this change fixes some of the layout issues present in add railbutton dialog. Closes #554 Signed-off-by: Billy Olsen --- core/resources/l10n/messages.properties | 2 ++ .../rocketcomponent/RailButton.java | 10 +++--- .../gui/configdialog/RailButtonConfig.java | 31 ++++++++++++++----- 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties index 32268fa3f..17ba58b38 100644 --- a/core/resources/l10n/messages.properties +++ b/core/resources/l10n/messages.properties @@ -1993,6 +1993,8 @@ table.column.AftShoulderDiameter = Aft Shoulder Diameter table.column.ForeShoulderLength = Fore Shoulder Length table.column.ForeShoulderDiameter = Fore Shoulder Diameter table.column.ForeOuterDiameter = Fore Outer Diameter +table.column.StandoffHeight = Standoff Height +table.column.FlangeHeight = Flange Height table.column.Shape = Shape table.column.Material = Material table.column.Finish = Finish diff --git a/core/src/net/sf/openrocket/rocketcomponent/RailButton.java b/core/src/net/sf/openrocket/rocketcomponent/RailButton.java index df6ea275a..711ead701 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/RailButton.java +++ b/core/src/net/sf/openrocket/rocketcomponent/RailButton.java @@ -16,7 +16,7 @@ import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.MathUtil; /** - * WARNING: This class is only partially implemented. Recomend a bit of testing before you attach it to the GUI. + * WARNING: This class is only partially implemented. Recommend a bit of testing before you attach it to the GUI. * @author widget (Daniel Williams) * */ @@ -59,12 +59,12 @@ public class RailButton extends ExternalComponent implements AnglePositionable, public RailButton(){ super(AxialMethod.MIDDLE); - this.outerDiameter_m = 1.0; - this.totalHeight_m = 1.0; - this.innerDiameter_m = 0.8; + this.outerDiameter_m = 0.0097; + this.totalHeight_m = 0.0097; + this.innerDiameter_m = 0.008; this.flangeHeight_m = 0.002; this.setStandoff( 0.002); - this.setInstanceSeparation( 1.0); + this.setInstanceSeparation( this.outerDiameter_m * 6); } public RailButton( final double od, final double ht ) { diff --git a/swing/src/net/sf/openrocket/gui/configdialog/RailButtonConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/RailButtonConfig.java index 7db26103c..5724342ab 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/RailButtonConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/RailButtonConfig.java @@ -43,6 +43,9 @@ public class RailButtonConfig extends RocketComponentConfig { } private JPanel buttonTab( final RailButton rbc ){ + + JPanel primary = new JPanel(new MigLayout("fill")); + JPanel panel = new JPanel( new MigLayout()); @@ -75,12 +78,16 @@ public class RailButtonConfig extends RocketComponentConfig { panel.add(new BasicSlider( angleModel.getSliderModel(-180, 180)), "w 100lp, wrap"); } + primary.add(panel, "grow, gapright 201p"); + panel = new JPanel(new MigLayout("gap rel unrel", "[][65lp::][30lp::][]", "")); + + { //// Position relative to: panel.add(new JLabel(trans.get("RailBtnCfg.lbl.PosRelativeTo"))); final EnumModel methodModel = new EnumModel(component, "AxialMethod", AxialMethod.axialOffsetMethods ); JComboBox relToCombo = new JComboBox( methodModel ); - panel.add( relToCombo, "growx, wrap rel"); + panel.add( relToCombo, "spanx, growx, wrap"); } { //// plus @@ -90,20 +97,30 @@ public class RailButtonConfig extends RocketComponentConfig { JSpinner offsetSpinner = new JSpinner(offsetModel.getSpinnerModel()); offsetSpinner.setEditor(new SpinnerEditor(offsetSpinner)); panel.add(offsetSpinner, "growx"); - panel.add(new UnitSelector( offsetModel), "growx"); - panel.add(new BasicSlider( offsetModel.getSliderModel(0, parentLength)), "w 100lp, wrap para"); + panel.add(new UnitSelector(offsetModel), "growx"); + panel.add(new BasicSlider(offsetModel.getSliderModel( + new DoubleModel(component.getParent(), "Length", -1.0, UnitGroup.UNITS_NONE), + new DoubleModel(component.getParent(), "Length"))), + "w 100lp, wrap para"); } //// Material - panel.add( instanceablePanel(rbc), "cell 4 0, spany 3, wrap para"); + /* TODO (wolsen) confirm this removal + * I think the instanceablePanel should be removed and doesn't make much sense. I understand + * the idea that you may want to say "I have 2 rail buttons, 12 inches apart". I think in reality + * that most people would add 2 (or more) individual rail buttons at specific locations on the + * rocket. That will keep consistency with other components such as launch lugs. + */ + //panel.add( instanceablePanel(rbc), "cell 4 0, spany 3, wrap para"); //// Material - panel.add(materialPanel(Material.Type.BULK),"cell 4 2, spany 2, gapleft paragraph, aligny 0%, growy"); - // ... spany"); + panel.add(materialPanel(Material.Type.BULK),"span, wrap"); - return panel; + primary.add(panel, "grow"); + + return primary; } @Override From f8993e89db91c5b352302fda36fd097a2113a81a Mon Sep 17 00:00:00 2001 From: Billy Olsen Date: Sun, 1 Mar 2020 18:24:54 -0700 Subject: [PATCH 2/4] Add rail button presets options Allow rail buttons to define presets. This change doesn't actually add any default presets to the library, but enables the ability to add some preset options for rail buttons. Partially Closes #554 Signed-off-by: Billy Olsen --- .../sf/openrocket/preset/ComponentPreset.java | 4 + .../preset/ComponentPresetFactory.java | 29 +++ .../preset/loader/RailButtonLoader.java | 32 +++ .../preset/xml/OpenRocketComponentDTO.java | 1 + .../preset/xml/OpenRocketComponentSaver.java | 2 + .../openrocket/preset/xml/RailButtonDTO.java | 132 ++++++++++++ .../gui/preset/PresetEditorDialog.java | 197 ++++++++++++++++++ 7 files changed, 397 insertions(+) create mode 100644 core/src/net/sf/openrocket/preset/loader/RailButtonLoader.java create mode 100644 core/src/net/sf/openrocket/preset/xml/RailButtonDTO.java diff --git a/core/src/net/sf/openrocket/preset/ComponentPreset.java b/core/src/net/sf/openrocket/preset/ComponentPreset.java index 80ac45135..debd4bae3 100644 --- a/core/src/net/sf/openrocket/preset/ComponentPreset.java +++ b/core/src/net/sf/openrocket/preset/ComponentPreset.java @@ -200,6 +200,8 @@ public class ComponentPreset implements Comparable, Serializabl public final static TypedKey LINE_LENGTH = new TypedKey("LineLength", Double.class, UnitGroup.UNITS_LENGTH); public final static TypedKey LINE_MATERIAL = new TypedKey("LineMaterial", Material.class); public final static TypedKey IMAGE = new TypedKey("Image", byte[].class); + public final static TypedKey STANDOFF_HEIGHT = new TypedKey("StandoffHeight", Double.class, UnitGroup.UNITS_LENGTH); + public final static TypedKey FLANGE_HEIGHT = new TypedKey("FlangeHeight", Double.class, UnitGroup.UNITS_LENGTH); public final static List> ORDERED_KEY_LIST = Collections.unmodifiableList(Arrays.> asList( MANUFACTURER, @@ -215,6 +217,8 @@ public class ComponentPreset implements Comparable, Serializabl AFT_SHOULDER_LENGTH, FORE_SHOULDER_DIAMETER, FORE_SHOULDER_LENGTH, + STANDOFF_HEIGHT, + FLANGE_HEIGHT, SHAPE, THICKNESS, FILLED, diff --git a/core/src/net/sf/openrocket/preset/ComponentPresetFactory.java b/core/src/net/sf/openrocket/preset/ComponentPresetFactory.java index 7d2677b34..77ecc3691 100644 --- a/core/src/net/sf/openrocket/preset/ComponentPresetFactory.java +++ b/core/src/net/sf/openrocket/preset/ComponentPresetFactory.java @@ -5,6 +5,7 @@ import net.sf.openrocket.database.Databases; import net.sf.openrocket.material.Material; import net.sf.openrocket.preset.ComponentPreset.Type; import net.sf.openrocket.rocketcomponent.NoseCone; +import net.sf.openrocket.rocketcomponent.RailButton; import net.sf.openrocket.rocketcomponent.Transition; public abstract class ComponentPresetFactory { @@ -67,6 +68,10 @@ public abstract class ComponentPresetFactory { makeBodyTube(exceptions, preset); break; } + case RAIL_BUTTON: { + makeRailButton(exceptions, preset); + break; + } case STREAMER: { makeStreamer(exceptions, preset); break; @@ -108,6 +113,30 @@ public abstract class ComponentPresetFactory { } + private static void makeRailButton(InvalidComponentPresetException exceptions, ComponentPreset preset) throws InvalidComponentPresetException { + + checkRequiredFields(exceptions, preset, HEIGHT); + checkRequiredFields(exceptions, preset, OUTER_DIAMETER); + checkRequiredFields(exceptions, preset, INNER_DIAMETER); + checkRequiredFields(exceptions, preset, FLANGE_HEIGHT); + checkRequiredFields(exceptions, preset, STANDOFF_HEIGHT); + + if (preset.has(MASS)) { + double mass = preset.get(MASS); + RailButton rb = new RailButton(); + rb.loadPreset(preset); + double density = mass / rb.getComponentVolume(); + + String materialName = "RailButtonCustom"; + if (preset.has(MATERIAL)) { + materialName = preset.get(MATERIAL).getName(); + } + + Material m = Databases.findMaterial(Material.Type.BULK, materialName, density); + preset.put(MATERIAL, m); + } + } + private static void makeNoseCone(InvalidComponentPresetException exceptions, ComponentPreset preset) { checkRequiredFields(exceptions, preset, LENGTH, SHAPE, AFT_OUTER_DIAMETER); diff --git a/core/src/net/sf/openrocket/preset/loader/RailButtonLoader.java b/core/src/net/sf/openrocket/preset/loader/RailButtonLoader.java new file mode 100644 index 000000000..5980ed0c5 --- /dev/null +++ b/core/src/net/sf/openrocket/preset/loader/RailButtonLoader.java @@ -0,0 +1,32 @@ +package net.sf.openrocket.preset.loader; + +import net.sf.openrocket.preset.ComponentPreset; +import net.sf.openrocket.preset.ComponentPreset.Type; + +import java.io.File; + +public class RailButtonLoader extends BaseComponentLoader { + + public RailButtonLoader(MaterialHolder materials, File theBasePath) { + super(materials, theBasePath); + fileColumns.add(new DoubleUnitColumnParser("ID","Units",ComponentPreset.INNER_DIAMETER)); + fileColumns.add(new DoubleUnitColumnParser("OD","Units",ComponentPreset.OUTER_DIAMETER)); + fileColumns.add(new DoubleUnitColumnParser("Height","Units",ComponentPreset.HEIGHT)); + fileColumns.add(new DoubleUnitColumnParser("Flange Height", "Units", ComponentPreset.FLANGE_HEIGHT)); + fileColumns.add(new DoubleUnitColumnParser("Standoff Height", "Units", ComponentPreset.STANDOFF_HEIGHT)); + + } + + + @Override + protected Type getComponentPresetType() { + return ComponentPreset.Type.RAIL_BUTTON; + } + + + @Override + protected RocksimComponentFileType getFileType() { + return RocksimComponentFileType.LAUNCH_LUG; + } + +} diff --git a/core/src/net/sf/openrocket/preset/xml/OpenRocketComponentDTO.java b/core/src/net/sf/openrocket/preset/xml/OpenRocketComponentDTO.java index 69da4e859..7294019c0 100644 --- a/core/src/net/sf/openrocket/preset/xml/OpenRocketComponentDTO.java +++ b/core/src/net/sf/openrocket/preset/xml/OpenRocketComponentDTO.java @@ -39,6 +39,7 @@ public class OpenRocketComponentDTO { @XmlElementRef(name = "CenteringRings", type = CenteringRingDTO.class), @XmlElementRef(name = "EngineBlocks", type = EngineBlockDTO.class), @XmlElementRef(name = "LaunchLugs", type = LaunchLugDTO.class), + @XmlElementRef(name = "RailButtons", type = RailButtonDTO.class), @XmlElementRef(name = "Streamers", type = StreamerDTO.class), @XmlElementRef(name = "Parachutes", type = ParachuteDTO.class)}) private List components = new ArrayList(); diff --git a/core/src/net/sf/openrocket/preset/xml/OpenRocketComponentSaver.java b/core/src/net/sf/openrocket/preset/xml/OpenRocketComponentSaver.java index 282e0b902..191a69a6c 100644 --- a/core/src/net/sf/openrocket/preset/xml/OpenRocketComponentSaver.java +++ b/core/src/net/sf/openrocket/preset/xml/OpenRocketComponentSaver.java @@ -198,6 +198,8 @@ public class OpenRocketComponentSaver { return new EngineBlockDTO(thePreset); case LAUNCH_LUG: return new LaunchLugDTO(thePreset); + case RAIL_BUTTON: + return new RailButtonDTO(thePreset); case STREAMER: return new StreamerDTO(thePreset); case PARACHUTE: diff --git a/core/src/net/sf/openrocket/preset/xml/RailButtonDTO.java b/core/src/net/sf/openrocket/preset/xml/RailButtonDTO.java new file mode 100644 index 000000000..ab42e38df --- /dev/null +++ b/core/src/net/sf/openrocket/preset/xml/RailButtonDTO.java @@ -0,0 +1,132 @@ + +package net.sf.openrocket.preset.xml; + +import net.sf.openrocket.preset.ComponentPreset; +import net.sf.openrocket.preset.ComponentPresetFactory; +import net.sf.openrocket.preset.InvalidComponentPresetException; +import net.sf.openrocket.preset.TypedPropertyMap; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.List; + +/** + * Body tube preset XML handler. + */ +@XmlRootElement(name = "RailButton") +@XmlAccessorType(XmlAccessType.FIELD) +public class RailButtonDTO extends BaseComponentDTO { + + @XmlElement(name = "InsideDiameter") + private AnnotatedLengthDTO insideDiameter; + @XmlElement(name = "OutsideDiameter") + private AnnotatedLengthDTO outsideDiameter; + @XmlElement(name = "Height") + private AnnotatedLengthDTO height; + @XmlElement(name = "StandoffHeight") + private AnnotatedLengthDTO standoffHeight; + @XmlElement(name = "FlangeHeight") + private AnnotatedLengthDTO flangeHeight; + + /** + * Default constructor. + */ + public RailButtonDTO() { + } + + /** + * Most-useful constructor that maps a RailButton preset to a RailButtonDTO. + * + * @param preset the preset + * + * @throws net.sf.openrocket.util.BugException thrown if the expected body tube keys are not in the preset + */ + public RailButtonDTO(final ComponentPreset preset) { + super(preset); + setInsideDiameter(preset.get(ComponentPreset.INNER_DIAMETER)); + setOutsideDiameter(preset.get(ComponentPreset.OUTER_DIAMETER)); + setHeight(preset.get(ComponentPreset.HEIGHT)); + setStandoffHeight(preset.get(ComponentPreset.STANDOFF_HEIGHT)); + setFlangeHeight(preset.get(ComponentPreset.FLANGE_HEIGHT)); + } + + public double getInsideDiameter() { + return insideDiameter.getValue(); + } + + public void setInsideDiameter( final AnnotatedLengthDTO theLength ) { + insideDiameter = theLength; + } + + public void setInsideDiameter(final double theId) { + insideDiameter = new AnnotatedLengthDTO(theId); + } + + public double getOutsideDiameter() { + return outsideDiameter.getValue(); + } + + public void setOutsideDiameter(final AnnotatedLengthDTO theOd) { + outsideDiameter = theOd; + } + + public void setOutsideDiameter(final double theOd) { + outsideDiameter = new AnnotatedLengthDTO(theOd); + } + + public double getHeight() { + return height.getValue(); + } + + public void setHeight(final AnnotatedLengthDTO theHeight) { + height = theHeight; + } + + public void setHeight(final double theHeight) { + height = new AnnotatedLengthDTO(theHeight); + } + + public double getStandoffHeight() { + return standoffHeight.getValue(); + } + + public void setStandoffHeight(final AnnotatedLengthDTO theStandoffHeight) { + standoffHeight = theStandoffHeight; + } + + public void setStandoffHeight(final double theStandoffHeight) { + standoffHeight = new AnnotatedLengthDTO(theStandoffHeight); + } + + public double getFlangeHeight() { + return flangeHeight.getValue(); + } + + public void setFlangeHeight(final AnnotatedLengthDTO theFlangeHeight) { + flangeHeight = theFlangeHeight; + } + + public void setFlangeHeight(final double theFlangeHeight) { + flangeHeight = new AnnotatedLengthDTO(theFlangeHeight); + } + + @Override + public ComponentPreset asComponentPreset(java.util.List materials) throws InvalidComponentPresetException { + return asComponentPreset(ComponentPreset.Type.RAIL_BUTTON, materials); + } + + public ComponentPreset asComponentPreset(ComponentPreset.Type type, List materials) throws InvalidComponentPresetException { + TypedPropertyMap props = new TypedPropertyMap(); + addProps(props, materials); + props.put(ComponentPreset.INNER_DIAMETER, this.getInsideDiameter()); + props.put(ComponentPreset.OUTER_DIAMETER, this.getOutsideDiameter()); + props.put(ComponentPreset.HEIGHT, this.getHeight()); + props.put(ComponentPreset.STANDOFF_HEIGHT, this.getStandoffHeight()); + props.put(ComponentPreset.FLANGE_HEIGHT, this.getFlangeHeight()); + props.put(ComponentPreset.TYPE, type); + + return ComponentPresetFactory.create(props); + } +} diff --git a/swing/src/net/sf/openrocket/gui/preset/PresetEditorDialog.java b/swing/src/net/sf/openrocket/gui/preset/PresetEditorDialog.java index 1689c08df..60ec9f6e4 100644 --- a/swing/src/net/sf/openrocket/gui/preset/PresetEditorDialog.java +++ b/swing/src/net/sf/openrocket/gui/preset/PresetEditorDialog.java @@ -168,6 +168,17 @@ public class PresetEditorDialog extends JDialog implements ItemListener { private ImageIcon llImage; private JButton llImageBtn; + private JTextField rbPartNoTextField; + private JTextField rbDescTextField; + private DoubleModel rbOuterDia; + private DoubleModel rbInnerDia; + private DoubleModel rbHeight; + private DoubleModel rbStandoffHeight; + private DoubleModel rbFlangeHeight; + private DoubleModel rbMass; + private ImageIcon rbImage; + private JButton rbImageBtn; + private JTextField stPartNoTextField; private JTextField stDescTextField; private DoubleModel stThickness; @@ -204,6 +215,7 @@ public class PresetEditorDialog extends JDialog implements ItemListener { private static final String BULKHEAD_KEY = "Bulkhead.Bulkhead"; private static final String EB_KEY = "ComponentIcons.Engineblock"; private static final String LAUNCH_LUG_KEY = "ComponentIcons.Launchlug"; + private static final String RAIL_BUTTON_KEY = "ComponentIcons.RailButton"; private static final String STREAMER_KEY = "ComponentIcons.Streamer"; private static final String PARACHUTE_KEY = "ComponentIcons.Parachute"; @@ -217,6 +229,7 @@ public class PresetEditorDialog extends JDialog implements ItemListener { componentMap.put(trans.get(BULKHEAD_KEY), "BULKHEAD"); componentMap.put(trans.get(EB_KEY), "ENGINEBLOCK"); componentMap.put(trans.get(LAUNCH_LUG_KEY), "LAUNCHLUG"); + componentMap.put(trans.get(RAIL_BUTTON_KEY), "RAILBUTTON"); componentMap.put(trans.get(PARACHUTE_KEY), "PARACHUTE"); componentMap.put(trans.get(STREAMER_KEY), "STREAMER"); } @@ -961,6 +974,103 @@ public class PresetEditorDialog extends JDialog implements ItemListener { }); } + // Railbutton + { + JPanel rbPanel = new JPanel(); + componentOverlayPanel.add(rbPanel, "RAILBUTTON"); + rbPanel.setLayout(new MigLayout("", "[][grow][][grow]", "[][][][]")); + JLabel rbPartNoLabel = new JLabel("Part No:"); + rbPanel.add(rbPartNoLabel, "cell 0 0,alignx left"); + + rbPartNoTextField = new JTextField(); + rbPanel.add(rbPartNoTextField, "cell 1 0,growx"); + rbPartNoTextField.setColumns(10); + + JLabel rbDescLabel = new JLabel("Description:"); + rbPanel.add(rbDescLabel, "cell 3 0,alignx left"); + + rbDescTextField = new JTextField(); + rbPanel.add(rbDescTextField, "cell 4 0,growx"); + rbDescTextField.setColumns(10); + + JLabel rbOuterDiaLabel = new JLabel("Outer Dia.:"); + rbPanel.add(rbOuterDiaLabel, "cell 0 1,alignx left"); + + rbOuterDia = new DoubleModel(0, UnitGroup.UNITS_LENGTH, 0); + JSpinner spin = new JSpinner(rbOuterDia.getSpinnerModel()); + spin.setEditor(new SpinnerEditor(spin)); + rbPanel.add(spin, "cell 1 1, growx"); + rbPanel.add(new UnitSelector(rbOuterDia), "growx"); + + JLabel rbMassLabel = new JLabel("Mass:"); + rbPanel.add(rbMassLabel, "cell 3 1,alignx left"); + + rbMass = new DoubleModel(0, UnitGroup.UNITS_MASS, 0); + spin = new JSpinner(rbMass.getSpinnerModel()); + spin.setEditor(new SpinnerEditor(spin)); + rbPanel.add(spin, "cell 4 1, growx"); + rbPanel.add(new UnitSelector(llMass), "w 34lp!"); + + JLabel rbInnerDiaLabel = new JLabel("Inner Dia.:"); + rbPanel.add(rbInnerDiaLabel, "cell 0 2,alignx left"); + + rbInnerDia = new DoubleModel(0, UnitGroup.UNITS_LENGTH, 0); + spin = new JSpinner(rbInnerDia.getSpinnerModel()); + spin.setEditor(new SpinnerEditor(spin)); + rbPanel.add(spin, "cell 1 2, growx"); + rbPanel.add(new UnitSelector(rbInnerDia), "growx"); + + JLabel rbHeightLabel = new JLabel("Height:"); + rbPanel.add(rbHeightLabel, "cell 3 2,alignx left"); + + rbHeight = new DoubleModel(0, UnitGroup.UNITS_LENGTH, 0); + spin = new JSpinner(rbHeight.getSpinnerModel()); + spin.setEditor(new SpinnerEditor(spin)); + rbPanel.add(spin, "cell 4 2, growx"); + rbPanel.add(new UnitSelector(rbHeight), "w 34lp!"); + + JLabel rbStandoffLabel = new JLabel("Standoff:"); + rbPanel.add(rbStandoffLabel, "cell 0 3,alignx left"); + + rbStandoffHeight = new DoubleModel(0, UnitGroup.UNITS_LENGTH, 0); + spin = new JSpinner(rbStandoffHeight.getSpinnerModel()); + spin.setEditor(new SpinnerEditor(spin)); + rbPanel.add(spin, "cell 1 3, growx"); + rbPanel.add(new UnitSelector(rbStandoffHeight), "growx"); + + JLabel rbFlangeLabel = new JLabel("Flange:"); + rbPanel.add(rbFlangeLabel, "cell 3 3,alignx left"); + + rbFlangeHeight = new DoubleModel(0, UnitGroup.UNITS_LENGTH, 0); + spin = new JSpinner(rbFlangeHeight.getSpinnerModel()); + spin.setEditor(new SpinnerEditor(spin)); + rbPanel.add(spin, "cell 4 3, growx"); + rbPanel.add(new UnitSelector(rbFlangeHeight), "w 34lp!"); + + JPanel panel = new JPanel(); + panel.setMinimumSize(new Dimension(200, 200)); + rbPanel.add(panel, "cell 4 4"); + panel.setLayout(null); + rbImageBtn = new JButton("No Image"); + rbImageBtn.setMaximumSize(new Dimension(75, 75)); + rbImageBtn.setMinimumSize(new Dimension(75, 75)); + panel.add(rbImageBtn); + rbImageBtn.setBounds(new Rectangle(6, 6, 132, 145)); + + rbImageBtn.addActionListener(new ActionListener() { + @Override + public void actionPerformed(final ActionEvent e) { + int returnVal = imageChooser.showOpenDialog(PresetEditorDialog.this); + + if (returnVal == JFileChooser.APPROVE_OPTION) { + File file = imageChooser.getSelectedFile(); + rbImage = scaleImage(new ImageIcon(file.getAbsolutePath()).getImage(), 155); + rbImageBtn.setIcon(rbImage); + } + } + }); + } + { JPanel stPanel = new JPanel(); componentOverlayPanel.add(stPanel, "STREAMER"); @@ -1188,6 +1298,7 @@ public class PresetEditorDialog extends JDialog implements ItemListener { cb.addItem(trans.get(TRANSITION_KEY), preset != null && !preset.get(ComponentPreset.TYPE).equals(ComponentPreset.Type.TRANSITION)); cb.addItem(trans.get(TUBE_COUPLER_KEY), preset != null && !preset.get(ComponentPreset.TYPE).equals(ComponentPreset.Type.TUBE_COUPLER)); cb.addItem(trans.get(LAUNCH_LUG_KEY), preset != null && !preset.get(ComponentPreset.TYPE).equals(ComponentPreset.Type.LAUNCH_LUG)); + cb.addItem(trans.get(RAIL_BUTTON_KEY), preset != null && !preset.get(ComponentPreset.TYPE).equals(ComponentPreset.Type.RAIL_BUTTON)); cb.addItem(trans.get(PARACHUTE_KEY), preset != null && !preset.get(ComponentPreset.TYPE).equals(ComponentPreset.Type.PARACHUTE)); cb.addItem(trans.get(STREAMER_KEY), preset != null && !preset.get(ComponentPreset.TYPE).equals(ComponentPreset.Type.STREAMER)); } @@ -1447,6 +1558,40 @@ public class PresetEditorDialog extends JDialog implements ItemListener { llImageBtn.setIcon(llImage); } break; + case RAIL_BUTTON: + typeCombo.setSelectedItem(trans.get(RAIL_BUTTON_KEY)); + rbDescTextField.setText(preset.get(ComponentPreset.DESCRIPTION)); + if (preset.has(ComponentPreset.INNER_DIAMETER)) { + rbInnerDia.setValue(preset.get(ComponentPreset.INNER_DIAMETER)); + rbInnerDia.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit()); + } + if (preset.has(ComponentPreset.OUTER_DIAMETER)) { + rbOuterDia.setValue(preset.get(ComponentPreset.OUTER_DIAMETER)); + rbOuterDia.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit()); + } + if (preset.has(ComponentPreset.HEIGHT)) { + rbHeight.setValue(preset.get(ComponentPreset.HEIGHT)); + rbHeight.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit()); + } + if (preset.has(ComponentPreset.STANDOFF_HEIGHT)) { + rbStandoffHeight.setValue(preset.get(ComponentPreset.STANDOFF_HEIGHT)); + rbStandoffHeight.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit()); + } + if (preset.has(ComponentPreset.FLANGE_HEIGHT)) { + rbFlangeHeight.setValue(preset.get(ComponentPreset.FLANGE_HEIGHT)); + rbFlangeHeight.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit()); + } + if (preset.has(ComponentPreset.MASS)) { + rbMass.setValue(preset.get(ComponentPreset.MASS)); + rbMass.setCurrentUnit(UnitGroup.UNITS_MASS.getDefaultUnit()); + } + + rbPartNoTextField.setText(preset.get(ComponentPreset.PARTNO)); + if (preset.has(ComponentPreset.IMAGE)) { + rbImage = new ImageIcon(byteArrayToImage(preset.get(ComponentPreset.IMAGE))); + rbImageBtn.setIcon(llImage); + } + break; case PARACHUTE: setMaterial(materialChooser, preset, matHolder, Material.Type.SURFACE, ComponentPreset.MATERIAL); typeCombo.setSelectedItem(trans.get(PARACHUTE_KEY)); @@ -1579,6 +1724,12 @@ public class PresetEditorDialog extends JDialog implements ItemListener { clearLaunchLug(); } } + else if (type.equals(trans.get(RAIL_BUTTON_KEY))) { + result = extractRailButton(); + if (result != null) { + clearRailButton(); + } + } else if (type.equals(trans.get(PARACHUTE_KEY))) { result = extractParachute(); if (result != null) { @@ -1954,6 +2105,52 @@ public class PresetEditorDialog extends JDialog implements ItemListener { llImageBtn.setIcon(null); } + public ComponentPreset extractRailButton() { + TypedPropertyMap props = new TypedPropertyMap(); + try { + props.put(ComponentPreset.TYPE, ComponentPreset.Type.RAIL_BUTTON); + props.put(ComponentPreset.OUTER_DIAMETER, rbOuterDia.getValue()); + props.put(ComponentPreset.INNER_DIAMETER, rbInnerDia.getValue()); + props.put(ComponentPreset.STANDOFF_HEIGHT, rbStandoffHeight.getValue()); + props.put(ComponentPreset.FLANGE_HEIGHT, rbFlangeHeight.getValue()); + props.put(ComponentPreset.DESCRIPTION, rbDescTextField.getText()); + props.put(ComponentPreset.PARTNO, rbPartNoTextField.getText()); + props.put(ComponentPreset.MANUFACTURER, Manufacturer.getManufacturer(mfgTextField.getText())); + props.put(ComponentPreset.HEIGHT, rbHeight.getValue()); + final Material material = (Material) materialChooser.getSelectedItem(); + if (material != null) { + props.put(ComponentPreset.MATERIAL, material); + } + else { + JOptionPane.showMessageDialog(null, "A material must be selected.", "Error", JOptionPane.ERROR_MESSAGE); + return null; + } + props.put(ComponentPreset.MASS, rbMass.getValue()); + if (llImage != null) { + props.put(ComponentPreset.IMAGE, imageToByteArray(rbImage.getImage())); + } + return ComponentPresetFactory.create(props); + } catch (NumberFormatException nfe) { + JOptionPane.showMessageDialog(null, "Could not convert rail button attribute.", "Error", JOptionPane.ERROR_MESSAGE); + } catch (InvalidComponentPresetException e) { + JOptionPane.showMessageDialog(null, craftErrorMessage(e, "Mandatory rail button attribute not set."), "Error", JOptionPane.ERROR_MESSAGE); + } + return null; + } + + private void clearRailButton() { + rbOuterDia.setValue(0); + rbInnerDia.setValue(0); + rbDescTextField.setText(""); + rbPartNoTextField.setText(""); + rbFlangeHeight.setValue(0); + rbHeight.setValue(0); + rbStandoffHeight.setValue(0); + rbMass.setValue(0); + rbImage = null; + rbImageBtn.setIcon(null); + } + public ComponentPreset extractParachute() { TypedPropertyMap props = new TypedPropertyMap(); try { From 3995a330da8999ad037a48f245cedfad2a38e33f Mon Sep 17 00:00:00 2001 From: Billy Olsen Date: Mon, 2 Mar 2020 20:30:49 -0700 Subject: [PATCH 3/4] Add new material types for rail buttons Add two new material types for rail buttons, delrin and nylon. The material densities are pulled from wikipedia and cross-referenced with Dupont's material database. Additionally, set Delrin as the default material for RailButtons. Closes #554 Signed-off-by: Billy Olsen --- core/resources/l10n/messages.properties | 2 ++ .../src/net/sf/openrocket/database/Databases.java | 2 ++ .../sf/openrocket/rocketcomponent/RailButton.java | 4 ++++ .../gui/configdialog/RailButtonConfig.java | 15 ++------------- .../openrocket/gui/preset/PresetEditorDialog.java | 1 + 5 files changed, 11 insertions(+), 13 deletions(-) diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties index 17ba58b38..15b1f97d8 100644 --- a/core/resources/l10n/messages.properties +++ b/core/resources/l10n/messages.properties @@ -1317,10 +1317,12 @@ material.brass = Brass material.cardboard = Cardboard material.carbon_fiber = Carbon fiber material.cork = Cork +material.delrin = Delrin material.depron_xps = Depron (XPS) material.fiberglass = Fiberglass material.kraft_phenolic = Kraft phenolic material.maple = Maple +material.nylon = Nylon material.paper_office = Paper (office) material.pine = Pine material.plywood_birch = Plywood (birch) diff --git a/core/src/net/sf/openrocket/database/Databases.java b/core/src/net/sf/openrocket/database/Databases.java index d28e92ac0..0337f5b5f 100644 --- a/core/src/net/sf/openrocket/database/Databases.java +++ b/core/src/net/sf/openrocket/database/Databases.java @@ -50,10 +50,12 @@ public class Databases { BULK_MATERIAL.add(newMaterial(Material.Type.BULK, "Cardboard", 680)); BULK_MATERIAL.add(newMaterial(Material.Type.BULK, "Carbon fiber", 1780)); BULK_MATERIAL.add(newMaterial(Material.Type.BULK, "Cork", 240)); + BULK_MATERIAL.add(newMaterial(Material.Type.BULK, "Delrin", 1420)); BULK_MATERIAL.add(newMaterial(Material.Type.BULK, "Depron (XPS)", 40)); BULK_MATERIAL.add(newMaterial(Material.Type.BULK, "Fiberglass", 1850)); BULK_MATERIAL.add(newMaterial(Material.Type.BULK, "Kraft phenolic", 950)); BULK_MATERIAL.add(newMaterial(Material.Type.BULK, "Maple", 755)); + BULK_MATERIAL.add(newMaterial(Material.Type.BULK, "Nylon", 1150)); BULK_MATERIAL.add(newMaterial(Material.Type.BULK, "Paper (office)", 820)); BULK_MATERIAL.add(newMaterial(Material.Type.BULK, "Pine", 530)); BULK_MATERIAL.add(newMaterial(Material.Type.BULK, "Plywood (birch)", 630)); diff --git a/core/src/net/sf/openrocket/rocketcomponent/RailButton.java b/core/src/net/sf/openrocket/rocketcomponent/RailButton.java index 711ead701..9dfd98dc1 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/RailButton.java +++ b/core/src/net/sf/openrocket/rocketcomponent/RailButton.java @@ -3,7 +3,9 @@ package net.sf.openrocket.rocketcomponent; import java.util.ArrayList; import java.util.Collection; +import net.sf.openrocket.database.Databases; import net.sf.openrocket.l10n.Translator; +import net.sf.openrocket.material.Material; import net.sf.openrocket.preset.ComponentPreset; import net.sf.openrocket.preset.ComponentPreset.Type; import net.sf.openrocket.rocketcomponent.position.AngleMethod; @@ -65,6 +67,7 @@ public class RailButton extends ExternalComponent implements AnglePositionable, this.flangeHeight_m = 0.002; this.setStandoff( 0.002); this.setInstanceSeparation( this.outerDiameter_m * 6); + this.setMaterial(Databases.findMaterial(Material.Type.BULK, "Delrin")); } public RailButton( final double od, final double ht ) { @@ -81,6 +84,7 @@ public class RailButton extends ExternalComponent implements AnglePositionable, this.flangeHeight_m = flangeThickness; this.setStandoff( _standoff); this.setInstanceSeparation( od*2); + this.setMaterial(Databases.findMaterial(Material.Type.BULK, "Delrin")); } private static final RailButton make1010Button(){ diff --git a/swing/src/net/sf/openrocket/gui/configdialog/RailButtonConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/RailButtonConfig.java index 5724342ab..23d6ae2f4 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/RailButtonConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/RailButtonConfig.java @@ -6,6 +6,7 @@ import javax.swing.JPanel; import javax.swing.JSpinner; import net.miginfocom.swing.MigLayout; +import net.sf.openrocket.database.Databases; import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.gui.SpinnerEditor; import net.sf.openrocket.gui.adaptors.DoubleModel; @@ -14,7 +15,6 @@ import net.sf.openrocket.gui.components.BasicSlider; import net.sf.openrocket.gui.components.UnitSelector; import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.material.Material; -import net.sf.openrocket.rocketcomponent.BodyTube; import net.sf.openrocket.rocketcomponent.RailButton; import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.rocketcomponent.position.AxialMethod; @@ -91,7 +91,6 @@ public class RailButtonConfig extends RocketComponentConfig { } { //// plus - final double parentLength = ((BodyTube)rbc.getParent()).getLength(); panel.add(new JLabel(trans.get("RailBtnCfg.lbl.Plus")), "right"); DoubleModel offsetModel = new DoubleModel(component, "AxialOffset", UnitGroup.UNITS_LENGTH); JSpinner offsetSpinner = new JSpinner(offsetModel.getSpinnerModel()); @@ -104,17 +103,7 @@ public class RailButtonConfig extends RocketComponentConfig { "w 100lp, wrap para"); } - - //// Material - /* TODO (wolsen) confirm this removal - * I think the instanceablePanel should be removed and doesn't make much sense. I understand - * the idea that you may want to say "I have 2 rail buttons, 12 inches apart". I think in reality - * that most people would add 2 (or more) individual rail buttons at specific locations on the - * rocket. That will keep consistency with other components such as launch lugs. - */ - //panel.add( instanceablePanel(rbc), "cell 4 0, spany 3, wrap para"); - - + //// Material panel.add(materialPanel(Material.Type.BULK),"span, wrap"); diff --git a/swing/src/net/sf/openrocket/gui/preset/PresetEditorDialog.java b/swing/src/net/sf/openrocket/gui/preset/PresetEditorDialog.java index 60ec9f6e4..6a35f286f 100644 --- a/swing/src/net/sf/openrocket/gui/preset/PresetEditorDialog.java +++ b/swing/src/net/sf/openrocket/gui/preset/PresetEditorDialog.java @@ -1559,6 +1559,7 @@ public class PresetEditorDialog extends JDialog implements ItemListener { } break; case RAIL_BUTTON: + setMaterial(materialChooser, preset, matHolder, Material.Type.BULK, ComponentPreset.MATERIAL); typeCombo.setSelectedItem(trans.get(RAIL_BUTTON_KEY)); rbDescTextField.setText(preset.get(ComponentPreset.DESCRIPTION)); if (preset.has(ComponentPreset.INNER_DIAMETER)) { From e0983c05cc4bbd8dfd8a3b090ee0833731089811 Mon Sep 17 00:00:00 2001 From: Billy Olsen Date: Tue, 3 Mar 2020 09:37:56 -0700 Subject: [PATCH 4/4] Add back instance panel dropped in previous commit Adds back the instance options in the previous commit for specifying instance details about rail buttons. This change adds it back but slightly tweaks the layout and location in order to keep the config panel in a 2 column arrangement. Signed-off-by: Billy Olsen --- .../gui/configdialog/RailButtonConfig.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/swing/src/net/sf/openrocket/gui/configdialog/RailButtonConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/RailButtonConfig.java index 23d6ae2f4..9a7d2759f 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/RailButtonConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/RailButtonConfig.java @@ -77,11 +77,7 @@ public class RailButtonConfig extends RocketComponentConfig { panel.add(new UnitSelector( angleModel), "growx"); panel.add(new BasicSlider( angleModel.getSliderModel(-180, 180)), "w 100lp, wrap"); } - - primary.add(panel, "grow, gapright 201p"); - panel = new JPanel(new MigLayout("gap rel unrel", "[][65lp::][30lp::][]", "")); - - + { //// Position relative to: panel.add(new JLabel(trans.get("RailBtnCfg.lbl.PosRelativeTo"))); @@ -103,10 +99,16 @@ public class RailButtonConfig extends RocketComponentConfig { "w 100lp, wrap para"); } - + + primary.add(panel, "grow, gapright 201p"); + panel = new JPanel(new MigLayout("gap rel unrel", "[][65lp::][30lp::][]", "")); + + //// Instance count + panel.add( instanceablePanel(rbc), "span, wrap"); + //// Material panel.add(materialPanel(Material.Type.BULK),"span, wrap"); - + primary.add(panel, "grow"); return primary;