[GUI Options Implemented] Implemented GUI elements to change the position of external components.

External Components are pods and parallel stages.  Slightly different UI options have been implemented for each.
This commit is contained in:
Daniel_M_Williams 2015-06-03 15:48:13 -04:00
parent 5d2e7730f5
commit b8b1e6576e
6 changed files with 168 additions and 13 deletions

View File

@ -823,6 +823,14 @@ RocketCompCfg.lbl.Componentname = Component name:
RocketCompCfg.ttip.Thecomponentname = The component name. RocketCompCfg.ttip.Thecomponentname = The component name.
RocketCompCfg.tab.Override = Override RocketCompCfg.tab.Override = Override
RocketCompCfg.tab.MassandCGoverride = Mass and CG override options RocketCompCfg.tab.MassandCGoverride = Mass and CG override options
RocketCompCfg.tab.Pod = Pod
RocketCompCfg.tab.PodComment = Options for locating ExteriorComponents outside the Rocket
RocketCompCfg.tab.Parallel = Parallel
RocketCompCfg.tab.ParallelComment = Options for locating Stages parallel to other stages
RocketCompCfg.parallel.inline = Make this Stage Parallel
RocketCompCfg.parallel.radius = Radial Distance (meters)
RocketCompCfg.parallel.angle = Angle (Radians)
RocketCompCfg.parallel.rotation = Rotation (Radians)
RocketCompCfg.tab.Figure = Figure RocketCompCfg.tab.Figure = Figure
RocketCompCfg.tab.Figstyleopt = Figure style options RocketCompCfg.tab.Figstyleopt = Figure style options
RocketCompCfg.tab.Comment = Comment RocketCompCfg.tab.Comment = Comment

View File

@ -131,15 +131,18 @@ public abstract class ExternalComponent extends RocketComponent implements Outsi
fireComponentChangeEvent(ComponentChangeEvent.AERODYNAMIC_CHANGE); fireComponentChangeEvent(ComponentChangeEvent.AERODYNAMIC_CHANGE);
} }
@Override
public boolean isInline() { public boolean isInline() {
return this.axial; return this.axial;
} }
@Override @Override
public void setInline(final boolean inline) { public boolean getParallel() {
this.axial = inline; return !this.axial;
}
@Override
public void setParallel(final boolean parallel) {
this.axial = !parallel;
} }
@Override @Override

View File

@ -9,14 +9,14 @@ public interface OutsideComponent {
* @return <code> True </code> This component is aligned with its parent * @return <code> True </code> This component is aligned with its parent
* <code> False </code> This component is offset from its parent -- like an external pod, or strap-on stage * <code> False </code> This component is offset from its parent -- like an external pod, or strap-on stage
*/ */
public boolean isInline(); public boolean getParallel();
/** /**
* Change whether this component is located inside or outside of the rest of the rocket. (Specifically, inside or outside its parent.) * Change whether this component is located inside or outside of the rest of the rocket. (Specifically, inside or outside its parent.)
* *
* @param inline True indicates that this component axially aligned with its parent. False indicates an off-center component. * @param inline True indicates that this component axially aligned with its parent. False indicates an off-center component.
*/ */
public void setInline(final boolean inline); public void setParallel(final boolean inline);
/** /**
* Get the position of this component in polar coordinates * Get the position of this component in polar coordinates

View File

@ -14,6 +14,8 @@ public class Stage extends ComponentAssembly implements FlightConfigurableCompon
private double position_radial_m = 0; private double position_radial_m = 0;
private double rotation_rad = 0; private double rotation_rad = 0;
// ParallelStagingConfiguration parallelConfiguration = null;
public Stage() { public Stage() {
this.separationConfigurations = new FlightConfigurationImpl<StageSeparationConfiguration>(this, ComponentChangeEvent.EVENT_CHANGE, new StageSeparationConfiguration()); this.separationConfigurations = new FlightConfigurationImpl<StageSeparationConfiguration>(this, ComponentChangeEvent.EVENT_CHANGE, new StageSeparationConfiguration());
} }
@ -29,7 +31,9 @@ public class Stage extends ComponentAssembly implements FlightConfigurableCompon
return separationConfigurations; return separationConfigurations;
} }
// public ParallelStagingConfiguration getParallelStageConfiguration() {
// return parallelConfiguration;
// }
@Override @Override
@ -66,13 +70,17 @@ public class Stage extends ComponentAssembly implements FlightConfigurableCompon
} }
@Override @Override
public boolean isInline() { public boolean getParallel() {
return !this.axial;
}
public boolean getInline() {
return this.axial; return this.axial;
} }
@Override @Override
public void setInline(final boolean inline) { public void setParallel(final boolean parallel) {
this.axial = inline; this.axial = !parallel;
} }
@Override @Override
@ -84,8 +92,8 @@ public class Stage extends ComponentAssembly implements FlightConfigurableCompon
} }
@Override @Override
public void setAngularPosition(final double phi) { public void setAngularPosition(final double angle_rad) {
this.position_angular_rad = phi; this.position_angular_rad = angle_rad;
} }
@Override @Override

View File

@ -1,6 +1,8 @@
package net.sf.openrocket.gui.configdialog; package net.sf.openrocket.gui.configdialog;
import java.awt.Component;
import java.awt.Container;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.awt.event.FocusEvent; import java.awt.event.FocusEvent;
@ -17,10 +19,14 @@ import javax.swing.JComboBox;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JScrollPane; import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JSpinner; import javax.swing.JSpinner;
import javax.swing.JTabbedPane; import javax.swing.JTabbedPane;
import javax.swing.JTextArea; import javax.swing.JTextArea;
import javax.swing.JTextField; import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.database.ComponentPresetDatabase; import net.sf.openrocket.database.ComponentPresetDatabase;
@ -41,6 +47,8 @@ import net.sf.openrocket.material.Material;
import net.sf.openrocket.preset.ComponentPreset; import net.sf.openrocket.preset.ComponentPreset;
import net.sf.openrocket.rocketcomponent.ComponentAssembly; import net.sf.openrocket.rocketcomponent.ComponentAssembly;
import net.sf.openrocket.rocketcomponent.ExternalComponent; import net.sf.openrocket.rocketcomponent.ExternalComponent;
import net.sf.openrocket.rocketcomponent.OutsideComponent;
import net.sf.openrocket.rocketcomponent.Stage;
import net.sf.openrocket.rocketcomponent.ExternalComponent.Finish; import net.sf.openrocket.rocketcomponent.ExternalComponent.Finish;
import net.sf.openrocket.rocketcomponent.NoseCone; import net.sf.openrocket.rocketcomponent.NoseCone;
import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.rocketcomponent.RocketComponent;
@ -65,6 +73,9 @@ public class RocketComponentConfig extends JPanel {
protected JTextArea commentTextArea; protected JTextArea commentTextArea;
private final TextFieldListener textFieldListener; private final TextFieldListener textFieldListener;
private BooleanModel podsEnabledModel = null;
private JPanel podsEnabledPanel = null;
private JPanel buttonPanel; private JPanel buttonPanel;
private JLabel infoLabel; private JLabel infoLabel;
@ -115,6 +126,8 @@ public class RocketComponentConfig extends JPanel {
tabbedPane.addTab(trans.get("RocketCompCfg.tab.Comment"), null, commentTab(), tabbedPane.addTab(trans.get("RocketCompCfg.tab.Comment"), null, commentTab(),
trans.get("RocketCompCfg.tab.Specifyacomment")); trans.get("RocketCompCfg.tab.Specifyacomment"));
addButtons(); addButtons();
updateFields(); updateFields();
@ -146,6 +159,10 @@ public class RocketComponentConfig extends JPanel {
}); });
buttonPanel.add(closeButton, "right, gap 30lp"); buttonPanel.add(closeButton, "right, gap 30lp");
if( component instanceof ExternalComponent ){
tabbedPane.insertTab( trans.get("RocketCompCfg.tab.Pod"), null, podTab( (ExternalComponent) component ), trans.get("RocketCompCfg.tab.PodComment"), 2);
}
updateFields(); updateFields();
this.add(buttonPanel, "spanx, growx"); this.add(buttonPanel, "spanx, growx");
@ -268,6 +285,53 @@ public class RocketComponentConfig extends JPanel {
return subPanel; return subPanel;
} }
private JPanel podTab( final ExternalComponent pod ){
// enable parallel staging
JPanel motherPanel = new JPanel( new MigLayout("fill"));
podsEnabledModel = new BooleanModel( component, "Parallel");
podsEnabledModel.setValue(false);
JCheckBox parallelEnabled = new JCheckBox( podsEnabledModel);
parallelEnabled.setText(trans.get("RocketCompCfg.parallel.inline"));
motherPanel.add(parallelEnabled, "wrap");
JPanel enabledPanel = new JPanel( new MigLayout("fill"));
this.podsEnabledPanel = enabledPanel;
enabledPanel.add(new JSeparator(SwingConstants.HORIZONTAL), "growx,wrap");
// set radial distance
enabledPanel.add(new JLabel(trans.get("RocketCompCfg.parallel.radius")), "align left");
DoubleModel radiusModel = new DoubleModel( pod, "RadialPosition", 0.);
JSpinner radiusSpinner = new JSpinner( radiusModel.getSpinnerModel());
radiusSpinner.setEditor(new SpinnerEditor(radiusSpinner ));
enabledPanel.add(radiusSpinner , "growx, wrap, align right");
// set angle around the primary stage
enabledPanel.add(new JLabel(trans.get("RocketCompCfg.parallel.angle")), "align left");
DoubleModel angleModel = new DoubleModel( pod, "AngularPosition", 0., Math.PI*2);
JSpinner angleSpinner = new JSpinner(angleModel.getSpinnerModel());
angleSpinner.setEditor(new SpinnerEditor(angleSpinner));
enabledPanel.add(angleSpinner, "growx, wrap");
enabledPanel.add(new JLabel(trans.get("RocketCompCfg.parallel.rotation")), "align left");
DoubleModel rotationModel = new DoubleModel( pod, "Rotation", 0.0, Math.PI*2);
JSpinner rotationSpinner = new JSpinner(rotationModel.getSpinnerModel());
rotationSpinner.setEditor(new SpinnerEditor(rotationSpinner));
enabledPanel.add(rotationSpinner, "growx, wrap");
setDeepEnabled( enabledPanel, podsEnabledModel.getValue());
parallelEnabled.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
setDeepEnabled( podsEnabledPanel, podsEnabledModel.getValue());
}
});
motherPanel.add( enabledPanel , "growx, wrap");
return motherPanel;
}
private JPanel overrideTab() { private JPanel overrideTab() {
JPanel panel = new JPanel(new MigLayout("align 50% 20%, fillx, gap rel unrel", JPanel panel = new JPanel(new MigLayout("align 50% 20%, fillx, gap rel unrel",
@ -569,4 +633,12 @@ public class RocketComponentConfig extends JPanel {
} }
protected static void setDeepEnabled(Component component, boolean enabled) {
component.setEnabled(enabled);
if (component instanceof Container) {
for (Component c : ((Container) component).getComponents()) {
setDeepEnabled(c, enabled);
}
}
}
} }

View File

@ -1,18 +1,28 @@
package net.sf.openrocket.gui.configdialog; package net.sf.openrocket.gui.configdialog;
import java.awt.Component;
import java.awt.Container;
import javax.swing.JCheckBox;
import javax.swing.JComboBox; import javax.swing.JComboBox;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.JSpinner; import javax.swing.JSpinner;
import javax.swing.SwingConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.document.OpenRocketDocument;
import net.sf.openrocket.gui.SpinnerEditor; import net.sf.openrocket.gui.SpinnerEditor;
import net.sf.openrocket.gui.adaptors.BooleanModel;
import net.sf.openrocket.gui.adaptors.DoubleModel; import net.sf.openrocket.gui.adaptors.DoubleModel;
import net.sf.openrocket.gui.adaptors.EnumModel; import net.sf.openrocket.gui.adaptors.EnumModel;
import net.sf.openrocket.gui.components.StyledLabel; import net.sf.openrocket.gui.components.StyledLabel;
import net.sf.openrocket.gui.components.StyledLabel.Style; import net.sf.openrocket.gui.components.StyledLabel.Style;
import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.rocketcomponent.OutsideComponent;
import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.rocketcomponent.Stage; import net.sf.openrocket.rocketcomponent.Stage;
import net.sf.openrocket.rocketcomponent.StageSeparationConfiguration; import net.sf.openrocket.rocketcomponent.StageSeparationConfiguration;
@ -21,6 +31,9 @@ import net.sf.openrocket.startup.Application;
public class StageConfig extends RocketComponentConfig { public class StageConfig extends RocketComponentConfig {
private static final Translator trans = Application.getTranslator(); private static final Translator trans = Application.getTranslator();
private BooleanModel parallelEnabledModel = null;
private JPanel parallelEnabledPanel = null;
public StageConfig(OpenRocketDocument document, RocketComponent component) { public StageConfig(OpenRocketDocument document, RocketComponent component) {
super(document, component); super(document, component);
@ -30,9 +43,59 @@ public class StageConfig extends RocketComponentConfig {
tabbedPane.insertTab(trans.get("tab.Separation"), null, tab, tabbedPane.insertTab(trans.get("tab.Separation"), null, tab,
trans.get("tab.Separation.ttip"), 1); trans.get("tab.Separation.ttip"), 1);
} }
// all stage instances should qualify here...
if( component instanceof OutsideComponent ){
tabbedPane.insertTab( trans.get("RocketCompCfg.tab.Parallel"), null, parallelTab( (Stage) component ), trans.get("RocketCompCfg.tab.ParallelComment"), 2);
}
} }
private JPanel parallelTab( final Stage stage ){
// enable parallel staging
JPanel motherPanel = new JPanel( new MigLayout("fill"));
parallelEnabledModel = new BooleanModel( component, "Parallel");
parallelEnabledModel.setValue(false);
JCheckBox parallelEnabled = new JCheckBox( parallelEnabledModel);
parallelEnabled.setText(trans.get("RocketCompCfg.parallel.inline"));
motherPanel.add(parallelEnabled, "wrap");
JPanel enabledPanel = new JPanel( new MigLayout("fill"));
this.parallelEnabledPanel = enabledPanel;
enabledPanel.add(new JSeparator(SwingConstants.HORIZONTAL), "growx,wrap");
// set radial distance
enabledPanel.add(new JLabel(trans.get("RocketCompCfg.parallel.radius")), "align left");
DoubleModel radiusModel = new DoubleModel( stage, "RadialPosition", 0.0);
JSpinner radiusSpinner = new JSpinner( radiusModel.getSpinnerModel());
radiusSpinner.setEditor(new SpinnerEditor(radiusSpinner ));
enabledPanel.add(radiusSpinner , "growx, wrap, align right");
// set angle around the primary stage
enabledPanel.add(new JLabel(trans.get("RocketCompCfg.parallel.angle")), "align left");
DoubleModel angleModel = new DoubleModel( stage, "AngularPosition", 0.0, Math.PI*2);
JSpinner angleSpinner = new JSpinner(angleModel.getSpinnerModel());
angleSpinner.setEditor(new SpinnerEditor(angleSpinner));
enabledPanel.add(angleSpinner, "growx, wrap");
enabledPanel.add(new JLabel(trans.get("RocketCompCfg.parallel.rotation")), "align left");
DoubleModel rotationModel = new DoubleModel( stage, "Rotation", 0.0, Math.PI*2);
JSpinner rotationSpinner = new JSpinner(rotationModel.getSpinnerModel());
rotationSpinner.setEditor(new SpinnerEditor(rotationSpinner));
enabledPanel.add(rotationSpinner, "growx, wrap");
setDeepEnabled( enabledPanel, parallelEnabledModel.getValue());
parallelEnabled.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
setDeepEnabled( parallelEnabledPanel, parallelEnabledModel.getValue());
}
});
motherPanel.add( enabledPanel , "growx, wrap");
return motherPanel;
}
private JPanel separationTab(Stage stage) { private JPanel separationTab(Stage stage) {
JPanel panel = new JPanel(new MigLayout("fill")); JPanel panel = new JPanel(new MigLayout("fill"));
@ -59,5 +122,6 @@ public class StageConfig extends RocketComponentConfig {
return panel; return panel;
} }
} }