Added full support for per flight-config stage separation: simulation,
ork file, and gui configuration.
This commit is contained in:
parent
4490a6c1cb
commit
b32be42092
@ -187,6 +187,7 @@ edtmotorconfdlg.lbl.Motorconfig = <html><b>Motor configurations:</b>
|
|||||||
edtmotorconfdlg.lbl.Configname = Configuration name:
|
edtmotorconfdlg.lbl.Configname = Configuration name:
|
||||||
edtmotorconfdlg.lbl.Motortab = Motors
|
edtmotorconfdlg.lbl.Motortab = Motors
|
||||||
edtmotorconfdlg.lbl.Recoverytab = Recovery
|
edtmotorconfdlg.lbl.Recoverytab = Recovery
|
||||||
|
edtmotorconfdlg.lbl.Stagetab = Stages
|
||||||
edtmotorconfdlg.tbl.None = None
|
edtmotorconfdlg.tbl.None = None
|
||||||
edtmotorconfdlg.tbl.Motorheader = Motor
|
edtmotorconfdlg.tbl.Motorheader = Motor
|
||||||
edtmotorconfdlg.tbl.Mountheader = Motor Mount
|
edtmotorconfdlg.tbl.Mountheader = Motor Mount
|
||||||
@ -195,6 +196,10 @@ edtmotorconfdlg.but.Resetdeployment = Reset to default
|
|||||||
edtmotorconfdlg.but.Selectdeployment = Select deployment
|
edtmotorconfdlg.but.Selectdeployment = Select deployment
|
||||||
edtmotorconfdlg.tbl.Recoveryheader = Recovery Device
|
edtmotorconfdlg.tbl.Recoveryheader = Recovery Device
|
||||||
edtmotorconfdlg.tbl.Deploymentheader = Deployment
|
edtmotorconfdlg.tbl.Deploymentheader = Deployment
|
||||||
|
edtmotorconfdlg.but.Resetseparation = Reset to default
|
||||||
|
edtmotorconfdlg.but.Selectseparation = Select separation
|
||||||
|
edtmotorconfdlg.tbl.Stageheader = Stage
|
||||||
|
edtmotorconfdlg.tbl.Separationheader = Separation
|
||||||
|
|
||||||
! Example design dialog
|
! Example design dialog
|
||||||
exdesigndlg.but.open = Open
|
exdesigndlg.but.open = Open
|
||||||
|
@ -64,6 +64,7 @@ import net.sf.openrocket.rocketcomponent.RocketComponent.Position;
|
|||||||
import net.sf.openrocket.rocketcomponent.ShockCord;
|
import net.sf.openrocket.rocketcomponent.ShockCord;
|
||||||
import net.sf.openrocket.rocketcomponent.Stage;
|
import net.sf.openrocket.rocketcomponent.Stage;
|
||||||
import net.sf.openrocket.rocketcomponent.StageSeparationConfiguration;
|
import net.sf.openrocket.rocketcomponent.StageSeparationConfiguration;
|
||||||
|
import net.sf.openrocket.rocketcomponent.StageSeparationConfiguration.SeparationEvent;
|
||||||
import net.sf.openrocket.rocketcomponent.Streamer;
|
import net.sf.openrocket.rocketcomponent.Streamer;
|
||||||
import net.sf.openrocket.rocketcomponent.StructuralComponent;
|
import net.sf.openrocket.rocketcomponent.StructuralComponent;
|
||||||
import net.sf.openrocket.rocketcomponent.SymmetricComponent;
|
import net.sf.openrocket.rocketcomponent.SymmetricComponent;
|
||||||
@ -886,6 +887,13 @@ class ComponentParameterHandler extends AbstractElementHandler {
|
|||||||
}
|
}
|
||||||
return new DeploymentConfigurationHandler( (RecoveryDevice) component, context );
|
return new DeploymentConfigurationHandler( (RecoveryDevice) component, context );
|
||||||
}
|
}
|
||||||
|
if ( element.equals("separationconfiguration")) {
|
||||||
|
if ( !(component instanceof Stage) ) {
|
||||||
|
warnings.add(Warning.fromString("Illegal component defined as stage."));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new StageSeparationConfigurationHandler( (Stage) component, context );
|
||||||
|
}
|
||||||
|
|
||||||
return PlainTextHandler.INSTANCE;
|
return PlainTextHandler.INSTANCE;
|
||||||
}
|
}
|
||||||
@ -896,7 +904,7 @@ class ComponentParameterHandler extends AbstractElementHandler {
|
|||||||
|
|
||||||
if (element.equals("subcomponents") || element.equals("motormount") ||
|
if (element.equals("subcomponents") || element.equals("motormount") ||
|
||||||
element.equals("finpoints") || element.equals("motorconfiguration") ||
|
element.equals("finpoints") || element.equals("motorconfiguration") ||
|
||||||
element.equals("deploymentconfiguration")) {
|
element.equals("deploymentconfiguration") || element.equals("separationconfiguration")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1350,6 +1358,51 @@ class DeploymentConfigurationHandler extends AbstractElementHandler {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class StageSeparationConfigurationHandler extends AbstractElementHandler {
|
||||||
|
private final Stage stage;
|
||||||
|
private StageSeparationConfiguration config;
|
||||||
|
|
||||||
|
public StageSeparationConfigurationHandler( Stage stage, DocumentLoadingContext context ) {
|
||||||
|
this.stage = stage;
|
||||||
|
config = new StageSeparationConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ElementHandler openElement(String element, HashMap<String, String> attributes, WarningSet warnings)
|
||||||
|
throws SAXException {
|
||||||
|
return PlainTextHandler.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void closeElement(String element, HashMap<String, String> attributes, String content,
|
||||||
|
WarningSet warnings) throws SAXException {
|
||||||
|
|
||||||
|
content = content.trim();
|
||||||
|
|
||||||
|
if ( "separationevent".equals(element) ) {
|
||||||
|
SeparationEvent type = (SeparationEvent) DocumentConfig.findEnum(content, SeparationEvent.class);
|
||||||
|
if ( type == null ) {
|
||||||
|
warnings.add(Warning.FILE_INVALID_PARAMETER);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
config.setSeparationEvent( type );
|
||||||
|
return;
|
||||||
|
} else if ( "separationdelay".equals(element) ) {
|
||||||
|
config.setSeparationDelay( Double.parseDouble(content));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
super.closeElement(element, attributes, content, warnings);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endHandler(String element, HashMap<String, String> attributes, String content, WarningSet warnings) throws SAXException {
|
||||||
|
String configId = attributes.get("configid");
|
||||||
|
stage.setFlightConfiguration(configId, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
class SimulationsHandler extends AbstractElementHandler {
|
class SimulationsHandler extends AbstractElementHandler {
|
||||||
private final DocumentLoadingContext context;
|
private final DocumentLoadingContext context;
|
||||||
private final OpenRocketDocument doc;
|
private final OpenRocketDocument doc;
|
||||||
|
@ -4,8 +4,11 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import net.sf.openrocket.rocketcomponent.DeploymentConfiguration;
|
||||||
|
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||||
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;
|
||||||
|
|
||||||
public class StageSaver extends ComponentAssemblySaver {
|
public class StageSaver extends ComponentAssemblySaver {
|
||||||
|
|
||||||
@ -27,10 +30,37 @@ public class StageSaver extends ComponentAssemblySaver {
|
|||||||
Stage stage = (Stage) c;
|
Stage stage = (Stage) c;
|
||||||
|
|
||||||
if (stage.getStageNumber() > 0) {
|
if (stage.getStageNumber() > 0) {
|
||||||
elements.add("<separationevent>"
|
elements.addAll( separationConfig( stage.getDefaultFlightConfiguration(), false));
|
||||||
+ stage.getDefaultSeparationEvent().name().toLowerCase(Locale.ENGLISH).replace("_", "")
|
|
||||||
+ "</separationevent>");
|
Rocket rocket = stage.getRocket();
|
||||||
elements.add("<separationdelay>" + stage.getDefaultSeparationDelay() + "</separationdelay>");
|
// Note - getFlightConfigurationIDs returns at least one element. The first element
|
||||||
|
// is null and means "default".
|
||||||
|
String[] configs = rocket.getFlightConfigurationIDs();
|
||||||
|
if ( configs.length > 1 ) {
|
||||||
|
|
||||||
|
for( String id : configs ) {
|
||||||
|
if ( id == null ) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
StageSeparationConfiguration config = stage.getFlightConfiguration(id);
|
||||||
|
if ( config == null ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
elements.add("<separationconfiguration configid=\"" + id + "\">");
|
||||||
|
elements.addAll( separationConfig(config, true) );
|
||||||
|
elements.add("</separationconfiguration>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> separationConfig( StageSeparationConfiguration config, boolean indent ) {
|
||||||
|
List<String> elements = new ArrayList<String>(2);
|
||||||
|
elements.add((indent?" ":"")+ "<separationevent>"
|
||||||
|
+ config.getSeparationEvent().name().toLowerCase(Locale.ENGLISH).replace("_", "")
|
||||||
|
+ "</separationevent>");
|
||||||
|
elements.add((indent?" ":"")+ "<separationdelay>" + config.getSeparationDelay() + "</separationdelay>");
|
||||||
|
return elements;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ import net.sf.openrocket.gui.main.BasicFrame;
|
|||||||
import net.sf.openrocket.gui.util.GUIUtil;
|
import net.sf.openrocket.gui.util.GUIUtil;
|
||||||
import net.sf.openrocket.l10n.Translator;
|
import net.sf.openrocket.l10n.Translator;
|
||||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||||
|
import net.sf.openrocket.rocketcomponent.StageSeparationConfiguration;
|
||||||
import net.sf.openrocket.rocketvisitors.CopyFlightConfigurationVisitor;
|
import net.sf.openrocket.rocketvisitors.CopyFlightConfigurationVisitor;
|
||||||
import net.sf.openrocket.startup.Application;
|
import net.sf.openrocket.startup.Application;
|
||||||
|
|
||||||
@ -34,6 +35,7 @@ public class FlightConfigurationDialog extends JDialog {
|
|||||||
|
|
||||||
private final MotorConfigurationPanel motorConfigurationPanel;
|
private final MotorConfigurationPanel motorConfigurationPanel;
|
||||||
private final RecoveryConfigurationPanel recoveryConfigurationPanel;
|
private final RecoveryConfigurationPanel recoveryConfigurationPanel;
|
||||||
|
private final SeparationConfigurationPanel separationConfigurationPanel;
|
||||||
|
|
||||||
private String currentID = null;
|
private String currentID = null;
|
||||||
|
|
||||||
@ -113,6 +115,12 @@ public class FlightConfigurationDialog extends JDialog {
|
|||||||
recoveryConfigurationPanel = new RecoveryConfigurationPanel(this,rocket);
|
recoveryConfigurationPanel = new RecoveryConfigurationPanel(this,rocket);
|
||||||
tabs.add(trans.get("edtmotorconfdlg.lbl.Recoverytab"), recoveryConfigurationPanel );
|
tabs.add(trans.get("edtmotorconfdlg.lbl.Recoverytab"), recoveryConfigurationPanel );
|
||||||
|
|
||||||
|
//// Stage tab
|
||||||
|
separationConfigurationPanel = new SeparationConfigurationPanel(this,rocket);
|
||||||
|
if ( rocket.getStageCount() > 1 ) {
|
||||||
|
tabs.add(trans.get("edtmotorconfdlg.lbl.Stagetab"), separationConfigurationPanel );
|
||||||
|
}
|
||||||
|
|
||||||
//// Close button
|
//// Close button
|
||||||
JButton close = new JButton(trans.get("dlg.but.close"));
|
JButton close = new JButton(trans.get("dlg.but.close"));
|
||||||
close.addActionListener(new ActionListener() {
|
close.addActionListener(new ActionListener() {
|
||||||
@ -151,6 +159,7 @@ public class FlightConfigurationDialog extends JDialog {
|
|||||||
rocket.getDefaultConfiguration().setFlightConfigurationID(currentID);
|
rocket.getDefaultConfiguration().setFlightConfigurationID(currentID);
|
||||||
motorConfigurationPanel.fireTableDataChanged();
|
motorConfigurationPanel.fireTableDataChanged();
|
||||||
recoveryConfigurationPanel.fireTableDataChanged();
|
recoveryConfigurationPanel.fireTableDataChanged();
|
||||||
|
separationConfigurationPanel.fireTableDataChanged();
|
||||||
updateButtonState();
|
updateButtonState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,6 +169,7 @@ public class FlightConfigurationDialog extends JDialog {
|
|||||||
motorConfigurationPanel.fireTableDataChanged();
|
motorConfigurationPanel.fireTableDataChanged();
|
||||||
flightConfigurationModel.fireContentsUpdated();
|
flightConfigurationModel.fireContentsUpdated();
|
||||||
recoveryConfigurationPanel.fireTableDataChanged();
|
recoveryConfigurationPanel.fireTableDataChanged();
|
||||||
|
separationConfigurationPanel.fireTableDataChanged();
|
||||||
updateButtonState();
|
updateButtonState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,6 +181,7 @@ public class FlightConfigurationDialog extends JDialog {
|
|||||||
motorConfigurationPanel.fireTableDataChanged();
|
motorConfigurationPanel.fireTableDataChanged();
|
||||||
flightConfigurationModel.fireContentsUpdated();
|
flightConfigurationModel.fireContentsUpdated();
|
||||||
recoveryConfigurationPanel.fireTableDataChanged();
|
recoveryConfigurationPanel.fireTableDataChanged();
|
||||||
|
separationConfigurationPanel.fireTableDataChanged();
|
||||||
updateButtonState();
|
updateButtonState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,6 +198,7 @@ public class FlightConfigurationDialog extends JDialog {
|
|||||||
motorConfigurationPanel.fireTableDataChanged();
|
motorConfigurationPanel.fireTableDataChanged();
|
||||||
flightConfigurationModel.fireContentsUpdated();
|
flightConfigurationModel.fireContentsUpdated();
|
||||||
recoveryConfigurationPanel.fireTableDataChanged();
|
recoveryConfigurationPanel.fireTableDataChanged();
|
||||||
|
separationConfigurationPanel.fireTableDataChanged();
|
||||||
updateButtonState();
|
updateButtonState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,6 +214,7 @@ public class FlightConfigurationDialog extends JDialog {
|
|||||||
renameConfButton.setEnabled(currentID != null);
|
renameConfButton.setEnabled(currentID != null);
|
||||||
motorConfigurationPanel.updateButtonState();
|
motorConfigurationPanel.updateButtonState();
|
||||||
recoveryConfigurationPanel.updateButtonState();
|
recoveryConfigurationPanel.updateButtonState();
|
||||||
|
separationConfigurationPanel.updateButtonState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -0,0 +1,105 @@
|
|||||||
|
package net.sf.openrocket.gui.dialogs.flightconfiguration;
|
||||||
|
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
|
||||||
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JComboBox;
|
||||||
|
import javax.swing.JDialog;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JSpinner;
|
||||||
|
|
||||||
|
import net.miginfocom.swing.MigLayout;
|
||||||
|
import net.sf.openrocket.gui.SpinnerEditor;
|
||||||
|
import net.sf.openrocket.gui.adaptors.BasicEnumModel;
|
||||||
|
import net.sf.openrocket.gui.adaptors.DoubleModel;
|
||||||
|
import net.sf.openrocket.gui.components.StyledLabel;
|
||||||
|
import net.sf.openrocket.gui.components.StyledLabel.Style;
|
||||||
|
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||||
|
import net.sf.openrocket.rocketcomponent.Stage;
|
||||||
|
import net.sf.openrocket.rocketcomponent.StageSeparationConfiguration;
|
||||||
|
import net.sf.openrocket.rocketcomponent.StageSeparationConfiguration.SeparationEvent;
|
||||||
|
import net.sf.openrocket.unit.UnitGroup;
|
||||||
|
|
||||||
|
public class SelectSeparationConfigDialog extends JDialog {
|
||||||
|
|
||||||
|
StageSeparationConfiguration newConfiguration;
|
||||||
|
|
||||||
|
SelectSeparationConfigDialog( JDialog parent, final Rocket rocket, final Stage component ) {
|
||||||
|
super(parent);
|
||||||
|
super.setModal(true);
|
||||||
|
final String configId = rocket.getDefaultConfiguration().getFlightConfigurationID();
|
||||||
|
|
||||||
|
newConfiguration = component.getFlightConfiguration(configId);
|
||||||
|
if ( newConfiguration == null ) {
|
||||||
|
newConfiguration = component.getDefaultFlightConfiguration().clone();
|
||||||
|
} else {
|
||||||
|
// Clone the existing so cancel works. When the user selects OK, this configuration
|
||||||
|
// is put back in there.
|
||||||
|
newConfiguration = newConfiguration.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
JPanel panel = new JPanel(new MigLayout("fill"));
|
||||||
|
|
||||||
|
// Select separation event
|
||||||
|
panel.add(new StyledLabel(FlightConfigurationDialog.trans.get("StageConfig.separation.lbl.title"), Style.BOLD), "spanx, wrap rel");
|
||||||
|
|
||||||
|
final JComboBox event = new JComboBox(new BasicEnumModel<SeparationEvent>(SeparationEvent.class));
|
||||||
|
event.setSelectedItem( newConfiguration.getSeparationEvent() );
|
||||||
|
panel.add(event, "");
|
||||||
|
|
||||||
|
// ... and delay
|
||||||
|
panel.add(new JLabel(FlightConfigurationDialog.trans.get("StageConfig.separation.lbl.plus")), "");
|
||||||
|
|
||||||
|
final DoubleModel delay = new DoubleModel(newConfiguration.getSeparationDelay(), UnitGroup.UNITS_NONE, 0);
|
||||||
|
JSpinner spin = new JSpinner(delay.getSpinnerModel());
|
||||||
|
spin.setEditor(new SpinnerEditor(spin));
|
||||||
|
panel.add(spin, "width 45");
|
||||||
|
|
||||||
|
//// seconds
|
||||||
|
panel.add(new JLabel(FlightConfigurationDialog.trans.get("StageConfig.separation.lbl.seconds")), "wrap unrel");
|
||||||
|
|
||||||
|
|
||||||
|
JButton okButton = new JButton(FlightConfigurationDialog.trans.get("button.ok"));
|
||||||
|
okButton.addActionListener( new ActionListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
|
||||||
|
//// extract event type;
|
||||||
|
SeparationEvent eventType = (SeparationEvent) event.getSelectedItem();
|
||||||
|
newConfiguration.setSeparationEvent(eventType);
|
||||||
|
|
||||||
|
//// extract delay time;
|
||||||
|
double separationDelay = delay.getValue();
|
||||||
|
newConfiguration.setSeparationDelay(separationDelay);
|
||||||
|
|
||||||
|
component.setFlightConfiguration(configId, newConfiguration);
|
||||||
|
|
||||||
|
SelectSeparationConfigDialog.this.setVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
panel.add( okButton );
|
||||||
|
|
||||||
|
JButton cancel = new JButton(FlightConfigurationDialog.trans.get("button.cancel"));
|
||||||
|
cancel.addActionListener( new ActionListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
SelectSeparationConfigDialog.this.setVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
panel.add( cancel );
|
||||||
|
|
||||||
|
this.setContentPane(panel);
|
||||||
|
this.validate();
|
||||||
|
this.pack();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,183 @@
|
|||||||
|
package net.sf.openrocket.gui.dialogs.flightconfiguration;
|
||||||
|
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.awt.event.MouseAdapter;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JDialog;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JScrollPane;
|
||||||
|
import javax.swing.JTable;
|
||||||
|
import javax.swing.ListSelectionModel;
|
||||||
|
import javax.swing.table.AbstractTableModel;
|
||||||
|
|
||||||
|
import net.miginfocom.swing.MigLayout;
|
||||||
|
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||||
|
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||||
|
import net.sf.openrocket.rocketcomponent.Stage;
|
||||||
|
import net.sf.openrocket.rocketcomponent.StageSeparationConfiguration;
|
||||||
|
|
||||||
|
public class SeparationConfigurationPanel extends JPanel {
|
||||||
|
|
||||||
|
private final FlightConfigurationDialog flightConfigurationDialog;
|
||||||
|
private final Rocket rocket;
|
||||||
|
private final Stage[] stages;
|
||||||
|
|
||||||
|
private final SeparationTableModel separationTableModel;
|
||||||
|
private final JButton selectSeparationButton;
|
||||||
|
private final JButton resetDeploymentButton;
|
||||||
|
|
||||||
|
private Stage selectedComponent;
|
||||||
|
|
||||||
|
SeparationConfigurationPanel( FlightConfigurationDialog flightConfigurationDialog, Rocket rocket ) {
|
||||||
|
super( new MigLayout("fill") );
|
||||||
|
this.flightConfigurationDialog = flightConfigurationDialog;
|
||||||
|
this.rocket = rocket;
|
||||||
|
|
||||||
|
int stageCount = rocket.getStageCount() -1;
|
||||||
|
stages = new Stage[stageCount];
|
||||||
|
Iterator<RocketComponent> it = rocket.iterator();
|
||||||
|
{
|
||||||
|
int stageIndex = -1;
|
||||||
|
while( it.hasNext() ) {
|
||||||
|
RocketComponent c = it.next();
|
||||||
|
if ( c instanceof Stage ) {
|
||||||
|
if ( stageIndex >= 0 ){
|
||||||
|
stages[stageIndex] = (Stage) c;
|
||||||
|
}
|
||||||
|
stageIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//// Recovery selection
|
||||||
|
separationTableModel = new SeparationTableModel();
|
||||||
|
JTable table = new JTable( separationTableModel );
|
||||||
|
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||||
|
table.setCellSelectionEnabled(true);
|
||||||
|
table.addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mouseClicked(MouseEvent e) {
|
||||||
|
JTable table = (JTable) e.getComponent();
|
||||||
|
int row = table.getSelectedRow();
|
||||||
|
int column = table.getSelectedColumn();
|
||||||
|
|
||||||
|
if ( row >= 0 ) {
|
||||||
|
selectedComponent = stages[row];
|
||||||
|
} else {
|
||||||
|
selectedComponent = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.getClickCount() == 1) {
|
||||||
|
// Single click updates selection
|
||||||
|
updateButtonState();
|
||||||
|
} else if (e.getClickCount() == 2) {
|
||||||
|
// Double-click edits
|
||||||
|
selectDeployment();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
JScrollPane scroll = new JScrollPane(table);
|
||||||
|
this.add(scroll, "span, grow, wrap");
|
||||||
|
|
||||||
|
//// Select deployment
|
||||||
|
selectSeparationButton = new JButton(FlightConfigurationDialog.trans.get("edtmotorconfdlg.but.Selectseparation"));
|
||||||
|
selectSeparationButton.setEnabled(false);
|
||||||
|
selectSeparationButton.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
selectDeployment();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.add(selectSeparationButton, "skip, split, sizegroup button");
|
||||||
|
|
||||||
|
//// Reset deployment
|
||||||
|
resetDeploymentButton = new JButton(FlightConfigurationDialog.trans.get("edtmotorconfdlg.but.Resetseparation"));
|
||||||
|
resetDeploymentButton.setEnabled(false);
|
||||||
|
resetDeploymentButton.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
resetDeployment();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.add(resetDeploymentButton,"sizegroup button, wrap");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fireTableDataChanged() {
|
||||||
|
selectedComponent = null;
|
||||||
|
separationTableModel.fireTableDataChanged();
|
||||||
|
updateButtonState();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void selectDeployment() {
|
||||||
|
JDialog d = new SelectSeparationConfigDialog( flightConfigurationDialog, rocket, selectedComponent );
|
||||||
|
d.setVisible(true);
|
||||||
|
fireTableDataChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resetDeployment() {
|
||||||
|
selectedComponent.setFlightConfiguration(rocket.getDefaultConfiguration().getFlightConfigurationID(), null);
|
||||||
|
fireTableDataChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateButtonState() {
|
||||||
|
boolean componentSelected = selectedComponent != null;
|
||||||
|
boolean isDefaulted = true;
|
||||||
|
if ( componentSelected ) {
|
||||||
|
isDefaulted = selectedComponent.getFlightConfiguration(rocket.getDefaultConfiguration().getFlightConfigurationID()) == null;
|
||||||
|
}
|
||||||
|
selectSeparationButton.setEnabled(componentSelected);
|
||||||
|
resetDeploymentButton.setEnabled(componentSelected & ! isDefaulted);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class SeparationTableModel extends AbstractTableModel {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRowCount() {
|
||||||
|
return stages.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getColumnCount() {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||||
|
Stage d = SeparationConfigurationPanel.this.stages[rowIndex];
|
||||||
|
switch ( columnIndex ) {
|
||||||
|
case 0:
|
||||||
|
return d.getName();
|
||||||
|
case 1:
|
||||||
|
StageSeparationConfiguration separationConfig = d.getFlightConfiguration(rocket.getDefaultConfiguration().getFlightConfigurationID());
|
||||||
|
if ( separationConfig == null ) {
|
||||||
|
return "[" + d.getDefaultFlightConfiguration().toString() + "]";
|
||||||
|
} else {
|
||||||
|
return separationConfig.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getColumnName(int column) {
|
||||||
|
switch ( column ) {
|
||||||
|
case 0:
|
||||||
|
return FlightConfigurationDialog.trans.get("edtmotorconfdlg.tbl.Stageheader");
|
||||||
|
case 1:
|
||||||
|
return FlightConfigurationDialog.trans.get("edtmotorconfdlg.tbl.Separationheader");
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,14 +1,18 @@
|
|||||||
package net.sf.openrocket.rocketcomponent;
|
package net.sf.openrocket.rocketcomponent;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import net.sf.openrocket.l10n.Translator;
|
import net.sf.openrocket.l10n.Translator;
|
||||||
import net.sf.openrocket.startup.Application;
|
import net.sf.openrocket.startup.Application;
|
||||||
import net.sf.openrocket.util.MathUtil;
|
import net.sf.openrocket.util.MathUtil;
|
||||||
|
|
||||||
public class Stage extends ComponentAssembly {
|
public class Stage extends ComponentAssembly implements FlightConfigurable<StageSeparationConfiguration> {
|
||||||
|
|
||||||
static final Translator trans = Application.getTranslator();
|
static final Translator trans = Application.getTranslator();
|
||||||
|
|
||||||
private final StageSeparationConfiguration defaultConfiguration = new StageSeparationConfiguration();
|
private StageSeparationConfiguration defaultConfiguration = new StageSeparationConfiguration();
|
||||||
|
private final Map<String,StageSeparationConfiguration> configuration = new HashMap<String,StageSeparationConfiguration>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getComponentName() {
|
public String getComponentName() {
|
||||||
@ -61,4 +65,57 @@ public class Stage extends ComponentAssembly {
|
|||||||
public boolean isCompatible(Class<? extends RocketComponent> type) {
|
public boolean isCompatible(Class<? extends RocketComponent> type) {
|
||||||
return BodyComponent.class.isAssignableFrom(type);
|
return BodyComponent.class.isAssignableFrom(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StageSeparationConfiguration getFlightConfiguration(String configId) {
|
||||||
|
return configuration.get(configId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFlightConfiguration(String configId, StageSeparationConfiguration config) {
|
||||||
|
if ( config == null ) {
|
||||||
|
configuration.remove(configId);
|
||||||
|
} else {
|
||||||
|
configuration.put(configId,config);
|
||||||
|
}
|
||||||
|
fireComponentChangeEvent(ComponentChangeEvent.EVENT_CHANGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cloneFlightConfiguration(String oldConfigId, String newConfigId) {
|
||||||
|
StageSeparationConfiguration oldConfig = configuration.get(oldConfigId);
|
||||||
|
if ( oldConfig == null ) {
|
||||||
|
configuration.remove(newConfigId);
|
||||||
|
} else {
|
||||||
|
StageSeparationConfiguration newConfig = oldConfig.clone();
|
||||||
|
configuration.put(newConfigId, newConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StageSeparationConfiguration getDefaultFlightConfiguration() {
|
||||||
|
return defaultConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDefaultFlightConfiguration(StageSeparationConfiguration config) {
|
||||||
|
this.defaultConfiguration = config;
|
||||||
|
fireComponentChangeEvent(ComponentChangeEvent.EVENT_CHANGE);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Object clone() throws CloneNotSupportedException {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return super.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,19 @@
|
|||||||
package net.sf.openrocket.rocketcomponent;
|
package net.sf.openrocket.rocketcomponent;
|
||||||
|
|
||||||
|
import net.sf.openrocket.l10n.Translator;
|
||||||
import net.sf.openrocket.simulation.FlightEvent;
|
import net.sf.openrocket.simulation.FlightEvent;
|
||||||
|
import net.sf.openrocket.startup.Application;
|
||||||
|
|
||||||
public class StageSeparationConfiguration {
|
public class StageSeparationConfiguration implements Cloneable {
|
||||||
|
|
||||||
|
private static final Translator trans = Application.getTranslator();
|
||||||
|
|
||||||
private StageSeparationConfiguration.SeparationEvent separationEvent = StageSeparationConfiguration.SeparationEvent.UPPER_IGNITION;
|
private StageSeparationConfiguration.SeparationEvent separationEvent = StageSeparationConfiguration.SeparationEvent.UPPER_IGNITION;
|
||||||
private double separationDelay = 0;
|
private double separationDelay = 0;
|
||||||
|
|
||||||
public static enum SeparationEvent {
|
public static enum SeparationEvent {
|
||||||
//// Upper stage motor ignition
|
//// Upper stage motor ignition
|
||||||
UPPER_IGNITION("Stage.SeparationEvent.UPPER_IGNITION") {
|
UPPER_IGNITION(trans.get("Stage.SeparationEvent.UPPER_IGNITION")) {
|
||||||
@Override
|
@Override
|
||||||
public boolean isSeparationEvent(FlightEvent e, Stage stage) {
|
public boolean isSeparationEvent(FlightEvent e, Stage stage) {
|
||||||
if (e.getType() != FlightEvent.Type.IGNITION)
|
if (e.getType() != FlightEvent.Type.IGNITION)
|
||||||
@ -21,7 +25,7 @@ public class StageSeparationConfiguration {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
//// Current stage motor ignition
|
//// Current stage motor ignition
|
||||||
IGNITION("Stage.SeparationEvent.IGNITION") {
|
IGNITION(trans.get("Stage.SeparationEvent.IGNITION")) {
|
||||||
@Override
|
@Override
|
||||||
public boolean isSeparationEvent(FlightEvent e, Stage stage) {
|
public boolean isSeparationEvent(FlightEvent e, Stage stage) {
|
||||||
if (e.getType() != FlightEvent.Type.IGNITION)
|
if (e.getType() != FlightEvent.Type.IGNITION)
|
||||||
@ -33,7 +37,7 @@ public class StageSeparationConfiguration {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
//// Current stage motor burnout
|
//// Current stage motor burnout
|
||||||
BURNOUT("Stage.SeparationEvent.BURNOUT") {
|
BURNOUT(trans.get("Stage.SeparationEvent.BURNOUT")) {
|
||||||
@Override
|
@Override
|
||||||
public boolean isSeparationEvent(FlightEvent e, Stage stage) {
|
public boolean isSeparationEvent(FlightEvent e, Stage stage) {
|
||||||
if (e.getType() != FlightEvent.Type.BURNOUT)
|
if (e.getType() != FlightEvent.Type.BURNOUT)
|
||||||
@ -45,7 +49,7 @@ public class StageSeparationConfiguration {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
//// Current stage ejection charge
|
//// Current stage ejection charge
|
||||||
EJECTION("Stage.SeparationEvent.EJECTION") {
|
EJECTION(trans.get("Stage.SeparationEvent.EJECTION")) {
|
||||||
@Override
|
@Override
|
||||||
public boolean isSeparationEvent(FlightEvent e, Stage stage) {
|
public boolean isSeparationEvent(FlightEvent e, Stage stage) {
|
||||||
if (e.getType() != FlightEvent.Type.EJECTION_CHARGE)
|
if (e.getType() != FlightEvent.Type.EJECTION_CHARGE)
|
||||||
@ -57,14 +61,14 @@ public class StageSeparationConfiguration {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
//// Launch
|
//// Launch
|
||||||
LAUNCH("Stage.SeparationEvent.LAUNCH") {
|
LAUNCH(trans.get("Stage.SeparationEvent.LAUNCH")) {
|
||||||
@Override
|
@Override
|
||||||
public boolean isSeparationEvent(FlightEvent e, Stage stage) {
|
public boolean isSeparationEvent(FlightEvent e, Stage stage) {
|
||||||
return e.getType() == FlightEvent.Type.LAUNCH;
|
return e.getType() == FlightEvent.Type.LAUNCH;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
//// Never
|
//// Never
|
||||||
NEVER("Stage.SeparationEvent.NEVER") {
|
NEVER(trans.get("Stage.SeparationEvent.NEVER")) {
|
||||||
@Override
|
@Override
|
||||||
public boolean isSeparationEvent(FlightEvent e, Stage stage) {
|
public boolean isSeparationEvent(FlightEvent e, Stage stage) {
|
||||||
return false;
|
return false;
|
||||||
@ -86,7 +90,7 @@ public class StageSeparationConfiguration {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return Stage.trans.get(description);
|
return description;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,4 +111,21 @@ public class StageSeparationConfiguration {
|
|||||||
this.separationDelay = separationDelay;
|
this.separationDelay = separationDelay;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
if ( separationDelay > 0 ) {
|
||||||
|
return separationEvent.toString() + " +" + separationDelay + "s";
|
||||||
|
} else {
|
||||||
|
return separationEvent.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StageSeparationConfiguration clone() {
|
||||||
|
StageSeparationConfiguration clone = new StageSeparationConfiguration();
|
||||||
|
clone.separationEvent = this.separationEvent;
|
||||||
|
clone.separationDelay = this.separationDelay;
|
||||||
|
return clone;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ import net.sf.openrocket.rocketcomponent.MotorMount;
|
|||||||
import net.sf.openrocket.rocketcomponent.RecoveryDevice;
|
import net.sf.openrocket.rocketcomponent.RecoveryDevice;
|
||||||
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.simulation.exception.MotorIgnitionException;
|
import net.sf.openrocket.simulation.exception.MotorIgnitionException;
|
||||||
import net.sf.openrocket.simulation.exception.SimulationException;
|
import net.sf.openrocket.simulation.exception.SimulationException;
|
||||||
import net.sf.openrocket.simulation.exception.SimulationLaunchException;
|
import net.sf.openrocket.simulation.exception.SimulationLaunchException;
|
||||||
@ -367,9 +368,13 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
Stage stage = (Stage) status.getConfiguration().getRocket().getChild(stageNo);
|
Stage stage = (Stage) status.getConfiguration().getRocket().getChild(stageNo);
|
||||||
if (stage.getDefaultSeparationEvent().isSeparationEvent(event, stage)) {
|
StageSeparationConfiguration separationConfig = stage.getFlightConfiguration(flightConfigurationId);
|
||||||
|
if ( separationConfig == null ) {
|
||||||
|
separationConfig = stage.getDefaultFlightConfiguration();
|
||||||
|
}
|
||||||
|
if (separationConfig.getSeparationEvent().isSeparationEvent(event, stage)) {
|
||||||
addEvent(new FlightEvent(FlightEvent.Type.STAGE_SEPARATION,
|
addEvent(new FlightEvent(FlightEvent.Type.STAGE_SEPARATION,
|
||||||
event.getTime() + stage.getDefaultSeparationDelay(), stage));
|
event.getTime() + separationConfig.getSeparationDelay(), stage));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user