diff --git a/.gitignore b/.gitignore index 896cbbf5f..ae7b42e47 100644 --- a/.gitignore +++ b/.gitignore @@ -37,9 +37,6 @@ /core/resources-src/pix/sormus.xcf.gz /core/resources-src/pix/splashscreen-sormus.png /core/resources-src/pix/splashscreen-sormus.xcf.gz -<<<<<<< HEAD -/*/bin/ -/android-libraries/*/bin/ -======= ->>>>>>> Convert svn:ignore properties to .gitignore. +/swing/build +/swing/tmp diff --git a/.travis.yml b/.travis.yml index bb0b5b3ad..5d030ed65 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,4 @@ language: java jdk: - oraclejdk7 script: - - "cd core" - - "ant -buildfile build.xml clean checkascii build jar" - - "ant -buildfile build.xml unittest-no-junit-report" + - "ant -buildfile build.xml clean check jar unittest" diff --git a/build.xml b/build.xml new file mode 100644 index 000000000..b568e33ea --- /dev/null +++ b/build.xml @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Checking project for FIXMEs. + + + + + + + + + + + + + + + + + + + + + + CRITICAL TODOs exist in project: +${criticaltodos} + No critical TODOs in project. + + + + + + + Checking project for non-ASCII characters. + + + + + + + + + + + + + + + + + + + + + + Non-ASCII characters exist in project: +${nonascii} + No non-ASCII characters in project. + + + diff --git a/core/.classpath b/core/.classpath index 40137a329..753ef1030 100644 --- a/core/.classpath +++ b/core/.classpath @@ -10,29 +10,20 @@ - - - - - - - - - - - - - - - - - + + + + + + + + diff --git a/core/.project b/core/.project index 977f74894..c92bdfc1f 100644 --- a/core/.project +++ b/core/.project @@ -1,6 +1,6 @@ - OpenRocket + OpenRocket Core diff --git a/core/build.xml b/core/build.xml index 48f7aed46..bc94e848c 100644 --- a/core/build.xml +++ b/core/build.xml @@ -1,4 +1,4 @@ - + @@ -7,7 +7,7 @@ - + @@ -23,14 +23,6 @@ - - - - - - - - @@ -51,13 +43,6 @@ - - - - - - - @@ -74,56 +59,20 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Generating ORC file for vendor @{vendor} - - - - - - - - - - - - - - - - - - - - - - Building source distribution - - - - - - - - - - - - - - - - - - Testing source distribution - - - - - - - - - Source distribution test successful - - - - - - - - - - - - - Distribution ${build.version} (${build.source}) built into directory ${jar.dir} - - - - - - - - - - - Checking project for FIXMEs. - - - - - - - - - - - - - - - - CRITICAL TODOs exist in project: -${criticaltodos} - No critical TODOs in project. - - - - - - - - Checking project for non-ASCII characters. - - - - - - - - - - - - - - - - Non-ASCII characters exist in project: -${nonascii} - No non-ASCII characters in project. - - @@ -278,7 +92,7 @@ ${nonascii} Running unit tests - + @@ -291,6 +105,7 @@ ${nonascii} + diff --git a/core/lib/annotation-detector-3.0.2-SNAPSHOT.jar b/core/lib/annotation-detector-3.0.2-SNAPSHOT.jar deleted file mode 100644 index bab8dc3e1..000000000 Binary files a/core/lib/annotation-detector-3.0.2-SNAPSHOT.jar and /dev/null differ diff --git a/core/lib/annotation-detector-3.0.2.jar b/core/lib/annotation-detector-3.0.2.jar new file mode 100644 index 000000000..bcf3a6212 Binary files /dev/null and b/core/lib/annotation-detector-3.0.2.jar differ diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties index 7d169196e..3a3c4ab53 100644 --- a/core/resources/l10n/messages.properties +++ b/core/resources/l10n/messages.properties @@ -52,12 +52,12 @@ RocketPanel.FigTypeAct.Unfinished = 3D Unfinished RocketPanel.lbl.Flightcfg = Flight configuration: -RocketPanel.but.FlightcfgEdit = Edit RocketPanel.lbl.infoMessage = Click to select    Shift+click to select other    Double-click to edit    Click+drag to move RocketPanel.lbl.ViewType = View Type: ! BasicFrame BasicFrame.tab.Rocketdesign = Rocket design +BasicFrame.tab.Flightconfig = Configurations BasicFrame.tab.Flightsim = Flight simulations BasicFrame.title.Addnewcomp = Add new component BasicFrame.dlg.lbl1 = Design ' @@ -174,10 +174,11 @@ debuglogdlg.lbl.Stacktrace = Stack trace: MotorChooserDialog.title = Select a rocket motor ! Edit Motor configuration dialog -edtmotorconfdlg.but.Removeconfiguration = Remove -edtmotorconfdlg.but.Renameconfiguration = Rename -edtmotorconfdlg.but.Newconfiguration = New -edtmotorconfdlg.but.Copyconfiguration = Copy +edtmotorconfdlg.col.configuration = Configuration +edtmotorconfdlg.but.Removeconfiguration = Remove Configuration +edtmotorconfdlg.but.Renameconfiguration = Rename Configuration +edtmotorconfdlg.but.Newconfiguration = New Configuration +edtmotorconfdlg.but.Copyconfiguration = Copy Configuration edtmotorconfdlg.title.Editmotorconf = Edit Flight configurations edtmotorconfdlg.title.Renameconf = Rename Flight Configuration edtmotorconfdlg.title.Selectdeploymentconf = Select Deployment Configuration @@ -325,7 +326,6 @@ simedtdlg.tab.Plotdata = Plot data simedtdlg.tab.CustomExpressions = Custom expressions simedtdlg.tab.Exportdata = Export data simedtdlg.lbl.Flightcfg = Flight configuration: -simedtdlg.but.FlightcfgEdit = Edit simedtdlg.lbl.ttip.Flightcfg = Select the flight configuration to use. simedtdlg.combo.ttip.Flightcfg = Select the flight configuration to use. simedtdlg.lbl.Wind = Wind @@ -1064,9 +1064,6 @@ TrapezoidFinSetCfg.lbl.plus = plus TrapezoidFinSetCfg.tab.General = General TrapezoidFinSetCfg.tab.Generalproperties = General properties -!MotorConfigurationModel -MotorCfgModel.Editcfg = Edit configurations - ! StorageOptionChooser StorageOptChooser.lbl.Simdatatostore = Simulated data to store: StorageOptChooser.rdbut.Allsimdata = All simulated data @@ -1087,10 +1084,15 @@ StorageOptChooser.lbl.Saveopt = Save options ! ThrustCurveMotorSelectionPanel TCMotorSelPan.lbl.Selrocketmotor = Select rocket motor: TCMotorSelPan.checkbox.hideSimilar = Hide very similar thrust curves -TCMotorSelPan.SHOW_DESCRIPTIONS.desc1 = Show all motors -TCMotorSelPan.SHOW_DESCRIPTIONS.desc2 = Show motors with diameter less than that of the motor mount -TCMotorSelPan.SHOW_DESCRIPTIONS.desc3 = Show motors with diameter equal to that of the motor mount -TCMotorSelPan.lbl.Motormountdia = Motor mount diameter: +TCMotorSelPan.checkbox.hideUsed = Hide motors already used in the mount +TCMotorSelPan.checkbox.limitlength = Limit motor length to mount length +TCMotorSelPan.checkbox.limitdiameter = Limit motor diameter to mount diameter +TCMotorSelPan.btn.details = Show Details +TCMotorSelPan.btn.filter = Filter Motors +TCMotorSelPan.MotorSize = Motor Dimensions +TCMotorSelPan.Diameter = Daimeter +TCMotorSelPan.Length = Length +TCMotorSelPan.MotorMountDimensions = Motor mount dimensions: TCMotorSelPan.lbl.Search = Search: TCMotorSelPan.lbl.Selectthrustcurve = Select thrust curve: TCMotorSelPan.lbl.Ejectionchargedelay = Ejection charge delay: @@ -1108,6 +1110,10 @@ TCMotorSelPan.title.Thrustcurve = Thrust curve: TCMotorSelPan.title.Thrust = Thrust TCMotorSelPan.delayBox.None = None TCMotorSelPan.noDescription = No description available. +TCMotorSelPan.btn.checkAll = Select All +TCMotorSelPan.btn.checkNone = Clear All +TCMotorSelPan.btn.close = Close + ! PlotDialog diff --git a/core/src/net/sf/openrocket/file/rocksim/export/InnerBodyTubeDTO.java b/core/src/net/sf/openrocket/file/rocksim/export/InnerBodyTubeDTO.java index 8b040395e..cf995a54d 100644 --- a/core/src/net/sf/openrocket/file/rocksim/export/InnerBodyTubeDTO.java +++ b/core/src/net/sf/openrocket/file/rocksim/export/InnerBodyTubeDTO.java @@ -1,7 +1,12 @@ package net.sf.openrocket.file.rocksim.export; +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + import net.sf.openrocket.file.rocksim.RocksimCommonConstants; -import net.sf.openrocket.gui.configdialog.InnerTubeConfig; import net.sf.openrocket.rocketcomponent.BodyTube; import net.sf.openrocket.rocketcomponent.Bulkhead; import net.sf.openrocket.rocketcomponent.CenteringRing; @@ -15,110 +20,105 @@ import net.sf.openrocket.rocketcomponent.Transition; import net.sf.openrocket.rocketcomponent.TubeCoupler; import net.sf.openrocket.util.Coordinate; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; -import java.util.List; - /** * This class models the XML element for a Rocksim inside tube. */ @XmlRootElement(name = RocksimCommonConstants.BODY_TUBE) @XmlAccessorType(XmlAccessType.FIELD) public class InnerBodyTubeDTO extends BodyTubeDTO implements AttachableParts { - - /** - * Constructor. - */ - public InnerBodyTubeDTO() { - super.setInsideTube(true); - } - - /** - * Full copy constructor. - * - * @param bt the corresponding OR inner body tube - * @param parent the attached parts (subcomponents in Rocksim speak) of the InnerTube's parent. This instance - * is a member of those attached parts, as well as all sibling components. This is passed in the - * event that the inner tube is a cluster. In that situation this instance will be removed and - * individual instances for each cluster member will be added. - */ - public InnerBodyTubeDTO(InnerTube bt, AttachableParts parent) { - super(bt); - setEngineOverhang(bt.getMotorOverhang() * RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH); - setID(bt.getInnerRadius() * RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS); - setOD(bt.getOuterRadius() * RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS); - setMotorDia((bt.getMotorMountDiameter() / 2) * RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS); - setMotorMount(bt.isMotorMount()); - setInsideTube(true); - setRadialAngle(bt.getRadialDirection()); - setRadialLoc(bt.getRadialPosition() * RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH); - - List children = bt.getChildren(); - for (int i = 0; i < children.size(); i++) { - RocketComponent rocketComponents = children.get(i); - if (rocketComponents instanceof InnerTube) { - final InnerTube innerTube = (InnerTube) rocketComponents; - //Only if the inner tube is NOT a cluster, then create the corresponding Rocksim DTO and add it - //to the list of attached parts. If it is a cluster, then it is handled specially outside of this - //loop. - if (innerTube.getClusterCount() == 1) { - attachedParts.add(new InnerBodyTubeDTO(innerTube, this)); - } - } else if (rocketComponents instanceof BodyTube) { - attachedParts.add(new BodyTubeDTO((BodyTube) rocketComponents)); - } else if (rocketComponents instanceof Transition) { - attachedParts.add(new TransitionDTO((Transition) rocketComponents)); - } else if (rocketComponents instanceof EngineBlock) { - attachedParts.add(new EngineBlockDTO((EngineBlock) rocketComponents)); - } else if (rocketComponents instanceof TubeCoupler) { - attachedParts.add(new TubeCouplerDTO((TubeCoupler) rocketComponents)); - } else if (rocketComponents instanceof CenteringRing) { - attachedParts.add(new CenteringRingDTO((CenteringRing) rocketComponents)); - } else if (rocketComponents instanceof Bulkhead) { - attachedParts.add(new BulkheadDTO((Bulkhead) rocketComponents)); - } else if (rocketComponents instanceof Streamer) { - attachedParts.add(new StreamerDTO((Streamer) rocketComponents)); - } else if (rocketComponents instanceof Parachute) { - attachedParts.add(new ParachuteDTO((Parachute) rocketComponents)); - } else if (rocketComponents instanceof MassObject) { - attachedParts.add(new MassObjectDTO((MassObject) rocketComponents)); - } - } - //Do the cluster. For now this splits the cluster into separate tubes, which is how Rocksim represents it. - //The import (from Rocksim to OR) could be augmented to be more intelligent and try to determine if the - //co-located tubes are a cluster. - if (bt.getClusterConfiguration().getClusterCount() > 1) { - handleCluster(bt, parent); - parent.removeAttachedPart(this); - } - } - - - /** - * Handle the inner tube as a cluster. This amounts to splitting it up so that each motor mount in the cluster - * is created individually to support Rocksim's view of clusters. - * - * @param it the clustered tube - * @param p the collection (parent's attached parts really) to which all cluster tubes will be added - */ - private void handleCluster(InnerTube it, AttachableParts p) { - - Coordinate[] coords = {Coordinate.NUL}; - coords = it.shiftCoordinates(coords); - for (int x = 0; x < coords.length; x++) { - InnerTube partialClone = InnerTubeConfig.makeIndividualClusterComponent(coords[x], it.getName() + " #" + (x + 1), it); - p.addAttachedPart(new InnerBodyTubeDTO(partialClone, p)); - } - } - - @Override - public void addAttachedPart(BasePartDTO part) { - attachedParts.add(part); - } - - @Override - public void removeAttachedPart(BasePartDTO part) { - attachedParts.remove(part); - } + + /** + * Constructor. + */ + public InnerBodyTubeDTO() { + super.setInsideTube(true); + } + + /** + * Full copy constructor. + * + * @param bt the corresponding OR inner body tube + * @param parent the attached parts (subcomponents in Rocksim speak) of the InnerTube's parent. This instance + * is a member of those attached parts, as well as all sibling components. This is passed in the + * event that the inner tube is a cluster. In that situation this instance will be removed and + * individual instances for each cluster member will be added. + */ + public InnerBodyTubeDTO(InnerTube bt, AttachableParts parent) { + super(bt); + setEngineOverhang(bt.getMotorOverhang() * RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH); + setID(bt.getInnerRadius() * RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS); + setOD(bt.getOuterRadius() * RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS); + setMotorDia((bt.getMotorMountDiameter() / 2) * RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS); + setMotorMount(bt.isMotorMount()); + setInsideTube(true); + setRadialAngle(bt.getRadialDirection()); + setRadialLoc(bt.getRadialPosition() * RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH); + + List children = bt.getChildren(); + for (int i = 0; i < children.size(); i++) { + RocketComponent rocketComponents = children.get(i); + if (rocketComponents instanceof InnerTube) { + final InnerTube innerTube = (InnerTube) rocketComponents; + //Only if the inner tube is NOT a cluster, then create the corresponding Rocksim DTO and add it + //to the list of attached parts. If it is a cluster, then it is handled specially outside of this + //loop. + if (innerTube.getClusterCount() == 1) { + attachedParts.add(new InnerBodyTubeDTO(innerTube, this)); + } + } else if (rocketComponents instanceof BodyTube) { + attachedParts.add(new BodyTubeDTO((BodyTube) rocketComponents)); + } else if (rocketComponents instanceof Transition) { + attachedParts.add(new TransitionDTO((Transition) rocketComponents)); + } else if (rocketComponents instanceof EngineBlock) { + attachedParts.add(new EngineBlockDTO((EngineBlock) rocketComponents)); + } else if (rocketComponents instanceof TubeCoupler) { + attachedParts.add(new TubeCouplerDTO((TubeCoupler) rocketComponents)); + } else if (rocketComponents instanceof CenteringRing) { + attachedParts.add(new CenteringRingDTO((CenteringRing) rocketComponents)); + } else if (rocketComponents instanceof Bulkhead) { + attachedParts.add(new BulkheadDTO((Bulkhead) rocketComponents)); + } else if (rocketComponents instanceof Streamer) { + attachedParts.add(new StreamerDTO((Streamer) rocketComponents)); + } else if (rocketComponents instanceof Parachute) { + attachedParts.add(new ParachuteDTO((Parachute) rocketComponents)); + } else if (rocketComponents instanceof MassObject) { + attachedParts.add(new MassObjectDTO((MassObject) rocketComponents)); + } + } + //Do the cluster. For now this splits the cluster into separate tubes, which is how Rocksim represents it. + //The import (from Rocksim to OR) could be augmented to be more intelligent and try to determine if the + //co-located tubes are a cluster. + if (bt.getClusterConfiguration().getClusterCount() > 1) { + handleCluster(bt, parent); + parent.removeAttachedPart(this); + } + } + + + /** + * Handle the inner tube as a cluster. This amounts to splitting it up so that each motor mount in the cluster + * is created individually to support Rocksim's view of clusters. + * + * @param it the clustered tube + * @param p the collection (parent's attached parts really) to which all cluster tubes will be added + */ + private void handleCluster(InnerTube it, AttachableParts p) { + + Coordinate[] coords = { Coordinate.NUL }; + coords = it.shiftCoordinates(coords); + for (int x = 0; x < coords.length; x++) { + InnerTube partialClone = InnerTube.makeIndividualClusterComponent(coords[x], it.getName() + " #" + (x + 1), it); + p.addAttachedPart(new InnerBodyTubeDTO(partialClone, p)); + } + } + + @Override + public void addAttachedPart(BasePartDTO part) { + attachedParts.add(part); + } + + @Override + public void removeAttachedPart(BasePartDTO part) { + attachedParts.remove(part); + } } diff --git a/core/src/net/sf/openrocket/gui/configdialog/MotorConfig.java b/core/src/net/sf/openrocket/gui/configdialog/MotorConfig.java deleted file mode 100644 index 03882cce5..000000000 --- a/core/src/net/sf/openrocket/gui/configdialog/MotorConfig.java +++ /dev/null @@ -1,261 +0,0 @@ -package net.sf.openrocket.gui.configdialog; - - -import java.awt.Component; -import java.awt.Container; -import java.awt.Font; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; - -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JComboBox; -import javax.swing.JDialog; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JSpinner; -import javax.swing.SwingUtilities; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; - -import net.miginfocom.swing.MigLayout; -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.EnumModel; -import net.sf.openrocket.gui.adaptors.FlightConfigurationModel; -import net.sf.openrocket.gui.components.BasicSlider; -import net.sf.openrocket.gui.components.StyledLabel; -import net.sf.openrocket.gui.components.UnitSelector; -import net.sf.openrocket.gui.dialogs.flightconfiguration.FlightConfigurationDialog; -import net.sf.openrocket.gui.dialogs.motor.MotorChooserDialog; -import net.sf.openrocket.l10n.Translator; -import net.sf.openrocket.motor.Motor; -import net.sf.openrocket.motor.ThrustCurveMotor; -import net.sf.openrocket.rocketcomponent.Configuration; -import net.sf.openrocket.rocketcomponent.IgnitionConfiguration; -import net.sf.openrocket.rocketcomponent.MotorConfiguration; -import net.sf.openrocket.rocketcomponent.MotorMount; -import net.sf.openrocket.rocketcomponent.Rocket; -import net.sf.openrocket.rocketcomponent.RocketComponent; -import net.sf.openrocket.startup.Application; -import net.sf.openrocket.unit.UnitGroup; - -public class MotorConfig extends JPanel { - - private final Rocket rocket; - private final MotorMount mount; - private final Configuration configuration; - private JPanel panel; - private JLabel motorLabel; - private static final Translator trans = Application.getTranslator(); - - public MotorConfig(MotorMount motorMount) { - super(new MigLayout("fill")); - - this.rocket = ((RocketComponent) motorMount).getRocket(); - this.mount = motorMount; - this.configuration = ((RocketComponent) motorMount).getRocket().getDefaultConfiguration(); - - BooleanModel model; - - model = new BooleanModel(motorMount, "MotorMount"); - JCheckBox check = new JCheckBox(model); - ////This component is a motor mount - check.setText(trans.get("MotorCfg.checkbox.compmotormount")); - this.add(check, "wrap"); - - - panel = new JPanel(new MigLayout("fill")); - this.add(panel, "grow, wrap"); - - - // Motor configuration selector - //// Motor configuration: - panel.add(new JLabel(trans.get("MotorCfg.lbl.Flightcfg")), "shrink"); - - JComboBox combo = new JComboBox(new FlightConfigurationModel(configuration)); - panel.add(combo, "growx"); - combo.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - updateFields(); - } - - }); - - //// New button - JButton button = new JButton(trans.get("MotorCfg.but.New")); - button.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - String id = rocket.newFlightConfigurationID(); - configuration.setFlightConfigurationID(id); - } - }); - panel.add(button, ""); - - //// Edit button - button = new JButton(trans.get("MotorCfg.but.FlightcfgEdit")); - button.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - JDialog configDialog = new FlightConfigurationDialog(rocket, SwingUtilities.windowForComponent(MotorConfig.this)); - configDialog.show(); - } - }); - panel.add(button, "wrap unrel"); - - - // Current motor: - panel.add(new JLabel(trans.get("MotorCfg.lbl.Currentmotor")), "shrink"); - - motorLabel = new JLabel(); - motorLabel.setFont(motorLabel.getFont().deriveFont(Font.BOLD)); - updateFields(); - panel.add(motorLabel, "wrap unrel"); - - - - // Overhang - //// Motor overhang: - panel.add(new JLabel(trans.get("MotorCfg.lbl.Motoroverhang"))); - - DoubleModel dm = new DoubleModel(motorMount, "MotorOverhang", UnitGroup.UNITS_LENGTH); - - JSpinner spin = new JSpinner(dm.getSpinnerModel()); - spin.setEditor(new SpinnerEditor(spin)); - panel.add(spin, "span, split, width :65lp:"); - - panel.add(new UnitSelector(dm), "width :30lp:"); - panel.add(new BasicSlider(dm.getSliderModel(-0.02, 0.06)), "w 100lp, wrap unrel"); - - - - // Select ignition event - //// Ignition at: - panel.add(new JLabel(trans.get("MotorCfg.lbl.Ignitionat") + " " + CommonStrings.dagger), ""); - - IgnitionConfiguration ignitionConfig = mount.getIgnitionConfiguration().getDefault(); - combo = new JComboBox(new EnumModel(ignitionConfig, "IgnitionEvent")); - panel.add(combo, "growx, wrap"); - - // ... and delay - //// plus - panel.add(new JLabel(trans.get("MotorCfg.lbl.plus")), "gap indent, skip 1, span, split"); - - dm = new DoubleModel(ignitionConfig, "IgnitionDelay", 0); - spin = new JSpinner(dm.getSpinnerModel()); - spin.setEditor(new SpinnerEditor(spin, 3)); - panel.add(spin, "gap rel rel"); - - //// seconds - panel.add(new JLabel(trans.get("MotorCfg.lbl.seconds")), "wrap unrel"); - - panel.add(new StyledLabel(CommonStrings.override_description, -1), "spanx, wrap para"); - - - // Check stage count - RocketComponent c = (RocketComponent) mount; - c = c.getRocket(); - int stages = c.getChildCount(); - - if (stages == 1) { - //// The current design has only one stage. - //// Stages can be added by clicking \"New stage\". - - panel.add(new StyledLabel(trans.get("MotorCfg.lbl.longA1") + " " + - trans.get("MotorCfg.lbl.longA2"), -1), - "spanx, wrap para"); - } else { - //// The current design has - //// stages. - panel.add(new StyledLabel(trans.get("MotorCfg.lbl.longB1") + " " + stages + " " + - trans.get("MotorCfg.lbl.longB2"), -1), - "spanx, wrap para"); - } - - - // Select etc. buttons - //// Select motor - button = new JButton(trans.get("MotorCfg.but.Selectmotor")); - button.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - String id = configuration.getFlightConfigurationID(); - - MotorChooserDialog dialog = new MotorChooserDialog(mount.getMotor(id), - mount.getMotorDelay(id), mount.getMotorMountDiameter(), - SwingUtilities.getWindowAncestor(MotorConfig.this)); - dialog.setVisible(true); - Motor m = dialog.getSelectedMotor(); - double d = dialog.getSelectedDelay(); - - if (m != null) { - if (id == null) { - id = rocket.newFlightConfigurationID(); - configuration.setFlightConfigurationID(id); - } - MotorConfiguration config = new MotorConfiguration(); - config.setMotor(m); - config.setEjectionDelay(d); - mount.getMotorConfiguration().set(id, config); - } - updateFields(); - } - }); - panel.add(button, "span, split, growx"); - - //// Remove motor - button = new JButton(trans.get("MotorCfg.but.Removemotor")); - button.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - mount.getMotorConfiguration().resetDefault(configuration.getFlightConfigurationID()); - updateFields(); - } - }); - panel.add(button, "growx, wrap"); - - - - - - // Set enabled status - - setDeepEnabled(panel, motorMount.isMotorMount()); - check.addChangeListener(new ChangeListener() { - @Override - public void stateChanged(ChangeEvent e) { - setDeepEnabled(panel, mount.isMotorMount()); - } - }); - - } - - public void updateFields() { - String id = configuration.getFlightConfigurationID(); - Motor m = mount.getMotor(id); - if (m == null) { - //// None - motorLabel.setText(trans.get("MotorCfg.lbl.motorLabel")); - } else { - String str = ""; - if (m instanceof ThrustCurveMotor) - str = ((ThrustCurveMotor) m).getManufacturer() + " "; - str += m.getDesignation(mount.getMotorDelay(id)); - motorLabel.setText(str); - } - } - - - private static void setDeepEnabled(Component component, boolean enabled) { - component.setEnabled(enabled); - if (component instanceof Container) { - for (Component c : ((Container) component).getComponents()) { - setDeepEnabled(c, enabled); - } - } - } - -} diff --git a/core/src/net/sf/openrocket/gui/configdialog/ThicknessRingComponentConfig.java b/core/src/net/sf/openrocket/gui/configdialog/ThicknessRingComponentConfig.java deleted file mode 100644 index 3013b7c97..000000000 --- a/core/src/net/sf/openrocket/gui/configdialog/ThicknessRingComponentConfig.java +++ /dev/null @@ -1,34 +0,0 @@ -package net.sf.openrocket.gui.configdialog; - - -import javax.swing.JPanel; - -import net.sf.openrocket.document.OpenRocketDocument; -import net.sf.openrocket.l10n.Translator; -import net.sf.openrocket.rocketcomponent.RocketComponent; -import net.sf.openrocket.startup.Application; - - - -public class ThicknessRingComponentConfig extends RingComponentConfig { - private static final Translator trans = Application.getTranslator(); - - public ThicknessRingComponentConfig(OpenRocketDocument d, RocketComponent c) { - super(d, c); - - JPanel tab; - - //// Outer diameter: - //// Inner diameter: - //// Wall thickness: - //// Length: - tab = generalTab(trans.get("ThicknessRingCompCfg.tab.Outerdiam"), - trans.get("ThicknessRingCompCfg.tab.Innerdiam"), - trans.get("ThicknessRingCompCfg.tab.Wallthickness"), trans.get("ThicknessRingCompCfg.tab.Length")); - //// General and General properties - tabbedPane.insertTab(trans.get("ThicknessRingCompCfg.tab.General"), null, tab, - trans.get("ThicknessRingCompCfg.tab.Generalprop"), 0); - tabbedPane.setSelectedIndex(0); - } - -} \ No newline at end of file diff --git a/core/src/net/sf/openrocket/gui/dialogs/flightconfiguration/MotorConfigurationPanel.java b/core/src/net/sf/openrocket/gui/dialogs/flightconfiguration/MotorConfigurationPanel.java deleted file mode 100644 index 811169dd0..000000000 --- a/core/src/net/sf/openrocket/gui/dialogs/flightconfiguration/MotorConfigurationPanel.java +++ /dev/null @@ -1,318 +0,0 @@ -package net.sf.openrocket.gui.dialogs.flightconfiguration; - -import java.awt.Color; -import java.awt.Component; -import java.awt.Font; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; - -import javax.swing.JButton; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTable; -import javax.swing.ListSelectionModel; -import javax.swing.table.DefaultTableCellRenderer; -import javax.swing.table.TableColumn; -import javax.swing.table.TableColumnModel; - -import net.miginfocom.swing.MigLayout; -import net.sf.openrocket.gui.components.DescriptionArea; -import net.sf.openrocket.gui.components.StyledLabel; -import net.sf.openrocket.gui.components.StyledLabel.Style; -import net.sf.openrocket.gui.dialogs.motor.MotorChooserDialog; -import net.sf.openrocket.gui.util.GUIUtil; -import net.sf.openrocket.l10n.Translator; -import net.sf.openrocket.motor.Motor; -import net.sf.openrocket.rocketcomponent.MotorConfiguration; -import net.sf.openrocket.rocketcomponent.MotorMount; -import net.sf.openrocket.rocketcomponent.Rocket; -import net.sf.openrocket.rocketcomponent.RocketComponent; -import net.sf.openrocket.startup.Application; - -public class MotorConfigurationPanel extends JPanel { - - private static final Translator trans = Application.getTranslator(); - - private final FlightConfigurationDialog flightConfigurationDialog; - private final Rocket rocket; - - private final JTable configurationTable; - private final MotorConfigurationTableModel configurationTableModel; - private final JButton selectMotorButton, removeMotorButton, selectIgnitionButton, resetIgnitionButton; - - - MotorConfigurationPanel(FlightConfigurationDialog flightConfigurationDialog, Rocket rocket) { - super(new MigLayout("fill")); - this.flightConfigurationDialog = flightConfigurationDialog; - this.rocket = rocket; - - DescriptionArea desc = new DescriptionArea(trans.get("description"), 3, -1); - this.add(desc, "spanx, growx, wrap para"); - - - //// Motor mount selection - JLabel label = new StyledLabel(trans.get("lbl.motorMounts"), Style.BOLD); - this.add(label, ""); - - //// Motor selection - label = new StyledLabel(trans.get("lbl.motorConfiguration"), Style.BOLD); - this.add(label, "wrap rel"); - - - //// Motor Mount selection - JTable table = new JTable(new MotorMountTableModel(this, rocket)); - table.setTableHeader(null); - table.setShowVerticalLines(false); - table.setRowSelectionAllowed(false); - table.setColumnSelectionAllowed(false); - - TableColumnModel columnModel = table.getColumnModel(); - TableColumn col0 = columnModel.getColumn(0); - int w = table.getRowHeight() + 2; - col0.setMinWidth(w); - col0.setPreferredWidth(w); - col0.setMaxWidth(w); - - table.addMouseListener(new GUIUtil.BooleanTableClickListener(table)); - JScrollPane scroll = new JScrollPane(table); - this.add(scroll, "w 200lp, h 150lp, grow"); - - - //// Motor selection table. - configurationTableModel = new MotorConfigurationTableModel(rocket); - configurationTable = new JTable(configurationTableModel); - configurationTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - configurationTable.setRowSelectionAllowed(true); - configurationTable.setDefaultRenderer(Object.class, new MotorTableCellRenderer()); - - configurationTable.addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - updateButtonState(); - int selectedColumn = configurationTable.getSelectedColumn(); - if (e.getClickCount() == 2) { - if (selectedColumn == 2) { - // user double clicked in ignition column - selectIgnition(); - } else { - // Double-click edits motor - selectMotor(); - } - } - } - }); - - scroll = new JScrollPane(configurationTable); - this.add(scroll, "w 500lp, h 150lp, grow, wrap"); - - //// Select motor - selectMotorButton = new JButton(trans.get("MotorConfigurationPanel.btn.selectMotor")); - selectMotorButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - selectMotor(); - } - }); - this.add(selectMotorButton, "skip, split, sizegroup button"); - - //// Remove motor button - removeMotorButton = new JButton(trans.get("MotorConfigurationPanel.btn.removeMotor")); - removeMotorButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - removeMotor(); - } - }); - this.add(removeMotorButton, "sizegroup button"); - - //// Select Ignition button - selectIgnitionButton = new JButton(trans.get("MotorConfigurationPanel.btn.selectIgnition")); - selectIgnitionButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - selectIgnition(); - } - }); - this.add(selectIgnitionButton, "sizegroup button"); - - //// Reset Ignition button - resetIgnitionButton = new JButton(trans.get("MotorConfigurationPanel.btn.resetIgnition")); - resetIgnitionButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - resetIgnition(); - } - }); - this.add(resetIgnitionButton, "sizegroup button, wrap"); - - } - - public void fireTableDataChanged() { - int selected = configurationTable.getSelectedRow(); - configurationTableModel.fireTableDataChanged(); - if (selected >= 0) { - selected = Math.min(selected, configurationTable.getRowCount() - 1); - configurationTable.getSelectionModel().setSelectionInterval(selected, selected); - } - updateButtonState(); - } - - private void updateButtonState() { - String currentID = rocket.getDefaultConfiguration().getFlightConfigurationID(); - MotorMount currentMount = getCurrentMount(); - selectMotorButton.setEnabled(currentMount != null && currentID != null); - removeMotorButton.setEnabled(currentMount != null && currentID != null); - selectIgnitionButton.setEnabled(currentMount != null && currentID != null); - resetIgnitionButton.setEnabled(currentMount != null && currentID != null); - } - - - private MotorMount getCurrentMount() { - int row = configurationTable.getSelectedRow(); - if (row < 0) { - return null; - } - - return getMount(row); - } - - - private MotorMount getMount(int row) { - int count = 0; - for (RocketComponent c : rocket) { - if (c instanceof MotorMount) { - MotorMount mount = (MotorMount) c; - if (mount.isMotorMount()) { - count++; - } - if (count > row) { - return mount; - } - } - } - - throw new IndexOutOfBoundsException("Invalid row, row=" + row + " count=" + count); - } - - - - private void selectMotor() { - String id = rocket.getDefaultConfiguration().getFlightConfigurationID(); - MotorMount mount = getCurrentMount(); - if (id == null || mount == null) - return; - - MotorConfiguration config = mount.getMotorConfiguration().get(id); - - MotorChooserDialog dialog = new MotorChooserDialog( - config.getMotor(), - config.getEjectionDelay(), - mount.getMotorMountDiameter(), - flightConfigurationDialog); - dialog.setVisible(true); - Motor m = dialog.getSelectedMotor(); - double d = dialog.getSelectedDelay(); - - if (m != null) { - config = new MotorConfiguration(); - config.setMotor(m); - config.setEjectionDelay(d); - mount.getMotorConfiguration().set(id, config); - } - - fireTableDataChanged(); - } - - private void removeMotor() { - String id = rocket.getDefaultConfiguration().getFlightConfigurationID(); - MotorMount mount = getCurrentMount(); - if (id == null || mount == null) - return; - - mount.getMotorConfiguration().resetDefault(id); - - fireTableDataChanged(); - } - - private void selectIgnition() { - String currentID = rocket.getDefaultConfiguration().getFlightConfigurationID(); - MotorMount currentMount = getCurrentMount(); - if (currentID == null || currentMount == null) - return; - - IgnitionSelectionDialog dialog = new IgnitionSelectionDialog( - this.flightConfigurationDialog, - rocket, - currentMount); - dialog.setVisible(true); - - fireTableDataChanged(); - } - - - private void resetIgnition() { - String currentID = rocket.getDefaultConfiguration().getFlightConfigurationID(); - MotorMount currentMount = getCurrentMount(); - if (currentID == null || currentMount == null) - return; - - currentMount.getIgnitionConfiguration().resetDefault(currentID); - - fireTableDataChanged(); - } - - - private class MotorTableCellRenderer extends DefaultTableCellRenderer { - - @Override - public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { - Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); - if (!(c instanceof JLabel)) { - return c; - } - JLabel label = (JLabel) c; - - MotorMount mount = getMount(row); - String id = rocket.getDefaultConfiguration().getFlightConfigurationID(); - - switch (column) { - case 0: - regular(label); - break; - - case 1: - if (mount.getMotorConfiguration().get(id).getMotor() != null) { - regular(label); - } else { - shaded(label); - } - break; - - case 2: - if (mount.getIgnitionConfiguration().isDefault(id)) { - shaded(label); - } else { - regular(label); - } - break; - } - - return label; - } - - private void shaded(JLabel label) { - GUIUtil.changeFontStyle(label, Font.ITALIC); - label.setForeground(Color.GRAY); - } - - private void regular(JLabel label) { - GUIUtil.changeFontStyle(label, Font.PLAIN); - label.setForeground(Color.BLACK); - } - - } - -} diff --git a/core/src/net/sf/openrocket/gui/dialogs/flightconfiguration/MotorConfigurationTableModel.java b/core/src/net/sf/openrocket/gui/dialogs/flightconfiguration/MotorConfigurationTableModel.java deleted file mode 100644 index ce900e72f..000000000 --- a/core/src/net/sf/openrocket/gui/dialogs/flightconfiguration/MotorConfigurationTableModel.java +++ /dev/null @@ -1,146 +0,0 @@ -package net.sf.openrocket.gui.dialogs.flightconfiguration; - -import javax.swing.table.AbstractTableModel; - -import net.sf.openrocket.l10n.Translator; -import net.sf.openrocket.motor.Motor; -import net.sf.openrocket.rocketcomponent.IgnitionConfiguration; -import net.sf.openrocket.rocketcomponent.MotorConfiguration; -import net.sf.openrocket.rocketcomponent.MotorMount; -import net.sf.openrocket.rocketcomponent.Rocket; -import net.sf.openrocket.rocketcomponent.RocketComponent; -import net.sf.openrocket.startup.Application; -import net.sf.openrocket.unit.UnitGroup; -import net.sf.openrocket.util.Chars; -import net.sf.openrocket.util.Coordinate; - -/** - * The table model for selecting and editing the motor configurations. - */ -class MotorConfigurationTableModel extends AbstractTableModel { - - private static final Translator trans = Application.getTranslator(); - - private static final String NONE = trans.get("edtmotorconfdlg.tbl.None"); - private static final String MOTOR_MOUNT = trans.get("edtmotorconfdlg.tbl.Mountheader"); - private static final String MOTOR = trans.get("edtmotorconfdlg.tbl.Motorheader"); - private static final String IGNITION = trans.get("edtmotorconfdlg.tbl.Ignitionheader"); - - private final Rocket rocket; - - - public MotorConfigurationTableModel(Rocket rocket) { - this.rocket = rocket; - } - - @Override - public int getColumnCount() { - return 3; - } - - @Override - public int getRowCount() { - int count = 0; - for (RocketComponent c : rocket) { - if (c instanceof MotorMount && ((MotorMount) c).isMotorMount()) { - count++; - } - } - return count; - } - - @Override - public Object getValueAt(int row, int column) { - switch (column) { - case 0: { - MotorMount mount = findMount(row); - String name = mount.toString(); - int count = getMountMultiplicity(mount); - if (count > 1) { - name = name + " (" + Chars.TIMES + count + ")"; - } - return name; - } - case 1: { - MotorMount mount = findMount(row); - String id = rocket.getDefaultConfiguration().getFlightConfigurationID(); - MotorConfiguration config = mount.getMotorConfiguration().get(id); - Motor motor = config.getMotor(); - - if (motor == null) - return NONE; - - String str = motor.getDesignation(config.getEjectionDelay()); - int count = getMountMultiplicity(mount); - if (count > 1) { - str = "" + count + Chars.TIMES + " " + str; - } - return str; - } - case 2: { - return getIgnitionEventString(row); - - } - default: - throw new IndexOutOfBoundsException("column=" + column); - } - } - - - - @Override - public String getColumnName(int column) { - switch (column) { - case 0: - return MOTOR_MOUNT; - case 1: - return MOTOR; - case 2: - return IGNITION; - default: - throw new IndexOutOfBoundsException("column=" + column); - } - } - - - private MotorMount findMount(int row) { - int count = row; - for (RocketComponent c : rocket) { - if (c instanceof MotorMount && ((MotorMount) c).isMotorMount()) { - count--; - if (count < 0) { - return (MotorMount) c; - } - } - } - throw new IndexOutOfBoundsException("Requesting row=" + row + " but only " + getRowCount() + " rows exist"); - } - - - private int getMountMultiplicity(MotorMount mount) { - RocketComponent c = (RocketComponent) mount; - return c.toAbsolute(Coordinate.NUL).length; - } - - - - private String getIgnitionEventString(int row) { - String id = rocket.getDefaultConfiguration().getFlightConfigurationID(); - MotorMount mount = findMount(row); - IgnitionConfiguration ignitionConfig = mount.getIgnitionConfiguration().get(id); - - IgnitionConfiguration.IgnitionEvent ignitionEvent = ignitionConfig.getIgnitionEvent(); - Double ignitionDelay = ignitionConfig.getIgnitionDelay(); - boolean isDefault = mount.getIgnitionConfiguration().isDefault(id); - - String str = trans.get("MotorMount.IgnitionEvent.short." + ignitionEvent.name()); - if (ignitionDelay > 0.001) { - str = str + " + " + UnitGroup.UNITS_SHORT_TIME.toStringUnit(ignitionDelay); - } - if (isDefault) { - String def = trans.get("table.ignition.default"); - str = def.replace("{0}", str); - } - return str; - } -} \ No newline at end of file diff --git a/core/src/net/sf/openrocket/gui/dialogs/flightconfiguration/RecoveryConfigurationPanel.java b/core/src/net/sf/openrocket/gui/dialogs/flightconfiguration/RecoveryConfigurationPanel.java deleted file mode 100644 index 42b974c1c..000000000 --- a/core/src/net/sf/openrocket/gui/dialogs/flightconfiguration/RecoveryConfigurationPanel.java +++ /dev/null @@ -1,264 +0,0 @@ -package net.sf.openrocket.gui.dialogs.flightconfiguration; - -import java.awt.Color; -import java.awt.Component; -import java.awt.Font; -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.JLabel; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTable; -import javax.swing.ListSelectionModel; -import javax.swing.table.AbstractTableModel; -import javax.swing.table.DefaultTableCellRenderer; - -import net.miginfocom.swing.MigLayout; -import net.sf.openrocket.gui.util.GUIUtil; -import net.sf.openrocket.l10n.Translator; -import net.sf.openrocket.rocketcomponent.DeploymentConfiguration; -import net.sf.openrocket.rocketcomponent.DeploymentConfiguration.DeployEvent; -import net.sf.openrocket.rocketcomponent.RecoveryDevice; -import net.sf.openrocket.rocketcomponent.Rocket; -import net.sf.openrocket.rocketcomponent.RocketComponent; -import net.sf.openrocket.startup.Application; -import net.sf.openrocket.unit.UnitGroup; - -public class RecoveryConfigurationPanel extends JPanel { - - private Translator trans = Application.getTranslator(); - - - private final FlightConfigurationDialog flightConfigurationDialog; - private final Rocket rocket; - - private final RecoveryTableModel recoveryTableModel; - private final JTable recoveryTable; - private final JButton selectDeploymentButton; - private final JButton resetDeploymentButton; - - - RecoveryConfigurationPanel(FlightConfigurationDialog flightConfigurationDialog, Rocket rocket) { - super(new MigLayout("fill")); - this.flightConfigurationDialog = flightConfigurationDialog; - this.rocket = rocket; - - //// Recovery selection - recoveryTableModel = new RecoveryTableModel(); - recoveryTable = new JTable(recoveryTableModel); - recoveryTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - recoveryTable.setRowSelectionAllowed(true); - recoveryTable.addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - updateButtonState(); - - if (e.getClickCount() == 2) { - // Double-click edits - selectDeployment(); - } - } - }); - recoveryTable.setDefaultRenderer(Object.class, new RecoveryTableCellRenderer()); - - JScrollPane scroll = new JScrollPane(recoveryTable); - this.add(scroll, "span, grow, wrap"); - - //// Select deployment - selectDeploymentButton = new JButton(trans.get("edtmotorconfdlg.but.Selectdeployment")); - selectDeploymentButton.setEnabled(false); - selectDeploymentButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - selectDeployment(); - } - }); - this.add(selectDeploymentButton, "skip, split, sizegroup button"); - - //// Reset deployment - resetDeploymentButton = new JButton(trans.get("edtmotorconfdlg.but.Resetdeployment")); - resetDeploymentButton.setEnabled(false); - resetDeploymentButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - resetDeployment(); - } - }); - this.add(resetDeploymentButton, "sizegroup button, wrap"); - } - - public void fireTableDataChanged() { - int selected = recoveryTable.getSelectedRow(); - recoveryTableModel.fireTableDataChanged(); - if (selected >= 0) { - selected = Math.min(selected, recoveryTable.getRowCount() - 1); - recoveryTable.getSelectionModel().setSelectionInterval(selected, selected); - } - updateButtonState(); - } - - private void selectDeployment() { - RecoveryDevice c = getSelectedComponent(); - if (c == null) { - return; - } - JDialog d = new DeploymentSelectionDialog(flightConfigurationDialog, rocket, c); - d.setVisible(true); - fireTableDataChanged(); - } - - private void resetDeployment() { - RecoveryDevice c = getSelectedComponent(); - if (c == null) { - return; - } - String id = rocket.getDefaultConfiguration().getFlightConfigurationID(); - c.getDeploymentConfiguration().resetDefault(id); - fireTableDataChanged(); - } - - public void updateButtonState() { - boolean componentSelected = getSelectedComponent() != null; - selectDeploymentButton.setEnabled(componentSelected); - resetDeploymentButton.setEnabled(componentSelected); - } - - - private RecoveryDevice getSelectedComponent() { - int row = recoveryTable.getSelectedRow(); - return findRecoveryDevice(row); - } - - private RecoveryDevice findRecoveryDevice(int count) { - RecoveryDevice d = null; - Iterator it = rocket.iterator(); - while (it.hasNext() && count >= 0) { - RocketComponent c = it.next(); - if (c instanceof RecoveryDevice) { - d = (RecoveryDevice) c; - count--; - } - } - return d; - } - - - - private class RecoveryTableModel extends AbstractTableModel { - - @Override - public int getRowCount() { - int count = 0; - Iterator it = rocket.iterator(); - while (it.hasNext()) { - RocketComponent c = it.next(); - if (c instanceof RecoveryDevice) { - count++; - } - } - return count; - } - - @Override - public int getColumnCount() { - return 2; - } - - @Override - public Object getValueAt(int rowIndex, int columnIndex) { - RecoveryDevice d = findRecoveryDevice(rowIndex); - switch (columnIndex) { - case 0: - return d.getName(); - case 1: - String id = rocket.getDefaultConfiguration().getFlightConfigurationID(); - DeploymentConfiguration config = d.getDeploymentConfiguration().get(id); - boolean isDefault = d.getDeploymentConfiguration().isDefault(id); - - String str; - - str = trans.get("RecoveryDevice.DeployEvent.short." + config.getDeployEvent().name()); - if (config.getDeployEvent() == DeployEvent.ALTITUDE) { - str += " " + UnitGroup.UNITS_DISTANCE.toStringUnit(config.getDeployAltitude()); - } - if (config.getDeployDelay() > 0.001) { - str += " + " + UnitGroup.UNITS_SHORT_TIME.toStringUnit(config.getDeployDelay()); - } - - - if (isDefault) { - String def = trans.get("table.deployment.default"); - str = def.replace("{0}", str); - } - return str; - - default: - throw new IndexOutOfBoundsException("columnIndex=" + columnIndex); - } - - } - - @Override - public String getColumnName(int column) { - switch (column) { - case 0: - return trans.get("edtmotorconfdlg.tbl.Recoveryheader"); - case 1: - return trans.get("edtmotorconfdlg.tbl.Deploymentheader"); - default: - return ""; - } - } - - } - - - private class RecoveryTableCellRenderer extends DefaultTableCellRenderer { - - @Override - public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { - Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); - if (!(c instanceof JLabel)) { - return c; - } - JLabel label = (JLabel) c; - - RecoveryDevice recoveryDevice = findRecoveryDevice(row); - String id = rocket.getDefaultConfiguration().getFlightConfigurationID(); - - switch (column) { - case 0: - regular(label); - break; - - case 1: - if (recoveryDevice.getDeploymentConfiguration().isDefault(id)) { - shaded(label); - } else { - regular(label); - } - break; - } - - return label; - } - - private void shaded(JLabel label) { - GUIUtil.changeFontStyle(label, Font.ITALIC); - label.setForeground(Color.GRAY); - } - - private void regular(JLabel label) { - GUIUtil.changeFontStyle(label, Font.PLAIN); - label.setForeground(Color.BLACK); - } - - } - -} diff --git a/core/src/net/sf/openrocket/gui/dialogs/flightconfiguration/SeparationConfigurationPanel.java b/core/src/net/sf/openrocket/gui/dialogs/flightconfiguration/SeparationConfigurationPanel.java deleted file mode 100644 index 8094a35d0..000000000 --- a/core/src/net/sf/openrocket/gui/dialogs/flightconfiguration/SeparationConfigurationPanel.java +++ /dev/null @@ -1,259 +0,0 @@ -package net.sf.openrocket.gui.dialogs.flightconfiguration; - -import java.awt.Color; -import java.awt.Component; -import java.awt.Font; -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.JLabel; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTable; -import javax.swing.ListSelectionModel; -import javax.swing.table.AbstractTableModel; -import javax.swing.table.DefaultTableCellRenderer; - -import net.miginfocom.swing.MigLayout; -import net.sf.openrocket.gui.util.GUIUtil; -import net.sf.openrocket.l10n.Translator; -import net.sf.openrocket.rocketcomponent.Rocket; -import net.sf.openrocket.rocketcomponent.RocketComponent; -import net.sf.openrocket.rocketcomponent.Stage; -import net.sf.openrocket.rocketcomponent.StageSeparationConfiguration; -import net.sf.openrocket.startup.Application; -import net.sf.openrocket.unit.UnitGroup; - -public class SeparationConfigurationPanel extends JPanel { - - private static final Translator trans = Application.getTranslator(); - - private final FlightConfigurationDialog flightConfigurationDialog; - private final Rocket rocket; - private final Stage[] stages; - - private final JTable separationTable; - private final SeparationTableModel separationTableModel; - private final JButton selectSeparationButton; - private final JButton resetDeploymentButton; - - - 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 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(); - separationTable = new JTable(separationTableModel); - separationTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - separationTable.setRowSelectionAllowed(true); - separationTable.addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - updateButtonState(); - if (e.getClickCount() == 2) { - // Double-click edits - selectDeployment(); - } - } - }); - separationTable.setDefaultRenderer(Object.class, new SeparationTableCellRenderer()); - - JScrollPane scroll = new JScrollPane(separationTable); - this.add(scroll, "span, grow, wrap"); - - //// Select deployment - selectSeparationButton = new JButton(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(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() { - int selected = separationTable.getSelectedRow(); - separationTableModel.fireTableDataChanged(); - if (selected >= 0) { - selected = Math.min(selected, separationTable.getRowCount() - 1); - separationTable.getSelectionModel().setSelectionInterval(selected, selected); - } - updateButtonState(); - } - - private Stage getSelectedStage() { - int row = separationTable.getSelectedRow(); - return getStage(row); - } - - private Stage getStage(int row) { - if (row >= 0 && row < stages.length) { - return stages[row]; - } - return null; - } - - private void selectDeployment() { - Stage stage = getSelectedStage(); - if (stage == null) { - return; - } - JDialog d = new SeparationSelectionDialog(flightConfigurationDialog, rocket, stage); - d.setVisible(true); - fireTableDataChanged(); - } - - private void resetDeployment() { - Stage stage = getSelectedStage(); - if (stage == null) { - return; - } - String id = rocket.getDefaultConfiguration().getFlightConfigurationID(); - stage.getStageSeparationConfiguration().resetDefault(id); - fireTableDataChanged(); - } - - public void updateButtonState() { - boolean componentSelected = getSelectedStage() != null; - selectSeparationButton.setEnabled(componentSelected); - resetDeploymentButton.setEnabled(componentSelected); - } - - 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: - String id = rocket.getDefaultConfiguration().getFlightConfigurationID(); - StageSeparationConfiguration config = d.getStageSeparationConfiguration().get(id); - - String str; - - str = config.getSeparationEvent().toString(); - if (config.getSeparationDelay() > 0.001) { - str += " + " + UnitGroup.UNITS_SHORT_TIME.toStringUnit(config.getSeparationDelay()); - } - - if (d.getStageSeparationConfiguration().isDefault(id)) { - String def = trans.get("SeparationConfigurationPanel.table.separation.default"); - str = def.replace("{0}", str); - } - - return str; - - default: - throw new IndexOutOfBoundsException("column=" + columnIndex); - } - - } - - @Override - public String getColumnName(int column) { - switch (column) { - case 0: - return trans.get("edtmotorconfdlg.tbl.Stageheader"); - case 1: - return trans.get("edtmotorconfdlg.tbl.Separationheader"); - default: - return ""; - } - } - } - - - private class SeparationTableCellRenderer extends DefaultTableCellRenderer { - - @Override - public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { - Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); - if (!(c instanceof JLabel)) { - return c; - } - JLabel label = (JLabel) c; - - Stage stage = getStage(row); - String id = rocket.getDefaultConfiguration().getFlightConfigurationID(); - - switch (column) { - case 0: - regular(label); - break; - - case 1: - if (stage.getStageSeparationConfiguration().isDefault(id)) { - shaded(label); - } else { - regular(label); - } - break; - } - - return label; - } - - private void shaded(JLabel label) { - GUIUtil.changeFontStyle(label, Font.ITALIC); - label.setForeground(Color.GRAY); - } - - private void regular(JLabel label) { - GUIUtil.changeFontStyle(label, Font.PLAIN); - label.setForeground(Color.BLACK); - } - - } - - -} diff --git a/core/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/ThrustCurveMotorSelectionPanel.java b/core/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/ThrustCurveMotorSelectionPanel.java deleted file mode 100644 index e9781b210..000000000 --- a/core/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/ThrustCurveMotorSelectionPanel.java +++ /dev/null @@ -1,1013 +0,0 @@ -package net.sf.openrocket.gui.dialogs.motor.thrustcurve; - -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Component; -import java.awt.Cursor; -import java.awt.Font; -import java.awt.Paint; -import java.awt.Rectangle; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Locale; -import java.util.prefs.Preferences; - -import javax.swing.BorderFactory; -import javax.swing.DefaultComboBoxModel; -import javax.swing.JCheckBox; -import javax.swing.JComboBox; -import javax.swing.JComponent; -import javax.swing.JLabel; -import javax.swing.JLayeredPane; -import javax.swing.JList; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JSeparator; -import javax.swing.JTable; -import javax.swing.JTextArea; -import javax.swing.JTextField; -import javax.swing.ListCellRenderer; -import javax.swing.ListSelectionModel; -import javax.swing.RowFilter; -import javax.swing.RowSorter; -import javax.swing.SortOrder; -import javax.swing.SwingUtilities; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; -import javax.swing.event.ListSelectionEvent; -import javax.swing.event.ListSelectionListener; -import javax.swing.table.TableModel; -import javax.swing.table.TableRowSorter; - -import net.miginfocom.swing.MigLayout; -import net.sf.openrocket.database.motor.ThrustCurveMotorSet; -import net.sf.openrocket.gui.components.StyledLabel; -import net.sf.openrocket.gui.components.StyledLabel.Style; -import net.sf.openrocket.gui.dialogs.motor.CloseableDialog; -import net.sf.openrocket.gui.dialogs.motor.MotorSelector; -import net.sf.openrocket.gui.util.GUIUtil; -import net.sf.openrocket.gui.util.Icons; -import net.sf.openrocket.gui.util.SwingPreferences; -import net.sf.openrocket.l10n.Translator; -import net.sf.openrocket.logging.Markers; -import net.sf.openrocket.motor.Motor; -import net.sf.openrocket.motor.ThrustCurveMotor; -import net.sf.openrocket.startup.Application; -import net.sf.openrocket.unit.UnitGroup; -import net.sf.openrocket.util.BugException; -import net.sf.openrocket.utils.MotorCorrelation; - -import org.jfree.chart.ChartColor; -import org.jfree.chart.ChartFactory; -import org.jfree.chart.ChartPanel; -import org.jfree.chart.JFreeChart; -import org.jfree.chart.axis.ValueAxis; -import org.jfree.chart.plot.PlotOrientation; -import org.jfree.chart.plot.XYPlot; -import org.jfree.chart.title.TextTitle; -import org.jfree.data.xy.XYSeries; -import org.jfree.data.xy.XYSeriesCollection; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelector { - private static final Logger log = LoggerFactory.getLogger(ThrustCurveMotorSelectionPanel.class); - private static final Translator trans = Application.getTranslator(); - - private static final double MOTOR_SIMILARITY_THRESHOLD = 0.95; - - private static final int SHOW_ALL = 0; - private static final int SHOW_SMALLER = 1; - private static final int SHOW_EXACT = 2; - private static final String[] SHOW_DESCRIPTIONS = { - //// Show all motors - trans.get("TCMotorSelPan.SHOW_DESCRIPTIONS.desc1"), - //// Show motors with diameter less than that of the motor mount - trans.get("TCMotorSelPan.SHOW_DESCRIPTIONS.desc2"), - //// Show motors with diameter equal to that of the motor mount - trans.get("TCMotorSelPan.SHOW_DESCRIPTIONS.desc3") - }; - private static final int SHOW_MAX = 2; - - private static final int ZOOM_ICON_POSITION_NEGATIVE_X = 50; - private static final int ZOOM_ICON_POSITION_POSITIVE_Y = 12; - - private static final Paint[] CURVE_COLORS = ChartColor.createDefaultPaintArray(); - - private static final Color NO_COMMENT_COLOR = Color.GRAY; - private static final Color WITH_COMMENT_COLOR = Color.BLACK; - - private static final ThrustCurveMotorComparator MOTOR_COMPARATOR = new ThrustCurveMotorComparator(); - - - - private final List database; - - private final double diameter; - private CloseableDialog dialog = null; - - - private final ThrustCurveMotorDatabaseModel model; - private final JTable table; - private final TableRowSorter sorter; - - private final JCheckBox hideSimilarBox; - - private final JTextField searchField; - private String[] searchTerms = new String[0]; - - - private final JLabel curveSelectionLabel; - private final JComboBox curveSelectionBox; - private final DefaultComboBoxModel curveSelectionModel; - - private final JLabel totalImpulseLabel; - private final JLabel classificationLabel; - private final JLabel avgThrustLabel; - private final JLabel maxThrustLabel; - private final JLabel burnTimeLabel; - private final JLabel launchMassLabel; - private final JLabel emptyMassLabel; - private final JLabel dataPointsLabel; - private final JLabel digestLabel; - - private final JTextArea comment; - private final Font noCommentFont; - private final Font withCommentFont; - - private final JFreeChart chart; - private final ChartPanel chartPanel; - private final JLabel zoomIcon; - - private final JComboBox delayBox; - - private ThrustCurveMotor selectedMotor; - private ThrustCurveMotorSet selectedMotorSet; - private double selectedDelay; - - - /** - * Sole constructor. - * - * @param current the currently selected ThrustCurveMotor, or null for none. - * @param delay the currently selected ejection charge delay. - * @param diameter the diameter of the motor mount. - */ - public ThrustCurveMotorSelectionPanel(ThrustCurveMotor current, double delay, double diameter) { - super(new MigLayout("fill", "[grow][]")); - - this.diameter = diameter; - - - // Construct the database (adding the current motor if not in the db already) - List db; - db = Application.getThrustCurveMotorSetDatabase().getMotorSets(); - - // If current motor is not found in db, add a new ThrustCurveMotorSet containing it - if (current != null) { - selectedMotor = current; - for (ThrustCurveMotorSet motorSet : db) { - if (motorSet.getMotors().contains(current)) { - selectedMotorSet = motorSet; - break; - } - } - if (selectedMotorSet == null) { - db = new ArrayList(db); - ThrustCurveMotorSet extra = new ThrustCurveMotorSet(); - extra.addMotor(current); - selectedMotorSet = extra; - db.add(extra); - Collections.sort(db); - } - } - database = db; - - - - //// GUI - - JPanel panel; - JLabel label; - - panel = new JPanel(new MigLayout("fill")); - this.add(panel, "grow"); - - - - // Selection label - //// Select rocket motor: - label = new StyledLabel(trans.get("TCMotorSelPan.lbl.Selrocketmotor"), Style.BOLD); - panel.add(label, "spanx, wrap para"); - - // Diameter selection - JComboBox filterComboBox = new JComboBox(SHOW_DESCRIPTIONS); - filterComboBox.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - JComboBox cb = (JComboBox) e.getSource(); - int sel = cb.getSelectedIndex(); - if ((sel < 0) || (sel > SHOW_MAX)) - sel = SHOW_ALL; - switch (sel) { - case SHOW_ALL: - sorter.setRowFilter(new MotorRowFilterAll()); - break; - - case SHOW_SMALLER: - sorter.setRowFilter(new MotorRowFilterSmaller()); - break; - - case SHOW_EXACT: - sorter.setRowFilter(new MotorRowFilterExact()); - break; - - default: - throw new BugException("Invalid selection mode sel=" + sel); - } - Application.getPreferences().putChoice("MotorDiameterMatch", sel); - scrollSelectionVisible(); - } - }); - panel.add(filterComboBox, "spanx, growx, wrap rel"); - - //// Hide very similar thrust curves - hideSimilarBox = new JCheckBox(trans.get("TCMotorSelPan.checkbox.hideSimilar")); - GUIUtil.changeFontSize(hideSimilarBox, -1); - hideSimilarBox.setSelected(Application.getPreferences().getBoolean(net.sf.openrocket.startup.Preferences.MOTOR_HIDE_SIMILAR, true)); - hideSimilarBox.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - Application.getPreferences().putBoolean(net.sf.openrocket.startup.Preferences.MOTOR_HIDE_SIMILAR, hideSimilarBox.isSelected()); - updateData(); - } - }); - panel.add(hideSimilarBox, "gapleft para, spanx, growx, wrap para"); - - - // Motor selection table - model = new ThrustCurveMotorDatabaseModel(database); - table = new JTable(model); - - - // Set comparators and widths - table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - sorter = new TableRowSorter(model); - for (int i = 0; i < ThrustCurveMotorColumns.values().length; i++) { - ThrustCurveMotorColumns column = ThrustCurveMotorColumns.values()[i]; - sorter.setComparator(i, column.getComparator()); - table.getColumnModel().getColumn(i).setPreferredWidth(column.getWidth()); - } - table.setRowSorter(sorter); - // force initial sort order to by diameter, total impulse, manufacturer - { - RowSorter.SortKey[] sortKeys = { - new RowSorter.SortKey(ThrustCurveMotorColumns.DIAMETER.ordinal(), SortOrder.ASCENDING), - new RowSorter.SortKey(ThrustCurveMotorColumns.TOTAL_IMPULSE.ordinal(), SortOrder.ASCENDING), - new RowSorter.SortKey(ThrustCurveMotorColumns.MANUFACTURER.ordinal(), SortOrder.ASCENDING) - }; - sorter.setSortKeys(Arrays.asList(sortKeys)); - } - - // Set selection and double-click listeners - table.getSelectionModel().addListSelectionListener(new ListSelectionListener() { - @Override - public void valueChanged(ListSelectionEvent e) { - int row = table.getSelectedRow(); - if (row >= 0) { - row = table.convertRowIndexToModel(row); - ThrustCurveMotorSet motorSet = model.getMotorSet(row); - log.info(Markers.USER_MARKER, "Selected table row " + row + ": " + motorSet); - if (motorSet != selectedMotorSet) { - select(selectMotor(motorSet)); - } - } else { - log.info(Markers.USER_MARKER, "Selected table row " + row + ", nothing selected"); - } - } - }); - table.addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 2) { - if (dialog != null) { - dialog.close(true); - } - } - } - }); - - - JScrollPane scrollpane = new JScrollPane(); - scrollpane.setViewportView(table); - panel.add(scrollpane, "grow, width :500:, height :300:, spanx, wrap para"); - - - - - // Motor mount diameter label - //// Motor mount diameter: - label = new StyledLabel(trans.get("TCMotorSelPan.lbl.Motormountdia") + " " + - UnitGroup.UNITS_MOTOR_DIMENSIONS.getDefaultUnit().toStringUnit(diameter)); - panel.add(label, "gapright 30lp, spanx, split"); - - - - // Search field - //// Search: - label = new StyledLabel(trans.get("TCMotorSelPan.lbl.Search")); - panel.add(label, ""); - - searchField = new JTextField(); - searchField.getDocument().addDocumentListener(new DocumentListener() { - @Override - public void changedUpdate(DocumentEvent e) { - update(); - } - - @Override - public void insertUpdate(DocumentEvent e) { - update(); - } - - @Override - public void removeUpdate(DocumentEvent e) { - update(); - } - - private void update() { - String text = searchField.getText().trim(); - String[] split = text.split("\\s+"); - ArrayList list = new ArrayList(); - for (String s : split) { - s = s.trim().toLowerCase(Locale.getDefault()); - if (s.length() > 0) { - list.add(s); - } - } - searchTerms = list.toArray(new String[0]); - sorter.sort(); - scrollSelectionVisible(); - } - }); - panel.add(searchField, "growx, wrap"); - - - - // Vertical split - this.add(panel, "grow"); - this.add(new JSeparator(JSeparator.VERTICAL), "growy, gap para para"); - panel = new JPanel(new MigLayout("fill")); - - - - // Thrust curve selection - //// Select thrust curve: - curveSelectionLabel = new JLabel(trans.get("TCMotorSelPan.lbl.Selectthrustcurve")); - panel.add(curveSelectionLabel); - - curveSelectionModel = new DefaultComboBoxModel(); - curveSelectionBox = new JComboBox(curveSelectionModel); - curveSelectionBox.setRenderer(new CurveSelectionRenderer(curveSelectionBox.getRenderer())); - curveSelectionBox.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - Object value = curveSelectionBox.getSelectedItem(); - if (value != null) { - select(((MotorHolder) value).getMotor()); - } - } - }); - panel.add(curveSelectionBox, "growx, wrap para"); - - - - - - // Ejection charge delay: - panel.add(new JLabel(trans.get("TCMotorSelPan.lbl.Ejectionchargedelay"))); - - delayBox = new JComboBox(); - delayBox.setEditable(true); - delayBox.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - JComboBox cb = (JComboBox) e.getSource(); - String sel = (String) cb.getSelectedItem(); - //// None - if (sel.equalsIgnoreCase(trans.get("TCMotorSelPan.equalsIgnoreCase.None"))) { - selectedDelay = Motor.PLUGGED; - } else { - try { - selectedDelay = Double.parseDouble(sel); - } catch (NumberFormatException ignore) { - } - } - setDelays(false); - } - }); - panel.add(delayBox, "growx, wrap rel"); - //// (Number of seconds or \"None\") - panel.add(new StyledLabel(trans.get("TCMotorSelPan.lbl.NumberofsecondsorNone"), -3), "skip, wrap para"); - setDelays(false); - - - panel.add(new JSeparator(), "spanx, growx, wrap para"); - - - - // Thrust curve info - //// Total impulse: - panel.add(new JLabel(trans.get("TCMotorSelPan.lbl.Totalimpulse"))); - totalImpulseLabel = new JLabel(); - panel.add(totalImpulseLabel, "split"); - classificationLabel = new JLabel(); - classificationLabel.setEnabled(false); // Gray out - panel.add(classificationLabel, "gapleft unrel, wrap"); - - //// Avg. thrust: - panel.add(new JLabel(trans.get("TCMotorSelPan.lbl.Avgthrust"))); - avgThrustLabel = new JLabel(); - panel.add(avgThrustLabel, "wrap"); - - //// Max. thrust: - panel.add(new JLabel(trans.get("TCMotorSelPan.lbl.Maxthrust"))); - maxThrustLabel = new JLabel(); - panel.add(maxThrustLabel, "wrap"); - - //// Burn time: - panel.add(new JLabel(trans.get("TCMotorSelPan.lbl.Burntime"))); - burnTimeLabel = new JLabel(); - panel.add(burnTimeLabel, "wrap"); - - //// Launch mass: - panel.add(new JLabel(trans.get("TCMotorSelPan.lbl.Launchmass"))); - launchMassLabel = new JLabel(); - panel.add(launchMassLabel, "wrap"); - - //// Empty mass: - panel.add(new JLabel(trans.get("TCMotorSelPan.lbl.Emptymass"))); - emptyMassLabel = new JLabel(); - panel.add(emptyMassLabel, "wrap"); - - //// Data points: - panel.add(new JLabel(trans.get("TCMotorSelPan.lbl.Datapoints"))); - dataPointsLabel = new JLabel(); - panel.add(dataPointsLabel, "wrap para"); - - if (System.getProperty("openrocket.debug.motordigest") != null) { - //// Digest: - panel.add(new JLabel(trans.get("TCMotorSelPan.lbl.Digest"))); - digestLabel = new JLabel(); - panel.add(digestLabel, "w :300:, wrap para"); - } else { - digestLabel = null; - } - - - comment = new JTextArea(5, 5); - GUIUtil.changeFontSize(comment, -2); - withCommentFont = comment.getFont(); - noCommentFont = withCommentFont.deriveFont(Font.ITALIC); - comment.setLineWrap(true); - comment.setWrapStyleWord(true); - comment.setEditable(false); - scrollpane = new JScrollPane(comment); - panel.add(scrollpane, "spanx, growx, wrap para"); - - - - - // Thrust curve plot - chart = ChartFactory.createXYLineChart( - null, // title - null, // xAxisLabel - null, // yAxisLabel - null, // dataset - PlotOrientation.VERTICAL, - false, // legend - false, // tooltips - false // urls - ); - - - // Add the data and formatting to the plot - XYPlot plot = chart.getXYPlot(); - - changeLabelFont(plot.getRangeAxis(), -2); - changeLabelFont(plot.getDomainAxis(), -2); - - //// Thrust curve: - chart.setTitle(new TextTitle(trans.get("TCMotorSelPan.title.Thrustcurve"), this.getFont())); - chart.setBackgroundPaint(this.getBackground()); - plot.setBackgroundPaint(Color.WHITE); - plot.setDomainGridlinePaint(Color.LIGHT_GRAY); - plot.setRangeGridlinePaint(Color.LIGHT_GRAY); - - chartPanel = new ChartPanel(chart, - false, // properties - false, // save - false, // print - false, // zoom - false); // tooltips - chartPanel.setMouseZoomable(false); - chartPanel.setPopupMenu(null); - chartPanel.setMouseWheelEnabled(false); - chartPanel.setRangeZoomable(false); - chartPanel.setDomainZoomable(false); - - chartPanel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); - chartPanel.addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - if (selectedMotor == null || selectedMotorSet == null) - return; - if (e.getButton() == MouseEvent.BUTTON1) { - // Open plot dialog - List motors = getFilteredCurves(); - ThrustCurveMotorPlotDialog plotDialog = new ThrustCurveMotorPlotDialog(motors, - motors.indexOf(selectedMotor), - SwingUtilities.getWindowAncestor(ThrustCurveMotorSelectionPanel.this)); - plotDialog.setVisible(true); - } - } - }); - - JLayeredPane layer = new CustomLayeredPane(); - - layer.setBorder(BorderFactory.createLineBorder(Color.BLUE)); - - layer.add(chartPanel, (Integer) 0); - - zoomIcon = new JLabel(Icons.ZOOM_IN); - zoomIcon.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); - layer.add(zoomIcon, (Integer) 1); - - - panel.add(layer, "width 300:300:, height 180:180:, grow, spanx"); - - - - this.add(panel, "grow"); - - - - // Sets the filter: - int showMode = Application.getPreferences().getChoice(net.sf.openrocket.startup.Preferences.MOTOR_DIAMETER_FILTER, SHOW_MAX, SHOW_EXACT); - filterComboBox.setSelectedIndex(showMode); - - - // Update the panel data - updateData(); - selectedDelay = delay; - setDelays(false); - - } - - @Override - public Motor getSelectedMotor() { - return selectedMotor; - } - - - @Override - public double getSelectedDelay() { - return selectedDelay; - } - - - @Override - public JComponent getDefaultFocus() { - return searchField; - } - - @Override - public void selectedMotor(Motor motorSelection) { - if (!(motorSelection instanceof ThrustCurveMotor)) { - log.error("Received argument that was not ThrustCurveMotor: " + motorSelection); - return; - } - - ThrustCurveMotor motor = (ThrustCurveMotor) motorSelection; - ThrustCurveMotorSet set = findMotorSet(motor); - if (set == null) { - log.error("Could not find set for motor:" + motorSelection); - return; - } - - // Store selected motor in preferences node, set all others to false - Preferences prefs = ((SwingPreferences) Application.getPreferences()).getNode(net.sf.openrocket.startup.Preferences.PREFERRED_THRUST_CURVE_MOTOR_NODE); - for (ThrustCurveMotor m : set.getMotors()) { - String digest = m.getDigest(); - prefs.putBoolean(digest, m == motor); - } - } - - public void setCloseableDialog(CloseableDialog dialog) { - this.dialog = dialog; - } - - - - private void changeLabelFont(ValueAxis axis, float size) { - Font font = axis.getTickLabelFont(); - font = font.deriveFont(font.getSize2D() + size); - axis.setTickLabelFont(font); - } - - - /** - * Called when a different motor is selected from within the panel. - */ - private void select(ThrustCurveMotor motor) { - if (selectedMotor == motor) - return; - - ThrustCurveMotorSet set = findMotorSet(motor); - if (set == null) { - throw new BugException("Could not find motor from database, motor=" + motor); - } - - boolean updateDelays = (selectedMotorSet != set); - - selectedMotor = motor; - selectedMotorSet = set; - updateData(); - if (updateDelays) { - setDelays(true); - } - } - - - private void updateData() { - - if (selectedMotorSet == null) { - // No motor selected - curveSelectionModel.removeAllElements(); - curveSelectionBox.setEnabled(false); - curveSelectionLabel.setEnabled(false); - totalImpulseLabel.setText(""); - totalImpulseLabel.setToolTipText(null); - classificationLabel.setText(""); - classificationLabel.setToolTipText(null); - avgThrustLabel.setText(""); - maxThrustLabel.setText(""); - burnTimeLabel.setText(""); - launchMassLabel.setText(""); - emptyMassLabel.setText(""); - dataPointsLabel.setText(""); - if (digestLabel != null) { - digestLabel.setText(""); - } - setComment(""); - chart.getXYPlot().setDataset(new XYSeriesCollection()); - return; - } - - - // Check which thrust curves to display - List motors = getFilteredCurves(); - final int index = motors.indexOf(selectedMotor); - - - // Update the thrust curve selection box - curveSelectionModel.removeAllElements(); - for (int i = 0; i < motors.size(); i++) { - curveSelectionModel.addElement(new MotorHolder(motors.get(i), i)); - } - curveSelectionBox.setSelectedIndex(index); - - if (motors.size() > 1) { - curveSelectionBox.setEnabled(true); - curveSelectionLabel.setEnabled(true); - } else { - curveSelectionBox.setEnabled(false); - curveSelectionLabel.setEnabled(false); - } - - - // Update thrust curve data - double impulse = selectedMotor.getTotalImpulseEstimate(); - MotorClass mc = MotorClass.getMotorClass(impulse); - totalImpulseLabel.setText(UnitGroup.UNITS_IMPULSE.getDefaultUnit().toStringUnit(impulse)); - classificationLabel.setText("(" + mc.getDescription(impulse) + ")"); - totalImpulseLabel.setToolTipText(mc.getClassDescription()); - classificationLabel.setToolTipText(mc.getClassDescription()); - - avgThrustLabel.setText(UnitGroup.UNITS_FORCE.getDefaultUnit().toStringUnit( - selectedMotor.getAverageThrustEstimate())); - maxThrustLabel.setText(UnitGroup.UNITS_FORCE.getDefaultUnit().toStringUnit( - selectedMotor.getMaxThrustEstimate())); - burnTimeLabel.setText(UnitGroup.UNITS_SHORT_TIME.getDefaultUnit().toStringUnit( - selectedMotor.getBurnTimeEstimate())); - launchMassLabel.setText(UnitGroup.UNITS_MASS.getDefaultUnit().toStringUnit( - selectedMotor.getLaunchCG().weight)); - emptyMassLabel.setText(UnitGroup.UNITS_MASS.getDefaultUnit().toStringUnit( - selectedMotor.getEmptyCG().weight)); - dataPointsLabel.setText("" + (selectedMotor.getTimePoints().length - 1)); - if (digestLabel != null) { - digestLabel.setText(selectedMotor.getDigest()); - } - - setComment(selectedMotor.getDescription()); - - - // Update the plot - XYPlot plot = chart.getXYPlot(); - - XYSeriesCollection dataset = new XYSeriesCollection(); - for (int i = 0; i < motors.size(); i++) { - ThrustCurveMotor m = motors.get(i); - - //// Thrust - XYSeries series = new XYSeries(trans.get("TCMotorSelPan.title.Thrust") + " (" + i + ")"); - double[] time = m.getTimePoints(); - double[] thrust = m.getThrustPoints(); - - for (int j = 0; j < time.length; j++) { - series.add(time[j], thrust[j]); - } - - dataset.addSeries(series); - - boolean selected = (i == index); - plot.getRenderer().setSeriesStroke(i, new BasicStroke(selected ? 3 : 1)); - plot.getRenderer().setSeriesPaint(i, getColor(i)); - } - - plot.setDataset(dataset); - } - - private List getFilteredCurves() { - List motors = selectedMotorSet.getMotors(); - if (hideSimilarBox.isSelected()) { - List filtered = new ArrayList(motors.size()); - for (int i = 0; i < motors.size(); i++) { - ThrustCurveMotor m = motors.get(i); - if (m.equals(selectedMotor)) { - filtered.add(m); - continue; - } - - double similarity = MotorCorrelation.similarity(selectedMotor, m); - log.debug("Motor similarity: " + similarity); - if (similarity < MOTOR_SIMILARITY_THRESHOLD) { - filtered.add(m); - } - } - motors = filtered; - } - - Collections.sort(motors, MOTOR_COMPARATOR); - - return motors; - } - - - private void setComment(String s) { - s = s.trim(); - if (s.length() == 0) { - //// No description available. - comment.setText(trans.get("TCMotorSelPan.noDescription")); - comment.setFont(noCommentFont); - comment.setForeground(NO_COMMENT_COLOR); - } else { - comment.setText(s); - comment.setFont(withCommentFont); - comment.setForeground(WITH_COMMENT_COLOR); - } - comment.setCaretPosition(0); - } - - private void scrollSelectionVisible() { - if (selectedMotorSet != null) { - int index = table.convertRowIndexToView(model.getIndex(selectedMotorSet)); - //System.out.println("index=" + index); - table.getSelectionModel().setSelectionInterval(index, index); - Rectangle rect = table.getCellRect(index, 0, true); - rect = new Rectangle(rect.x, rect.y - 100, rect.width, rect.height + 200); - table.scrollRectToVisible(rect); - } - } - - - public static Color getColor(int index) { - return (Color) CURVE_COLORS[index % CURVE_COLORS.length]; - } - - - /** - * Find the ThrustCurveMotorSet that contains a motor. - * - * @param motor the motor to look for. - * @return the ThrustCurveMotorSet, or null if not found. - */ - private ThrustCurveMotorSet findMotorSet(ThrustCurveMotor motor) { - for (ThrustCurveMotorSet set : database) { - if (set.getMotors().contains(motor)) { - return set; - } - } - - return null; - } - - - - /** - * Select the default motor from this ThrustCurveMotorSet. This uses primarily motors - * that the user has previously used, and secondarily a heuristic method of selecting which - * thrust curve seems to be better or more reliable. - * - * @param set the motor set - * @return the default motor in this set - */ - private ThrustCurveMotor selectMotor(ThrustCurveMotorSet set) { - if (set.getMotorCount() == 0) { - throw new BugException("Attempting to select motor from empty ThrustCurveMotorSet: " + set); - } - if (set.getMotorCount() == 1) { - return set.getMotors().get(0); - } - - - // Find which motor has been used the most recently - List list = set.getMotors(); - Preferences prefs = ((SwingPreferences) Application.getPreferences()).getNode(net.sf.openrocket.startup.Preferences.PREFERRED_THRUST_CURVE_MOTOR_NODE); - for (ThrustCurveMotor m : list) { - String digest = m.getDigest(); - if (prefs.getBoolean(digest, false)) { - return m; - } - } - - // No motor has been used - Collections.sort(list, MOTOR_COMPARATOR); - return list.get(0); - } - - - /** - * Set the values in the delay combo box. If reset is true - * then sets the selected value as the value closest to selectedDelay, otherwise - * leaves selection alone. - */ - private void setDelays(boolean reset) { - if (selectedMotor == null) { - - //// None - delayBox.setModel(new DefaultComboBoxModel(new String[] { trans.get("TCMotorSelPan.delayBox.None") })); - delayBox.setSelectedIndex(0); - - } else { - - List delays = selectedMotorSet.getDelays(); - String[] delayStrings = new String[delays.size()]; - double currentDelay = selectedDelay; // Store current setting locally - - for (int i = 0; i < delays.size(); i++) { - //// None - delayStrings[i] = ThrustCurveMotor.getDelayString(delays.get(i), trans.get("TCMotorSelPan.delayBox.None")); - } - delayBox.setModel(new DefaultComboBoxModel(delayStrings)); - - if (reset) { - - // Find and set the closest value - double closest = Double.NaN; - for (int i = 0; i < delays.size(); i++) { - // if-condition to always become true for NaN - if (!(Math.abs(delays.get(i) - currentDelay) > Math.abs(closest - currentDelay))) { - closest = delays.get(i); - } - } - if (!Double.isNaN(closest)) { - selectedDelay = closest; - //// None - delayBox.setSelectedItem(ThrustCurveMotor.getDelayString(closest, trans.get("TCMotorSelPan.delayBox.None"))); - } else { - delayBox.setSelectedItem("None"); - } - - } else { - - selectedDelay = currentDelay; - //// None - delayBox.setSelectedItem(ThrustCurveMotor.getDelayString(currentDelay, trans.get("TCMotorSelPan.delayBox.None"))); - - } - - } - } - - - - - ////////////////////// - - - private class CurveSelectionRenderer implements ListCellRenderer { - - private final ListCellRenderer renderer; - - public CurveSelectionRenderer(ListCellRenderer renderer) { - this.renderer = renderer; - } - - @Override - public Component getListCellRendererComponent(JList list, Object value, int index, - boolean isSelected, boolean cellHasFocus) { - - Component c = renderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); - if (value instanceof MotorHolder) { - MotorHolder m = (MotorHolder) value; - c.setForeground(getColor(m.getIndex())); - } - - return c; - } - - } - - - //////// Row filters - - /** - * Abstract adapter class. - */ - private abstract class MotorRowFilter extends RowFilter { - @Override - public boolean include(RowFilter.Entry entry) { - int index = entry.getIdentifier(); - ThrustCurveMotorSet m = model.getMotorSet(index); - return filterByDiameter(m) && filterByString(m); - } - - public abstract boolean filterByDiameter(ThrustCurveMotorSet m); - - - public boolean filterByString(ThrustCurveMotorSet m) { - main: for (String s : searchTerms) { - for (ThrustCurveMotorColumns col : ThrustCurveMotorColumns.values()) { - String str = col.getValue(m).toString().toLowerCase(Locale.getDefault()); - if (str.indexOf(s) >= 0) - continue main; - } - return false; - } - return true; - } - } - - /** - * Show all motors. - */ - private class MotorRowFilterAll extends MotorRowFilter { - @Override - public boolean filterByDiameter(ThrustCurveMotorSet m) { - return true; - } - } - - /** - * Show motors smaller than the mount. - */ - private class MotorRowFilterSmaller extends MotorRowFilter { - @Override - public boolean filterByDiameter(ThrustCurveMotorSet m) { - return (m.getDiameter() <= diameter + 0.0004); - } - } - - /** - * Show motors that fit the mount. - */ - private class MotorRowFilterExact extends MotorRowFilter { - @Override - public boolean filterByDiameter(ThrustCurveMotorSet m) { - return ((m.getDiameter() <= diameter + 0.0004) && (m.getDiameter() >= diameter - 0.0015)); - } - } - - - /** - * Custom layered pane that sets the bounds of the components on every layout. - */ - public class CustomLayeredPane extends JLayeredPane { - @Override - public void doLayout() { - synchronized (getTreeLock()) { - int w = getWidth(); - int h = getHeight(); - chartPanel.setBounds(0, 0, w, h); - zoomIcon.setBounds(w - ZOOM_ICON_POSITION_NEGATIVE_X, ZOOM_ICON_POSITION_POSITIVE_Y, 50, 50); - } - } - } -} diff --git a/core/src/net/sf/openrocket/preset/loader/RocksimComponentFileLoader.java b/core/src/net/sf/openrocket/preset/loader/RocksimComponentFileLoader.java index cb285a216..eef411558 100644 --- a/core/src/net/sf/openrocket/preset/loader/RocksimComponentFileLoader.java +++ b/core/src/net/sf/openrocket/preset/loader/RocksimComponentFileLoader.java @@ -1,13 +1,5 @@ package net.sf.openrocket.preset.loader; -import au.com.bytecode.opencsv.CSVReader; -import net.sf.openrocket.gui.print.PrintUnit; -import net.sf.openrocket.preset.TypedPropertyMap; -import net.sf.openrocket.unit.Unit; -import net.sf.openrocket.unit.UnitGroup; -import net.sf.openrocket.util.ArrayList; -import net.sf.openrocket.util.StringUtil; - import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -17,19 +9,26 @@ import java.io.InputStreamReader; import java.io.PrintStream; import java.util.List; +import net.sf.openrocket.preset.TypedPropertyMap; +import net.sf.openrocket.unit.Unit; +import net.sf.openrocket.unit.UnitGroup; +import net.sf.openrocket.util.ArrayList; +import net.sf.openrocket.util.StringUtil; +import au.com.bytecode.opencsv.CSVReader; + /** * Primary entry point for parsing component CSV files that are in Rocksim format. */ public abstract class RocksimComponentFileLoader { - - private static final PrintStream LOGGER = System.err; - + + private static final PrintStream LOGGER = System.err; + private String basePath = ""; - + private File dir; - + protected List fileColumns = new ArrayList(); - + /** * Constructor. * @@ -39,7 +38,7 @@ public abstract class RocksimComponentFileLoader { dir = theBasePathToLoadFrom; basePath = dir.getAbsolutePath(); } - + /** * Constructor. * @@ -49,17 +48,17 @@ public abstract class RocksimComponentFileLoader { dir = new File(basePath); basePath = theBasePathToLoadFrom; } - + protected abstract RocksimComponentFileType getFileType(); - + public void load() { try { - load(getFileType()); - } catch (FileNotFoundException fex ) { - LOGGER.println( fex.getLocalizedMessage() ); + load(getFileType()); + } catch (FileNotFoundException fex) { + LOGGER.println(fex.getLocalizedMessage()); } } - + /** * Read a comma separated component file and return the parsed contents as a list of string arrays. Not for * production use - just here for smoke testing. @@ -83,7 +82,7 @@ public abstract class RocksimComponentFileLoader { FileInputStream fis = new FileInputStream(new File(dir, type.getDefaultFileName())); load(fis); } - + /** * Read a comma separated component file and return the parsed contents as a list of string arrays. * @@ -97,7 +96,7 @@ public abstract class RocksimComponentFileLoader { private void load(File file) throws FileNotFoundException { load(new FileInputStream(file)); } - + /** * Read a comma separated component file and return the parsed contents as a list of string arrays. * @@ -114,13 +113,13 @@ public abstract class RocksimComponentFileLoader { InputStreamReader r = null; try { r = new InputStreamReader(is); - + // Create the CSV reader. Use comma separator. CSVReader reader = new CSVReader(r, ',', '\'', '\\'); - + //Read and throw away the header row. parseHeaders(reader.readNext()); - + String[] data = null; while ((data = reader.readNext()) != null) { // detect empty lines and skip: @@ -134,41 +133,38 @@ public abstract class RocksimComponentFileLoader { } //Read the rest of the file as data rows. return; - } - catch (IOException e) { - } - finally { + } catch (IOException e) { + } finally { if (r != null) { try { r.close(); - } - catch (IOException e) { + } catch (IOException e) { } } } - + } - + protected void parseHeaders(String[] headers) { for (RocksimComponentFileColumnParser column : fileColumns) { column.configure(headers); } } - + protected void parseData(String[] data) { if (data == null || data.length == 0) { return; } TypedPropertyMap props = new TypedPropertyMap(); - + preProcess(data); - + for (RocksimComponentFileColumnParser column : fileColumns) { column.parse(data, props); } postProcess(props); } - + protected void preProcess(String[] data) { for (int i = 0; i < data.length; i++) { String d = data[i]; @@ -177,13 +173,13 @@ public abstract class RocksimComponentFileLoader { } d = d.trim(); d = stripAll(d, '"'); - + data[i] = d; } } - + protected abstract void postProcess(TypedPropertyMap props); - + /** * Rocksim CSV units are either inches or mm. A value of 0 or "in." indicate inches. A value of 1 or "mm" indicate * millimeters. @@ -196,7 +192,7 @@ public abstract class RocksimComponentFileLoader { String tmp = units.trim().toLowerCase(); return "0".equals(tmp) || tmp.startsWith("in"); } - + /** * Convert inches or millimeters to meters. * @@ -207,13 +203,13 @@ public abstract class RocksimComponentFileLoader { */ protected static double convertLength(String units, double value) { if (isInches(units)) { - return PrintUnit.INCHES.toMeters(value); + return UnitGroup.UNITS_LENGTH.getUnit("in").fromUnit(value); } else { - return PrintUnit.MILLIMETERS.toMeters(value); + return UnitGroup.UNITS_LENGTH.getUnit("mm").fromUnit(value); } } - + protected static double convertMass(String units, double value) { if ("oz".equals(units)) { Unit u = UnitGroup.UNITS_MASS.getUnit(2); @@ -221,7 +217,7 @@ public abstract class RocksimComponentFileLoader { } return value; } - + /** * Remove all occurrences of the given character. Note: this is done because some manufacturers embed double quotes * in their descriptions or material names. Those are stripped away because they cause all sorts of matching/lookup @@ -242,7 +238,7 @@ public abstract class RocksimComponentFileLoader { } return sb.toString(); } - + /** * Convert all words in a given string to Camel Case (first letter capitalized). Words are assumed to be separated * by a space. Note: this is done because some manufacturers define their material name in Camel Case but the @@ -268,7 +264,7 @@ public abstract class RocksimComponentFileLoader { return target; } } - + } //Errata: diff --git a/core/src/net/sf/openrocket/rocketcomponent/FlightConfiguration.java b/core/src/net/sf/openrocket/rocketcomponent/FlightConfiguration.java index d99c81b9e..054f50cf3 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/FlightConfiguration.java +++ b/core/src/net/sf/openrocket/rocketcomponent/FlightConfiguration.java @@ -11,7 +11,7 @@ import net.sf.openrocket.util.ChangeSource; * * @param the parameter type */ -public interface FlightConfiguration extends FlightConfigurableComponent { +public interface FlightConfiguration extends FlightConfigurableComponent, Iterable { /** * Return the default parameter value for this FlightConfiguration. diff --git a/core/src/net/sf/openrocket/rocketcomponent/FlightConfigurationImpl.java b/core/src/net/sf/openrocket/rocketcomponent/FlightConfigurationImpl.java index f69fa6b22..91fa99d60 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/FlightConfigurationImpl.java +++ b/core/src/net/sf/openrocket/rocketcomponent/FlightConfigurationImpl.java @@ -2,6 +2,7 @@ package net.sf.openrocket.rocketcomponent; import java.util.EventObject; import java.util.HashMap; +import java.util.Iterator; import net.sf.openrocket.util.StateChangeListener; import net.sf.openrocket.util.Utils; @@ -79,6 +80,10 @@ class FlightConfigurationImpl> implemen fireEvent(); } + @Override + public Iterator iterator() { + return map.values().iterator(); + } @Override diff --git a/core/src/net/sf/openrocket/rocketcomponent/InnerTube.java b/core/src/net/sf/openrocket/rocketcomponent/InnerTube.java index 2f9ab99d2..4b9737028 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/InnerTube.java +++ b/core/src/net/sf/openrocket/rocketcomponent/InnerTube.java @@ -309,6 +309,25 @@ public class InnerTube extends ThicknessRingComponent implements Clusterable, Ra return copy; } - + /** + * For a given coordinate that represents one tube in a cluster, create an instance of that tube. Must be called + * once for each tube in the cluster. + * + * @param coord the coordinate of the clustered tube to create + * @param splitName the name of the individual tube + * @param theInnerTube the 'parent' from which this tube will be created. + * + * @return an instance of an inner tube that represents ONE of the clustered tubes in the cluster represented + * by theInnerTube + */ + public static InnerTube makeIndividualClusterComponent(Coordinate coord, String splitName, RocketComponent theInnerTube) { + InnerTube copy = (InnerTube) theInnerTube.copy(); + copy.setClusterConfiguration(ClusterConfiguration.SINGLE); + copy.setClusterRotation(0.0); + copy.setClusterScale(1.0); + copy.setRadialShift(coord.y, coord.z); + copy.setName(splitName); + return copy; + } } \ No newline at end of file diff --git a/core/src/net/sf/openrocket/rocketcomponent/Rocket.java b/core/src/net/sf/openrocket/rocketcomponent/Rocket.java index 144706f7b..2bbe48757 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/Rocket.java +++ b/core/src/net/sf/openrocket/rocketcomponent/Rocket.java @@ -545,7 +545,14 @@ public class Rocket extends RocketComponent { checkState(); if (id == null) return; + // Get current configuration: + String currentId = getDefaultConfiguration().getFlightConfigurationID(); + // If we're removing the current configuration, we need to switch to a different one first. + if (currentId != null && currentId.equals(id)) { + getDefaultConfiguration().setFlightConfigurationID(null); + } flightConfigurationIDs.remove(id); + // FIXME - remove corresponding simulations? fireComponentChangeEvent(ComponentChangeEvent.MOTOR_CHANGE); } diff --git a/core/src/net/sf/openrocket/unit/Unit.java b/core/src/net/sf/openrocket/unit/Unit.java index 7ac073a8d..75931d050 100644 --- a/core/src/net/sf/openrocket/unit/Unit.java +++ b/core/src/net/sf/openrocket/unit/Unit.java @@ -103,6 +103,10 @@ public abstract class Unit { } val = roundForDecimalFormat(val); + // Check for approximate integer + if (Math.abs(val - Math.floor(val)) < 0.0001) { + return intFormat.format(val); + } return decFormat.format(val); } diff --git a/core/test/net/sf/openrocket/ServicesForTesting.java b/core/test/net/sf/openrocket/ServicesForTesting.java new file mode 100644 index 000000000..2d6ec6743 --- /dev/null +++ b/core/test/net/sf/openrocket/ServicesForTesting.java @@ -0,0 +1,155 @@ +package net.sf.openrocket; + +import java.util.Collections; +import java.util.Locale; +import java.util.Set; +import java.util.concurrent.atomic.AtomicReference; + +import net.sf.openrocket.formatting.RocketDescriptor; +import net.sf.openrocket.formatting.RocketDescriptorImpl; +import net.sf.openrocket.l10n.DebugTranslator; +import net.sf.openrocket.l10n.ResourceBundleTranslator; +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.startup.Preferences; + +import com.google.inject.AbstractModule; +import com.google.inject.Provider; + +public class ServicesForTesting extends AbstractModule { + + @Override + protected void configure() { + bind(Preferences.class).to(PreferencesForTesting.class); + bind(Translator.class).toProvider(TranslatorProviderForTesting.class); + bind(RocketDescriptor.class).to(RocketDescriptorImpl.class); + } + + public static class TranslatorProviderForTesting implements Provider { + + private AtomicReference translator = new AtomicReference(); + + @Override + public Translator get() { + + Translator oldTranslator = translator.get(); + + if (oldTranslator != null) { + return oldTranslator; + } + + + Locale.setDefault(Locale.US); + + // Setup the translator + Translator newTranslator; + newTranslator = new ResourceBundleTranslator("l10n.messages"); + if (Locale.getDefault().getLanguage().equals("xx")) { + newTranslator = new DebugTranslator(newTranslator); + } + + if (translator.compareAndSet(null, newTranslator)) { + return newTranslator; + } else { + return translator.get(); + } + + } + + } + + public static class PreferencesForTesting extends Preferences { + + @Override + public boolean getBoolean(String key, boolean defaultValue) { + // TODO Auto-generated method stub + return false; + } + + @Override + public void putBoolean(String key, boolean value) { + // TODO Auto-generated method stub + + } + + @Override + public int getInt(String key, int defaultValue) { + // TODO Auto-generated method stub + return 0; + } + + @Override + public void putInt(String key, int value) { + // TODO Auto-generated method stub + + } + + @Override + public double getDouble(String key, double defaultValue) { + // TODO Auto-generated method stub + return 0; + } + + @Override + public void putDouble(String key, double value) { + // TODO Auto-generated method stub + + } + + @Override + public String getString(String key, String defaultValue) { + // TODO Auto-generated method stub + return null; + } + + @Override + public void putString(String key, String value) { + // TODO Auto-generated method stub + + } + + @Override + public String getString(String directory, String key, String defaultValue) { + // TODO Auto-generated method stub + return null; + } + + @Override + public void putString(String directory, String key, String value) { + // TODO Auto-generated method stub + + } + + @Override + public void addUserMaterial(Material m) { + // TODO Auto-generated method stub + + } + + @Override + public Set getUserMaterials() { + return Collections. emptySet(); + } + + @Override + public void removeUserMaterial(Material m) { + // TODO Auto-generated method stub + + } + + @Override + public void setComponentFavorite(ComponentPreset preset, Type type, boolean favorite) { + // TODO Auto-generated method stub + + } + + @Override + public Set getComponentFavorites(Type type) { + // TODO Auto-generated method stub + return null; + } + + } +} diff --git a/core/test/net/sf/openrocket/file/openrocket/OpenRocketSaverTest.java b/core/test/net/sf/openrocket/file/openrocket/OpenRocketSaverTest.java index 7d80a0cfd..96f826c08 100644 --- a/core/test/net/sf/openrocket/file/openrocket/OpenRocketSaverTest.java +++ b/core/test/net/sf/openrocket/file/openrocket/OpenRocketSaverTest.java @@ -13,7 +13,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; -import net.sf.openrocket.IntegrationTest; +import net.sf.openrocket.ServicesForTesting; import net.sf.openrocket.database.ComponentPresetDao; import net.sf.openrocket.database.ComponentPresetDatabase; import net.sf.openrocket.database.motor.MotorDatabase; @@ -30,7 +30,6 @@ import net.sf.openrocket.motor.ThrustCurveMotor; import net.sf.openrocket.plugin.PluginModule; import net.sf.openrocket.startup.Application; import net.sf.openrocket.util.TestRockets; -import net.sf.openrocket.utils.CoreServicesModule; import org.junit.After; import org.junit.BeforeClass; @@ -50,7 +49,7 @@ public class OpenRocketSaverTest { @BeforeClass public static void setup() { - Module applicationModule = new CoreServicesModule(); + Module applicationModule = new ServicesForTesting(); Module pluginModule = new PluginModule(); Module dbOverrides = new AbstractModule() { @@ -307,7 +306,7 @@ public class OpenRocketSaverTest { private static ThrustCurveMotor readMotor() { GeneralMotorLoader loader = new GeneralMotorLoader(); - InputStream is = IntegrationTest.class.getResourceAsStream("Estes_A8.rse"); + InputStream is = OpenRocketSaverTest.class.getResourceAsStream("/net/sf/openrocket/Estes_A8.rse"); assertNotNull("Problem in unit test, cannot find Estes_A8.rse", is); try { for (Motor m : loader.load(is, "Estes_A8.rse")) { diff --git a/core/test/net/sf/openrocket/plugin/PluginTest.java b/core/test/net/sf/openrocket/plugin/PluginTest.java index bff5bf9c1..6dacbeae4 100644 --- a/core/test/net/sf/openrocket/plugin/PluginTest.java +++ b/core/test/net/sf/openrocket/plugin/PluginTest.java @@ -1,6 +1,6 @@ package net.sf.openrocket.plugin; -import net.sf.openrocket.utils.CoreServicesModule; +import net.sf.openrocket.ServicesForTesting; import org.junit.Test; @@ -20,7 +20,7 @@ public class PluginTest { @Test public void testPluginModule() { - Module applicationModule = new CoreServicesModule(); + Module applicationModule = new ServicesForTesting(); Injector injector = Guice.createInjector(applicationModule, new PluginModule()); PluginTester tester = injector.getInstance(PluginTester.class); diff --git a/core/test/net/sf/openrocket/rocketcomponent/ComponentCompareTest.java b/core/test/net/sf/openrocket/rocketcomponent/ComponentCompareTest.java index d1797c2c7..c954edbd6 100644 --- a/core/test/net/sf/openrocket/rocketcomponent/ComponentCompareTest.java +++ b/core/test/net/sf/openrocket/rocketcomponent/ComponentCompareTest.java @@ -4,10 +4,9 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import java.awt.Color; import java.util.Iterator; -import net.sf.openrocket.gui.util.ColorConversion; +import net.sf.openrocket.util.Color; import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.BaseTestCase.BaseTestCase; @@ -41,7 +40,7 @@ public class ComponentCompareTest extends BaseTestCase { ComponentCompare.assertDeepSimilarity(r1, r2, false); - r1.setColor(ColorConversion.fromAwtColor(Color.YELLOW)); + r1.setColor(Color.BLACK); try { ComponentCompare.assertEquality(r1, r2); fail(); diff --git a/core/test/net/sf/openrocket/rocketcomponent/FinSetTest.java b/core/test/net/sf/openrocket/rocketcomponent/FinSetTest.java index 14299440c..9febe3256 100644 --- a/core/test/net/sf/openrocket/rocketcomponent/FinSetTest.java +++ b/core/test/net/sf/openrocket/rocketcomponent/FinSetTest.java @@ -3,16 +3,13 @@ package net.sf.openrocket.rocketcomponent; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; - -import java.awt.Color; - -import net.sf.openrocket.gui.util.ColorConversion; import net.sf.openrocket.material.Material; import net.sf.openrocket.material.Material.Type; import net.sf.openrocket.rocketcomponent.ExternalComponent.Finish; import net.sf.openrocket.rocketcomponent.FinSet.CrossSection; import net.sf.openrocket.rocketcomponent.FinSet.TabRelativePosition; import net.sf.openrocket.rocketcomponent.RocketComponent.Position; +import net.sf.openrocket.util.Color; import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.LineStyle; import net.sf.openrocket.util.BaseTestCase.BaseTestCase; @@ -20,22 +17,22 @@ import net.sf.openrocket.util.BaseTestCase.BaseTestCase; import org.junit.Test; public class FinSetTest extends BaseTestCase { - + @Test public void testTrapezoidCGComputation() { - + { // This is a simple square fin with sides of 1.0. TrapezoidFinSet fins = new TrapezoidFinSet(); fins.setFinCount(1); fins.setFinShape(1.0, 1.0, 0.0, 1.0, .005); - + Coordinate coords = fins.getCG(); assertEquals(1.0, fins.getFinArea(), 0.001); assertEquals(0.5, coords.x, 0.001); assertEquals(0.5, coords.y, 0.001); } - + { // This is a trapezoid. Height 1, root 1, tip 1/2 no sweep. // It can be decomposed into a rectangle followed by a triangle @@ -46,18 +43,18 @@ public class FinSetTest extends BaseTestCase { TrapezoidFinSet fins = new TrapezoidFinSet(); fins.setFinCount(1); fins.setFinShape(1.0, 0.5, 0.0, 1.0, .005); - + Coordinate coords = fins.getCG(); assertEquals(0.75, fins.getFinArea(), 0.001); assertEquals(0.3889, coords.x, 0.001); assertEquals(0.4444, coords.y, 0.001); } - + } - + @Test public void testFreeformCGComputation() throws Exception { - + { // This is a trapezoid. Height 1, root 1, tip 1/2 no sweep. // It can be decomposed into a rectangle followed by a triangle @@ -68,10 +65,10 @@ public class FinSetTest extends BaseTestCase { FreeformFinSet fins = new FreeformFinSet(); fins.setFinCount(1); Coordinate[] points = new Coordinate[] { - new Coordinate(0,0), - new Coordinate(0,1), - new Coordinate(.5,1), - new Coordinate(1,0) + new Coordinate(0, 0), + new Coordinate(0, 1), + new Coordinate(.5, 1), + new Coordinate(1, 0) }; fins.setPoints(points); Coordinate coords = fins.getCG(); @@ -79,20 +76,20 @@ public class FinSetTest extends BaseTestCase { assertEquals(0.3889, coords.x, 0.001); assertEquals(0.4444, coords.y, 0.001); } - + { // This is the same trapezoid as previous free form, but it has // some extra points along the lines. FreeformFinSet fins = new FreeformFinSet(); fins.setFinCount(1); Coordinate[] points = new Coordinate[] { - new Coordinate(0,0), - new Coordinate(0,.5), - new Coordinate(0,1), - new Coordinate(.25,1), - new Coordinate(.5,1), - new Coordinate(.75,.5), - new Coordinate(1,0) + new Coordinate(0, 0), + new Coordinate(0, .5), + new Coordinate(0, 1), + new Coordinate(.25, 1), + new Coordinate(.5, 1), + new Coordinate(.75, .5), + new Coordinate(1, 0) }; fins.setPoints(points); Coordinate coords = fins.getCG(); @@ -100,7 +97,7 @@ public class FinSetTest extends BaseTestCase { assertEquals(0.3889, coords.x, 0.001); assertEquals(0.4444, coords.y, 0.001); } - + { // This is the same trapezoid as previous free form, but it has // some extra points which are very close to previous points. @@ -109,14 +106,14 @@ public class FinSetTest extends BaseTestCase { FreeformFinSet fins = new FreeformFinSet(); fins.setFinCount(1); Coordinate[] points = new Coordinate[] { - new Coordinate(0,0), - new Coordinate(0,1E-15), - new Coordinate(0,1), - new Coordinate(1E-15,1), - new Coordinate(.5,1), - new Coordinate(.5,1-1E-15), - new Coordinate(1,1E-15), - new Coordinate(1,0) + new Coordinate(0, 0), + new Coordinate(0, 1E-15), + new Coordinate(0, 1), + new Coordinate(1E-15, 1), + new Coordinate(.5, 1), + new Coordinate(.5, 1 - 1E-15), + new Coordinate(1, 1E-15), + new Coordinate(1, 0) }; fins.setPoints(points); Coordinate coords = fins.getCG(); @@ -124,9 +121,9 @@ public class FinSetTest extends BaseTestCase { assertEquals(0.3889, coords.x, 0.001); assertEquals(0.4444, coords.y, 0.001); } - + } - + @Test public void testFreeFormCGWithNegativeY() throws Exception { // This particular fin shape is currently not allowed in OR since the y values are negative @@ -151,38 +148,38 @@ public class FinSetTest extends BaseTestCase { FreeformFinSet fins = new FreeformFinSet(); fins.setFinCount(1); Coordinate[] points = new Coordinate[] { - new Coordinate(0,0), - new Coordinate(0,1), - new Coordinate(2,1), - new Coordinate(2,-1), - new Coordinate(1,-1), - new Coordinate(1,0) + new Coordinate(0, 0), + new Coordinate(0, 1), + new Coordinate(2, 1), + new Coordinate(2, -1), + new Coordinate(1, -1), + new Coordinate(1, 0) }; fins.setPoints(points); Coordinate coords = fins.getCG(); assertEquals(3.0, fins.getFinArea(), 0.001); - assertEquals(3.5/3.0, coords.x, 0.001); - assertEquals(0.5/3.0, coords.y, 0.001); - + assertEquals(3.5 / 3.0, coords.x, 0.001); + assertEquals(0.5 / 3.0, coords.y, 0.001); + } - - + + @Test public void testFreeformConvert() { testFreeformConvert(new TrapezoidFinSet()); testFreeformConvert(new EllipticalFinSet()); testFreeformConvert(new FreeformFinSet()); } - - + + private void testFreeformConvert(FinSet fin) { FreeformFinSet converted; Material mat = Material.newMaterial(Type.BULK, "foo", 0.1, true); - + fin.setBaseRotation(1.1); fin.setCantAngle(0.001); fin.setCGOverridden(true); - fin.setColor(ColorConversion.fromAwtColor(Color.YELLOW)); + fin.setColor(Color.BLACK); fin.setComment("cmt"); fin.setCrossSection(CrossSection.ROUNDED); fin.setFinCount(5); @@ -200,57 +197,57 @@ public class FinSetTest extends BaseTestCase { fin.setTabRelativePosition(TabRelativePosition.END); fin.setTabShift(0.015); fin.setThickness(0.005); - - + + converted = FreeformFinSet.convertFinSet((FinSet) fin.copy()); - + ComponentCompare.assertSimilarity(fin, converted, true); - + assertEquals(converted.getComponentName(), converted.getName()); - - + + // Create test rocket Rocket rocket = new Rocket(); Stage stage = new Stage(); BodyTube body = new BodyTube(); - + rocket.addChild(stage); stage.addChild(body); body.addChild(fin); - + Listener l1 = new Listener("l1"); rocket.addComponentChangeListener(l1); - + fin.setName("Custom name"); assertTrue(l1.changed); assertEquals(ComponentChangeEvent.NONFUNCTIONAL_CHANGE, l1.changetype); - - + + // Create copy RocketComponent rocketcopy = rocket.copy(); - + Listener l2 = new Listener("l2"); rocketcopy.addComponentChangeListener(l2); - + FinSet fincopy = (FinSet) rocketcopy.getChild(0).getChild(0).getChild(0); FreeformFinSet.convertFinSet(fincopy); - + assertTrue(l2.changed); assertEquals(ComponentChangeEvent.TREE_CHANGE, l2.changetype & ComponentChangeEvent.TREE_CHANGE); - + } - - + + private static class Listener implements ComponentChangeListener { private boolean changed = false; private int changetype = 0; private final String name; - + public Listener(String name) { this.name = name; } - + @Override public void componentChanged(ComponentChangeEvent e) { assertFalse("Ensuring listener " + name + " has not been called.", changed); @@ -258,5 +255,5 @@ public class FinSetTest extends BaseTestCase { changetype = e.getType(); } } - + } diff --git a/core/test/net/sf/openrocket/util/BaseTestCase/BaseTestCase.java b/core/test/net/sf/openrocket/util/BaseTestCase/BaseTestCase.java index db762dfab..454e133cb 100644 --- a/core/test/net/sf/openrocket/util/BaseTestCase/BaseTestCase.java +++ b/core/test/net/sf/openrocket/util/BaseTestCase/BaseTestCase.java @@ -1,10 +1,10 @@ package net.sf.openrocket.util.BaseTestCase; +import net.sf.openrocket.ServicesForTesting; import net.sf.openrocket.l10n.DebugTranslator; import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.plugin.PluginModule; import net.sf.openrocket.startup.Application; -import net.sf.openrocket.utils.CoreServicesModule; import org.junit.BeforeClass; @@ -18,7 +18,7 @@ public class BaseTestCase { @BeforeClass public static void setUp() throws Exception { - Module applicationModule = new CoreServicesModule(); + Module applicationModule = new ServicesForTesting(); Module debugTranslator = new AbstractModule() { @Override diff --git a/lib-ant/ant-contrib-1.0b3.jar b/lib-ant/ant-contrib-1.0b3.jar new file mode 100644 index 000000000..062537661 Binary files /dev/null and b/lib-ant/ant-contrib-1.0b3.jar differ diff --git a/core/lib-test/hamcrest-core-1.3.0RC1.jar b/lib-test/hamcrest-core-1.3.0RC1.jar similarity index 100% rename from core/lib-test/hamcrest-core-1.3.0RC1.jar rename to lib-test/hamcrest-core-1.3.0RC1.jar diff --git a/core/lib-test/hamcrest-library-1.3.0RC1.jar b/lib-test/hamcrest-library-1.3.0RC1.jar similarity index 100% rename from core/lib-test/hamcrest-library-1.3.0RC1.jar rename to lib-test/hamcrest-library-1.3.0RC1.jar diff --git a/core/lib-test/jmock-2.6.0-RC2.jar b/lib-test/jmock-2.6.0-RC2.jar similarity index 100% rename from core/lib-test/jmock-2.6.0-RC2.jar rename to lib-test/jmock-2.6.0-RC2.jar diff --git a/core/lib-test/jmock-junit4-2.6.0-RC2.jar b/lib-test/jmock-junit4-2.6.0-RC2.jar similarity index 100% rename from core/lib-test/jmock-junit4-2.6.0-RC2.jar rename to lib-test/jmock-junit4-2.6.0-RC2.jar diff --git a/core/lib-test/junit-dep-4.8.2.jar b/lib-test/junit-dep-4.8.2.jar similarity index 100% rename from core/lib-test/junit-dep-4.8.2.jar rename to lib-test/junit-dep-4.8.2.jar diff --git a/core/lib-test/test-plugin.jar b/lib-test/test-plugin.jar similarity index 100% rename from core/lib-test/test-plugin.jar rename to lib-test/test-plugin.jar diff --git a/core/lib-test/uispec4j-2.3-jdk16.jar b/lib-test/uispec4j-2.3-jdk16.jar similarity index 100% rename from core/lib-test/uispec4j-2.3-jdk16.jar rename to lib-test/uispec4j-2.3-jdk16.jar diff --git a/swing/.classpath b/swing/.classpath new file mode 100644 index 000000000..94bc55d43 --- /dev/null +++ b/swing/.classpath @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/swing/.gitignore b/swing/.gitignore new file mode 100644 index 000000000..348c102af --- /dev/null +++ b/swing/.gitignore @@ -0,0 +1,2 @@ +/build +/bin diff --git a/swing/.project b/swing/.project new file mode 100644 index 000000000..f8a30912c --- /dev/null +++ b/swing/.project @@ -0,0 +1,17 @@ + + + OpenRocket Swing + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/swing/.settings/org.eclipse.jdt.core.prefs b/swing/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..779e3273d --- /dev/null +++ b/swing/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,89 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled +org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore +org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull +org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault +org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable +org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled +org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.comparingIdentical=error +org.eclipse.jdt.core.compiler.problem.deadCode=warning +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore +org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore +org.eclipse.jdt.core.compiler.problem.fallthroughCase=error +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled +org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning +org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=error +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore +org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning +org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error +org.eclipse.jdt.core.compiler.problem.nullReference=warning +org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error +org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=error +org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore +org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning +org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore +org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore +org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore +org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore +org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedImport=warning +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning diff --git a/swing/build.xml b/swing/build.xml new file mode 100644 index 000000000..53afdf087 --- /dev/null +++ b/swing/build.xml @@ -0,0 +1,333 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Compiling main classes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Generating ORC file for vendor @{vendor} + + + + + + + + + + + + + + + + + + + + + + Building source distribution + + + + + + + + + + + + + + + + + + Testing source distribution + + + + + + + + + Source distribution test successful + + + + + + + + + + + + + Distribution ${build.version} (${build.source}) built into directory ${jar.dir} + + + + + + + + + + + Checking project for FIXMEs. + + + + + + + + + + + + + + + + CRITICAL TODOs exist in project: +${criticaltodos} + No critical TODOs in project. + + + + + + + + Checking project for non-ASCII characters. + + + + + + + + + + + + + + + + Non-ASCII characters exist in project: +${nonascii} + No non-ASCII characters in project. + + + + + + Building unit tests + + + + Running unit tests + + + + + + + + + + + + + + + + + + + + + + + + Unit tests passed successfully. + + + + + + Building unit tests + + + + Running unit tests + + + + + + + + + + + + + + + + + + + + + Unit tests passed successfully. + + + + + diff --git a/core/lib/OrangeExtensions-1.2.jar b/swing/lib/OrangeExtensions-1.2.jar similarity index 100% rename from core/lib/OrangeExtensions-1.2.jar rename to swing/lib/OrangeExtensions-1.2.jar diff --git a/core/lib/iText-5.0.2.jar b/swing/lib/iText-5.0.2.jar similarity index 100% rename from core/lib/iText-5.0.2.jar rename to swing/lib/iText-5.0.2.jar diff --git a/core/lib/jcommon-1.0.18.jar b/swing/lib/jcommon-1.0.18.jar similarity index 100% rename from core/lib/jcommon-1.0.18.jar rename to swing/lib/jcommon-1.0.18.jar diff --git a/core/lib/jfreechart-1.0.15.jar b/swing/lib/jfreechart-1.0.15.jar similarity index 100% rename from core/lib/jfreechart-1.0.15.jar rename to swing/lib/jfreechart-1.0.15.jar diff --git a/core/lib/jogl/gluegen-rt-natives-linux-amd64.jar b/swing/lib/jogl/gluegen-rt-natives-linux-amd64.jar similarity index 100% rename from core/lib/jogl/gluegen-rt-natives-linux-amd64.jar rename to swing/lib/jogl/gluegen-rt-natives-linux-amd64.jar diff --git a/core/lib/jogl/gluegen-rt-natives-linux-i586.jar b/swing/lib/jogl/gluegen-rt-natives-linux-i586.jar similarity index 100% rename from core/lib/jogl/gluegen-rt-natives-linux-i586.jar rename to swing/lib/jogl/gluegen-rt-natives-linux-i586.jar diff --git a/core/lib/jogl/gluegen-rt-natives-macosx-universal.jar b/swing/lib/jogl/gluegen-rt-natives-macosx-universal.jar similarity index 100% rename from core/lib/jogl/gluegen-rt-natives-macosx-universal.jar rename to swing/lib/jogl/gluegen-rt-natives-macosx-universal.jar diff --git a/core/lib/jogl/gluegen-rt-natives-windows-amd64.jar b/swing/lib/jogl/gluegen-rt-natives-windows-amd64.jar similarity index 100% rename from core/lib/jogl/gluegen-rt-natives-windows-amd64.jar rename to swing/lib/jogl/gluegen-rt-natives-windows-amd64.jar diff --git a/core/lib/jogl/gluegen-rt-natives-windows-i586.jar b/swing/lib/jogl/gluegen-rt-natives-windows-i586.jar similarity index 100% rename from core/lib/jogl/gluegen-rt-natives-windows-i586.jar rename to swing/lib/jogl/gluegen-rt-natives-windows-i586.jar diff --git a/core/lib/jogl/gluegen-rt.jar b/swing/lib/jogl/gluegen-rt.jar similarity index 100% rename from core/lib/jogl/gluegen-rt.jar rename to swing/lib/jogl/gluegen-rt.jar diff --git a/core/lib/jogl/jogl-all-natives-linux-amd64.jar b/swing/lib/jogl/jogl-all-natives-linux-amd64.jar similarity index 100% rename from core/lib/jogl/jogl-all-natives-linux-amd64.jar rename to swing/lib/jogl/jogl-all-natives-linux-amd64.jar diff --git a/core/lib/jogl/jogl-all-natives-linux-i586.jar b/swing/lib/jogl/jogl-all-natives-linux-i586.jar similarity index 100% rename from core/lib/jogl/jogl-all-natives-linux-i586.jar rename to swing/lib/jogl/jogl-all-natives-linux-i586.jar diff --git a/core/lib/jogl/jogl-all-natives-macosx-universal.jar b/swing/lib/jogl/jogl-all-natives-macosx-universal.jar similarity index 100% rename from core/lib/jogl/jogl-all-natives-macosx-universal.jar rename to swing/lib/jogl/jogl-all-natives-macosx-universal.jar diff --git a/core/lib/jogl/jogl-all-natives-windows-amd64.jar b/swing/lib/jogl/jogl-all-natives-windows-amd64.jar similarity index 100% rename from core/lib/jogl/jogl-all-natives-windows-amd64.jar rename to swing/lib/jogl/jogl-all-natives-windows-amd64.jar diff --git a/core/lib/jogl/jogl-all-natives-windows-i586.jar b/swing/lib/jogl/jogl-all-natives-windows-i586.jar similarity index 100% rename from core/lib/jogl/jogl-all-natives-windows-i586.jar rename to swing/lib/jogl/jogl-all-natives-windows-i586.jar diff --git a/core/lib/jogl/jogl-all.jar b/swing/lib/jogl/jogl-all.jar similarity index 100% rename from core/lib/jogl/jogl-all.jar rename to swing/lib/jogl/jogl-all.jar diff --git a/core/lib/logback-classic-1.0.12.jar b/swing/lib/logback-classic-1.0.12.jar similarity index 100% rename from core/lib/logback-classic-1.0.12.jar rename to swing/lib/logback-classic-1.0.12.jar diff --git a/core/lib/logback-core-1.0.12.jar b/swing/lib/logback-core-1.0.12.jar similarity index 100% rename from core/lib/logback-core-1.0.12.jar rename to swing/lib/logback-core-1.0.12.jar diff --git a/core/lib/miglayout15-swing.jar b/swing/lib/miglayout15-swing.jar similarity index 100% rename from core/lib/miglayout15-swing.jar rename to swing/lib/miglayout15-swing.jar diff --git a/core/reference/jfreechart-1.0.15-sources.jar b/swing/reference/jfreechart-1.0.15-sources.jar similarity index 100% rename from core/reference/jfreechart-1.0.15-sources.jar rename to swing/reference/jfreechart-1.0.15-sources.jar diff --git a/core/reference/jogl-all-2.0.2-sources.jar b/swing/reference/jogl-all-2.0.2-sources.jar similarity index 100% rename from core/reference/jogl-all-2.0.2-sources.jar rename to swing/reference/jogl-all-2.0.2-sources.jar diff --git a/core/resources-src/datafiles/presets/Estes.orc b/swing/resources-src/datafiles/presets/Estes.orc similarity index 100% rename from core/resources-src/datafiles/presets/Estes.orc rename to swing/resources-src/datafiles/presets/Estes.orc diff --git a/core/resources-src/datafiles/presets/LocPrecision.orc b/swing/resources-src/datafiles/presets/LocPrecision.orc similarity index 100% rename from core/resources-src/datafiles/presets/LocPrecision.orc rename to swing/resources-src/datafiles/presets/LocPrecision.orc diff --git a/core/resources-src/datafiles/presets/Quest.orc b/swing/resources-src/datafiles/presets/Quest.orc similarity index 100% rename from core/resources-src/datafiles/presets/Quest.orc rename to swing/resources-src/datafiles/presets/Quest.orc diff --git a/core/resources-src/datafiles/presets/bluetube.orc b/swing/resources-src/datafiles/presets/bluetube.orc similarity index 100% rename from core/resources-src/datafiles/presets/bluetube.orc rename to swing/resources-src/datafiles/presets/bluetube.orc diff --git a/core/resources-src/datafiles/presets/bms.orc b/swing/resources-src/datafiles/presets/bms.orc similarity index 100% rename from core/resources-src/datafiles/presets/bms.orc rename to swing/resources-src/datafiles/presets/bms.orc diff --git a/core/resources-src/datafiles/presets/fliskits.orc b/swing/resources-src/datafiles/presets/fliskits.orc similarity index 100% rename from core/resources-src/datafiles/presets/fliskits.orc rename to swing/resources-src/datafiles/presets/fliskits.orc diff --git a/core/resources-src/datafiles/presets/giantleaprocketry.orc b/swing/resources-src/datafiles/presets/giantleaprocketry.orc similarity index 100% rename from core/resources-src/datafiles/presets/giantleaprocketry.orc rename to swing/resources-src/datafiles/presets/giantleaprocketry.orc diff --git a/core/resources-src/datafiles/presets/publicmissiles.orc b/swing/resources-src/datafiles/presets/publicmissiles.orc similarity index 100% rename from core/resources-src/datafiles/presets/publicmissiles.orc rename to swing/resources-src/datafiles/presets/publicmissiles.orc diff --git a/core/resources-src/datafiles/presets/semroc.orc b/swing/resources-src/datafiles/presets/semroc.orc similarity index 100% rename from core/resources-src/datafiles/presets/semroc.orc rename to swing/resources-src/datafiles/presets/semroc.orc diff --git a/core/resources-src/datafiles/rocksim_components/bluetube/BTDATA.CSV b/swing/resources-src/datafiles/rocksim_components/bluetube/BTDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/bluetube/BTDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/bluetube/BTDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/bluetube/MATERIAL.CSV b/swing/resources-src/datafiles/rocksim_components/bluetube/MATERIAL.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/bluetube/MATERIAL.CSV rename to swing/resources-src/datafiles/rocksim_components/bluetube/MATERIAL.CSV diff --git a/core/resources-src/datafiles/rocksim_components/bluetube/TCDATA.CSV b/swing/resources-src/datafiles/rocksim_components/bluetube/TCDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/bluetube/TCDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/bluetube/TCDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/bluetube/readme.txt b/swing/resources-src/datafiles/rocksim_components/bluetube/readme.txt similarity index 100% rename from core/resources-src/datafiles/rocksim_components/bluetube/readme.txt rename to swing/resources-src/datafiles/rocksim_components/bluetube/readme.txt diff --git a/core/resources-src/datafiles/rocksim_components/bms/BHdata.csv b/swing/resources-src/datafiles/rocksim_components/bms/BHdata.csv similarity index 100% rename from core/resources-src/datafiles/rocksim_components/bms/BHdata.csv rename to swing/resources-src/datafiles/rocksim_components/bms/BHdata.csv diff --git a/core/resources-src/datafiles/rocksim_components/bms/BTdata.csv b/swing/resources-src/datafiles/rocksim_components/bms/BTdata.csv similarity index 100% rename from core/resources-src/datafiles/rocksim_components/bms/BTdata.csv rename to swing/resources-src/datafiles/rocksim_components/bms/BTdata.csv diff --git a/core/resources-src/datafiles/rocksim_components/bms/CRdata.csv b/swing/resources-src/datafiles/rocksim_components/bms/CRdata.csv similarity index 100% rename from core/resources-src/datafiles/rocksim_components/bms/CRdata.csv rename to swing/resources-src/datafiles/rocksim_components/bms/CRdata.csv diff --git a/core/resources-src/datafiles/rocksim_components/bms/LLdata.csv b/swing/resources-src/datafiles/rocksim_components/bms/LLdata.csv similarity index 100% rename from core/resources-src/datafiles/rocksim_components/bms/LLdata.csv rename to swing/resources-src/datafiles/rocksim_components/bms/LLdata.csv diff --git a/core/resources-src/datafiles/rocksim_components/bms/MATERIAL.CSV b/swing/resources-src/datafiles/rocksim_components/bms/MATERIAL.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/bms/MATERIAL.CSV rename to swing/resources-src/datafiles/rocksim_components/bms/MATERIAL.CSV diff --git a/core/resources-src/datafiles/rocksim_components/bms/NCdata.csv b/swing/resources-src/datafiles/rocksim_components/bms/NCdata.csv similarity index 100% rename from core/resources-src/datafiles/rocksim_components/bms/NCdata.csv rename to swing/resources-src/datafiles/rocksim_components/bms/NCdata.csv diff --git a/core/resources-src/datafiles/rocksim_components/bms/TCdata.csv b/swing/resources-src/datafiles/rocksim_components/bms/TCdata.csv similarity index 100% rename from core/resources-src/datafiles/rocksim_components/bms/TCdata.csv rename to swing/resources-src/datafiles/rocksim_components/bms/TCdata.csv diff --git a/core/resources-src/datafiles/rocksim_components/bms/TRdata.csv b/swing/resources-src/datafiles/rocksim_components/bms/TRdata.csv similarity index 100% rename from core/resources-src/datafiles/rocksim_components/bms/TRdata.csv rename to swing/resources-src/datafiles/rocksim_components/bms/TRdata.csv diff --git a/core/resources-src/datafiles/rocksim_components/bms/ebdata.csv b/swing/resources-src/datafiles/rocksim_components/bms/ebdata.csv similarity index 100% rename from core/resources-src/datafiles/rocksim_components/bms/ebdata.csv rename to swing/resources-src/datafiles/rocksim_components/bms/ebdata.csv diff --git a/core/resources-src/datafiles/rocksim_components/estes/BTDATA.CSV b/swing/resources-src/datafiles/rocksim_components/estes/BTDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/estes/BTDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/estes/BTDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/estes/EBDATA.CSV b/swing/resources-src/datafiles/rocksim_components/estes/EBDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/estes/EBDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/estes/EBDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/estes/LLDATA.CSV b/swing/resources-src/datafiles/rocksim_components/estes/LLDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/estes/LLDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/estes/LLDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/estes/MATERIAL.CSV b/swing/resources-src/datafiles/rocksim_components/estes/MATERIAL.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/estes/MATERIAL.CSV rename to swing/resources-src/datafiles/rocksim_components/estes/MATERIAL.CSV diff --git a/core/resources-src/datafiles/rocksim_components/estes/MODATA.CSV b/swing/resources-src/datafiles/rocksim_components/estes/MODATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/estes/MODATA.CSV rename to swing/resources-src/datafiles/rocksim_components/estes/MODATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/estes/NCDATA.CSV b/swing/resources-src/datafiles/rocksim_components/estes/NCDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/estes/NCDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/estes/NCDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/estes/PCDATA.CSV b/swing/resources-src/datafiles/rocksim_components/estes/PCDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/estes/PCDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/estes/PCDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/estes/TCDATA.CSV b/swing/resources-src/datafiles/rocksim_components/estes/TCDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/estes/TCDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/estes/TCDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/estes/TRDATA.CSV b/swing/resources-src/datafiles/rocksim_components/estes/TRDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/estes/TRDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/estes/TRDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/giantleaprocketry/BHDATA.CSV b/swing/resources-src/datafiles/rocksim_components/giantleaprocketry/BHDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/giantleaprocketry/BHDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/giantleaprocketry/BHDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/giantleaprocketry/BTDATA.CSV b/swing/resources-src/datafiles/rocksim_components/giantleaprocketry/BTDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/giantleaprocketry/BTDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/giantleaprocketry/BTDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/giantleaprocketry/CRDATA.CSV b/swing/resources-src/datafiles/rocksim_components/giantleaprocketry/CRDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/giantleaprocketry/CRDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/giantleaprocketry/CRDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/giantleaprocketry/LLDATA.CSV b/swing/resources-src/datafiles/rocksim_components/giantleaprocketry/LLDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/giantleaprocketry/LLDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/giantleaprocketry/LLDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/giantleaprocketry/MATERIAL.CSV b/swing/resources-src/datafiles/rocksim_components/giantleaprocketry/MATERIAL.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/giantleaprocketry/MATERIAL.CSV rename to swing/resources-src/datafiles/rocksim_components/giantleaprocketry/MATERIAL.CSV diff --git a/core/resources-src/datafiles/rocksim_components/giantleaprocketry/MODATA.CSV b/swing/resources-src/datafiles/rocksim_components/giantleaprocketry/MODATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/giantleaprocketry/MODATA.CSV rename to swing/resources-src/datafiles/rocksim_components/giantleaprocketry/MODATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/giantleaprocketry/NCDATA.CSV b/swing/resources-src/datafiles/rocksim_components/giantleaprocketry/NCDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/giantleaprocketry/NCDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/giantleaprocketry/NCDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/giantleaprocketry/PCDATA.CSV b/swing/resources-src/datafiles/rocksim_components/giantleaprocketry/PCDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/giantleaprocketry/PCDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/giantleaprocketry/PCDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/giantleaprocketry/TCDATA.CSV b/swing/resources-src/datafiles/rocksim_components/giantleaprocketry/TCDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/giantleaprocketry/TCDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/giantleaprocketry/TCDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/publicmissiles/BHDATA.CSV b/swing/resources-src/datafiles/rocksim_components/publicmissiles/BHDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/publicmissiles/BHDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/publicmissiles/BHDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/publicmissiles/BTDATA.CSV b/swing/resources-src/datafiles/rocksim_components/publicmissiles/BTDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/publicmissiles/BTDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/publicmissiles/BTDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/publicmissiles/CFDATA.CSV b/swing/resources-src/datafiles/rocksim_components/publicmissiles/CFDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/publicmissiles/CFDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/publicmissiles/CFDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/publicmissiles/CRDATA.CSV b/swing/resources-src/datafiles/rocksim_components/publicmissiles/CRDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/publicmissiles/CRDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/publicmissiles/CRDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/publicmissiles/EBDATA.CSV b/swing/resources-src/datafiles/rocksim_components/publicmissiles/EBDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/publicmissiles/EBDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/publicmissiles/EBDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/publicmissiles/FSDATA.CSV b/swing/resources-src/datafiles/rocksim_components/publicmissiles/FSDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/publicmissiles/FSDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/publicmissiles/FSDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/publicmissiles/GRAPHS.CSV b/swing/resources-src/datafiles/rocksim_components/publicmissiles/GRAPHS.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/publicmissiles/GRAPHS.CSV rename to swing/resources-src/datafiles/rocksim_components/publicmissiles/GRAPHS.CSV diff --git a/core/resources-src/datafiles/rocksim_components/publicmissiles/LLDATA.CSV b/swing/resources-src/datafiles/rocksim_components/publicmissiles/LLDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/publicmissiles/LLDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/publicmissiles/LLDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/publicmissiles/MATERIAL.CSV b/swing/resources-src/datafiles/rocksim_components/publicmissiles/MATERIAL.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/publicmissiles/MATERIAL.CSV rename to swing/resources-src/datafiles/rocksim_components/publicmissiles/MATERIAL.CSV diff --git a/core/resources-src/datafiles/rocksim_components/publicmissiles/MODATA.CSV b/swing/resources-src/datafiles/rocksim_components/publicmissiles/MODATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/publicmissiles/MODATA.CSV rename to swing/resources-src/datafiles/rocksim_components/publicmissiles/MODATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/publicmissiles/NCDATA.CSV b/swing/resources-src/datafiles/rocksim_components/publicmissiles/NCDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/publicmissiles/NCDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/publicmissiles/NCDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/publicmissiles/PCDATA.CSV b/swing/resources-src/datafiles/rocksim_components/publicmissiles/PCDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/publicmissiles/PCDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/publicmissiles/PCDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/publicmissiles/SLDATA.CSV b/swing/resources-src/datafiles/rocksim_components/publicmissiles/SLDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/publicmissiles/SLDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/publicmissiles/SLDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/publicmissiles/STDATA.CSV b/swing/resources-src/datafiles/rocksim_components/publicmissiles/STDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/publicmissiles/STDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/publicmissiles/STDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/publicmissiles/TCDATA.CSV b/swing/resources-src/datafiles/rocksim_components/publicmissiles/TCDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/publicmissiles/TCDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/publicmissiles/TCDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/publicmissiles/TRDATA.CSV b/swing/resources-src/datafiles/rocksim_components/publicmissiles/TRDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/publicmissiles/TRDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/publicmissiles/TRDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/quest/BTDATA.CSV b/swing/resources-src/datafiles/rocksim_components/quest/BTDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/quest/BTDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/quest/BTDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/quest/CRDATA.CSV b/swing/resources-src/datafiles/rocksim_components/quest/CRDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/quest/CRDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/quest/CRDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/quest/EBDATA.CSV b/swing/resources-src/datafiles/rocksim_components/quest/EBDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/quest/EBDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/quest/EBDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/quest/MATERIAL.CSV b/swing/resources-src/datafiles/rocksim_components/quest/MATERIAL.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/quest/MATERIAL.CSV rename to swing/resources-src/datafiles/rocksim_components/quest/MATERIAL.CSV diff --git a/core/resources-src/datafiles/rocksim_components/quest/NCDATA.CSV b/swing/resources-src/datafiles/rocksim_components/quest/NCDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/quest/NCDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/quest/NCDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/quest/PCDATA.CSV b/swing/resources-src/datafiles/rocksim_components/quest/PCDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/quest/PCDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/quest/PCDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/quest/STDATA.CSV b/swing/resources-src/datafiles/rocksim_components/quest/STDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/quest/STDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/quest/STDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/quest/TCDATA.CSV b/swing/resources-src/datafiles/rocksim_components/quest/TCDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/quest/TCDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/quest/TCDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/quest/TRDATA.CSV b/swing/resources-src/datafiles/rocksim_components/quest/TRDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/quest/TRDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/quest/TRDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/semroc/BHDATA.CSV b/swing/resources-src/datafiles/rocksim_components/semroc/BHDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/semroc/BHDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/semroc/BHDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/semroc/BTDATA.CSV b/swing/resources-src/datafiles/rocksim_components/semroc/BTDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/semroc/BTDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/semroc/BTDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/semroc/CRDATA.CSV b/swing/resources-src/datafiles/rocksim_components/semroc/CRDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/semroc/CRDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/semroc/CRDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/semroc/EBDATA.CSV b/swing/resources-src/datafiles/rocksim_components/semroc/EBDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/semroc/EBDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/semroc/EBDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/semroc/LLDATA.CSV b/swing/resources-src/datafiles/rocksim_components/semroc/LLDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/semroc/LLDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/semroc/LLDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/semroc/MATERIAL.CSV b/swing/resources-src/datafiles/rocksim_components/semroc/MATERIAL.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/semroc/MATERIAL.CSV rename to swing/resources-src/datafiles/rocksim_components/semroc/MATERIAL.CSV diff --git a/core/resources-src/datafiles/rocksim_components/semroc/NCDATA.CSV b/swing/resources-src/datafiles/rocksim_components/semroc/NCDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/semroc/NCDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/semroc/NCDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/semroc/PCDATA.CSV b/swing/resources-src/datafiles/rocksim_components/semroc/PCDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/semroc/PCDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/semroc/PCDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/semroc/STDATA.CSV b/swing/resources-src/datafiles/rocksim_components/semroc/STDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/semroc/STDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/semroc/STDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/semroc/TCDATA.CSV b/swing/resources-src/datafiles/rocksim_components/semroc/TCDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/semroc/TCDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/semroc/TCDATA.CSV diff --git a/core/resources-src/datafiles/rocksim_components/semroc/TRDATA.CSV b/swing/resources-src/datafiles/rocksim_components/semroc/TRDATA.CSV similarity index 100% rename from core/resources-src/datafiles/rocksim_components/semroc/TRDATA.CSV rename to swing/resources-src/datafiles/rocksim_components/semroc/TRDATA.CSV diff --git a/core/resources-src/datafiles/tours/convert-images.sh b/swing/resources-src/datafiles/tours/convert-images.sh similarity index 100% rename from core/resources-src/datafiles/tours/convert-images.sh rename to swing/resources-src/datafiles/tours/convert-images.sh diff --git a/core/resources-src/datafiles/tours/creating_design/dialog-1-nosecone.xcf.gz b/swing/resources-src/datafiles/tours/creating_design/dialog-1-nosecone.xcf.gz similarity index 100% rename from core/resources-src/datafiles/tours/creating_design/dialog-1-nosecone.xcf.gz rename to swing/resources-src/datafiles/tours/creating_design/dialog-1-nosecone.xcf.gz diff --git a/core/resources-src/datafiles/tours/creating_design/dialog-2-bodytube.xcf.gz b/swing/resources-src/datafiles/tours/creating_design/dialog-2-bodytube.xcf.gz similarity index 100% rename from core/resources-src/datafiles/tours/creating_design/dialog-2-bodytube.xcf.gz rename to swing/resources-src/datafiles/tours/creating_design/dialog-2-bodytube.xcf.gz diff --git a/core/resources-src/datafiles/tours/creating_design/dialog-3-finset.xcf.gz b/swing/resources-src/datafiles/tours/creating_design/dialog-3-finset.xcf.gz similarity index 100% rename from core/resources-src/datafiles/tours/creating_design/dialog-3-finset.xcf.gz rename to swing/resources-src/datafiles/tours/creating_design/dialog-3-finset.xcf.gz diff --git a/core/resources-src/datafiles/tours/creating_design/dialog-4-innertube.xcf.gz b/swing/resources-src/datafiles/tours/creating_design/dialog-4-innertube.xcf.gz similarity index 100% rename from core/resources-src/datafiles/tours/creating_design/dialog-4-innertube.xcf.gz rename to swing/resources-src/datafiles/tours/creating_design/dialog-4-innertube.xcf.gz diff --git a/core/resources-src/datafiles/tours/creating_design/dialog-5-centeringring.xcf.gz b/swing/resources-src/datafiles/tours/creating_design/dialog-5-centeringring.xcf.gz similarity index 100% rename from core/resources-src/datafiles/tours/creating_design/dialog-5-centeringring.xcf.gz rename to swing/resources-src/datafiles/tours/creating_design/dialog-5-centeringring.xcf.gz diff --git a/core/resources-src/datafiles/tours/creating_design/dialog-6-parachute.xcf.gz b/swing/resources-src/datafiles/tours/creating_design/dialog-6-parachute.xcf.gz similarity index 100% rename from core/resources-src/datafiles/tours/creating_design/dialog-6-parachute.xcf.gz rename to swing/resources-src/datafiles/tours/creating_design/dialog-6-parachute.xcf.gz diff --git a/core/resources-src/datafiles/tours/creating_design/main-0-initial.png b/swing/resources-src/datafiles/tours/creating_design/main-0-initial.png similarity index 100% rename from core/resources-src/datafiles/tours/creating_design/main-0-initial.png rename to swing/resources-src/datafiles/tours/creating_design/main-0-initial.png diff --git a/core/resources-src/datafiles/tours/creating_design/main-1-nosecone.xcf.gz b/swing/resources-src/datafiles/tours/creating_design/main-1-nosecone.xcf.gz similarity index 100% rename from core/resources-src/datafiles/tours/creating_design/main-1-nosecone.xcf.gz rename to swing/resources-src/datafiles/tours/creating_design/main-1-nosecone.xcf.gz diff --git a/core/resources-src/datafiles/tours/creating_design/main-2-bodytube.xcf.gz b/swing/resources-src/datafiles/tours/creating_design/main-2-bodytube.xcf.gz similarity index 100% rename from core/resources-src/datafiles/tours/creating_design/main-2-bodytube.xcf.gz rename to swing/resources-src/datafiles/tours/creating_design/main-2-bodytube.xcf.gz diff --git a/core/resources-src/datafiles/tours/creating_design/main-3-finset.xcf.gz b/swing/resources-src/datafiles/tours/creating_design/main-3-finset.xcf.gz similarity index 100% rename from core/resources-src/datafiles/tours/creating_design/main-3-finset.xcf.gz rename to swing/resources-src/datafiles/tours/creating_design/main-3-finset.xcf.gz diff --git a/core/resources-src/datafiles/tours/creating_design/main-4-innertube.xcf.gz b/swing/resources-src/datafiles/tours/creating_design/main-4-innertube.xcf.gz similarity index 100% rename from core/resources-src/datafiles/tours/creating_design/main-4-innertube.xcf.gz rename to swing/resources-src/datafiles/tours/creating_design/main-4-innertube.xcf.gz diff --git a/core/resources-src/datafiles/tours/creating_design/main-5-centeringring.xcf.gz b/swing/resources-src/datafiles/tours/creating_design/main-5-centeringring.xcf.gz similarity index 100% rename from core/resources-src/datafiles/tours/creating_design/main-5-centeringring.xcf.gz rename to swing/resources-src/datafiles/tours/creating_design/main-5-centeringring.xcf.gz diff --git a/core/resources-src/datafiles/tours/creating_design/main-6-parachute.xcf.gz b/swing/resources-src/datafiles/tours/creating_design/main-6-parachute.xcf.gz similarity index 100% rename from core/resources-src/datafiles/tours/creating_design/main-6-parachute.xcf.gz rename to swing/resources-src/datafiles/tours/creating_design/main-6-parachute.xcf.gz diff --git a/core/resources-src/datafiles/tours/creating_design/main-7-rest.xcf.gz b/swing/resources-src/datafiles/tours/creating_design/main-7-rest.xcf.gz similarity index 100% rename from core/resources-src/datafiles/tours/creating_design/main-7-rest.xcf.gz rename to swing/resources-src/datafiles/tours/creating_design/main-7-rest.xcf.gz diff --git a/core/resources-src/datafiles/tours/creating_design/main-8-final.png b/swing/resources-src/datafiles/tours/creating_design/main-8-final.png similarity index 100% rename from core/resources-src/datafiles/tours/creating_design/main-8-final.png rename to swing/resources-src/datafiles/tours/creating_design/main-8-final.png diff --git a/core/resources-src/datafiles/tours/introduction/advanced_features.xcf.gz b/swing/resources-src/datafiles/tours/introduction/advanced_features.xcf.gz similarity index 100% rename from core/resources-src/datafiles/tours/introduction/advanced_features.xcf.gz rename to swing/resources-src/datafiles/tours/introduction/advanced_features.xcf.gz diff --git a/core/resources-src/datafiles/tours/introduction/flight_simulations.xcf.gz b/swing/resources-src/datafiles/tours/introduction/flight_simulations.xcf.gz similarity index 100% rename from core/resources-src/datafiles/tours/introduction/flight_simulations.xcf.gz rename to swing/resources-src/datafiles/tours/introduction/flight_simulations.xcf.gz diff --git a/core/resources-src/datafiles/tours/introduction/logo-MANUAL.xcf.gz b/swing/resources-src/datafiles/tours/introduction/logo-MANUAL.xcf.gz similarity index 100% rename from core/resources-src/datafiles/tours/introduction/logo-MANUAL.xcf.gz rename to swing/resources-src/datafiles/tours/introduction/logo-MANUAL.xcf.gz diff --git a/core/resources-src/datafiles/tours/introduction/main_window.png b/swing/resources-src/datafiles/tours/introduction/main_window.png similarity index 100% rename from core/resources-src/datafiles/tours/introduction/main_window.png rename to swing/resources-src/datafiles/tours/introduction/main_window.png diff --git a/core/resources-src/datafiles/tours/introduction/main_window_bottom.xcf.gz b/swing/resources-src/datafiles/tours/introduction/main_window_bottom.xcf.gz similarity index 100% rename from core/resources-src/datafiles/tours/introduction/main_window_bottom.xcf.gz rename to swing/resources-src/datafiles/tours/introduction/main_window_bottom.xcf.gz diff --git a/core/resources-src/datafiles/tours/introduction/main_window_top.xcf.gz b/swing/resources-src/datafiles/tours/introduction/main_window_top.xcf.gz similarity index 100% rename from core/resources-src/datafiles/tours/introduction/main_window_top.xcf.gz rename to swing/resources-src/datafiles/tours/introduction/main_window_top.xcf.gz diff --git a/core/resources/datafiles/examples/A simple model rocket.ork b/swing/resources/datafiles/examples/A simple model rocket.ork similarity index 100% rename from core/resources/datafiles/examples/A simple model rocket.ork rename to swing/resources/datafiles/examples/A simple model rocket.ork diff --git a/core/resources/datafiles/examples/Apocalypse with decals.ork b/swing/resources/datafiles/examples/Apocalypse with decals.ork similarity index 100% rename from core/resources/datafiles/examples/Apocalypse with decals.ork rename to swing/resources/datafiles/examples/Apocalypse with decals.ork diff --git a/core/resources/datafiles/examples/Boosted Dart.ork b/swing/resources/datafiles/examples/Boosted Dart.ork similarity index 100% rename from core/resources/datafiles/examples/Boosted Dart.ork rename to swing/resources/datafiles/examples/Boosted Dart.ork diff --git a/core/resources/datafiles/examples/Clustered rocket design.ork b/swing/resources/datafiles/examples/Clustered rocket design.ork similarity index 100% rename from core/resources/datafiles/examples/Clustered rocket design.ork rename to swing/resources/datafiles/examples/Clustered rocket design.ork diff --git a/core/resources/datafiles/examples/High Power Airstart.ork b/swing/resources/datafiles/examples/High Power Airstart.ork similarity index 100% rename from core/resources/datafiles/examples/High Power Airstart.ork rename to swing/resources/datafiles/examples/High Power Airstart.ork diff --git a/core/resources/datafiles/examples/Hybrid rocket with dual parachute deployment.ork b/swing/resources/datafiles/examples/Hybrid rocket with dual parachute deployment.ork similarity index 100% rename from core/resources/datafiles/examples/Hybrid rocket with dual parachute deployment.ork rename to swing/resources/datafiles/examples/Hybrid rocket with dual parachute deployment.ork diff --git a/core/resources/datafiles/examples/Preset Usage.ork b/swing/resources/datafiles/examples/Preset Usage.ork similarity index 100% rename from core/resources/datafiles/examples/Preset Usage.ork rename to swing/resources/datafiles/examples/Preset Usage.ork diff --git a/core/resources/datafiles/examples/Roll-stabilized rocket.ork b/swing/resources/datafiles/examples/Roll-stabilized rocket.ork similarity index 100% rename from core/resources/datafiles/examples/Roll-stabilized rocket.ork rename to swing/resources/datafiles/examples/Roll-stabilized rocket.ork diff --git a/core/resources/datafiles/examples/Simulation listeners.ork b/swing/resources/datafiles/examples/Simulation listeners.ork similarity index 100% rename from core/resources/datafiles/examples/Simulation listeners.ork rename to swing/resources/datafiles/examples/Simulation listeners.ork diff --git a/core/resources/datafiles/examples/TARC Payloader.ork b/swing/resources/datafiles/examples/TARC Payloader.ork similarity index 100% rename from core/resources/datafiles/examples/TARC Payloader.ork rename to swing/resources/datafiles/examples/TARC Payloader.ork diff --git a/core/resources/datafiles/examples/Three-stage rocket.ork b/swing/resources/datafiles/examples/Three-stage rocket.ork similarity index 100% rename from core/resources/datafiles/examples/Three-stage rocket.ork rename to swing/resources/datafiles/examples/Three-stage rocket.ork diff --git a/core/resources/datafiles/presets/system.ser b/swing/resources/datafiles/presets/system.ser similarity index 97% rename from core/resources/datafiles/presets/system.ser rename to swing/resources/datafiles/presets/system.ser index d1da35045..bd1b8da4e 100644 Binary files a/core/resources/datafiles/presets/system.ser and b/swing/resources/datafiles/presets/system.ser differ diff --git a/core/resources/datafiles/textures/balsa.jpg b/swing/resources/datafiles/textures/balsa.jpg similarity index 100% rename from core/resources/datafiles/textures/balsa.jpg rename to swing/resources/datafiles/textures/balsa.jpg diff --git a/core/resources/datafiles/textures/cardboard.jpg b/swing/resources/datafiles/textures/cardboard.jpg similarity index 100% rename from core/resources/datafiles/textures/cardboard.jpg rename to swing/resources/datafiles/textures/cardboard.jpg diff --git a/core/resources/datafiles/textures/chute.jpg b/swing/resources/datafiles/textures/chute.jpg similarity index 100% rename from core/resources/datafiles/textures/chute.jpg rename to swing/resources/datafiles/textures/chute.jpg diff --git a/core/resources/datafiles/textures/hardboard.jpg b/swing/resources/datafiles/textures/hardboard.jpg similarity index 100% rename from core/resources/datafiles/textures/hardboard.jpg rename to swing/resources/datafiles/textures/hardboard.jpg diff --git a/core/resources/datafiles/textures/motors/aerotech.png b/swing/resources/datafiles/textures/motors/aerotech.png similarity index 100% rename from core/resources/datafiles/textures/motors/aerotech.png rename to swing/resources/datafiles/textures/motors/aerotech.png diff --git a/core/resources/datafiles/textures/motors/estes.jpg b/swing/resources/datafiles/textures/motors/estes.jpg similarity index 100% rename from core/resources/datafiles/textures/motors/estes.jpg rename to swing/resources/datafiles/textures/motors/estes.jpg diff --git a/core/resources/datafiles/textures/motors/reusable.png b/swing/resources/datafiles/textures/motors/reusable.png similarity index 100% rename from core/resources/datafiles/textures/motors/reusable.png rename to swing/resources/datafiles/textures/motors/reusable.png diff --git a/core/resources/datafiles/textures/spiral-wound-alpha.png b/swing/resources/datafiles/textures/spiral-wound-alpha.png similarity index 100% rename from core/resources/datafiles/textures/spiral-wound-alpha.png rename to swing/resources/datafiles/textures/spiral-wound-alpha.png diff --git a/core/resources/datafiles/textures/wadding.png b/swing/resources/datafiles/textures/wadding.png similarity index 100% rename from core/resources/datafiles/textures/wadding.png rename to swing/resources/datafiles/textures/wadding.png diff --git a/core/resources/datafiles/textures/wood.jpg b/swing/resources/datafiles/textures/wood.jpg similarity index 100% rename from core/resources/datafiles/textures/wood.jpg rename to swing/resources/datafiles/textures/wood.jpg diff --git a/core/src/net/sf/openrocket/database/ComponentPresetDatabaseLoader.java b/swing/src/net/sf/openrocket/database/ComponentPresetDatabaseLoader.java similarity index 100% rename from core/src/net/sf/openrocket/database/ComponentPresetDatabaseLoader.java rename to swing/src/net/sf/openrocket/database/ComponentPresetDatabaseLoader.java diff --git a/core/src/net/sf/openrocket/database/MotorDatabaseLoader.java b/swing/src/net/sf/openrocket/database/MotorDatabaseLoader.java similarity index 100% rename from core/src/net/sf/openrocket/database/MotorDatabaseLoader.java rename to swing/src/net/sf/openrocket/database/MotorDatabaseLoader.java diff --git a/core/src/net/sf/openrocket/file/motor/MotorLoaderHelper.java b/swing/src/net/sf/openrocket/file/motor/MotorLoaderHelper.java similarity index 100% rename from core/src/net/sf/openrocket/file/motor/MotorLoaderHelper.java rename to swing/src/net/sf/openrocket/file/motor/MotorLoaderHelper.java diff --git a/core/src/net/sf/openrocket/gui/ExportDecalDialog.java b/swing/src/net/sf/openrocket/gui/ExportDecalDialog.java similarity index 100% rename from core/src/net/sf/openrocket/gui/ExportDecalDialog.java rename to swing/src/net/sf/openrocket/gui/ExportDecalDialog.java diff --git a/core/src/net/sf/openrocket/gui/Resettable.java b/swing/src/net/sf/openrocket/gui/Resettable.java similarity index 100% rename from core/src/net/sf/openrocket/gui/Resettable.java rename to swing/src/net/sf/openrocket/gui/Resettable.java diff --git a/core/src/net/sf/openrocket/gui/SpinnerEditor.java b/swing/src/net/sf/openrocket/gui/SpinnerEditor.java similarity index 100% rename from core/src/net/sf/openrocket/gui/SpinnerEditor.java rename to swing/src/net/sf/openrocket/gui/SpinnerEditor.java diff --git a/core/src/net/sf/openrocket/gui/StorageOptionChooser.java b/swing/src/net/sf/openrocket/gui/StorageOptionChooser.java similarity index 100% rename from core/src/net/sf/openrocket/gui/StorageOptionChooser.java rename to swing/src/net/sf/openrocket/gui/StorageOptionChooser.java diff --git a/core/src/net/sf/openrocket/gui/TextFieldListener.java b/swing/src/net/sf/openrocket/gui/TextFieldListener.java similarity index 100% rename from core/src/net/sf/openrocket/gui/TextFieldListener.java rename to swing/src/net/sf/openrocket/gui/TextFieldListener.java diff --git a/core/src/net/sf/openrocket/gui/adaptors/BooleanModel.java b/swing/src/net/sf/openrocket/gui/adaptors/BooleanModel.java similarity index 100% rename from core/src/net/sf/openrocket/gui/adaptors/BooleanModel.java rename to swing/src/net/sf/openrocket/gui/adaptors/BooleanModel.java diff --git a/core/src/net/sf/openrocket/gui/adaptors/Column.java b/swing/src/net/sf/openrocket/gui/adaptors/Column.java similarity index 100% rename from core/src/net/sf/openrocket/gui/adaptors/Column.java rename to swing/src/net/sf/openrocket/gui/adaptors/Column.java diff --git a/core/src/net/sf/openrocket/gui/adaptors/ColumnTableModel.java b/swing/src/net/sf/openrocket/gui/adaptors/ColumnTableModel.java similarity index 100% rename from core/src/net/sf/openrocket/gui/adaptors/ColumnTableModel.java rename to swing/src/net/sf/openrocket/gui/adaptors/ColumnTableModel.java diff --git a/core/src/net/sf/openrocket/gui/adaptors/DecalModel.java b/swing/src/net/sf/openrocket/gui/adaptors/DecalModel.java similarity index 100% rename from core/src/net/sf/openrocket/gui/adaptors/DecalModel.java rename to swing/src/net/sf/openrocket/gui/adaptors/DecalModel.java diff --git a/core/src/net/sf/openrocket/gui/adaptors/DoubleModel.java b/swing/src/net/sf/openrocket/gui/adaptors/DoubleModel.java similarity index 100% rename from core/src/net/sf/openrocket/gui/adaptors/DoubleModel.java rename to swing/src/net/sf/openrocket/gui/adaptors/DoubleModel.java diff --git a/core/src/net/sf/openrocket/gui/adaptors/EnumModel.java b/swing/src/net/sf/openrocket/gui/adaptors/EnumModel.java similarity index 100% rename from core/src/net/sf/openrocket/gui/adaptors/EnumModel.java rename to swing/src/net/sf/openrocket/gui/adaptors/EnumModel.java diff --git a/core/src/net/sf/openrocket/gui/adaptors/FlightConfigurationModel.java b/swing/src/net/sf/openrocket/gui/adaptors/FlightConfigurationModel.java similarity index 78% rename from core/src/net/sf/openrocket/gui/adaptors/FlightConfigurationModel.java rename to swing/src/net/sf/openrocket/gui/adaptors/FlightConfigurationModel.java index e37c488db..a0717117c 100644 --- a/core/src/net/sf/openrocket/gui/adaptors/FlightConfigurationModel.java +++ b/swing/src/net/sf/openrocket/gui/adaptors/FlightConfigurationModel.java @@ -6,14 +6,11 @@ import java.util.HashMap; import java.util.Map; import javax.swing.ComboBoxModel; -import javax.swing.SwingUtilities; import javax.swing.event.EventListenerList; import javax.swing.event.ListDataEvent; import javax.swing.event.ListDataListener; import net.sf.openrocket.formatting.RocketDescriptor; -import net.sf.openrocket.gui.dialogs.flightconfiguration.FlightConfigurationDialog; -import net.sf.openrocket.gui.main.BasicFrame; import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.rocketcomponent.ComponentChangeEvent; import net.sf.openrocket.rocketcomponent.Configuration; @@ -28,8 +25,6 @@ import net.sf.openrocket.util.StateChangeListener; public class FlightConfigurationModel implements ComboBoxModel, StateChangeListener { private static final Translator trans = Application.getTranslator(); - private static final String EDIT = trans.get("MotorCfgModel.Editcfg"); - private RocketDescriptor descriptor = Application.getInjector().getInstance(RocketDescriptor.class); @@ -37,20 +32,13 @@ public class FlightConfigurationModel implements ComboBoxModel, StateChangeListe private final Configuration config; private final Rocket rocket; - private final boolean showEditElement; private Map map = new HashMap(); public FlightConfigurationModel(Configuration config) { - this(config, true); - } - - - public FlightConfigurationModel(Configuration config, boolean showEditElement) { this.config = config; this.rocket = config.getRocket(); - this.showEditElement = showEditElement; config.addChangeListener(this); } @@ -61,23 +49,15 @@ public class FlightConfigurationModel implements ComboBoxModel, StateChangeListe if (index < 0) return null; - if ((showEditElement && index > ids.length) || - (!showEditElement && index >= ids.length)) + if ( index >= ids.length) return null; - if (index == ids.length) - return EDIT; - return get(ids[index]); } @Override public int getSize() { - if (showEditElement) { - return rocket.getFlightConfigurationIDs().length + 1; - } else { - return rocket.getFlightConfigurationIDs().length; - } + return rocket.getFlightConfigurationIDs().length; } @Override @@ -91,19 +71,6 @@ public class FlightConfigurationModel implements ComboBoxModel, StateChangeListe // Clear selection - huh? return; } - if (item == EDIT) { - - // Open edit dialog in the future, after combo box has closed - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - new FlightConfigurationDialog(rocket, BasicFrame.findFrame(rocket)) - .setVisible(true); - } - }); - - return; - } if (!(item instanceof ID)) { throw new IllegalArgumentException("MotorConfigurationModel item=" + item); } diff --git a/core/src/net/sf/openrocket/gui/adaptors/IntegerModel.java b/swing/src/net/sf/openrocket/gui/adaptors/IntegerModel.java similarity index 100% rename from core/src/net/sf/openrocket/gui/adaptors/IntegerModel.java rename to swing/src/net/sf/openrocket/gui/adaptors/IntegerModel.java diff --git a/core/src/net/sf/openrocket/gui/adaptors/MaterialModel.java b/swing/src/net/sf/openrocket/gui/adaptors/MaterialModel.java similarity index 100% rename from core/src/net/sf/openrocket/gui/adaptors/MaterialModel.java rename to swing/src/net/sf/openrocket/gui/adaptors/MaterialModel.java diff --git a/core/src/net/sf/openrocket/gui/adaptors/PresetModel.java b/swing/src/net/sf/openrocket/gui/adaptors/PresetModel.java similarity index 100% rename from core/src/net/sf/openrocket/gui/adaptors/PresetModel.java rename to swing/src/net/sf/openrocket/gui/adaptors/PresetModel.java diff --git a/core/src/net/sf/openrocket/gui/components/BasicSlider.java b/swing/src/net/sf/openrocket/gui/components/BasicSlider.java similarity index 100% rename from core/src/net/sf/openrocket/gui/components/BasicSlider.java rename to swing/src/net/sf/openrocket/gui/components/BasicSlider.java diff --git a/core/src/net/sf/openrocket/gui/components/BasicTree.java b/swing/src/net/sf/openrocket/gui/components/BasicTree.java similarity index 100% rename from core/src/net/sf/openrocket/gui/components/BasicTree.java rename to swing/src/net/sf/openrocket/gui/components/BasicTree.java diff --git a/core/src/net/sf/openrocket/gui/components/CollectionTable.java b/swing/src/net/sf/openrocket/gui/components/CollectionTable.java similarity index 100% rename from core/src/net/sf/openrocket/gui/components/CollectionTable.java rename to swing/src/net/sf/openrocket/gui/components/CollectionTable.java diff --git a/core/src/net/sf/openrocket/gui/components/ColorChooser.java b/swing/src/net/sf/openrocket/gui/components/ColorChooser.java similarity index 100% rename from core/src/net/sf/openrocket/gui/components/ColorChooser.java rename to swing/src/net/sf/openrocket/gui/components/ColorChooser.java diff --git a/core/src/net/sf/openrocket/gui/components/ColorChooserButton.java b/swing/src/net/sf/openrocket/gui/components/ColorChooserButton.java similarity index 100% rename from core/src/net/sf/openrocket/gui/components/ColorChooserButton.java rename to swing/src/net/sf/openrocket/gui/components/ColorChooserButton.java diff --git a/core/src/net/sf/openrocket/gui/components/ColorIcon.java b/swing/src/net/sf/openrocket/gui/components/ColorIcon.java similarity index 100% rename from core/src/net/sf/openrocket/gui/components/ColorIcon.java rename to swing/src/net/sf/openrocket/gui/components/ColorIcon.java diff --git a/core/src/net/sf/openrocket/gui/components/CsvOptionPanel.java b/swing/src/net/sf/openrocket/gui/components/CsvOptionPanel.java similarity index 100% rename from core/src/net/sf/openrocket/gui/components/CsvOptionPanel.java rename to swing/src/net/sf/openrocket/gui/components/CsvOptionPanel.java diff --git a/core/src/net/sf/openrocket/gui/components/DescriptionArea.java b/swing/src/net/sf/openrocket/gui/components/DescriptionArea.java similarity index 100% rename from core/src/net/sf/openrocket/gui/components/DescriptionArea.java rename to swing/src/net/sf/openrocket/gui/components/DescriptionArea.java diff --git a/core/src/net/sf/openrocket/gui/components/DoubleCellEditor.java b/swing/src/net/sf/openrocket/gui/components/DoubleCellEditor.java similarity index 100% rename from core/src/net/sf/openrocket/gui/components/DoubleCellEditor.java rename to swing/src/net/sf/openrocket/gui/components/DoubleCellEditor.java diff --git a/core/src/net/sf/openrocket/gui/components/FlatButton.java b/swing/src/net/sf/openrocket/gui/components/FlatButton.java similarity index 100% rename from core/src/net/sf/openrocket/gui/components/FlatButton.java rename to swing/src/net/sf/openrocket/gui/components/FlatButton.java diff --git a/core/src/net/sf/openrocket/gui/components/HtmlLabel.java b/swing/src/net/sf/openrocket/gui/components/HtmlLabel.java similarity index 100% rename from core/src/net/sf/openrocket/gui/components/HtmlLabel.java rename to swing/src/net/sf/openrocket/gui/components/HtmlLabel.java diff --git a/core/src/net/sf/openrocket/gui/components/ImageDisplayComponent.java b/swing/src/net/sf/openrocket/gui/components/ImageDisplayComponent.java similarity index 100% rename from core/src/net/sf/openrocket/gui/components/ImageDisplayComponent.java rename to swing/src/net/sf/openrocket/gui/components/ImageDisplayComponent.java diff --git a/core/src/net/sf/openrocket/gui/components/SelectableLabel.java b/swing/src/net/sf/openrocket/gui/components/SelectableLabel.java similarity index 100% rename from core/src/net/sf/openrocket/gui/components/SelectableLabel.java rename to swing/src/net/sf/openrocket/gui/components/SelectableLabel.java diff --git a/core/src/net/sf/openrocket/gui/components/SimulationExportPanel.java b/swing/src/net/sf/openrocket/gui/components/SimulationExportPanel.java similarity index 100% rename from core/src/net/sf/openrocket/gui/components/SimulationExportPanel.java rename to swing/src/net/sf/openrocket/gui/components/SimulationExportPanel.java diff --git a/core/src/net/sf/openrocket/gui/components/StageSelector.java b/swing/src/net/sf/openrocket/gui/components/StageSelector.java similarity index 100% rename from core/src/net/sf/openrocket/gui/components/StageSelector.java rename to swing/src/net/sf/openrocket/gui/components/StageSelector.java diff --git a/core/src/net/sf/openrocket/gui/components/StarCheckBox.java b/swing/src/net/sf/openrocket/gui/components/StarCheckBox.java similarity index 100% rename from core/src/net/sf/openrocket/gui/components/StarCheckBox.java rename to swing/src/net/sf/openrocket/gui/components/StarCheckBox.java diff --git a/core/src/net/sf/openrocket/gui/components/StyledLabel.java b/swing/src/net/sf/openrocket/gui/components/StyledLabel.java similarity index 100% rename from core/src/net/sf/openrocket/gui/components/StyledLabel.java rename to swing/src/net/sf/openrocket/gui/components/StyledLabel.java diff --git a/core/src/net/sf/openrocket/gui/components/URLLabel.java b/swing/src/net/sf/openrocket/gui/components/URLLabel.java similarity index 100% rename from core/src/net/sf/openrocket/gui/components/URLLabel.java rename to swing/src/net/sf/openrocket/gui/components/URLLabel.java diff --git a/core/src/net/sf/openrocket/gui/components/UnitCellEditor.java b/swing/src/net/sf/openrocket/gui/components/UnitCellEditor.java similarity index 100% rename from core/src/net/sf/openrocket/gui/components/UnitCellEditor.java rename to swing/src/net/sf/openrocket/gui/components/UnitCellEditor.java diff --git a/core/src/net/sf/openrocket/gui/components/UnitSelector.java b/swing/src/net/sf/openrocket/gui/components/UnitSelector.java similarity index 100% rename from core/src/net/sf/openrocket/gui/components/UnitSelector.java rename to swing/src/net/sf/openrocket/gui/components/UnitSelector.java diff --git a/core/src/net/sf/openrocket/gui/components/compass/CompassPointer.java b/swing/src/net/sf/openrocket/gui/components/compass/CompassPointer.java similarity index 100% rename from core/src/net/sf/openrocket/gui/components/compass/CompassPointer.java rename to swing/src/net/sf/openrocket/gui/components/compass/CompassPointer.java diff --git a/core/src/net/sf/openrocket/gui/components/compass/CompassRose.java b/swing/src/net/sf/openrocket/gui/components/compass/CompassRose.java similarity index 100% rename from core/src/net/sf/openrocket/gui/components/compass/CompassRose.java rename to swing/src/net/sf/openrocket/gui/components/compass/CompassRose.java diff --git a/core/src/net/sf/openrocket/gui/components/compass/CompassSelectionButton.java b/swing/src/net/sf/openrocket/gui/components/compass/CompassSelectionButton.java similarity index 100% rename from core/src/net/sf/openrocket/gui/components/compass/CompassSelectionButton.java rename to swing/src/net/sf/openrocket/gui/components/compass/CompassSelectionButton.java diff --git a/core/src/net/sf/openrocket/gui/components/compass/CompassSelector.java b/swing/src/net/sf/openrocket/gui/components/compass/CompassSelector.java similarity index 100% rename from core/src/net/sf/openrocket/gui/components/compass/CompassSelector.java rename to swing/src/net/sf/openrocket/gui/components/compass/CompassSelector.java diff --git a/core/src/net/sf/openrocket/gui/components/compass/Tester.java b/swing/src/net/sf/openrocket/gui/components/compass/Tester.java similarity index 100% rename from core/src/net/sf/openrocket/gui/components/compass/Tester.java rename to swing/src/net/sf/openrocket/gui/components/compass/Tester.java diff --git a/core/src/net/sf/openrocket/gui/configdialog/AppearancePanel.java b/swing/src/net/sf/openrocket/gui/configdialog/AppearancePanel.java similarity index 100% rename from core/src/net/sf/openrocket/gui/configdialog/AppearancePanel.java rename to swing/src/net/sf/openrocket/gui/configdialog/AppearancePanel.java diff --git a/core/src/net/sf/openrocket/gui/configdialog/BodyTubeConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/BodyTubeConfig.java similarity index 91% rename from core/src/net/sf/openrocket/gui/configdialog/BodyTubeConfig.java rename to swing/src/net/sf/openrocket/gui/configdialog/BodyTubeConfig.java index c91871a1a..2e5dad565 100644 --- a/core/src/net/sf/openrocket/gui/configdialog/BodyTubeConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/BodyTubeConfig.java @@ -16,13 +16,13 @@ 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.MotorMount; import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.startup.Application; import net.sf.openrocket.unit.UnitGroup; public class BodyTubeConfig extends RocketComponentConfig { - private MotorConfig motorConfigPane = null; private DoubleModel maxLength; private static final Translator trans = Application.getTranslator(); @@ -98,7 +98,10 @@ public class BodyTubeConfig extends RocketComponentConfig { check.setText(trans.get("BodyTubecfg.checkbox.Filled")); panel.add(check, "skip, span 2, wrap"); + MotorConfig motorConfig = new MotorConfig((MotorMount)c); + panel.add(motorConfig,"spanx, growx"); + //// Material panel.add(materialPanel(new JPanel(new MigLayout()), Material.Type.BULK), "cell 4 0, gapleft paragraph, aligny 0%, spany"); @@ -106,10 +109,7 @@ public class BodyTubeConfig extends RocketComponentConfig { //// General and General properties tabbedPane.insertTab(trans.get("BodyTubecfg.tab.General"), null, panel, trans.get("BodyTubecfg.tab.Generalproperties"), 0); - motorConfigPane = new MotorConfig((BodyTube) c); - //// Motor and Motor mount configuration - tabbedPane.insertTab(trans.get("BodyTubecfg.tab.Motor"), null, motorConfigPane, - trans.get("BodyTubecfg.tab.Motormountconf"), 1); + tabbedPane.setSelectedIndex(0); @@ -118,8 +118,6 @@ public class BodyTubeConfig extends RocketComponentConfig { @Override public void updateFields() { super.updateFields(); - if (motorConfigPane != null) - motorConfigPane.updateFields(); } } diff --git a/core/src/net/sf/openrocket/gui/configdialog/BulkheadConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/BulkheadConfig.java similarity index 100% rename from core/src/net/sf/openrocket/gui/configdialog/BulkheadConfig.java rename to swing/src/net/sf/openrocket/gui/configdialog/BulkheadConfig.java diff --git a/core/src/net/sf/openrocket/gui/configdialog/CenteringRingConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/CenteringRingConfig.java similarity index 100% rename from core/src/net/sf/openrocket/gui/configdialog/CenteringRingConfig.java rename to swing/src/net/sf/openrocket/gui/configdialog/CenteringRingConfig.java diff --git a/core/src/net/sf/openrocket/gui/configdialog/CommonStrings.java b/swing/src/net/sf/openrocket/gui/configdialog/CommonStrings.java similarity index 100% rename from core/src/net/sf/openrocket/gui/configdialog/CommonStrings.java rename to swing/src/net/sf/openrocket/gui/configdialog/CommonStrings.java diff --git a/core/src/net/sf/openrocket/gui/configdialog/ComponentConfigDialog.java b/swing/src/net/sf/openrocket/gui/configdialog/ComponentConfigDialog.java similarity index 100% rename from core/src/net/sf/openrocket/gui/configdialog/ComponentConfigDialog.java rename to swing/src/net/sf/openrocket/gui/configdialog/ComponentConfigDialog.java diff --git a/core/src/net/sf/openrocket/gui/configdialog/EllipticalFinSetConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/EllipticalFinSetConfig.java similarity index 100% rename from core/src/net/sf/openrocket/gui/configdialog/EllipticalFinSetConfig.java rename to swing/src/net/sf/openrocket/gui/configdialog/EllipticalFinSetConfig.java diff --git a/core/src/net/sf/openrocket/gui/configdialog/FinSetConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/FinSetConfig.java similarity index 100% rename from core/src/net/sf/openrocket/gui/configdialog/FinSetConfig.java rename to swing/src/net/sf/openrocket/gui/configdialog/FinSetConfig.java diff --git a/core/src/net/sf/openrocket/gui/configdialog/FreeformFinSetConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/FreeformFinSetConfig.java similarity index 100% rename from core/src/net/sf/openrocket/gui/configdialog/FreeformFinSetConfig.java rename to swing/src/net/sf/openrocket/gui/configdialog/FreeformFinSetConfig.java diff --git a/core/src/net/sf/openrocket/gui/configdialog/InnerTubeConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/InnerTubeConfig.java similarity index 55% rename from core/src/net/sf/openrocket/gui/configdialog/InnerTubeConfig.java rename to swing/src/net/sf/openrocket/gui/configdialog/InnerTubeConfig.java index e679ed05d..4d981d7b3 100644 --- a/core/src/net/sf/openrocket/gui/configdialog/InnerTubeConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/InnerTubeConfig.java @@ -1,28 +1,12 @@ package net.sf.openrocket.gui.configdialog; -import net.miginfocom.swing.MigLayout; -import net.sf.openrocket.document.OpenRocketDocument; -import net.sf.openrocket.gui.Resettable; -import net.sf.openrocket.gui.SpinnerEditor; -import net.sf.openrocket.gui.adaptors.DoubleModel; -import net.sf.openrocket.gui.components.BasicSlider; -import net.sf.openrocket.gui.components.UnitSelector; -import net.sf.openrocket.l10n.Translator; -import net.sf.openrocket.rocketcomponent.ClusterConfiguration; -import net.sf.openrocket.rocketcomponent.Clusterable; -import net.sf.openrocket.rocketcomponent.InnerTube; -import net.sf.openrocket.rocketcomponent.MotorMount; -import net.sf.openrocket.rocketcomponent.RocketComponent; -import net.sf.openrocket.startup.Application; -import net.sf.openrocket.unit.UnitGroup; -import net.sf.openrocket.util.BugException; -import net.sf.openrocket.util.Coordinate; -import net.sf.openrocket.util.StateChangeListener; - -import javax.swing.*; -import javax.swing.border.BevelBorder; -import java.awt.*; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.RenderingHints; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; @@ -31,40 +15,258 @@ import java.awt.geom.Ellipse2D; import java.util.EventObject; import java.util.List; +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JSpinner; +import javax.swing.SwingUtilities; +import javax.swing.border.BevelBorder; -public class InnerTubeConfig extends ThicknessRingComponentConfig { +import net.miginfocom.swing.MigLayout; +import net.sf.openrocket.document.OpenRocketDocument; +import net.sf.openrocket.gui.Resettable; +import net.sf.openrocket.gui.SpinnerEditor; +import net.sf.openrocket.gui.adaptors.DoubleModel; +import net.sf.openrocket.gui.adaptors.EnumModel; +import net.sf.openrocket.gui.components.BasicSlider; +import net.sf.openrocket.gui.components.DescriptionArea; +import net.sf.openrocket.gui.components.UnitSelector; +import net.sf.openrocket.l10n.Translator; +import net.sf.openrocket.material.Material; +import net.sf.openrocket.rocketcomponent.ClusterConfiguration; +import net.sf.openrocket.rocketcomponent.Clusterable; +import net.sf.openrocket.rocketcomponent.EngineBlock; +import net.sf.openrocket.rocketcomponent.InnerTube; +import net.sf.openrocket.rocketcomponent.MotorMount; +import net.sf.openrocket.rocketcomponent.RingComponent; +import net.sf.openrocket.rocketcomponent.RocketComponent; +import net.sf.openrocket.startup.Application; +import net.sf.openrocket.unit.UnitGroup; +import net.sf.openrocket.util.BugException; +import net.sf.openrocket.util.Coordinate; +import net.sf.openrocket.util.StateChangeListener; + + +public class InnerTubeConfig extends RocketComponentConfig { private static final Translator trans = Application.getTranslator(); - - + + public InnerTubeConfig(OpenRocketDocument d, RocketComponent c) { super(d, c); + + //// General and General properties + JPanel panel = new JPanel(new MigLayout("gap rel unrel", "[][65lp::][30lp::][]", "")); + DoubleModel m; + JSpinner spin; + DoubleModel od = null; + + //// Outer diameter + panel.add(new JLabel(trans.get("ThicknessRingCompCfg.tab.Outerdiam"))); + + //// OuterRadius + od = new DoubleModel(component, "OuterRadius", 2, UnitGroup.UNITS_LENGTH, 0); + // Diameter = 2*Radius + + spin = new JSpinner(od.getSpinnerModel()); + spin.setEditor(new SpinnerEditor(spin)); + panel.add(spin, "growx"); + + panel.add(new UnitSelector(od), "growx"); + panel.add(new BasicSlider(od.getSliderModel(0, 0.04, 0.2)), "w 100lp, wrap"); + + if (od.isAutomaticAvailable()) { + JCheckBox check = new JCheckBox(od.getAutomaticAction()); + //// Automatic + check.setText(trans.get("ringcompcfg.Automatic")); + panel.add(check, "skip, span 2, wrap"); + } + + //// Inner diameter + panel.add(new JLabel(trans.get("ThicknessRingCompCfg.tab.Innerdiam"))); + + //// InnerRadius + m = new DoubleModel(component, "InnerRadius", 2, UnitGroup.UNITS_LENGTH, 0); + + spin = new JSpinner(m.getSpinnerModel()); + spin.setEditor(new SpinnerEditor(spin)); + panel.add(spin, "growx"); + + panel.add(new UnitSelector(m), "growx"); + if (od == null) + panel.add(new BasicSlider(m.getSliderModel(0, 0.04, 0.2)), "w 100lp, wrap"); + else + panel.add(new BasicSlider(m.getSliderModel(new DoubleModel(0), od)), + "w 100lp, wrap"); + + if (m.isAutomaticAvailable()) { + JCheckBox check = new JCheckBox(m.getAutomaticAction()); + //// Automatic + check.setText(trans.get("ringcompcfg.Automatic")); + panel.add(check, "skip, span 2, wrap"); + } + + + //// Wall thickness + panel.add(new JLabel(trans.get("ThicknessRingCompCfg.tab.Wallthickness"))); + + //// Thickness + m = new DoubleModel(component, "Thickness", UnitGroup.UNITS_LENGTH, 0); + + spin = new JSpinner(m.getSpinnerModel()); + spin.setEditor(new SpinnerEditor(spin)); + panel.add(spin, "growx"); + + panel.add(new UnitSelector(m), "growx"); + panel.add(new BasicSlider(m.getSliderModel(0, 0.01)), "w 100lp, wrap"); + + + //// Inner tube length + panel.add(new JLabel(trans.get("ThicknessRingCompCfg.tab.Length"))); + + //// Length + m = new DoubleModel(component, "Length", UnitGroup.UNITS_LENGTH, 0); + + spin = new JSpinner(m.getSpinnerModel()); + spin.setEditor(new SpinnerEditor(spin)); + panel.add(spin, "growx"); + + panel.add(new UnitSelector(m), "growx"); + panel.add(new BasicSlider(m.getSliderModel(0, 0.1, 1.0)), "w 100lp, wrap"); + + + //// Position + + //// Position relative to: + panel.add(new JLabel(trans.get("ringcompcfg.Positionrelativeto"))); + + JComboBox combo = new JComboBox( + new EnumModel(component, "RelativePosition", + new RocketComponent.Position[] { + RocketComponent.Position.TOP, + RocketComponent.Position.MIDDLE, + RocketComponent.Position.BOTTOM, + RocketComponent.Position.ABSOLUTE + })); + panel.add(combo, "spanx 3, growx, wrap"); + + //// plus + panel.add(new JLabel(trans.get("ringcompcfg.plus")), "right"); + + //// PositionValue + m = new DoubleModel(component, "PositionValue", UnitGroup.UNITS_LENGTH); + spin = new JSpinner(m.getSpinnerModel()); + spin.setEditor(new SpinnerEditor(spin)); + panel.add(spin, "growx"); + + panel.add(new UnitSelector(m), "growx"); + panel.add(new BasicSlider(m.getSliderModel( + new DoubleModel(component.getParent(), "Length", -1.0, UnitGroup.UNITS_NONE), + new DoubleModel(component.getParent(), "Length"))), + "w 100lp, wrap"); + + MotorConfig motorConfig = new MotorConfig((MotorMount)c); - JPanel tab; + panel.add(motorConfig,"spanx, growx"); - tab = new MotorConfig((MotorMount) c); - //// Motor and Motor mount configuration - tabbedPane.insertTab(trans.get("InnerTubeCfg.tab.Motor"), null, tab, - trans.get("InnerTubeCfg.tab.ttip.Motor"), 1); - - tab = clusterTab(); + //// Material + panel.add(materialPanel(new JPanel(new MigLayout()), Material.Type.BULK), + "cell 4 0, gapleft paragraph, aligny 0%, spany"); + + tabbedPane.insertTab(trans.get("ThicknessRingCompCfg.tab.General"), null, panel, + trans.get("ThicknessRingCompCfg.tab.Generalprop"), 0); + + JPanel tab = clusterTab(); //// Cluster and Cluster configuration tabbedPane.insertTab(trans.get("InnerTubeCfg.tab.Cluster"), null, tab, trans.get("InnerTubeCfg.tab.ttip.Cluster"), 2); - + tab = positionTab(); //// Radial position tabbedPane.insertTab(trans.get("InnerTubeCfg.tab.Radialpos"), null, tab, trans.get("InnerTubeCfg.tab.ttip.Radialpos"), 3); - + tabbedPane.setSelectedIndex(0); } - - + + protected JPanel positionTab() { + JPanel panel = new JPanel(new MigLayout("align 20% 20%, gap rel unrel", + "[][65lp::][30lp::]", "")); + + //// Radial position + JLabel l = new JLabel(trans.get("ringcompcfg.Radialdistance")); + //// Distance from the rocket centerline + l.setToolTipText(trans.get("ringcompcfg.Distancefrom")); + panel.add(l); + + DoubleModel m = new DoubleModel(component, "RadialPosition", UnitGroup.UNITS_LENGTH, 0); + + JSpinner spin = new JSpinner(m.getSpinnerModel()); + spin.setEditor(new SpinnerEditor(spin)); + //// Distance from the rocket centerline + spin.setToolTipText(trans.get("ringcompcfg.Distancefrom")); + panel.add(spin, "growx"); + + panel.add(new UnitSelector(m), "growx"); + BasicSlider bs = new BasicSlider(m.getSliderModel(0, 0.1, 1.0)); + //// Distance from the rocket centerline + bs.setToolTipText(trans.get("ringcompcfg.Distancefrom")); + panel.add(bs, "w 100lp, wrap"); + + + //// Radial direction + l = new JLabel(trans.get("ringcompcfg.Radialdirection")); + //// The radial direction from the rocket centerline + l.setToolTipText(trans.get("ringcompcfg.radialdirectionfrom")); + panel.add(l); + + m = new DoubleModel(component, "RadialDirection", UnitGroup.UNITS_ANGLE); + + spin = new JSpinner(m.getSpinnerModel()); + spin.setEditor(new SpinnerEditor(spin)); + //// The radial direction from the rocket centerline + spin.setToolTipText(trans.get("ringcompcfg.radialdirectionfrom")); + panel.add(spin, "growx"); + + panel.add(new UnitSelector(m), "growx"); + bs = new BasicSlider(m.getSliderModel(-Math.PI, Math.PI)); + //// The radial direction from the rocket centerline + bs.setToolTipText(trans.get("ringcompcfg.radialdirectionfrom")); + panel.add(bs, "w 100lp, wrap"); + + + //// Reset button + JButton button = new JButton(trans.get("ringcompcfg.but.Reset")); + //// Reset the component to the rocket centerline + button.setToolTipText(trans.get("ringcompcfg.but.Resetcomponant")); + button.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + ((RingComponent) component).setRadialDirection(0.0); + ((RingComponent) component).setRadialPosition(0.0); + } + }); + panel.add(button, "spanx, right, wrap para"); + + + DescriptionArea note = new DescriptionArea(3); + //// Note: An inner tube will not affect the aerodynamics of the rocket even if it is located outside of the body tube. + note.setText(trans.get("ringcompcfg.note.desc")); + panel.add(note, "spanx, growx"); + + + return panel; + } + + private JPanel clusterTab() { JPanel panel = new JPanel(new MigLayout()); - + JPanel subPanel = new JPanel(new MigLayout()); - + // Cluster type selection //// Select cluster configuration: subPanel.add(new JLabel(trans.get("InnerTubeCfg.lbl.Selectclustercfg")), "spanx, wrap"); @@ -72,12 +274,12 @@ public class InnerTubeConfig extends ThicknessRingComponentConfig { // JPanel clusterSelection = new ClusterSelectionPanel((InnerTube)component); // clusterSelection.setBackground(Color.blue); // subPanel.add(clusterSelection); - + panel.add(subPanel); - + subPanel = new JPanel(new MigLayout("gap rel unrel", "[][65lp::][30lp::]")); - + // Tube separation scale //// Tube separation: JLabel l = new JLabel(trans.get("InnerTubeCfg.lbl.TubeSep")); @@ -85,18 +287,18 @@ public class InnerTubeConfig extends ThicknessRingComponentConfig { l.setToolTipText(trans.get("InnerTubeCfg.lbl.ttip.TubeSep")); subPanel.add(l); DoubleModel dm = new DoubleModel(component, "ClusterScale", 1, UnitGroup.UNITS_NONE, 0); - + JSpinner spin = new JSpinner(dm.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); //// The separation of the tubes, 1.0 = touching each other spin.setToolTipText(trans.get("InnerTubeCfg.lbl.ttip.TubeSep")); subPanel.add(spin, "growx"); - + BasicSlider bs = new BasicSlider(dm.getSliderModel(0, 1, 4)); //// The separation of the tubes, 1.0 = touching each other bs.setToolTipText(trans.get("InnerTubeCfg.lbl.ttip.TubeSep")); subPanel.add(bs, "skip,w 100lp, wrap"); - + // Rotation: l = new JLabel(trans.get("InnerTubeCfg.lbl.Rotation")); //// Rotation angle of the cluster configuration @@ -104,19 +306,19 @@ public class InnerTubeConfig extends ThicknessRingComponentConfig { subPanel.add(l); dm = new DoubleModel(component, "ClusterRotation", 1, UnitGroup.UNITS_ANGLE, -Math.PI, Math.PI); - + spin = new JSpinner(dm.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); //// Rotation angle of the cluster configuration spin.setToolTipText(trans.get("InnerTubeCfg.lbl.ttip.Rotation")); subPanel.add(spin, "growx"); - + subPanel.add(new UnitSelector(dm), "growx"); bs = new BasicSlider(dm.getSliderModel(-Math.PI, 0, Math.PI)); //// Rotation angle of the cluster configuration bs.setToolTipText(trans.get("InnerTubeCfg.lbl.ttip.Rotation")); subPanel.add(bs, "w 100lp, wrap para"); - + // Split button @@ -139,19 +341,19 @@ public class InnerTubeConfig extends ThicknessRingComponentConfig { throw new BugException("Inconsistent state: component=" + component + " parent=" + parent + " parent.children=" + parent.getChildren()); } - + InnerTube tube = (InnerTube) component; if (tube.getClusterCount() <= 1) return; - + document.addUndoPosition("Split cluster"); - + Coordinate[] coords = { Coordinate.NUL }; coords = component.shiftCoordinates(coords); parent.removeChild(index); for (int i = 0; i < coords.length; i++) { - InnerTube copy = makeIndividualClusterComponent(coords[i], component.getName() + " #" + (i + 1), component); - + InnerTube copy = InnerTube.makeIndividualClusterComponent(coords[i], component.getName() + " #" + (i + 1), component); + parent.addChild(copy, index + i); } } @@ -159,7 +361,7 @@ public class InnerTubeConfig extends ThicknessRingComponentConfig { } }); subPanel.add(split, "spanx, split 2, gapright para, sizegroup buttons, right"); - + // Reset button ///// Reset settings @@ -174,68 +376,49 @@ public class InnerTubeConfig extends ThicknessRingComponentConfig { } }); subPanel.add(reset, "sizegroup buttons, right"); - + panel.add(subPanel, "grow"); - + return panel; } - /** - * For a given coordinate that represents one tube in a cluster, create an instance of that tube. Must be called - * once for each tube in the cluster. - * - * @param coord the coordinate of the clustered tube to create - * @param splitName the name of the individual tube - * @param theInnerTube the 'parent' from which this tube will be created. - * - * @return an instance of an inner tube that represents ONE of the clustered tubes in the cluster represented - * by theInnerTube - */ - public static InnerTube makeIndividualClusterComponent(Coordinate coord, String splitName, RocketComponent theInnerTube) { - InnerTube copy = (InnerTube) theInnerTube.copy(); - copy.setClusterConfiguration(ClusterConfiguration.SINGLE); - copy.setClusterRotation(0.0); - copy.setClusterScale(1.0); - copy.setRadialShift(coord.y, coord.z); - copy.setName(splitName); - return copy; - } + } class ClusterSelectionPanel extends JPanel { private static final int BUTTON_SIZE = 50; private static final int MOTOR_DIAMETER = 10; - + private static final Color SELECTED_COLOR = Color.RED; private static final Color UNSELECTED_COLOR = Color.WHITE; private static final Color MOTOR_FILL_COLOR = Color.GREEN; private static final Color MOTOR_BORDER_COLOR = Color.BLACK; - + public ClusterSelectionPanel(Clusterable component) { super(new MigLayout("gap 0 0", "[" + BUTTON_SIZE + "!][" + BUTTON_SIZE + "!][" + BUTTON_SIZE + "!][" + BUTTON_SIZE + "!]", "[" + BUTTON_SIZE + "!][" + BUTTON_SIZE + "!][" + BUTTON_SIZE + "!]")); - + for (int i = 0; i < ClusterConfiguration.CONFIGURATIONS.length; i++) { ClusterConfiguration config = ClusterConfiguration.CONFIGURATIONS[i]; - + JComponent button = new ClusterButton(component, config); if (i % 4 == 3) add(button, "wrap"); else add(button); } - + } - - + + private class ClusterButton extends JPanel implements StateChangeListener, MouseListener, - Resettable { + Resettable { private Clusterable component; private ClusterConfiguration config; - + public ClusterButton(Clusterable c, ClusterConfiguration config) { component = c; this.config = config; @@ -247,81 +430,81 @@ class ClusterSelectionPanel extends JPanel { component.addChangeListener(this); addMouseListener(this); } - - + + @Override public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D) g; Rectangle area = g2.getClipBounds(); - + if (component.getClusterConfiguration() == config) g2.setColor(SELECTED_COLOR); else g2.setColor(UNSELECTED_COLOR); - + g2.fillRect(area.x, area.y, area.width, area.height); - + g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE); g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - + List points = config.getPoints(); Ellipse2D.Float circle = new Ellipse2D.Float(); for (int i = 0; i < points.size() / 2; i++) { double x = points.get(i * 2); double y = points.get(i * 2 + 1); - + double px = BUTTON_SIZE / 2 + x * MOTOR_DIAMETER; double py = BUTTON_SIZE / 2 - y * MOTOR_DIAMETER; circle.setFrameFromCenter(px, py, px + MOTOR_DIAMETER / 2, py + MOTOR_DIAMETER / 2); - + g2.setColor(MOTOR_FILL_COLOR); g2.fill(circle); g2.setColor(MOTOR_BORDER_COLOR); g2.draw(circle); } } - - + + @Override public void stateChanged(EventObject e) { repaint(); } - - + + @Override public void mouseClicked(MouseEvent e) { if (e.getButton() == MouseEvent.BUTTON1) { component.setClusterConfiguration(config); } } - + @Override public void mouseEntered(MouseEvent e) { } - + @Override public void mouseExited(MouseEvent e) { } - + @Override public void mousePressed(MouseEvent e) { } - + @Override public void mouseReleased(MouseEvent e) { } - - + + @Override public void resetModel() { component.removeChangeListener(this); removeMouseListener(this); } } - + } diff --git a/core/src/net/sf/openrocket/gui/configdialog/LaunchLugConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/LaunchLugConfig.java similarity index 98% rename from core/src/net/sf/openrocket/gui/configdialog/LaunchLugConfig.java rename to swing/src/net/sf/openrocket/gui/configdialog/LaunchLugConfig.java index 07248d113..6f6ff0a32 100644 --- a/core/src/net/sf/openrocket/gui/configdialog/LaunchLugConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/LaunchLugConfig.java @@ -154,8 +154,6 @@ public class LaunchLugConfig extends RocketComponentConfig { @Override public void updateFields() { super.updateFields(); - if (motorConfigPane != null) - motorConfigPane.updateFields(); } } diff --git a/core/src/net/sf/openrocket/gui/configdialog/MassComponentConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/MassComponentConfig.java similarity index 100% rename from core/src/net/sf/openrocket/gui/configdialog/MassComponentConfig.java rename to swing/src/net/sf/openrocket/gui/configdialog/MassComponentConfig.java diff --git a/swing/src/net/sf/openrocket/gui/configdialog/MotorConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/MotorConfig.java new file mode 100644 index 000000000..ca4538e38 --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/configdialog/MotorConfig.java @@ -0,0 +1,135 @@ +package net.sf.openrocket.gui.configdialog; + + +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; + +import javax.swing.BorderFactory; +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JSpinner; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + +import net.miginfocom.swing.MigLayout; +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.EnumModel; +import net.sf.openrocket.gui.components.BasicSlider; +import net.sf.openrocket.gui.components.StyledLabel; +import net.sf.openrocket.gui.components.UnitSelector; +import net.sf.openrocket.l10n.Translator; +import net.sf.openrocket.rocketcomponent.IgnitionConfiguration; +import net.sf.openrocket.rocketcomponent.MotorMount; +import net.sf.openrocket.rocketcomponent.RocketComponent; +import net.sf.openrocket.startup.Application; +import net.sf.openrocket.unit.UnitGroup; + +public class MotorConfig extends JPanel { + + private final MotorMount mount; + private static final Translator trans = Application.getTranslator(); + + public MotorConfig(MotorMount motorMount) { + super(new MigLayout("fill")); + + this.mount = motorMount; + + this.setBorder( BorderFactory.createLineBorder(Color.BLACK,1) ); + BooleanModel model; + + model = new BooleanModel(motorMount, "MotorMount"); + JCheckBox check = new JCheckBox(model); + ////This component is a motor mount + check.setText(trans.get("MotorCfg.checkbox.compmotormount")); + this.add(check, "wrap"); + + final JPanel panel = new JPanel(new MigLayout("fill")); + this.add(panel, "grow, wrap"); + + + // Overhang + //// Motor overhang: + panel.add(new JLabel(trans.get("MotorCfg.lbl.Motoroverhang"))); + + DoubleModel dm = new DoubleModel(motorMount, "MotorOverhang", UnitGroup.UNITS_LENGTH); + + JSpinner spin = new JSpinner(dm.getSpinnerModel()); + spin.setEditor(new SpinnerEditor(spin)); + panel.add(spin, "span, split, width :65lp:"); + + panel.add(new UnitSelector(dm), "width :30lp:"); + panel.add(new BasicSlider(dm.getSliderModel(-0.02, 0.06)), "w 100lp, wrap unrel"); + + + + // Select ignition event + //// Ignition at: + panel.add(new JLabel(trans.get("MotorCfg.lbl.Ignitionat") + " " + CommonStrings.dagger), ""); + + IgnitionConfiguration ignitionConfig = mount.getIgnitionConfiguration().getDefault(); + JComboBox combo = new JComboBox(new EnumModel(ignitionConfig, "IgnitionEvent")); + panel.add(combo, "growx, wrap"); + + // ... and delay + //// plus + panel.add(new JLabel(trans.get("MotorCfg.lbl.plus")), "gap indent, skip 1, span, split"); + + dm = new DoubleModel(ignitionConfig, "IgnitionDelay", 0); + spin = new JSpinner(dm.getSpinnerModel()); + spin.setEditor(new SpinnerEditor(spin, 3)); + panel.add(spin, "gap rel rel"); + + //// seconds + panel.add(new JLabel(trans.get("MotorCfg.lbl.seconds")), "wrap unrel"); + + panel.add(new StyledLabel(CommonStrings.override_description, -1), "spanx, wrap para"); + + + // Check stage count + RocketComponent c = (RocketComponent) mount; + c = c.getRocket(); + int stages = c.getChildCount(); + + if (stages == 1) { + //// The current design has only one stage. + //// Stages can be added by clicking \"New stage\". + + panel.add(new StyledLabel(trans.get("MotorCfg.lbl.longA1") + " " + + trans.get("MotorCfg.lbl.longA2"), -1), + "spanx, wrap para"); + } else { + //// The current design has + //// stages. + panel.add(new StyledLabel(trans.get("MotorCfg.lbl.longB1") + " " + stages + " " + + trans.get("MotorCfg.lbl.longB2"), -1), + "spanx, wrap para"); + } + + + // Set enabled status + + setDeepEnabled(panel, motorMount.isMotorMount()); + check.addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + setDeepEnabled(panel, mount.isMotorMount()); + } + }); + + } + + private static void setDeepEnabled(Component component, boolean enabled) { + component.setEnabled(enabled); + if (component instanceof Container) { + for (Component c : ((Container) component).getComponents()) { + setDeepEnabled(c, enabled); + } + } + } + +} diff --git a/core/src/net/sf/openrocket/gui/configdialog/NoseConeConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/NoseConeConfig.java similarity index 100% rename from core/src/net/sf/openrocket/gui/configdialog/NoseConeConfig.java rename to swing/src/net/sf/openrocket/gui/configdialog/NoseConeConfig.java diff --git a/core/src/net/sf/openrocket/gui/configdialog/ParachuteConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/ParachuteConfig.java similarity index 100% rename from core/src/net/sf/openrocket/gui/configdialog/ParachuteConfig.java rename to swing/src/net/sf/openrocket/gui/configdialog/ParachuteConfig.java diff --git a/core/src/net/sf/openrocket/gui/configdialog/RecoveryDeviceConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/RecoveryDeviceConfig.java similarity index 100% rename from core/src/net/sf/openrocket/gui/configdialog/RecoveryDeviceConfig.java rename to swing/src/net/sf/openrocket/gui/configdialog/RecoveryDeviceConfig.java diff --git a/core/src/net/sf/openrocket/gui/configdialog/RingComponentConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/RingComponentConfig.java similarity index 66% rename from core/src/net/sf/openrocket/gui/configdialog/RingComponentConfig.java rename to swing/src/net/sf/openrocket/gui/configdialog/RingComponentConfig.java index 803633004..10b6e8483 100644 --- a/core/src/net/sf/openrocket/gui/configdialog/RingComponentConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/RingComponentConfig.java @@ -1,10 +1,6 @@ package net.sf.openrocket.gui.configdialog; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; - -import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JLabel; @@ -22,7 +18,6 @@ import net.sf.openrocket.gui.components.UnitSelector; import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.material.Material; import net.sf.openrocket.rocketcomponent.EngineBlock; -import net.sf.openrocket.rocketcomponent.RingComponent; import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.startup.Application; import net.sf.openrocket.unit.UnitGroup; @@ -171,73 +166,4 @@ public class RingComponentConfig extends RocketComponentConfig { } - protected JPanel positionTab() { - JPanel panel = new JPanel(new MigLayout("align 20% 20%, gap rel unrel", - "[][65lp::][30lp::]", "")); - - //// Radial position - JLabel l = new JLabel(trans.get("ringcompcfg.Radialdistance")); - //// Distance from the rocket centerline - l.setToolTipText(trans.get("ringcompcfg.Distancefrom")); - panel.add(l); - - DoubleModel m = new DoubleModel(component, "RadialPosition", UnitGroup.UNITS_LENGTH, 0); - - JSpinner spin = new JSpinner(m.getSpinnerModel()); - spin.setEditor(new SpinnerEditor(spin)); - //// Distance from the rocket centerline - spin.setToolTipText(trans.get("ringcompcfg.Distancefrom")); - panel.add(spin, "growx"); - - panel.add(new UnitSelector(m), "growx"); - BasicSlider bs = new BasicSlider(m.getSliderModel(0, 0.1, 1.0)); - //// Distance from the rocket centerline - bs.setToolTipText(trans.get("ringcompcfg.Distancefrom")); - panel.add(bs, "w 100lp, wrap"); - - - //// Radial direction - l = new JLabel(trans.get("ringcompcfg.Radialdirection")); - //// The radial direction from the rocket centerline - l.setToolTipText(trans.get("ringcompcfg.radialdirectionfrom")); - panel.add(l); - - m = new DoubleModel(component, "RadialDirection", UnitGroup.UNITS_ANGLE); - - spin = new JSpinner(m.getSpinnerModel()); - spin.setEditor(new SpinnerEditor(spin)); - //// The radial direction from the rocket centerline - spin.setToolTipText(trans.get("ringcompcfg.radialdirectionfrom")); - panel.add(spin, "growx"); - - panel.add(new UnitSelector(m), "growx"); - bs = new BasicSlider(m.getSliderModel(-Math.PI, Math.PI)); - //// The radial direction from the rocket centerline - bs.setToolTipText(trans.get("ringcompcfg.radialdirectionfrom")); - panel.add(bs, "w 100lp, wrap"); - - - //// Reset button - JButton button = new JButton(trans.get("ringcompcfg.but.Reset")); - //// Reset the component to the rocket centerline - button.setToolTipText(trans.get("ringcompcfg.but.Resetcomponant")); - button.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - ((RingComponent) component).setRadialDirection(0.0); - ((RingComponent) component).setRadialPosition(0.0); - } - }); - panel.add(button, "spanx, right, wrap para"); - - - DescriptionArea note = new DescriptionArea(3); - //// Note: An inner tube will not affect the aerodynamics of the rocket even if it is located outside of the body tube. - note.setText(trans.get("ringcompcfg.note.desc")); - panel.add(note, "spanx, growx"); - - - return panel; - } - } diff --git a/core/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java similarity index 100% rename from core/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java rename to swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java diff --git a/core/src/net/sf/openrocket/gui/configdialog/RocketConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/RocketConfig.java similarity index 100% rename from core/src/net/sf/openrocket/gui/configdialog/RocketConfig.java rename to swing/src/net/sf/openrocket/gui/configdialog/RocketConfig.java diff --git a/core/src/net/sf/openrocket/gui/configdialog/ShockCordConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/ShockCordConfig.java similarity index 100% rename from core/src/net/sf/openrocket/gui/configdialog/ShockCordConfig.java rename to swing/src/net/sf/openrocket/gui/configdialog/ShockCordConfig.java diff --git a/core/src/net/sf/openrocket/gui/configdialog/SleeveConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/SleeveConfig.java similarity index 100% rename from core/src/net/sf/openrocket/gui/configdialog/SleeveConfig.java rename to swing/src/net/sf/openrocket/gui/configdialog/SleeveConfig.java diff --git a/core/src/net/sf/openrocket/gui/configdialog/StageConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/StageConfig.java similarity index 100% rename from core/src/net/sf/openrocket/gui/configdialog/StageConfig.java rename to swing/src/net/sf/openrocket/gui/configdialog/StageConfig.java diff --git a/core/src/net/sf/openrocket/gui/configdialog/StreamerConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/StreamerConfig.java similarity index 100% rename from core/src/net/sf/openrocket/gui/configdialog/StreamerConfig.java rename to swing/src/net/sf/openrocket/gui/configdialog/StreamerConfig.java diff --git a/core/src/net/sf/openrocket/gui/configdialog/TransitionConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/TransitionConfig.java similarity index 100% rename from core/src/net/sf/openrocket/gui/configdialog/TransitionConfig.java rename to swing/src/net/sf/openrocket/gui/configdialog/TransitionConfig.java diff --git a/core/src/net/sf/openrocket/gui/configdialog/TrapezoidFinSetConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/TrapezoidFinSetConfig.java similarity index 100% rename from core/src/net/sf/openrocket/gui/configdialog/TrapezoidFinSetConfig.java rename to swing/src/net/sf/openrocket/gui/configdialog/TrapezoidFinSetConfig.java diff --git a/core/src/net/sf/openrocket/gui/customexpression/CustomExpressionDialog.java b/swing/src/net/sf/openrocket/gui/customexpression/CustomExpressionDialog.java similarity index 100% rename from core/src/net/sf/openrocket/gui/customexpression/CustomExpressionDialog.java rename to swing/src/net/sf/openrocket/gui/customexpression/CustomExpressionDialog.java diff --git a/core/src/net/sf/openrocket/gui/customexpression/CustomExpressionPanel.java b/swing/src/net/sf/openrocket/gui/customexpression/CustomExpressionPanel.java similarity index 100% rename from core/src/net/sf/openrocket/gui/customexpression/CustomExpressionPanel.java rename to swing/src/net/sf/openrocket/gui/customexpression/CustomExpressionPanel.java diff --git a/core/src/net/sf/openrocket/gui/customexpression/ExpressionBuilderDialog.java b/swing/src/net/sf/openrocket/gui/customexpression/ExpressionBuilderDialog.java similarity index 100% rename from core/src/net/sf/openrocket/gui/customexpression/ExpressionBuilderDialog.java rename to swing/src/net/sf/openrocket/gui/customexpression/ExpressionBuilderDialog.java diff --git a/core/src/net/sf/openrocket/gui/customexpression/OperatorSelector.java b/swing/src/net/sf/openrocket/gui/customexpression/OperatorSelector.java similarity index 100% rename from core/src/net/sf/openrocket/gui/customexpression/OperatorSelector.java rename to swing/src/net/sf/openrocket/gui/customexpression/OperatorSelector.java diff --git a/core/src/net/sf/openrocket/gui/customexpression/OperatorTableModel.java b/swing/src/net/sf/openrocket/gui/customexpression/OperatorTableModel.java similarity index 100% rename from core/src/net/sf/openrocket/gui/customexpression/OperatorTableModel.java rename to swing/src/net/sf/openrocket/gui/customexpression/OperatorTableModel.java diff --git a/core/src/net/sf/openrocket/gui/customexpression/VariableSelector.java b/swing/src/net/sf/openrocket/gui/customexpression/VariableSelector.java similarity index 100% rename from core/src/net/sf/openrocket/gui/customexpression/VariableSelector.java rename to swing/src/net/sf/openrocket/gui/customexpression/VariableSelector.java diff --git a/core/src/net/sf/openrocket/gui/customexpression/VariableTableModel.java b/swing/src/net/sf/openrocket/gui/customexpression/VariableTableModel.java similarity index 100% rename from core/src/net/sf/openrocket/gui/customexpression/VariableTableModel.java rename to swing/src/net/sf/openrocket/gui/customexpression/VariableTableModel.java diff --git a/core/src/net/sf/openrocket/gui/dialogs/AboutDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/AboutDialog.java similarity index 100% rename from core/src/net/sf/openrocket/gui/dialogs/AboutDialog.java rename to swing/src/net/sf/openrocket/gui/dialogs/AboutDialog.java diff --git a/core/src/net/sf/openrocket/gui/dialogs/BugReportDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/BugReportDialog.java similarity index 100% rename from core/src/net/sf/openrocket/gui/dialogs/BugReportDialog.java rename to swing/src/net/sf/openrocket/gui/dialogs/BugReportDialog.java diff --git a/core/src/net/sf/openrocket/gui/dialogs/ComponentAnalysisDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/ComponentAnalysisDialog.java similarity index 100% rename from core/src/net/sf/openrocket/gui/dialogs/ComponentAnalysisDialog.java rename to swing/src/net/sf/openrocket/gui/dialogs/ComponentAnalysisDialog.java diff --git a/core/src/net/sf/openrocket/gui/dialogs/CustomMaterialDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/CustomMaterialDialog.java similarity index 100% rename from core/src/net/sf/openrocket/gui/dialogs/CustomMaterialDialog.java rename to swing/src/net/sf/openrocket/gui/dialogs/CustomMaterialDialog.java diff --git a/core/src/net/sf/openrocket/gui/dialogs/DebugLogDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/DebugLogDialog.java similarity index 100% rename from core/src/net/sf/openrocket/gui/dialogs/DebugLogDialog.java rename to swing/src/net/sf/openrocket/gui/dialogs/DebugLogDialog.java diff --git a/core/src/net/sf/openrocket/gui/dialogs/DetailDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/DetailDialog.java similarity index 100% rename from core/src/net/sf/openrocket/gui/dialogs/DetailDialog.java rename to swing/src/net/sf/openrocket/gui/dialogs/DetailDialog.java diff --git a/core/src/net/sf/openrocket/gui/dialogs/EditDecalDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/EditDecalDialog.java similarity index 100% rename from core/src/net/sf/openrocket/gui/dialogs/EditDecalDialog.java rename to swing/src/net/sf/openrocket/gui/dialogs/EditDecalDialog.java diff --git a/core/src/net/sf/openrocket/gui/dialogs/LicenseDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/LicenseDialog.java similarity index 100% rename from core/src/net/sf/openrocket/gui/dialogs/LicenseDialog.java rename to swing/src/net/sf/openrocket/gui/dialogs/LicenseDialog.java diff --git a/core/src/net/sf/openrocket/gui/dialogs/PrintDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/PrintDialog.java similarity index 100% rename from core/src/net/sf/openrocket/gui/dialogs/PrintDialog.java rename to swing/src/net/sf/openrocket/gui/dialogs/PrintDialog.java diff --git a/core/src/net/sf/openrocket/gui/dialogs/PrintSettingsDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/PrintSettingsDialog.java similarity index 100% rename from core/src/net/sf/openrocket/gui/dialogs/PrintSettingsDialog.java rename to swing/src/net/sf/openrocket/gui/dialogs/PrintSettingsDialog.java diff --git a/core/src/net/sf/openrocket/gui/dialogs/ScaleDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/ScaleDialog.java similarity index 100% rename from core/src/net/sf/openrocket/gui/dialogs/ScaleDialog.java rename to swing/src/net/sf/openrocket/gui/dialogs/ScaleDialog.java diff --git a/core/src/net/sf/openrocket/gui/dialogs/SwingWorkerDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/SwingWorkerDialog.java similarity index 100% rename from core/src/net/sf/openrocket/gui/dialogs/SwingWorkerDialog.java rename to swing/src/net/sf/openrocket/gui/dialogs/SwingWorkerDialog.java diff --git a/core/src/net/sf/openrocket/gui/dialogs/UpdateInfoDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/UpdateInfoDialog.java similarity index 100% rename from core/src/net/sf/openrocket/gui/dialogs/UpdateInfoDialog.java rename to swing/src/net/sf/openrocket/gui/dialogs/UpdateInfoDialog.java diff --git a/core/src/net/sf/openrocket/gui/dialogs/WarningDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/WarningDialog.java similarity index 100% rename from core/src/net/sf/openrocket/gui/dialogs/WarningDialog.java rename to swing/src/net/sf/openrocket/gui/dialogs/WarningDialog.java diff --git a/core/src/net/sf/openrocket/gui/dialogs/flightconfiguration/DeploymentSelectionDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/flightconfiguration/DeploymentSelectionDialog.java similarity index 97% rename from core/src/net/sf/openrocket/gui/dialogs/flightconfiguration/DeploymentSelectionDialog.java rename to swing/src/net/sf/openrocket/gui/dialogs/flightconfiguration/DeploymentSelectionDialog.java index 87bfe2a76..6744f07eb 100644 --- a/core/src/net/sf/openrocket/gui/dialogs/flightconfiguration/DeploymentSelectionDialog.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/flightconfiguration/DeploymentSelectionDialog.java @@ -1,6 +1,7 @@ package net.sf.openrocket.gui.dialogs.flightconfiguration; import java.awt.Dialog; +import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -43,7 +44,7 @@ public class DeploymentSelectionDialog extends JDialog { private final UnitSelector altUnit; private final JSlider altSlider; - DeploymentSelectionDialog(JDialog parent, final Rocket rocket, final RecoveryDevice component) { + public DeploymentSelectionDialog(Window parent, final Rocket rocket, final RecoveryDevice component) { super(parent, trans.get("edtmotorconfdlg.title.Selectdeploymentconf"), Dialog.ModalityType.APPLICATION_MODAL); final String id = rocket.getDefaultConfiguration().getFlightConfigurationID(); diff --git a/core/src/net/sf/openrocket/gui/dialogs/flightconfiguration/IgnitionSelectionDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/flightconfiguration/IgnitionSelectionDialog.java similarity index 97% rename from core/src/net/sf/openrocket/gui/dialogs/flightconfiguration/IgnitionSelectionDialog.java rename to swing/src/net/sf/openrocket/gui/dialogs/flightconfiguration/IgnitionSelectionDialog.java index f4e8cd4f6..8093deb34 100644 --- a/core/src/net/sf/openrocket/gui/dialogs/flightconfiguration/IgnitionSelectionDialog.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/flightconfiguration/IgnitionSelectionDialog.java @@ -1,6 +1,7 @@ package net.sf.openrocket.gui.dialogs.flightconfiguration; import java.awt.Dialog; +import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -36,7 +37,7 @@ public class IgnitionSelectionDialog extends JDialog { private IgnitionConfiguration newConfiguration; - public IgnitionSelectionDialog(JDialog parent, final Rocket rocket, final MotorMount component) { + public IgnitionSelectionDialog(Window parent, final Rocket rocket, final MotorMount component) { super(parent, trans.get("edtmotorconfdlg.title.Selectignitionconf"), Dialog.ModalityType.APPLICATION_MODAL); final String id = rocket.getDefaultConfiguration().getFlightConfigurationID(); diff --git a/swing/src/net/sf/openrocket/gui/dialogs/flightconfiguration/MotorMountConfigurationPanel.java b/swing/src/net/sf/openrocket/gui/dialogs/flightconfiguration/MotorMountConfigurationPanel.java new file mode 100644 index 000000000..2dc0501e1 --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/dialogs/flightconfiguration/MotorMountConfigurationPanel.java @@ -0,0 +1,48 @@ +package net.sf.openrocket.gui.dialogs.flightconfiguration; + +import java.awt.Component; + +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.table.TableColumn; +import javax.swing.table.TableColumnModel; + +import net.miginfocom.swing.MigLayout; +import net.sf.openrocket.gui.util.GUIUtil; +import net.sf.openrocket.rocketcomponent.Rocket; + +public abstract class MotorMountConfigurationPanel extends JPanel { + + + private final Rocket rocket; + private final Component parent; + + public MotorMountConfigurationPanel( Component parent, Rocket rocket ) { + super(new MigLayout("") ); + + this.parent = parent; + this.rocket = rocket; + + //// Motor Mount selection + JTable table = new JTable(new MotorMountTableModel(this, rocket)); + table.setTableHeader(null); + table.setShowVerticalLines(false); + table.setRowSelectionAllowed(false); + table.setColumnSelectionAllowed(false); + + TableColumnModel columnModel = table.getColumnModel(); + TableColumn col0 = columnModel.getColumn(0); + int w = table.getRowHeight() + 2; + col0.setMinWidth(w); + col0.setPreferredWidth(w); + col0.setMaxWidth(w); + + table.addMouseListener(new GUIUtil.BooleanTableClickListener(table)); + JScrollPane scroll = new JScrollPane(table); + this.add(scroll, "w 200lp, h 150lp, grow"); + + } + + public abstract void onDataChanged(); +} diff --git a/core/src/net/sf/openrocket/gui/dialogs/flightconfiguration/MotorMountTableModel.java b/swing/src/net/sf/openrocket/gui/dialogs/flightconfiguration/MotorMountTableModel.java similarity index 89% rename from core/src/net/sf/openrocket/gui/dialogs/flightconfiguration/MotorMountTableModel.java rename to swing/src/net/sf/openrocket/gui/dialogs/flightconfiguration/MotorMountTableModel.java index 29b1fab64..f4a1b9db2 100644 --- a/core/src/net/sf/openrocket/gui/dialogs/flightconfiguration/MotorMountTableModel.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/flightconfiguration/MotorMountTableModel.java @@ -14,14 +14,14 @@ import net.sf.openrocket.util.ArrayList; */ class MotorMountTableModel extends AbstractTableModel { - private final MotorConfigurationPanel motorConfigurationPanel; + private final MotorMountConfigurationPanel motorConfigurationPanel; private final List potentialMounts = new ArrayList(); /** * @param motorConfigurationPanel */ - MotorMountTableModel(MotorConfigurationPanel motorConfigurationPanel, Rocket rocket) { + MotorMountTableModel(MotorMountConfigurationPanel motorConfigurationPanel, Rocket rocket) { this.motorConfigurationPanel = motorConfigurationPanel; for (RocketComponent c : rocket) { @@ -82,6 +82,6 @@ class MotorMountTableModel extends AbstractTableModel { MotorMount mount = potentialMounts.get(row); mount.setMotorMount((Boolean) value); - this.motorConfigurationPanel.fireTableDataChanged(); + this.motorConfigurationPanel.onDataChanged(); } } \ No newline at end of file diff --git a/core/src/net/sf/openrocket/gui/dialogs/flightconfiguration/RenameConfigDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/flightconfiguration/RenameConfigDialog.java similarity index 95% rename from core/src/net/sf/openrocket/gui/dialogs/flightconfiguration/RenameConfigDialog.java rename to swing/src/net/sf/openrocket/gui/dialogs/flightconfiguration/RenameConfigDialog.java index bd5d5afeb..1b26bc5d8 100644 --- a/core/src/net/sf/openrocket/gui/dialogs/flightconfiguration/RenameConfigDialog.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/flightconfiguration/RenameConfigDialog.java @@ -1,6 +1,7 @@ package net.sf.openrocket.gui.dialogs.flightconfiguration; import java.awt.Dialog; +import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -20,7 +21,7 @@ public class RenameConfigDialog extends JDialog { private static final Translator trans = Application.getTranslator(); - RenameConfigDialog(final FlightConfigurationDialog parent, final Rocket rocket) { + public RenameConfigDialog(final Window parent, final Rocket rocket) { super(parent, trans.get("RenameConfigDialog.title"), Dialog.ModalityType.APPLICATION_MODAL); final String configId = rocket.getDefaultConfiguration().getFlightConfigurationID(); diff --git a/core/src/net/sf/openrocket/gui/dialogs/flightconfiguration/SeparationSelectionDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/flightconfiguration/SeparationSelectionDialog.java similarity index 97% rename from core/src/net/sf/openrocket/gui/dialogs/flightconfiguration/SeparationSelectionDialog.java rename to swing/src/net/sf/openrocket/gui/dialogs/flightconfiguration/SeparationSelectionDialog.java index 58a76f19f..2456d1694 100644 --- a/core/src/net/sf/openrocket/gui/dialogs/flightconfiguration/SeparationSelectionDialog.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/flightconfiguration/SeparationSelectionDialog.java @@ -1,6 +1,7 @@ package net.sf.openrocket.gui.dialogs.flightconfiguration; import java.awt.Dialog; +import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -35,7 +36,7 @@ public class SeparationSelectionDialog extends JDialog { private StageSeparationConfiguration newConfiguration; - SeparationSelectionDialog(JDialog parent, final Rocket rocket, final Stage component) { + public SeparationSelectionDialog(Window parent, final Rocket rocket, final Stage component) { super(parent, trans.get("edtmotorconfdlg.title.Selectseparationconf"), Dialog.ModalityType.APPLICATION_MODAL); final String id = rocket.getDefaultConfiguration().getFlightConfigurationID(); diff --git a/core/src/net/sf/openrocket/gui/dialogs/motor/CloseableDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/motor/CloseableDialog.java similarity index 100% rename from core/src/net/sf/openrocket/gui/dialogs/motor/CloseableDialog.java rename to swing/src/net/sf/openrocket/gui/dialogs/motor/CloseableDialog.java diff --git a/core/src/net/sf/openrocket/gui/dialogs/motor/MotorChooserDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/motor/MotorChooserDialog.java similarity index 84% rename from core/src/net/sf/openrocket/gui/dialogs/motor/MotorChooserDialog.java rename to swing/src/net/sf/openrocket/gui/dialogs/motor/MotorChooserDialog.java index 761d4dab6..5ff870e1b 100644 --- a/core/src/net/sf/openrocket/gui/dialogs/motor/MotorChooserDialog.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/motor/MotorChooserDialog.java @@ -16,7 +16,7 @@ import net.sf.openrocket.gui.dialogs.motor.thrustcurve.ThrustCurveMotorSelection import net.sf.openrocket.gui.util.GUIUtil; import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.motor.Motor; -import net.sf.openrocket.motor.ThrustCurveMotor; +import net.sf.openrocket.rocketcomponent.MotorMount; import net.sf.openrocket.startup.Application; public class MotorChooserDialog extends JDialog implements CloseableDialog { @@ -26,16 +26,20 @@ public class MotorChooserDialog extends JDialog implements CloseableDialog { private boolean okClicked = false; private static final Translator trans = Application.getTranslator(); + public MotorChooserDialog(MotorMount mount, String currentConfig, Window owner) { + this(owner); + setMotorMountAndConfig(mount, currentConfig); + } - public MotorChooserDialog(Motor current, double delay, double diameter, Window owner) { + public MotorChooserDialog(Window owner) { super(owner, trans.get("MotorChooserDialog.title"), Dialog.ModalityType.APPLICATION_MODAL); JPanel panel = new JPanel(new MigLayout("fill")); - selectionPanel = new ThrustCurveMotorSelectionPanel((ThrustCurveMotor) current, delay, diameter); + selectionPanel = new ThrustCurveMotorSelectionPanel(); - panel.add(selectionPanel, "grow, wrap para"); + panel.add(selectionPanel, "grow, wrap"); // OK / Cancel buttons @@ -74,6 +78,9 @@ public class MotorChooserDialog extends JDialog implements CloseableDialog { selectionPanel.setCloseableDialog(this); } + public void setMotorMountAndConfig( MotorMount mount, String currentConfig ) { + selectionPanel.setMotorMountAndConfig(mount, currentConfig); + } /** * Return the motor selected by this chooser dialog, or null if the selection has been aborted. diff --git a/core/src/net/sf/openrocket/gui/dialogs/motor/MotorSelector.java b/swing/src/net/sf/openrocket/gui/dialogs/motor/MotorSelector.java similarity index 100% rename from core/src/net/sf/openrocket/gui/dialogs/motor/MotorSelector.java rename to swing/src/net/sf/openrocket/gui/dialogs/motor/MotorSelector.java diff --git a/swing/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/ImpulseClass.java b/swing/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/ImpulseClass.java new file mode 100644 index 000000000..8f639c893 --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/ImpulseClass.java @@ -0,0 +1,44 @@ +package net.sf.openrocket.gui.dialogs.motor.thrustcurve; + + +public enum ImpulseClass { + + A("A",0.0, 2.5 ), + B("B",2.5, 5.0 ), + C("C",5.0, 10.0), + D("D",10.0, 20.0), + E("E",20.0, 40.0), + F("F", 40.0, 80.0), + G("G", 80.0, 160.0), + H("H", 160.0, 320.0), + I("I", 320.0, 640.0), + J("J", 640.0, 1280.0), + K("K", 1280.0, 2560.0), + L("L", 2560.0, 5120.0), + M("M", 5120.0, 10240.0), + N("N", 10240.0, 20480.0), + O("O", 20480.0, Double.MAX_VALUE); + + private ImpulseClass( String name, double low, double high ) { + this.name = name; + this.low = low; + this.high = high; + } + + public String toString() { + return name; + } + + public double getLow() { + return low; + } + + public double getHigh() { + return high; + } + + private double low; + private double high; + private String name; + +} diff --git a/core/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/MotorClass.java b/swing/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/MotorClass.java similarity index 100% rename from core/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/MotorClass.java rename to swing/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/MotorClass.java diff --git a/swing/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/MotorFilterPanel.java b/swing/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/MotorFilterPanel.java new file mode 100644 index 000000000..31ebf72bd --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/MotorFilterPanel.java @@ -0,0 +1,373 @@ +package net.sf.openrocket.gui.dialogs.motor.thrustcurve; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.Hashtable; +import java.util.List; + +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JSpinner; +import javax.swing.border.TitledBorder; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.event.ListDataEvent; +import javax.swing.event.ListDataListener; + +import net.miginfocom.swing.MigLayout; +import net.sf.openrocket.gui.SpinnerEditor; +import net.sf.openrocket.gui.adaptors.DoubleModel; +import net.sf.openrocket.gui.components.UnitSelector; +import net.sf.openrocket.gui.util.CheckList; +import net.sf.openrocket.gui.util.GUIUtil; +import net.sf.openrocket.gui.util.SwingPreferences; +import net.sf.openrocket.gui.widgets.MultiSlider; +import net.sf.openrocket.l10n.Translator; +import net.sf.openrocket.motor.Manufacturer; +import net.sf.openrocket.rocketcomponent.MotorMount; +import net.sf.openrocket.rocketcomponent.RocketComponent; +import net.sf.openrocket.startup.Application; +import net.sf.openrocket.unit.UnitGroup; + +import com.itextpdf.text.Font; + +public abstract class MotorFilterPanel extends JPanel { + + private static final Translator trans = Application.getTranslator(); + + private static Hashtable diameterLabels = new Hashtable(); + private static double[] diameterValues = new double[] { + 0, + .013, + .018, + .024, + .029, + .038, + .054, + .075, + .098, + 1.000 + }; + static { + for( int i = 0; i< diameterValues.length; i++ ) { + if( i == diameterValues.length-1) { + diameterLabels.put( i, new JLabel("+")); + } else { + diameterLabels.put( i, new JLabel(UnitGroup.UNITS_MOTOR_DIMENSIONS.toString(diameterValues[i]))); + } + } + } + + private static Hashtable impulseLabels = new Hashtable(); + static { + int i =0; + for( ImpulseClass impulseClass : ImpulseClass.values() ) { + impulseLabels.put(i, new JLabel( impulseClass.name() )); + i++; + } + } + + private final CheckList manufacturerCheckList; + + private final MotorRowFilter filter; + + private final JCheckBox limitLengthCheckBox; + private boolean limitLength = false; + private Double mountLength = null; + + private final JCheckBox limitDiameterCheckBox; + private boolean limitDiameter = false; + private Double mountDiameter = null; + + // Things we change the label on based on the MotorMount. + private final JLabel motorMountDimension; + private final MultiSlider lengthSlider; + private final MultiSlider diameterSlider; + + public MotorFilterPanel(Collection allManufacturers, MotorRowFilter filter ) { + super(new MigLayout("fill", "[grow]")); + this.filter = filter; + + List unselectedManusFromPreferences = ((SwingPreferences) Application.getPreferences()).getExcludedMotorManufacturers(); + filter.setExcludedManufacturers(unselectedManusFromPreferences); + + limitLength = ((SwingPreferences) Application.getPreferences()).getBoolean("motorFilterLimitLength", false); + limitDiameter = ((SwingPreferences) Application.getPreferences()).getBoolean("motorFilterLimitDiameter", false); + + //// Hide used motor files + { + final JCheckBox hideUsedBox = new JCheckBox(trans.get("TCMotorSelPan.checkbox.hideUsed")); + GUIUtil.changeFontSize(hideUsedBox, -1); + hideUsedBox.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + MotorFilterPanel.this.filter.setHideUsedMotors(hideUsedBox.isSelected()); + onSelectionChanged(); + } + }); + this.add(hideUsedBox, "gapleft para, spanx, growx, wrap"); + } + + // Manufacturer selection + JPanel sub = new JPanel(new MigLayout("fill")); + TitledBorder border = BorderFactory.createTitledBorder(trans.get("TCurveMotorCol.MANUFACTURER")); + GUIUtil.changeFontStyle(border, Font.BOLD); + sub.setBorder(border); + + this.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1)); + + List manufacturers = new ArrayList(); + for (Manufacturer m : allManufacturers) { + manufacturers.add(m); + } + + Collections.sort(manufacturers, new Comparator() { + @Override + public int compare(Manufacturer o1, Manufacturer o2) { + return o1.getSimpleName().compareTo( o2.getSimpleName()); + } + + }); + + manufacturerCheckList = new CheckList.Builder().build(); + manufacturerCheckList.setData(manufacturers); + + manufacturerCheckList.setUncheckedItems(unselectedManusFromPreferences); + manufacturerCheckList.getModel().addListDataListener( new ListDataListener() { + @Override + public void intervalAdded(ListDataEvent e) { + } + @Override + public void intervalRemoved(ListDataEvent e) { + } + + @Override + public void contentsChanged(ListDataEvent e) { + MotorFilterPanel.this.filter.setExcludedManufacturers( manufacturerCheckList.getUncheckedItems() ); + onSelectionChanged(); + } + }); + + sub.add(new JScrollPane(manufacturerCheckList.getList()), "grow,wrap"); + + JButton clearMotors = new JButton(trans.get("TCMotorSelPan.btn.checkNone")); + clearMotors.addActionListener( new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + MotorFilterPanel.this.manufacturerCheckList.clearAll(); + + } + }); + + sub.add(clearMotors,"split 2"); + + JButton selectMotors = new JButton(trans.get("TCMotorSelPan.btn.checkAll")); + selectMotors.addActionListener( new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + MotorFilterPanel.this.manufacturerCheckList.checkAll(); + + } + }); + + sub.add(selectMotors,"wrap"); + + this.add(sub,"grow, wrap"); + + // Impulse selection + { + sub = new JPanel(new MigLayout("fill")); + border = BorderFactory.createTitledBorder(trans.get("TCurveMotorCol.TOTAL_IMPULSE")); + GUIUtil.changeFontStyle(border, Font.BOLD); + sub.setBorder(border); + + final MultiSlider impulseSlider = new MultiSlider(MultiSlider.HORIZONTAL,0, ImpulseClass.values().length-1,0, ImpulseClass.values().length-1); + impulseSlider.setBounded(true); // thumbs cannot cross + impulseSlider.setMajorTickSpacing(1); + impulseSlider.setPaintTicks(true); + impulseSlider.setLabelTable(impulseLabels); + impulseSlider.setPaintLabels(true); + impulseSlider.addChangeListener( new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + int minimpulse = impulseSlider.getValueAt(0); + MotorFilterPanel.this.filter.setMinimumImpulse(ImpulseClass.values()[minimpulse]); + int maximpulse = impulseSlider.getValueAt(1); + MotorFilterPanel.this.filter.setMaximumImpulse(ImpulseClass.values()[maximpulse]); + onSelectionChanged(); + } + }); + sub.add( impulseSlider, "growx, wrap"); + } + this.add(sub,"grow, wrap"); + + + // Motor Dimensions + sub = new JPanel(new MigLayout("fill")); + TitledBorder diameterTitleBorder = BorderFactory.createTitledBorder(trans.get("TCMotorSelPan.MotorSize")); + GUIUtil.changeFontStyle(diameterTitleBorder, Font.BOLD); + sub.setBorder(diameterTitleBorder); + + motorMountDimension = new JLabel(); + GUIUtil.changeFontSize(motorMountDimension, -1); + sub.add(motorMountDimension,"growx,wrap"); + + // Diameter selection + { + sub.add( new JLabel(trans.get("TCMotorSelPan.Diameter")), "split 2, wrap"); + limitDiameterCheckBox = new JCheckBox( trans.get("TCMotorSelPan.checkbox.limitdiameter")); + GUIUtil.changeFontSize(limitDiameterCheckBox, -1); + limitDiameterCheckBox.setSelected(limitDiameter); + limitDiameterCheckBox.addActionListener(new ActionListener(){ + @Override + public void actionPerformed(ActionEvent e) { + limitDiameter = limitDiameterCheckBox.isSelected(); + MotorFilterPanel.this.setLimitDiameter(); + onSelectionChanged(); + } + }); + sub.add( limitDiameterCheckBox, "gapleft para, spanx, growx, wrap" ); + + diameterSlider = new MultiSlider(MultiSlider.HORIZONTAL,0, diameterValues.length-1, 0, diameterValues.length-1); + diameterSlider.setBounded(true); // thumbs cannot cross + diameterSlider.setMajorTickSpacing(1); + diameterSlider.setPaintTicks(true); + diameterSlider.setLabelTable(diameterLabels); + diameterSlider.setPaintLabels(true); + diameterSlider.addChangeListener( new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + int minDiameter = diameterSlider.getValueAt(0); + MotorFilterPanel.this.filter.setMinimumDiameter(diameterValues[minDiameter]); + int maxDiameter = diameterSlider.getValueAt(1); + if( maxDiameter == diameterValues.length-1 ) { + MotorFilterPanel.this.filter.setMaximumDiameter(null); + } else { + MotorFilterPanel.this.filter.setMaximumDiameter(diameterValues[maxDiameter]); + } + onSelectionChanged(); + } + }); + sub.add( diameterSlider, "growx, wrap"); + } + + { + sub.add( new JLabel(trans.get("TCMotorSelPan.Length")), "split 2, wrap"); + limitLengthCheckBox = new JCheckBox( trans.get("TCMotorSelPan.checkbox.limitlength")); + GUIUtil.changeFontSize(limitLengthCheckBox, -1); + limitLengthCheckBox.setSelected(limitLength); + limitLengthCheckBox.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + limitLength = limitLengthCheckBox.isSelected(); + MotorFilterPanel.this.setLimitLength(); + onSelectionChanged(); + } + }); + + sub.add( limitLengthCheckBox, "gapleft para, spanx, growx, wrap" ); + + + final DoubleModel minimumLength = new DoubleModel(filter, "MinimumLength", UnitGroup.UNITS_MOTOR_DIMENSIONS, 0); + final DoubleModel maximumLength = new DoubleModel(filter, "MaximumLength", UnitGroup.UNITS_MOTOR_DIMENSIONS, 0); + + JSpinner spin = new JSpinner(minimumLength.getSpinnerModel()); + spin.setEditor(new SpinnerEditor(spin)); + sub.add(spin, "split 5, growx"); + + sub.add(new UnitSelector(minimumLength), ""); + + lengthSlider = new MultiSlider(MultiSlider.HORIZONTAL,0, 1000, 0, 1000); + lengthSlider.setBounded(true); // thumbs cannot cross + lengthSlider.setMajorTickSpacing(100); + lengthSlider.setPaintTicks(true); + lengthSlider.setLabelTable(diameterLabels); + lengthSlider.addChangeListener( new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + int minLength = lengthSlider.getValueAt(0); + minimumLength.setValue(minLength/1000.0); + int maxLength = lengthSlider.getValueAt(1); + maximumLength.setValue(maxLength/1000.0); + onSelectionChanged(); + } + }); + + minimumLength.addChangeListener( new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + lengthSlider.setValueAt(0, (int)(1000* minimumLength.getValue())); + lengthSlider.setValueAt(1, (int) (1000* maximumLength.getValue())); + } + + }); + + sub.add( lengthSlider, "growx"); + + spin = new JSpinner(maximumLength.getSpinnerModel()); + spin.setEditor(new SpinnerEditor(spin)); + sub.add(spin, "growx"); + + sub.add(new UnitSelector(maximumLength), "wrap"); + } + this.add(sub, "grow,wrap"); + + } + + public void setMotorMount( MotorMount mount ) { + filter.setMotorMount(mount); + onSelectionChanged(); + if ( mount == null ) { + // Disable diameter controls? + mountLength = null; + mountDiameter = null; + motorMountDimension.setText(""); + } else { + mountLength = ((RocketComponent)mount).getLength(); + mountDiameter = mount.getMotorMountDiameter(); + motorMountDimension.setText( trans.get("TCMotorSelPan.MotorMountDimensions") + " " + + UnitGroup.UNITS_MOTOR_DIMENSIONS.toStringUnit(mountDiameter)+ " x " + UnitGroup.UNITS_MOTOR_DIMENSIONS.toStringUnit(mountLength)); + } + setLimitLength(); + setLimitDiameter(); + } + + private void setLimitLength( ) { + ((SwingPreferences) Application.getPreferences()).putBoolean("motorFilterLimitLength", limitLength); + if ( mountLength != null & limitLength ) { + lengthSlider.setValueAt(1, (int) Math.min(1000,Math.round(1000*mountLength))); + } else { + lengthSlider.setValueAt(1, 1000); + } + } + + private void setLimitDiameter( ) { + ((SwingPreferences) Application.getPreferences()).putBoolean("motorFilterLimitDiameter", limitDiameter); + if ( limitDiameter && mountDiameter != null) { + // find the next largest diameter + int i; + for( i =0; i< diameterValues.length; i++ ) { + if ( mountDiameter< diameterValues[i] - 0.0005 ) { + break; + } + } + if (i >= diameterValues.length ) { + i--; + } + diameterSlider.setValueAt(1, i-1); + } else { + diameterSlider.setValueAt(1, diameterValues.length-1); + } + } + + public abstract void onSelectionChanged(); + +} diff --git a/core/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/MotorHolder.java b/swing/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/MotorHolder.java similarity index 100% rename from core/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/MotorHolder.java rename to swing/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/MotorHolder.java diff --git a/swing/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/MotorInformationPanel.java b/swing/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/MotorInformationPanel.java new file mode 100644 index 000000000..8e5fb2ebb --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/MotorInformationPanel.java @@ -0,0 +1,315 @@ +package net.sf.openrocket.gui.dialogs.motor.thrustcurve; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Cursor; +import java.awt.Font; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.List; + +import javax.swing.BorderFactory; +import javax.swing.JLabel; +import javax.swing.JLayeredPane; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; +import javax.swing.SwingUtilities; + +import net.miginfocom.swing.MigLayout; +import net.sf.openrocket.gui.util.GUIUtil; +import net.sf.openrocket.gui.util.Icons; +import net.sf.openrocket.l10n.Translator; +import net.sf.openrocket.motor.ThrustCurveMotor; +import net.sf.openrocket.startup.Application; +import net.sf.openrocket.unit.UnitGroup; + +import org.jfree.chart.ChartFactory; +import org.jfree.chart.ChartPanel; +import org.jfree.chart.JFreeChart; +import org.jfree.chart.axis.ValueAxis; +import org.jfree.chart.plot.PlotOrientation; +import org.jfree.chart.plot.XYPlot; +import org.jfree.chart.title.TextTitle; +import org.jfree.data.xy.XYSeries; +import org.jfree.data.xy.XYSeriesCollection; + +class MotorInformationPanel extends JPanel { + + private static final int ZOOM_ICON_POSITION_NEGATIVE_X = 50; + private static final int ZOOM_ICON_POSITION_POSITIVE_Y = 12; + + private static final Color NO_COMMENT_COLOR = Color.GRAY; + private static final Color WITH_COMMENT_COLOR = Color.BLACK; + + private static final Translator trans = Application.getTranslator(); + + // Motors in set + private List selectedMotorSet; + // Selected motor + private ThrustCurveMotor selectedMotor; + + private final JLabel totalImpulseLabel; + private final JLabel classificationLabel; + private final JLabel avgThrustLabel; + private final JLabel maxThrustLabel; + private final JLabel burnTimeLabel; + private final JLabel launchMassLabel; + private final JLabel emptyMassLabel; + private final JLabel dataPointsLabel; + private final JLabel digestLabel; + + private final JTextArea comment; + private final Font noCommentFont; + private final Font withCommentFont; + + private final JFreeChart chart; + private final ChartPanel chartPanel; + private final JLabel zoomIcon; + + public MotorInformationPanel() { + super(new MigLayout("fill")); + + // Thrust curve info + //// Total impulse: + { + this.add(new JLabel(trans.get("TCMotorSelPan.lbl.Totalimpulse"))); + totalImpulseLabel = new JLabel(); + this.add(totalImpulseLabel, "split"); + + classificationLabel = new JLabel(); + classificationLabel.setEnabled(false); // Gray out + this.add(classificationLabel, "gapleft unrel, wrap"); + + //// Avg. thrust: + this.add(new JLabel(trans.get("TCMotorSelPan.lbl.Avgthrust"))); + avgThrustLabel = new JLabel(); + this.add(avgThrustLabel, "wrap"); + + //// Max. thrust: + this.add(new JLabel(trans.get("TCMotorSelPan.lbl.Maxthrust"))); + maxThrustLabel = new JLabel(); + this.add(maxThrustLabel, "wrap"); + + //// Burn time: + this.add(new JLabel(trans.get("TCMotorSelPan.lbl.Burntime"))); + burnTimeLabel = new JLabel(); + this.add(burnTimeLabel, "wrap"); + + //// Launch mass: + this.add(new JLabel(trans.get("TCMotorSelPan.lbl.Launchmass"))); + launchMassLabel = new JLabel(); + this.add(launchMassLabel, "wrap"); + + //// Empty mass: + this.add(new JLabel(trans.get("TCMotorSelPan.lbl.Emptymass"))); + emptyMassLabel = new JLabel(); + this.add(emptyMassLabel, "wrap"); + + //// Data points: + this.add(new JLabel(trans.get("TCMotorSelPan.lbl.Datapoints"))); + dataPointsLabel = new JLabel(); + this.add(dataPointsLabel, "wrap para"); + + if (System.getProperty("openrocket.debug.motordigest") != null) { + //// Digest: + this.add(new JLabel(trans.get("TCMotorSelPan.lbl.Digest"))); + digestLabel = new JLabel(); + this.add(digestLabel, "w :300:, wrap para"); + } else { + digestLabel = null; + } + + + comment = new JTextArea(5, 5); + GUIUtil.changeFontSize(comment, -2); + withCommentFont = comment.getFont(); + noCommentFont = withCommentFont.deriveFont(Font.ITALIC); + comment.setLineWrap(true); + comment.setWrapStyleWord(true); + comment.setEditable(false); + JScrollPane scrollpane = new JScrollPane(comment); + this.add(scrollpane, "spanx, growx, wrap para"); + } + + // Thrust curve plot + { + chart = ChartFactory.createXYLineChart( + null, // title + null, // xAxisLabel + null, // yAxisLabel + null, // dataset + PlotOrientation.VERTICAL, + false, // legend + false, // tooltips + false // urls + ); + + // Add the data and formatting to the plot + XYPlot plot = chart.getXYPlot(); + + changeLabelFont(plot.getRangeAxis(), -2); + changeLabelFont(plot.getDomainAxis(), -2); + + //// Thrust curve: + chart.setTitle(new TextTitle(trans.get("TCMotorSelPan.title.Thrustcurve"), this.getFont())); + chart.setBackgroundPaint(this.getBackground()); + plot.setBackgroundPaint(Color.WHITE); + plot.setDomainGridlinePaint(Color.LIGHT_GRAY); + plot.setRangeGridlinePaint(Color.LIGHT_GRAY); + + chartPanel = new ChartPanel(chart, + false, // properties + false, // save + false, // print + false, // zoom + false); // tooltips + chartPanel.setMouseZoomable(false); + chartPanel.setPopupMenu(null); + chartPanel.setMouseWheelEnabled(false); + chartPanel.setRangeZoomable(false); + chartPanel.setDomainZoomable(false); + + chartPanel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + chartPanel.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (selectedMotor == null || selectedMotorSet == null) + return; + if (e.getButton() == MouseEvent.BUTTON1) { + // Open plot dialog + ThrustCurveMotorPlotDialog plotDialog = new ThrustCurveMotorPlotDialog(selectedMotorSet, + selectedMotorSet.indexOf(selectedMotor), + SwingUtilities.getWindowAncestor(MotorInformationPanel.this)); + plotDialog.setVisible(true); + } + } + }); + + JLayeredPane layer = new CustomLayeredPane(); + + layer.setBorder(BorderFactory.createLineBorder(Color.BLUE)); + + layer.add(chartPanel, (Integer) 0); + + zoomIcon = new JLabel(Icons.ZOOM_IN); + zoomIcon.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + layer.add(zoomIcon, (Integer) 1); + + this.add(layer, "width 300:300:, height 180:180:, grow, spanx"); + } + } + + public void clearData() { + totalImpulseLabel.setText(""); + totalImpulseLabel.setToolTipText(null); + classificationLabel.setText(""); + classificationLabel.setToolTipText(null); + avgThrustLabel.setText(""); + maxThrustLabel.setText(""); + burnTimeLabel.setText(""); + launchMassLabel.setText(""); + emptyMassLabel.setText(""); + dataPointsLabel.setText(""); + if (digestLabel != null) { + digestLabel.setText(""); + } + setComment(""); + chart.getXYPlot().setDataset(new XYSeriesCollection()); + } + + public void updateData( List motors, ThrustCurveMotor selectedMotor ) { + + this.selectedMotorSet = motors; + this.selectedMotor = selectedMotor; + + // Update thrust curve data + double impulse = selectedMotor.getTotalImpulseEstimate(); + MotorClass mc = MotorClass.getMotorClass(impulse); + totalImpulseLabel.setText(UnitGroup.UNITS_IMPULSE.getDefaultUnit().toStringUnit(impulse)); + classificationLabel.setText("(" + mc.getDescription(impulse) + ")"); + totalImpulseLabel.setToolTipText(mc.getClassDescription()); + classificationLabel.setToolTipText(mc.getClassDescription()); + + avgThrustLabel.setText(UnitGroup.UNITS_FORCE.getDefaultUnit().toStringUnit( + selectedMotor.getAverageThrustEstimate())); + maxThrustLabel.setText(UnitGroup.UNITS_FORCE.getDefaultUnit().toStringUnit( + selectedMotor.getMaxThrustEstimate())); + burnTimeLabel.setText(UnitGroup.UNITS_SHORT_TIME.getDefaultUnit().toStringUnit( + selectedMotor.getBurnTimeEstimate())); + launchMassLabel.setText(UnitGroup.UNITS_MASS.getDefaultUnit().toStringUnit( + selectedMotor.getLaunchCG().weight)); + emptyMassLabel.setText(UnitGroup.UNITS_MASS.getDefaultUnit().toStringUnit( + selectedMotor.getEmptyCG().weight)); + dataPointsLabel.setText("" + (selectedMotor.getTimePoints().length - 1)); + if (digestLabel != null) { + digestLabel.setText(selectedMotor.getDigest()); + } + + setComment(selectedMotor.getDescription()); + + // Update the plot + XYPlot plot = chart.getXYPlot(); + final int index = motors.indexOf(selectedMotor); + + XYSeriesCollection dataset = new XYSeriesCollection(); + for (int i = 0; i < motors.size(); i++) { + ThrustCurveMotor m = motors.get(i); + + //// Thrust + XYSeries series = new XYSeries(trans.get("TCMotorSelPan.title.Thrust") + " (" + i + ")"); + double[] time = m.getTimePoints(); + double[] thrust = m.getThrustPoints(); + + for (int j = 0; j < time.length; j++) { + series.add(time[j], thrust[j]); + } + + dataset.addSeries(series); + + boolean selected = (i == index); + plot.getRenderer().setSeriesStroke(i, new BasicStroke(selected ? 3 : 1)); + plot.getRenderer().setSeriesPaint(i, ThrustCurveMotorSelectionPanel.getColor(i)); + } + + plot.setDataset(dataset); + + } + + private void setComment(String s) { + s = s.trim(); + if (s.length() == 0) { + //// No description available. + comment.setText(trans.get("TCMotorSelPan.noDescription")); + comment.setFont(noCommentFont); + comment.setForeground(NO_COMMENT_COLOR); + } else { + comment.setText(s); + comment.setFont(withCommentFont); + comment.setForeground(WITH_COMMENT_COLOR); + } + comment.setCaretPosition(0); + } + + void changeLabelFont(ValueAxis axis, float size) { + Font font = axis.getTickLabelFont(); + font = font.deriveFont(font.getSize2D() + size); + axis.setTickLabelFont(font); + } + + /** + * Custom layered pane that sets the bounds of the components on every layout. + */ + public class CustomLayeredPane extends JLayeredPane { + @Override + public void doLayout() { + synchronized (getTreeLock()) { + int w = getWidth(); + int h = getHeight(); + chartPanel.setBounds(0, 0, w, h); + zoomIcon.setBounds(w - ZOOM_ICON_POSITION_NEGATIVE_X, ZOOM_ICON_POSITION_POSITIVE_Y, 50, 50); + } + } + } + +} \ No newline at end of file diff --git a/swing/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/MotorRowFilter.java b/swing/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/MotorRowFilter.java new file mode 100644 index 000000000..b4ac85e9f --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/MotorRowFilter.java @@ -0,0 +1,242 @@ +package net.sf.openrocket.gui.dialogs.motor.thrustcurve; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Locale; + +import javax.swing.RowFilter; +import javax.swing.table.TableModel; + +import net.sf.openrocket.database.motor.ThrustCurveMotorSet; +import net.sf.openrocket.motor.Manufacturer; +import net.sf.openrocket.motor.ThrustCurveMotor; +import net.sf.openrocket.rocketcomponent.MotorConfiguration; +import net.sf.openrocket.rocketcomponent.MotorMount; +import net.sf.openrocket.util.AbstractChangeSource; +import net.sf.openrocket.util.ChangeSource; +import net.sf.openrocket.util.StateChangeListener; + +//////// Row filters + +/** + * Abstract adapter class. + */ +public class MotorRowFilter extends RowFilter implements ChangeSource { + + // configuration data used in the filter process + private final ThrustCurveMotorDatabaseModel model; + private List usedMotors = new ArrayList(); + + private final AbstractChangeSource changeSourceDelegate = new AbstractChangeSource(); + private final Object change = new Object(); + + // things which can be changed to modify filter behavior + + // Limit motors based on length + private double minimumLength = 0; + private double maximumLength = Double.MAX_VALUE; + + // Limit motors based on diameter + private Double minimumDiameter; + private Double maximumDiameter; + + // Collection of strings which match text in the motor + private List searchTerms = Collections. emptyList(); + + // Boolean which hides motors in the usedMotors list + private boolean hideUsedMotors = false; + + // List of manufacturers to exclude. + private List excludedManufacturers = new ArrayList(); + + // Impulse class filtering + private ImpulseClass minimumImpulse; + private ImpulseClass maximumImpulse; + + + public MotorRowFilter(ThrustCurveMotorDatabaseModel model) { + super(); + this.model = model; + } + + public void setMotorMount( MotorMount mount ) { + if (mount != null) { + for (MotorConfiguration m : mount.getMotorConfiguration()) { + this.usedMotors.add((ThrustCurveMotor) m.getMotor()); + } + } + } + + public void setSearchTerms(final List searchTerms) { + this.searchTerms = new ArrayList(); + for (String s : searchTerms) { + s = s.trim().toLowerCase(Locale.getDefault()); + if (s.length() > 0) { + this.searchTerms.add(s); + } + } + } + + public double getMinimumLength() { + return minimumLength; + } + + public void setMinimumLength(double minimumLength) { + if ( this.minimumLength != minimumLength ) { + this.minimumLength = minimumLength; + fireChangeEvent(change); + } + } + + public double getMaximumLength() { + return maximumLength; + } + + public void setMaximumLength(double maximumLength) { + if ( this.maximumLength != maximumLength ) { + this.maximumLength = maximumLength; + fireChangeEvent(change); + } + } + + Double getMinimumDiameter() { + return minimumDiameter; + } + + void setMinimumDiameter(Double minimumDiameter) { + this.minimumDiameter = minimumDiameter; + } + + Double getMaximumDiameter() { + return maximumDiameter; + } + + void setMaximumDiameter(Double maximumDiameter) { + this.maximumDiameter = maximumDiameter; + } + + void setHideUsedMotors(boolean hideUsedMotors) { + this.hideUsedMotors = hideUsedMotors; + } + + List getExcludedManufacturers() { + return excludedManufacturers; + } + + void setExcludedManufacturers(Collection excludedManufacturers) { + this.excludedManufacturers.clear(); + this.excludedManufacturers.addAll(excludedManufacturers); + } + + ImpulseClass getMinimumImpulse() { + return minimumImpulse; + } + + void setMinimumImpulse(ImpulseClass minimumImpulse) { + this.minimumImpulse = minimumImpulse; + } + + ImpulseClass getMaximumImpulse() { + return maximumImpulse; + } + + void setMaximumImpulse(ImpulseClass maximumImpulse) { + this.maximumImpulse = maximumImpulse; + } + + @Override + public boolean include(RowFilter.Entry entry) { + int index = entry.getIdentifier(); + ThrustCurveMotorSet m = model.getMotorSet(index); + return filterManufacturers(m) && filterUsed(m) && filterBySize(m) && filterByString(m) && filterByImpulseClass(m); + } + + private boolean filterManufacturers(ThrustCurveMotorSet m) { + if (excludedManufacturers.contains(m.getManufacturer())) { + return false; + } else { + return true; + } + } + + private boolean filterUsed(ThrustCurveMotorSet m) { + if (!hideUsedMotors) { + return true; + } + for (ThrustCurveMotor motor : usedMotors) { + if (m.matches(motor)) { + return false; + } + } + return true; + } + + private boolean filterBySize(ThrustCurveMotorSet m) { + + if ( minimumDiameter != null ) { + if ( m.getDiameter() <= minimumDiameter - 0.0015 ) { + return false; + } + } + + if ( maximumDiameter != null ) { + if ( m.getDiameter() >= maximumDiameter + 0.0004 ) { + return false; + } + } + + if ( m.getLength() > maximumLength ) { + return false; + } + + if ( m.getLength() < minimumLength ) { + return false; + } + + return true; + } + + + private boolean filterByString(ThrustCurveMotorSet m) { + main: for (String s : searchTerms) { + for (ThrustCurveMotorColumns col : ThrustCurveMotorColumns.values()) { + String str = col.getValue(m).toString().toLowerCase(Locale.getDefault()); + if (str.indexOf(s) >= 0) + continue main; + } + return false; + } + return true; + } + + private boolean filterByImpulseClass(ThrustCurveMotorSet m) { + if ( minimumImpulse != null ) { + if( m.getTotalImpuse() < minimumImpulse.getLow() ) { + return false; + } + } + + if ( maximumImpulse != null ) { + if( m.getTotalImpuse() > maximumImpulse.getHigh() ) { + return false; + } + } + + return true; + } + + public final void addChangeListener(StateChangeListener listener) { + changeSourceDelegate.addChangeListener(listener); + } + + public final void removeChangeListener(StateChangeListener listener) { + changeSourceDelegate.removeChangeListener(listener); + } + + public void fireChangeEvent(Object source) { + changeSourceDelegate.fireChangeEvent(source); + } + +} diff --git a/core/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/ThrustCurveMotorColumns.java b/swing/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/ThrustCurveMotorColumns.java similarity index 100% rename from core/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/ThrustCurveMotorColumns.java rename to swing/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/ThrustCurveMotorColumns.java diff --git a/core/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/ThrustCurveMotorComparator.java b/swing/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/ThrustCurveMotorComparator.java similarity index 100% rename from core/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/ThrustCurveMotorComparator.java rename to swing/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/ThrustCurveMotorComparator.java diff --git a/core/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/ThrustCurveMotorDatabaseModel.java b/swing/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/ThrustCurveMotorDatabaseModel.java similarity index 100% rename from core/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/ThrustCurveMotorDatabaseModel.java rename to swing/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/ThrustCurveMotorDatabaseModel.java diff --git a/core/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/ThrustCurveMotorPlotDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/ThrustCurveMotorPlotDialog.java similarity index 100% rename from core/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/ThrustCurveMotorPlotDialog.java rename to swing/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/ThrustCurveMotorPlotDialog.java diff --git a/swing/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/ThrustCurveMotorSelectionPanel.java b/swing/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/ThrustCurveMotorSelectionPanel.java new file mode 100644 index 000000000..e0eb134d1 --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/ThrustCurveMotorSelectionPanel.java @@ -0,0 +1,635 @@ +package net.sf.openrocket.gui.dialogs.motor.thrustcurve; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Font; +import java.awt.Paint; +import java.awt.Rectangle; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.prefs.Preferences; + +import javax.swing.DefaultComboBoxModel; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import javax.swing.JScrollPane; +import javax.swing.JSeparator; +import javax.swing.JTabbedPane; +import javax.swing.JTable; +import javax.swing.JTextField; +import javax.swing.ListCellRenderer; +import javax.swing.ListSelectionModel; +import javax.swing.RowSorter; +import javax.swing.SortOrder; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.table.TableModel; +import javax.swing.table.TableRowSorter; + +import net.miginfocom.swing.MigLayout; +import net.sf.openrocket.database.motor.ThrustCurveMotorSet; +import net.sf.openrocket.gui.components.StyledLabel; +import net.sf.openrocket.gui.dialogs.motor.CloseableDialog; +import net.sf.openrocket.gui.dialogs.motor.MotorSelector; +import net.sf.openrocket.gui.util.GUIUtil; +import net.sf.openrocket.gui.util.SwingPreferences; +import net.sf.openrocket.l10n.Translator; +import net.sf.openrocket.logging.Markers; +import net.sf.openrocket.motor.Manufacturer; +import net.sf.openrocket.motor.Motor; +import net.sf.openrocket.motor.ThrustCurveMotor; +import net.sf.openrocket.rocketcomponent.MotorConfiguration; +import net.sf.openrocket.rocketcomponent.MotorMount; +import net.sf.openrocket.startup.Application; +import net.sf.openrocket.unit.UnitGroup; +import net.sf.openrocket.util.BugException; +import net.sf.openrocket.utils.MotorCorrelation; + +import org.jfree.chart.ChartColor; +import org.jfree.chart.axis.ValueAxis; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelector { + private static final Logger log = LoggerFactory.getLogger(ThrustCurveMotorSelectionPanel.class); + + private static final Translator trans = Application.getTranslator(); + + private static final double MOTOR_SIMILARITY_THRESHOLD = 0.95; + + private static final Paint[] CURVE_COLORS = ChartColor.createDefaultPaintArray(); + + private static final ThrustCurveMotorComparator MOTOR_COMPARATOR = new ThrustCurveMotorComparator(); + + private List database; + + private CloseableDialog dialog = null; + + private final ThrustCurveMotorDatabaseModel model; + private final JTable table; + private final TableRowSorter sorter; + private final MotorRowFilter rowFilter; + + private final JCheckBox hideSimilarBox; + + private final JTextField searchField; + + private final JLabel curveSelectionLabel; + private final JComboBox curveSelectionBox; + private final DefaultComboBoxModel curveSelectionModel; + private final JComboBox delayBox; + + private final MotorInformationPanel motorInformationPanel; + private final MotorFilterPanel motorFilterPanel; + + private ThrustCurveMotor selectedMotor; + private ThrustCurveMotorSet selectedMotorSet; + private double selectedDelay; + + public ThrustCurveMotorSelectionPanel(MotorMount mount, String currentConfig) { + this(); + setMotorMountAndConfig( mount, currentConfig ); + + } + /** + * Sole constructor. + * + * @param current the currently selected ThrustCurveMotor, or null for none. + * @param delay the currently selected ejection charge delay. + * @param diameter the diameter of the motor mount. + */ + public ThrustCurveMotorSelectionPanel() { + super(new MigLayout("fill", "[grow][]")); + + // Construct the database (adding the current motor if not in the db already) + database = Application.getThrustCurveMotorSetDatabase().getMotorSets(); + + model = new ThrustCurveMotorDatabaseModel(database); + rowFilter = new MotorRowFilter(model); + motorInformationPanel = new MotorInformationPanel(); + + //// MotorFilter + { + // Find all the manufacturers: + Set allManufacturers = new HashSet(); + for (ThrustCurveMotorSet s : database) { + allManufacturers.add(s.getManufacturer()); + } + + motorFilterPanel = new MotorFilterPanel(allManufacturers, rowFilter) { + @Override + public void onSelectionChanged() { + sorter.sort(); + scrollSelectionVisible(); + } + }; + + } + + //// GUI + JPanel panel = new JPanel(new MigLayout("fill","[][grow]")); + this.add(panel, "grow"); + + //// Select thrust curve: + { + curveSelectionLabel = new JLabel(trans.get("TCMotorSelPan.lbl.Selectthrustcurve")); + panel.add(curveSelectionLabel); + + curveSelectionModel = new DefaultComboBoxModel(); + curveSelectionBox = new JComboBox(curveSelectionModel); + curveSelectionBox.setRenderer(new CurveSelectionRenderer(curveSelectionBox.getRenderer())); + curveSelectionBox.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + Object value = curveSelectionBox.getSelectedItem(); + if (value != null) { + select(((MotorHolder) value).getMotor()); + } + } + }); + panel.add(curveSelectionBox, "growx, wrap"); + } + + // Ejection charge delay: + { + panel.add(new JLabel(trans.get("TCMotorSelPan.lbl.Ejectionchargedelay"))); + + delayBox = new JComboBox(); + delayBox.setEditable(true); + delayBox.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + JComboBox cb = (JComboBox) e.getSource(); + String sel = (String) cb.getSelectedItem(); + //// None + if (sel.equalsIgnoreCase(trans.get("TCMotorSelPan.equalsIgnoreCase.None"))) { + selectedDelay = Motor.PLUGGED; + } else { + try { + selectedDelay = Double.parseDouble(sel); + } catch (NumberFormatException ignore) { + } + } + setDelays(false); + } + }); + panel.add(delayBox, "growx,wrap"); + //// (Number of seconds or \"None\") + panel.add(new StyledLabel(trans.get("TCMotorSelPan.lbl.NumberofsecondsorNone"), -3), "skip, wrap"); + setDelays(false); + } + + //// Hide very similar thrust curves + { + hideSimilarBox = new JCheckBox(trans.get("TCMotorSelPan.checkbox.hideSimilar")); + GUIUtil.changeFontSize(hideSimilarBox, -1); + hideSimilarBox.setSelected(Application.getPreferences().getBoolean(net.sf.openrocket.startup.Preferences.MOTOR_HIDE_SIMILAR, true)); + hideSimilarBox.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + Application.getPreferences().putBoolean(net.sf.openrocket.startup.Preferences.MOTOR_HIDE_SIMILAR, hideSimilarBox.isSelected()); + updateData(); + } + }); + panel.add(hideSimilarBox, "gapleft para, spanx, growx, wrap"); + } + + //// Motor selection table + { + table = new JTable(model); + + // Set comparators and widths + table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + sorter = new TableRowSorter(model); + for (int i = 0; i < ThrustCurveMotorColumns.values().length; i++) { + ThrustCurveMotorColumns column = ThrustCurveMotorColumns.values()[i]; + sorter.setComparator(i, column.getComparator()); + table.getColumnModel().getColumn(i).setPreferredWidth(column.getWidth()); + } + table.setRowSorter(sorter); + // force initial sort order to by diameter, total impulse, manufacturer + { + RowSorter.SortKey[] sortKeys = { + new RowSorter.SortKey(ThrustCurveMotorColumns.DIAMETER.ordinal(), SortOrder.ASCENDING), + new RowSorter.SortKey(ThrustCurveMotorColumns.TOTAL_IMPULSE.ordinal(), SortOrder.ASCENDING), + new RowSorter.SortKey(ThrustCurveMotorColumns.MANUFACTURER.ordinal(), SortOrder.ASCENDING) + }; + sorter.setSortKeys(Arrays.asList(sortKeys)); + } + + sorter.setRowFilter(rowFilter); + + // Set selection and double-click listeners + table.getSelectionModel().addListSelectionListener(new ListSelectionListener() { + @Override + public void valueChanged(ListSelectionEvent e) { + int row = table.getSelectedRow(); + if (row >= 0) { + row = table.convertRowIndexToModel(row); + ThrustCurveMotorSet motorSet = model.getMotorSet(row); + log.info(Markers.USER_MARKER, "Selected table row " + row + ": " + motorSet); + if (motorSet != selectedMotorSet) { + select(selectMotor(motorSet)); + } + } else { + log.info(Markers.USER_MARKER, "Selected table row " + row + ", nothing selected"); + } + } + }); + table.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 2) { + if (dialog != null) { + dialog.close(true); + } + } + } + }); + + JScrollPane scrollpane = new JScrollPane(); + scrollpane.setViewportView(table); + panel.add(scrollpane, "grow, width :500:, height :300:, spanx, wrap"); + + } + + // Search field + { + //// Search: + StyledLabel label = new StyledLabel(trans.get("TCMotorSelPan.lbl.Search")); + panel.add(label); + searchField = new JTextField(); + searchField.getDocument().addDocumentListener(new DocumentListener() { + @Override + public void changedUpdate(DocumentEvent e) { + update(); + } + @Override + public void insertUpdate(DocumentEvent e) { + update(); + } + @Override + public void removeUpdate(DocumentEvent e) { + update(); + } + private void update() { + String text = searchField.getText().trim(); + String[] split = text.split("\\s+"); + rowFilter.setSearchTerms(Arrays.asList(split)); + sorter.sort(); + scrollSelectionVisible(); + } + }); + panel.add(searchField, "span, growx"); + } + this.add(panel, "grow"); + + // Vertical split + this.add(new JSeparator(JSeparator.VERTICAL), "growy, gap para para"); + + JTabbedPane rightSide = new JTabbedPane(); + rightSide.add(trans.get("TCMotorSelPan.btn.filter"), motorFilterPanel); + rightSide.add(trans.get("TCMotorSelPan.btn.details"), motorInformationPanel); + + this.add(rightSide); + + // Update the panel data + scrollSelectionVisible(); + updateData(); + setDelays(false); + + } + + public void setMotorMountAndConfig( MotorMount mount, String currentConfig ) { + double diameter = 0; + + if ( mount != null ) { + diameter = mount.getMotorMountDiameter(); + } + + if (currentConfig != null && mount != null) { + MotorConfiguration motorConf = mount.getMotorConfiguration().get(currentConfig); + selectedMotor = (ThrustCurveMotor) motorConf.getMotor(); + selectedDelay = motorConf.getEjectionDelay(); + diameter = mount.getMotorMountDiameter(); + } + + // If current motor is not found in db, add a new ThrustCurveMotorSet containing it + if (selectedMotor != null) { + for (ThrustCurveMotorSet motorSet : database) { + if (motorSet.getMotors().contains(selectedMotor)) { + selectedMotorSet = motorSet; + break; + } + } + if (selectedMotorSet == null) { + database = new ArrayList(database); + ThrustCurveMotorSet extra = new ThrustCurveMotorSet(); + extra.addMotor(selectedMotor); + selectedMotorSet = extra; + database.add(extra); + Collections.sort(database); + } + } + + updateData(); + setDelays(true); + + motorFilterPanel.setMotorMount(mount); + scrollSelectionVisible(); + + } + + @Override + public Motor getSelectedMotor() { + return selectedMotor; + } + + + @Override + public double getSelectedDelay() { + return selectedDelay; + } + + + @Override + public JComponent getDefaultFocus() { + return searchField; + } + + @Override + public void selectedMotor(Motor motorSelection) { + if (!(motorSelection instanceof ThrustCurveMotor)) { + log.error("Received argument that was not ThrustCurveMotor: " + motorSelection); + return; + } + + ThrustCurveMotor motor = (ThrustCurveMotor) motorSelection; + ThrustCurveMotorSet set = findMotorSet(motor); + if (set == null) { + log.error("Could not find set for motor:" + motorSelection); + return; + } + + // Store selected motor in preferences node, set all others to false + Preferences prefs = ((SwingPreferences) Application.getPreferences()).getNode(net.sf.openrocket.startup.Preferences.PREFERRED_THRUST_CURVE_MOTOR_NODE); + for (ThrustCurveMotor m : set.getMotors()) { + String digest = m.getDigest(); + prefs.putBoolean(digest, m == motor); + } + } + + public void setCloseableDialog(CloseableDialog dialog) { + this.dialog = dialog; + } + + + + /** + * Called when a different motor is selected from within the panel. + */ + private void select(ThrustCurveMotor motor) { + if (selectedMotor == motor) + return; + + ThrustCurveMotorSet set = findMotorSet(motor); + if (set == null) { + throw new BugException("Could not find motor from database, motor=" + motor); + } + + boolean updateDelays = (selectedMotorSet != set); + + selectedMotor = motor; + selectedMotorSet = set; + updateData(); + if (updateDelays) { + setDelays(true); + } + } + + + private void updateData() { + + if (selectedMotorSet == null) { + // No motor selected + curveSelectionModel.removeAllElements(); + curveSelectionBox.setEnabled(false); + curveSelectionLabel.setEnabled(false); + motorInformationPanel.clearData(); + return; + } + + // Check which thrust curves to display + List motors = getFilteredCurves(); + final int index = motors.indexOf(selectedMotor); + + // Update the thrust curve selection box + curveSelectionModel.removeAllElements(); + for (int i = 0; i < motors.size(); i++) { + curveSelectionModel.addElement(new MotorHolder(motors.get(i), i)); + } + curveSelectionBox.setSelectedIndex(index); + + if (motors.size() > 1) { + curveSelectionBox.setEnabled(true); + curveSelectionLabel.setEnabled(true); + } else { + curveSelectionBox.setEnabled(false); + curveSelectionLabel.setEnabled(false); + } + + motorInformationPanel.updateData(motors, selectedMotor); + + } + + List getFilteredCurves() { + List motors = selectedMotorSet.getMotors(); + if (hideSimilarBox.isSelected() && selectedMotor != null) { + List filtered = new ArrayList(motors.size()); + for (int i = 0; i < motors.size(); i++) { + ThrustCurveMotor m = motors.get(i); + if (m.equals(selectedMotor)) { + filtered.add(m); + continue; + } + double similarity = MotorCorrelation.similarity(selectedMotor, m); + log.debug("Motor similarity: " + similarity); + if (similarity < MOTOR_SIMILARITY_THRESHOLD) { + filtered.add(m); + } + } + motors = filtered; + } + + Collections.sort(motors, MOTOR_COMPARATOR); + + return motors; + } + + + private void scrollSelectionVisible() { + if (selectedMotorSet != null) { + int index = table.convertRowIndexToView(model.getIndex(selectedMotorSet)); + //System.out.println("index=" + index); + table.getSelectionModel().setSelectionInterval(index, index); + Rectangle rect = table.getCellRect(index, 0, true); + rect = new Rectangle(rect.x, rect.y - 100, rect.width, rect.height + 200); + table.scrollRectToVisible(rect); + } + } + + + public static Color getColor(int index) { + return (Color) CURVE_COLORS[index % CURVE_COLORS.length]; + } + + + /** + * Find the ThrustCurveMotorSet that contains a motor. + * + * @param motor the motor to look for. + * @return the ThrustCurveMotorSet, or null if not found. + */ + private ThrustCurveMotorSet findMotorSet(ThrustCurveMotor motor) { + for (ThrustCurveMotorSet set : database) { + if (set.getMotors().contains(motor)) { + return set; + } + } + + return null; + } + + + + /** + * Select the default motor from this ThrustCurveMotorSet. This uses primarily motors + * that the user has previously used, and secondarily a heuristic method of selecting which + * thrust curve seems to be better or more reliable. + * + * @param set the motor set + * @return the default motor in this set + */ + private ThrustCurveMotor selectMotor(ThrustCurveMotorSet set) { + if (set.getMotorCount() == 0) { + throw new BugException("Attempting to select motor from empty ThrustCurveMotorSet: " + set); + } + if (set.getMotorCount() == 1) { + return set.getMotors().get(0); + } + + + // Find which motor has been used the most recently + List list = set.getMotors(); + Preferences prefs = ((SwingPreferences) Application.getPreferences()).getNode(net.sf.openrocket.startup.Preferences.PREFERRED_THRUST_CURVE_MOTOR_NODE); + for (ThrustCurveMotor m : list) { + String digest = m.getDigest(); + if (prefs.getBoolean(digest, false)) { + return m; + } + } + + // No motor has been used + Collections.sort(list, MOTOR_COMPARATOR); + return list.get(0); + } + + + /** + * Set the values in the delay combo box. If reset is true + * then sets the selected value as the value closest to selectedDelay, otherwise + * leaves selection alone. + */ + private void setDelays(boolean reset) { + if (selectedMotor == null) { + + //// None + delayBox.setModel(new DefaultComboBoxModel(new String[] { trans.get("TCMotorSelPan.delayBox.None") })); + delayBox.setSelectedIndex(0); + + } else { + + List delays = selectedMotorSet.getDelays(); + String[] delayStrings = new String[delays.size()]; + double currentDelay = selectedDelay; // Store current setting locally + + for (int i = 0; i < delays.size(); i++) { + //// None + delayStrings[i] = ThrustCurveMotor.getDelayString(delays.get(i), trans.get("TCMotorSelPan.delayBox.None")); + } + delayBox.setModel(new DefaultComboBoxModel(delayStrings)); + + if (reset) { + + // Find and set the closest value + double closest = Double.NaN; + for (int i = 0; i < delays.size(); i++) { + // if-condition to always become true for NaN + if (!(Math.abs(delays.get(i) - currentDelay) > Math.abs(closest - currentDelay))) { + closest = delays.get(i); + } + } + if (!Double.isNaN(closest)) { + selectedDelay = closest; + //// None + delayBox.setSelectedItem(ThrustCurveMotor.getDelayString(closest, trans.get("TCMotorSelPan.delayBox.None"))); + } else { + delayBox.setSelectedItem("None"); + } + + } else { + + selectedDelay = currentDelay; + //// None + delayBox.setSelectedItem(ThrustCurveMotor.getDelayString(currentDelay, trans.get("TCMotorSelPan.delayBox.None"))); + + } + + } + } + + ////////////////////// + + + private class CurveSelectionRenderer implements ListCellRenderer { + + private final ListCellRenderer renderer; + + public CurveSelectionRenderer(ListCellRenderer renderer) { + this.renderer = renderer; + } + + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, + boolean isSelected, boolean cellHasFocus) { + + Component c = renderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + if (value instanceof MotorHolder) { + MotorHolder m = (MotorHolder) value; + c.setForeground(getColor(m.getIndex())); + } + + return c; + } + + } + + +} diff --git a/core/src/net/sf/openrocket/gui/dialogs/optimization/FunctionEvaluationData.java b/swing/src/net/sf/openrocket/gui/dialogs/optimization/FunctionEvaluationData.java similarity index 100% rename from core/src/net/sf/openrocket/gui/dialogs/optimization/FunctionEvaluationData.java rename to swing/src/net/sf/openrocket/gui/dialogs/optimization/FunctionEvaluationData.java diff --git a/core/src/net/sf/openrocket/gui/dialogs/optimization/GeneralOptimizationDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/optimization/GeneralOptimizationDialog.java similarity index 100% rename from core/src/net/sf/openrocket/gui/dialogs/optimization/GeneralOptimizationDialog.java rename to swing/src/net/sf/openrocket/gui/dialogs/optimization/GeneralOptimizationDialog.java diff --git a/core/src/net/sf/openrocket/gui/dialogs/optimization/OptimizationPlotDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/optimization/OptimizationPlotDialog.java similarity index 100% rename from core/src/net/sf/openrocket/gui/dialogs/optimization/OptimizationPlotDialog.java rename to swing/src/net/sf/openrocket/gui/dialogs/optimization/OptimizationPlotDialog.java diff --git a/core/src/net/sf/openrocket/gui/dialogs/optimization/OptimizationStepData.java b/swing/src/net/sf/openrocket/gui/dialogs/optimization/OptimizationStepData.java similarity index 100% rename from core/src/net/sf/openrocket/gui/dialogs/optimization/OptimizationStepData.java rename to swing/src/net/sf/openrocket/gui/dialogs/optimization/OptimizationStepData.java diff --git a/core/src/net/sf/openrocket/gui/dialogs/optimization/OptimizationWorker.java b/swing/src/net/sf/openrocket/gui/dialogs/optimization/OptimizationWorker.java similarity index 100% rename from core/src/net/sf/openrocket/gui/dialogs/optimization/OptimizationWorker.java rename to swing/src/net/sf/openrocket/gui/dialogs/optimization/OptimizationWorker.java diff --git a/core/src/net/sf/openrocket/gui/dialogs/optimization/SimulationModifierTree.java b/swing/src/net/sf/openrocket/gui/dialogs/optimization/SimulationModifierTree.java similarity index 100% rename from core/src/net/sf/openrocket/gui/dialogs/optimization/SimulationModifierTree.java rename to swing/src/net/sf/openrocket/gui/dialogs/optimization/SimulationModifierTree.java diff --git a/core/src/net/sf/openrocket/gui/dialogs/preferences/MaterialEditPanel.java b/swing/src/net/sf/openrocket/gui/dialogs/preferences/MaterialEditPanel.java similarity index 100% rename from core/src/net/sf/openrocket/gui/dialogs/preferences/MaterialEditPanel.java rename to swing/src/net/sf/openrocket/gui/dialogs/preferences/MaterialEditPanel.java diff --git a/core/src/net/sf/openrocket/gui/dialogs/preferences/PreferencesDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/preferences/PreferencesDialog.java similarity index 100% rename from core/src/net/sf/openrocket/gui/dialogs/preferences/PreferencesDialog.java rename to swing/src/net/sf/openrocket/gui/dialogs/preferences/PreferencesDialog.java diff --git a/core/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetChooserDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetChooserDialog.java similarity index 100% rename from core/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetChooserDialog.java rename to swing/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetChooserDialog.java diff --git a/core/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetRowFilter.java b/swing/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetRowFilter.java similarity index 100% rename from core/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetRowFilter.java rename to swing/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetRowFilter.java diff --git a/core/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetTable.java b/swing/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetTable.java similarity index 100% rename from core/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetTable.java rename to swing/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetTable.java diff --git a/core/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetTableColumn.java b/swing/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetTableColumn.java similarity index 100% rename from core/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetTableColumn.java rename to swing/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetTableColumn.java diff --git a/core/src/net/sf/openrocket/gui/dialogs/preset/XTableColumnModel.java b/swing/src/net/sf/openrocket/gui/dialogs/preset/XTableColumnModel.java similarity index 100% rename from core/src/net/sf/openrocket/gui/dialogs/preset/XTableColumnModel.java rename to swing/src/net/sf/openrocket/gui/dialogs/preset/XTableColumnModel.java diff --git a/core/src/net/sf/openrocket/gui/figure3d/FigureRenderer.java b/swing/src/net/sf/openrocket/gui/figure3d/FigureRenderer.java similarity index 100% rename from core/src/net/sf/openrocket/gui/figure3d/FigureRenderer.java rename to swing/src/net/sf/openrocket/gui/figure3d/FigureRenderer.java diff --git a/core/src/net/sf/openrocket/gui/figure3d/RealisticRenderer.java b/swing/src/net/sf/openrocket/gui/figure3d/RealisticRenderer.java similarity index 100% rename from core/src/net/sf/openrocket/gui/figure3d/RealisticRenderer.java rename to swing/src/net/sf/openrocket/gui/figure3d/RealisticRenderer.java diff --git a/core/src/net/sf/openrocket/gui/figure3d/RocketFigure3d.java b/swing/src/net/sf/openrocket/gui/figure3d/RocketFigure3d.java similarity index 100% rename from core/src/net/sf/openrocket/gui/figure3d/RocketFigure3d.java rename to swing/src/net/sf/openrocket/gui/figure3d/RocketFigure3d.java diff --git a/core/src/net/sf/openrocket/gui/figure3d/RocketRenderer.java b/swing/src/net/sf/openrocket/gui/figure3d/RocketRenderer.java similarity index 100% rename from core/src/net/sf/openrocket/gui/figure3d/RocketRenderer.java rename to swing/src/net/sf/openrocket/gui/figure3d/RocketRenderer.java diff --git a/core/src/net/sf/openrocket/gui/figure3d/UnfinishedRenderer.java b/swing/src/net/sf/openrocket/gui/figure3d/UnfinishedRenderer.java similarity index 100% rename from core/src/net/sf/openrocket/gui/figure3d/UnfinishedRenderer.java rename to swing/src/net/sf/openrocket/gui/figure3d/UnfinishedRenderer.java diff --git a/core/src/net/sf/openrocket/gui/figure3d/geometry/ComponentRenderer.java b/swing/src/net/sf/openrocket/gui/figure3d/geometry/ComponentRenderer.java similarity index 100% rename from core/src/net/sf/openrocket/gui/figure3d/geometry/ComponentRenderer.java rename to swing/src/net/sf/openrocket/gui/figure3d/geometry/ComponentRenderer.java diff --git a/core/src/net/sf/openrocket/gui/figure3d/geometry/DisplayListComponentRenderer.java b/swing/src/net/sf/openrocket/gui/figure3d/geometry/DisplayListComponentRenderer.java similarity index 100% rename from core/src/net/sf/openrocket/gui/figure3d/geometry/DisplayListComponentRenderer.java rename to swing/src/net/sf/openrocket/gui/figure3d/geometry/DisplayListComponentRenderer.java diff --git a/core/src/net/sf/openrocket/gui/figure3d/geometry/FinRenderer.java b/swing/src/net/sf/openrocket/gui/figure3d/geometry/FinRenderer.java similarity index 100% rename from core/src/net/sf/openrocket/gui/figure3d/geometry/FinRenderer.java rename to swing/src/net/sf/openrocket/gui/figure3d/geometry/FinRenderer.java diff --git a/core/src/net/sf/openrocket/gui/figure3d/geometry/Geometry.java b/swing/src/net/sf/openrocket/gui/figure3d/geometry/Geometry.java similarity index 100% rename from core/src/net/sf/openrocket/gui/figure3d/geometry/Geometry.java rename to swing/src/net/sf/openrocket/gui/figure3d/geometry/Geometry.java diff --git a/core/src/net/sf/openrocket/gui/figure3d/geometry/MassObjectRenderer.java b/swing/src/net/sf/openrocket/gui/figure3d/geometry/MassObjectRenderer.java similarity index 100% rename from core/src/net/sf/openrocket/gui/figure3d/geometry/MassObjectRenderer.java rename to swing/src/net/sf/openrocket/gui/figure3d/geometry/MassObjectRenderer.java diff --git a/core/src/net/sf/openrocket/gui/figure3d/geometry/TransitionRenderer.java b/swing/src/net/sf/openrocket/gui/figure3d/geometry/TransitionRenderer.java similarity index 100% rename from core/src/net/sf/openrocket/gui/figure3d/geometry/TransitionRenderer.java rename to swing/src/net/sf/openrocket/gui/figure3d/geometry/TransitionRenderer.java diff --git a/core/src/net/sf/openrocket/gui/figureelements/CGCaret.java b/swing/src/net/sf/openrocket/gui/figureelements/CGCaret.java similarity index 100% rename from core/src/net/sf/openrocket/gui/figureelements/CGCaret.java rename to swing/src/net/sf/openrocket/gui/figureelements/CGCaret.java diff --git a/core/src/net/sf/openrocket/gui/figureelements/CPCaret.java b/swing/src/net/sf/openrocket/gui/figureelements/CPCaret.java similarity index 100% rename from core/src/net/sf/openrocket/gui/figureelements/CPCaret.java rename to swing/src/net/sf/openrocket/gui/figureelements/CPCaret.java diff --git a/core/src/net/sf/openrocket/gui/figureelements/Caret.java b/swing/src/net/sf/openrocket/gui/figureelements/Caret.java similarity index 100% rename from core/src/net/sf/openrocket/gui/figureelements/Caret.java rename to swing/src/net/sf/openrocket/gui/figureelements/Caret.java diff --git a/core/src/net/sf/openrocket/gui/figureelements/FigureElement.java b/swing/src/net/sf/openrocket/gui/figureelements/FigureElement.java similarity index 100% rename from core/src/net/sf/openrocket/gui/figureelements/FigureElement.java rename to swing/src/net/sf/openrocket/gui/figureelements/FigureElement.java diff --git a/core/src/net/sf/openrocket/gui/figureelements/RocketInfo.java b/swing/src/net/sf/openrocket/gui/figureelements/RocketInfo.java similarity index 100% rename from core/src/net/sf/openrocket/gui/figureelements/RocketInfo.java rename to swing/src/net/sf/openrocket/gui/figureelements/RocketInfo.java diff --git a/core/src/net/sf/openrocket/gui/help/tours/GuidedTourSelectionDialog.java b/swing/src/net/sf/openrocket/gui/help/tours/GuidedTourSelectionDialog.java similarity index 100% rename from core/src/net/sf/openrocket/gui/help/tours/GuidedTourSelectionDialog.java rename to swing/src/net/sf/openrocket/gui/help/tours/GuidedTourSelectionDialog.java diff --git a/core/src/net/sf/openrocket/gui/help/tours/Slide.java b/swing/src/net/sf/openrocket/gui/help/tours/Slide.java similarity index 100% rename from core/src/net/sf/openrocket/gui/help/tours/Slide.java rename to swing/src/net/sf/openrocket/gui/help/tours/Slide.java diff --git a/core/src/net/sf/openrocket/gui/help/tours/SlideSet.java b/swing/src/net/sf/openrocket/gui/help/tours/SlideSet.java similarity index 100% rename from core/src/net/sf/openrocket/gui/help/tours/SlideSet.java rename to swing/src/net/sf/openrocket/gui/help/tours/SlideSet.java diff --git a/core/src/net/sf/openrocket/gui/help/tours/SlideSetLoader.java b/swing/src/net/sf/openrocket/gui/help/tours/SlideSetLoader.java similarity index 100% rename from core/src/net/sf/openrocket/gui/help/tours/SlideSetLoader.java rename to swing/src/net/sf/openrocket/gui/help/tours/SlideSetLoader.java diff --git a/core/src/net/sf/openrocket/gui/help/tours/SlideSetManager.java b/swing/src/net/sf/openrocket/gui/help/tours/SlideSetManager.java similarity index 100% rename from core/src/net/sf/openrocket/gui/help/tours/SlideSetManager.java rename to swing/src/net/sf/openrocket/gui/help/tours/SlideSetManager.java diff --git a/core/src/net/sf/openrocket/gui/help/tours/SlideShowComponent.java b/swing/src/net/sf/openrocket/gui/help/tours/SlideShowComponent.java similarity index 100% rename from core/src/net/sf/openrocket/gui/help/tours/SlideShowComponent.java rename to swing/src/net/sf/openrocket/gui/help/tours/SlideShowComponent.java diff --git a/core/src/net/sf/openrocket/gui/help/tours/SlideShowDialog.java b/swing/src/net/sf/openrocket/gui/help/tours/SlideShowDialog.java similarity index 100% rename from core/src/net/sf/openrocket/gui/help/tours/SlideShowDialog.java rename to swing/src/net/sf/openrocket/gui/help/tours/SlideShowDialog.java diff --git a/core/src/net/sf/openrocket/gui/help/tours/SlideShowLinkListener.java b/swing/src/net/sf/openrocket/gui/help/tours/SlideShowLinkListener.java similarity index 100% rename from core/src/net/sf/openrocket/gui/help/tours/SlideShowLinkListener.java rename to swing/src/net/sf/openrocket/gui/help/tours/SlideShowLinkListener.java diff --git a/core/src/net/sf/openrocket/gui/help/tours/TextLineReader.java b/swing/src/net/sf/openrocket/gui/help/tours/TextLineReader.java similarity index 100% rename from core/src/net/sf/openrocket/gui/help/tours/TextLineReader.java rename to swing/src/net/sf/openrocket/gui/help/tours/TextLineReader.java diff --git a/core/src/net/sf/openrocket/gui/main/BasicFrame.java b/swing/src/net/sf/openrocket/gui/main/BasicFrame.java similarity index 99% rename from core/src/net/sf/openrocket/gui/main/BasicFrame.java rename to swing/src/net/sf/openrocket/gui/main/BasicFrame.java index e44fa0c24..0b754ef7e 100644 --- a/core/src/net/sf/openrocket/gui/main/BasicFrame.java +++ b/swing/src/net/sf/openrocket/gui/main/BasicFrame.java @@ -83,6 +83,7 @@ import net.sf.openrocket.gui.dialogs.optimization.GeneralOptimizationDialog; import net.sf.openrocket.gui.dialogs.preferences.PreferencesDialog; import net.sf.openrocket.gui.help.tours.GuidedTourSelectionDialog; import net.sf.openrocket.gui.main.componenttree.ComponentTree; +import net.sf.openrocket.gui.main.flightconfigpanel.FlightConfigurationPanel; import net.sf.openrocket.gui.scalefigure.RocketPanel; import net.sf.openrocket.gui.util.FileHelper; import net.sf.openrocket.gui.util.GUIUtil; @@ -100,10 +101,10 @@ import net.sf.openrocket.startup.Application; import net.sf.openrocket.util.BugException; import net.sf.openrocket.util.MemoryManagement; import net.sf.openrocket.util.MemoryManagement.MemoryData; -import net.sf.openrocket.utils.ComponentPresetEditor; import net.sf.openrocket.util.Reflection; import net.sf.openrocket.util.StateChangeListener; import net.sf.openrocket.util.TestRockets; +import net.sf.openrocket.utils.ComponentPresetEditor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -195,6 +196,8 @@ public class BasicFrame extends JFrame { tabbedPane = new JTabbedPane(); //// Rocket design tabbedPane.addTab(trans.get("BasicFrame.tab.Rocketdesign"), null, designTab()); + //// Flight configurations + tabbedPane.addTab(trans.get("BasicFrame.tab.Flightconfig"), null, new FlightConfigurationPanel(document)); //// Flight simulations tabbedPane.addTab(trans.get("BasicFrame.tab.Flightsim"), null, simulationPanel); @@ -251,7 +254,6 @@ public class BasicFrame extends JFrame { log.debug("BasicFrame instantiation complete"); } - /** * Construct the "Rocket design" tab. This contains a horizontal split pane * with the left component the design tree and the right component buttons diff --git a/core/src/net/sf/openrocket/gui/main/ClipboardListener.java b/swing/src/net/sf/openrocket/gui/main/ClipboardListener.java similarity index 100% rename from core/src/net/sf/openrocket/gui/main/ClipboardListener.java rename to swing/src/net/sf/openrocket/gui/main/ClipboardListener.java diff --git a/core/src/net/sf/openrocket/gui/main/ComponentAddButtons.java b/swing/src/net/sf/openrocket/gui/main/ComponentAddButtons.java similarity index 100% rename from core/src/net/sf/openrocket/gui/main/ComponentAddButtons.java rename to swing/src/net/sf/openrocket/gui/main/ComponentAddButtons.java diff --git a/core/src/net/sf/openrocket/gui/main/ComponentIcons.java b/swing/src/net/sf/openrocket/gui/main/ComponentIcons.java similarity index 100% rename from core/src/net/sf/openrocket/gui/main/ComponentIcons.java rename to swing/src/net/sf/openrocket/gui/main/ComponentIcons.java diff --git a/core/src/net/sf/openrocket/gui/main/DocumentSelectionListener.java b/swing/src/net/sf/openrocket/gui/main/DocumentSelectionListener.java similarity index 100% rename from core/src/net/sf/openrocket/gui/main/DocumentSelectionListener.java rename to swing/src/net/sf/openrocket/gui/main/DocumentSelectionListener.java diff --git a/core/src/net/sf/openrocket/gui/main/DocumentSelectionModel.java b/swing/src/net/sf/openrocket/gui/main/DocumentSelectionModel.java similarity index 100% rename from core/src/net/sf/openrocket/gui/main/DocumentSelectionModel.java rename to swing/src/net/sf/openrocket/gui/main/DocumentSelectionModel.java diff --git a/core/src/net/sf/openrocket/gui/main/ExampleDesignFile.java b/swing/src/net/sf/openrocket/gui/main/ExampleDesignFile.java similarity index 100% rename from core/src/net/sf/openrocket/gui/main/ExampleDesignFile.java rename to swing/src/net/sf/openrocket/gui/main/ExampleDesignFile.java diff --git a/core/src/net/sf/openrocket/gui/main/ExampleDesignFileAction.java b/swing/src/net/sf/openrocket/gui/main/ExampleDesignFileAction.java similarity index 100% rename from core/src/net/sf/openrocket/gui/main/ExampleDesignFileAction.java rename to swing/src/net/sf/openrocket/gui/main/ExampleDesignFileAction.java diff --git a/core/src/net/sf/openrocket/gui/main/MRUDesignFile.java b/swing/src/net/sf/openrocket/gui/main/MRUDesignFile.java similarity index 100% rename from core/src/net/sf/openrocket/gui/main/MRUDesignFile.java rename to swing/src/net/sf/openrocket/gui/main/MRUDesignFile.java diff --git a/core/src/net/sf/openrocket/gui/main/MRUDesignFileAction.java b/swing/src/net/sf/openrocket/gui/main/MRUDesignFileAction.java similarity index 100% rename from core/src/net/sf/openrocket/gui/main/MRUDesignFileAction.java rename to swing/src/net/sf/openrocket/gui/main/MRUDesignFileAction.java diff --git a/core/src/net/sf/openrocket/gui/main/OpenRocketClipboard.java b/swing/src/net/sf/openrocket/gui/main/OpenRocketClipboard.java similarity index 100% rename from core/src/net/sf/openrocket/gui/main/OpenRocketClipboard.java rename to swing/src/net/sf/openrocket/gui/main/OpenRocketClipboard.java diff --git a/core/src/net/sf/openrocket/gui/main/RocketActions.java b/swing/src/net/sf/openrocket/gui/main/RocketActions.java similarity index 100% rename from core/src/net/sf/openrocket/gui/main/RocketActions.java rename to swing/src/net/sf/openrocket/gui/main/RocketActions.java diff --git a/core/src/net/sf/openrocket/gui/main/SimulationPanel.java b/swing/src/net/sf/openrocket/gui/main/SimulationPanel.java similarity index 100% rename from core/src/net/sf/openrocket/gui/main/SimulationPanel.java rename to swing/src/net/sf/openrocket/gui/main/SimulationPanel.java diff --git a/core/src/net/sf/openrocket/gui/main/Splash.java b/swing/src/net/sf/openrocket/gui/main/Splash.java similarity index 100% rename from core/src/net/sf/openrocket/gui/main/Splash.java rename to swing/src/net/sf/openrocket/gui/main/Splash.java diff --git a/core/src/net/sf/openrocket/gui/main/SwingExceptionHandler.java b/swing/src/net/sf/openrocket/gui/main/SwingExceptionHandler.java similarity index 100% rename from core/src/net/sf/openrocket/gui/main/SwingExceptionHandler.java rename to swing/src/net/sf/openrocket/gui/main/SwingExceptionHandler.java diff --git a/core/src/net/sf/openrocket/gui/main/UndoRedoAction.java b/swing/src/net/sf/openrocket/gui/main/UndoRedoAction.java similarity index 100% rename from core/src/net/sf/openrocket/gui/main/UndoRedoAction.java rename to swing/src/net/sf/openrocket/gui/main/UndoRedoAction.java diff --git a/core/src/net/sf/openrocket/gui/main/componenttree/ComponentTree.java b/swing/src/net/sf/openrocket/gui/main/componenttree/ComponentTree.java similarity index 100% rename from core/src/net/sf/openrocket/gui/main/componenttree/ComponentTree.java rename to swing/src/net/sf/openrocket/gui/main/componenttree/ComponentTree.java diff --git a/core/src/net/sf/openrocket/gui/main/componenttree/ComponentTreeModel.java b/swing/src/net/sf/openrocket/gui/main/componenttree/ComponentTreeModel.java similarity index 100% rename from core/src/net/sf/openrocket/gui/main/componenttree/ComponentTreeModel.java rename to swing/src/net/sf/openrocket/gui/main/componenttree/ComponentTreeModel.java diff --git a/core/src/net/sf/openrocket/gui/main/componenttree/ComponentTreeRenderer.java b/swing/src/net/sf/openrocket/gui/main/componenttree/ComponentTreeRenderer.java similarity index 100% rename from core/src/net/sf/openrocket/gui/main/componenttree/ComponentTreeRenderer.java rename to swing/src/net/sf/openrocket/gui/main/componenttree/ComponentTreeRenderer.java diff --git a/core/src/net/sf/openrocket/gui/main/componenttree/ComponentTreeTransferHandler.java b/swing/src/net/sf/openrocket/gui/main/componenttree/ComponentTreeTransferHandler.java similarity index 100% rename from core/src/net/sf/openrocket/gui/main/componenttree/ComponentTreeTransferHandler.java rename to swing/src/net/sf/openrocket/gui/main/componenttree/ComponentTreeTransferHandler.java diff --git a/core/src/net/sf/openrocket/gui/main/componenttree/RocketComponentTransferable.java b/swing/src/net/sf/openrocket/gui/main/componenttree/RocketComponentTransferable.java similarity index 100% rename from core/src/net/sf/openrocket/gui/main/componenttree/RocketComponentTransferable.java rename to swing/src/net/sf/openrocket/gui/main/componenttree/RocketComponentTransferable.java diff --git a/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/FlightConfigurablePanel.java b/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/FlightConfigurablePanel.java new file mode 100644 index 000000000..4cfa8413a --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/FlightConfigurablePanel.java @@ -0,0 +1,173 @@ +package net.sf.openrocket.gui.main.flightconfigpanel; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Font; +import java.util.EventObject; + +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTable; +import javax.swing.ListSelectionModel; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.table.DefaultTableCellRenderer; + +import net.miginfocom.swing.MigLayout; +import net.sf.openrocket.formatting.RocketDescriptor; +import net.sf.openrocket.gui.util.GUIUtil; +import net.sf.openrocket.l10n.Translator; +import net.sf.openrocket.rocketcomponent.FlightConfigurableComponent; +import net.sf.openrocket.rocketcomponent.MotorConfiguration; +import net.sf.openrocket.rocketcomponent.MotorMount; +import net.sf.openrocket.rocketcomponent.Rocket; +import net.sf.openrocket.startup.Application; +import net.sf.openrocket.util.Pair; +import net.sf.openrocket.util.StateChangeListener; + +public abstract class FlightConfigurablePanel extends JPanel { + + protected static final Translator trans = Application.getTranslator(); + protected RocketDescriptor descriptor = Application.getInjector().getInstance(RocketDescriptor.class); + + protected final FlightConfigurationPanel flightConfigurationPanel; + protected final Rocket rocket; + protected final JTable table; + + public FlightConfigurablePanel(final FlightConfigurationPanel flightConfigurationPanel, Rocket rocket) { + super(new MigLayout("fill")); + this.flightConfigurationPanel = flightConfigurationPanel; + this.rocket = rocket; + table = initializeTable(); + rocket.getDefaultConfiguration().addChangeListener( new StateChangeListener() { + @Override + public void stateChanged(EventObject e) { + FlightConfigurablePanel.this.synchronizeConfigurationSelection(); + } + }); + installTableListener(); + synchronizeConfigurationSelection(); + } + + protected final void synchronizeConfigurationSelection() { + String id = rocket.getDefaultConfiguration().getFlightConfigurationID(); + + String selectedId = getSelectedConfigurationId(); + if ( id == null && selectedId == null ) { + // Nothing to do + } else if ( id == null ) { + // need to unselect + table.clearSelection(); + } else if ( !id.equals(selectedId)){ + // Need to change selection + // We'll select the correct row, in the currently selected column. + int col = table.getSelectedColumn(); + if ( col < 0 ) { + col = (table.getColumnCount() > 1) ? 1 : 0; + } + for( int row = 0; row < table.getRowCount(); row++ ) { + String rowId = rocket.getFlightConfigurationIDs()[row + 1]; + if ( rowId.equals(id) ) { + table.changeSelection(row, col, true, false); + } + } + } + } + + private final void installTableListener() { + table.getSelectionModel().addListSelectionListener(new ListSelectionListener() { + + @Override + public void valueChanged(ListSelectionEvent e) { + if ( e.getValueIsAdjusting() ) { + return; + } + int firstrow = e.getFirstIndex(); + int lastrow = e.getLastIndex(); + ListSelectionModel model = (ListSelectionModel) e.getSource(); + for( int row = firstrow; row <= lastrow; row ++) { + if ( model.isSelectedIndex(row) ) { + String id = (String) table.getValueAt(row, 0); + rocket.getDefaultConfiguration().setFlightConfigurationID(id); + return; + } + } + } + + }); + } + + /** + * Override this method to create the embedded JTable and it's backing Model. + * + * @return + */ + protected abstract JTable initializeTable(); + + protected T getSelectedComponent() { + + int col = table.getSelectedColumn(); + int row = table.getSelectedRow(); + if ( row < 0 || col < 0 ) { + return null; + } + Object tableValue = table.getModel().getValueAt(row, col); + if ( tableValue instanceof Pair ) { + Pair selectedComponent = (Pair) tableValue; + return selectedComponent.getV(); + } + return null; + } + + protected String getSelectedConfigurationId() { + int col = table.getSelectedColumn(); + int row = table.getSelectedRow(); + if ( row < 0 || col < 0 ) { + return null; + } + Object tableValue = table.getModel().getValueAt(row, col); + if ( tableValue instanceof Pair ) { + Pair selectedComponent = (Pair) tableValue; + return selectedComponent.getU(); + } else if ( tableValue instanceof String ){ + return (String) tableValue; + } + return null; + } + + protected abstract class FlightConfigurableCellRenderer extends DefaultTableCellRenderer { + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + JLabel label = (JLabel) c; + + switch (column) { + case 0: { + label.setText(descriptor.format(rocket, (String) value)); + return label; + } + default: { + Pair v = (Pair) value; + String id = v.getU(); + T component = v.getV(); + format(component, id, label ); + return label; + } + } + } + + protected final void shaded(JLabel label) { + GUIUtil.changeFontStyle(label, Font.ITALIC); + label.setForeground(Color.GRAY); + } + + protected final void regular(JLabel label) { + GUIUtil.changeFontStyle(label, Font.PLAIN); + label.setForeground(Color.BLACK); + } + + protected abstract void format( T component, String configId, JLabel label ); + + } + +} \ No newline at end of file diff --git a/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/FlightConfigurableTableModel.java b/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/FlightConfigurableTableModel.java new file mode 100644 index 000000000..14c31fd67 --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/FlightConfigurableTableModel.java @@ -0,0 +1,108 @@ +package net.sf.openrocket.gui.main.flightconfigpanel; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import javax.swing.table.AbstractTableModel; + +import net.sf.openrocket.l10n.Translator; +import net.sf.openrocket.rocketcomponent.ComponentChangeEvent; +import net.sf.openrocket.rocketcomponent.ComponentChangeListener; +import net.sf.openrocket.rocketcomponent.FlightConfigurableComponent; +import net.sf.openrocket.rocketcomponent.Rocket; +import net.sf.openrocket.rocketcomponent.RocketComponent; +import net.sf.openrocket.startup.Application; +import net.sf.openrocket.util.Pair; + +public class FlightConfigurableTableModel extends AbstractTableModel implements ComponentChangeListener{ + + private static final Translator trans = Application.getTranslator(); + private static final String CONFIGURATION = trans.get("edtmotorconfdlg.col.configuration"); + + protected final Rocket rocket; + protected final Class clazz; + private final List components = new ArrayList(); + + public FlightConfigurableTableModel(Class clazz, Rocket rocket) { + super(); + this.rocket = rocket; + this.clazz = clazz; + this.rocket.addComponentChangeListener(this); + initialize(); + } + + @Override + public void componentChanged(ComponentChangeEvent e) { + if ( e.isMotorChange() || e.isTreeChange() ) { + initialize(); + fireTableStructureChanged(); + } + } + + /** + * Return true if this component should be included in the table. + * @param component + * @return + */ + protected boolean includeComponent( T component ) { + return true; + } + + protected void initialize() { + components.clear(); + Iterator it = rocket.iterator(); + while (it.hasNext()) { + RocketComponent c = it.next(); + if (clazz.isAssignableFrom(c.getClass()) && includeComponent( (T) c) ) { + components.add( (T) c); + } + } + } + + @Override + public int getRowCount() { + return rocket.getFlightConfigurationIDs().length - 1; + } + + @Override + public int getColumnCount() { + return components.size() + 1; + } + + @Override + public Object getValueAt(int row, int column) { + String id = getConfiguration(row); + switch (column) { + case 0: { + return id; + } + default: { + int index = column - 1; + T d = components.get(index); + return new Pair(id, d); + } + } + } + + @Override + public String getColumnName(int column) { + switch (column) { + case 0: { + return CONFIGURATION; + } + default: { + int index = column - 1; + T d = components.get(index); + return d.toString(); + + } + } + } + + private String getConfiguration(int row) { + String id = rocket.getFlightConfigurationIDs()[row + 1]; + return id; + } + +} \ No newline at end of file diff --git a/core/src/net/sf/openrocket/gui/dialogs/flightconfiguration/FlightConfigurationDialog.java b/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/FlightConfigurationPanel.java similarity index 60% rename from core/src/net/sf/openrocket/gui/dialogs/flightconfiguration/FlightConfigurationDialog.java rename to swing/src/net/sf/openrocket/gui/main/flightconfigpanel/FlightConfigurationPanel.java index 487b0ac66..a9f3e2119 100644 --- a/core/src/net/sf/openrocket/gui/dialogs/flightconfiguration/FlightConfigurationDialog.java +++ b/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/FlightConfigurationPanel.java @@ -1,118 +1,59 @@ -package net.sf.openrocket.gui.dialogs.flightconfiguration; +package net.sf.openrocket.gui.main.flightconfigpanel; -import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; +import java.util.EventObject; import javax.swing.JButton; -import javax.swing.JComboBox; -import javax.swing.JDialog; -import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTabbedPane; +import javax.swing.SwingUtilities; import net.miginfocom.swing.MigLayout; import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.document.Simulation; -import net.sf.openrocket.gui.adaptors.FlightConfigurationModel; +import net.sf.openrocket.gui.dialogs.flightconfiguration.RenameConfigDialog; import net.sf.openrocket.gui.main.BasicFrame; -import net.sf.openrocket.gui.util.GUIUtil; import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.rocketcomponent.FlightConfigurableComponent; import net.sf.openrocket.rocketcomponent.Rocket; import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.startup.Application; +import net.sf.openrocket.util.StateChangeListener; -/** - * Dialog for configuring all flight-configuration specific properties. - * Content of individual tabs are in separate classes. - */ -public class FlightConfigurationDialog extends JDialog { +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class FlightConfigurationPanel extends JPanel implements StateChangeListener { + private static final Logger log = LoggerFactory.getLogger(FlightConfigurationPanel.class); private static final Translator trans = Application.getTranslator(); + private final OpenRocketDocument document; private final Rocket rocket; - private FlightConfigurationModel flightConfigurationModel; - - private final JButton renameConfButton, removeConfButton, copyConfButton; + private final JButton newConfButton, renameConfButton, removeConfButton, copyConfButton; + private final JTabbedPane tabs; private final MotorConfigurationPanel motorConfigurationPanel; private final RecoveryConfigurationPanel recoveryConfigurationPanel; private final SeparationConfigurationPanel separationConfigurationPanel; - - public FlightConfigurationDialog(final Rocket rocket, Window parent) { - //// Edit motor configurations - super(parent, trans.get("edtmotorconfdlg.title.Editmotorconf"), ModalityType.APPLICATION_MODAL); + @Override + public void stateChanged(EventObject e) { + updateButtonState(); + } + + public FlightConfigurationPanel(OpenRocketDocument doc) { + super(new MigLayout("fill","[grow][][][][][grow]")); - if (parent != null) - this.setModalityType(ModalityType.DOCUMENT_MODAL); - else - this.setModalityType(ModalityType.APPLICATION_MODAL); - - this.rocket = rocket; - - JPanel panel = new JPanel(new MigLayout("fill")); - - JLabel label = new JLabel(trans.get("edtmotorconfdlg.lbl.Selectedconf")); - panel.add(label, "span, split"); - - flightConfigurationModel = new FlightConfigurationModel(rocket.getDefaultConfiguration(), false); - JComboBox configSelector = new JComboBox(flightConfigurationModel); - configSelector.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - configurationChanged(); - } - }); - - panel.add(configSelector, "growx, gapright para"); - - JButton newConfButton = new JButton(trans.get("edtmotorconfdlg.but.Newconfiguration")); - newConfButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - addConfiguration(); - } - - }); - - panel.add(newConfButton); - - renameConfButton = new JButton(trans.get("edtmotorconfdlg.but.Renameconfiguration")); - renameConfButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - renameConfiguration(); - } - }); - panel.add(renameConfButton); - - removeConfButton = new JButton(trans.get("edtmotorconfdlg.but.Removeconfiguration")); - removeConfButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - removeConfiguration(); - } - }); - panel.add(removeConfButton); - - copyConfButton = new JButton(trans.get("edtmotorconfdlg.but.Copyconfiguration")); - copyConfButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - copyConfiguration(); - } - }); - panel.add(copyConfButton, "wrap para"); + this.document = doc; + this.rocket = doc.getRocket(); + //JPanel panel = new JPanel(new MigLayout("fill","[grow][][][][][grow]")); //// Tabs for advanced view. - JTabbedPane tabs = new JTabbedPane(); - panel.add(tabs, "grow, spanx, w 700lp, h 500lp, wrap"); + tabs = new JTabbedPane(); //// Motor tabs motorConfigurationPanel = new MotorConfigurationPanel(this, rocket); @@ -123,49 +64,56 @@ public class FlightConfigurationDialog extends JDialog { //// Stage tab separationConfigurationPanel = new SeparationConfigurationPanel(this, rocket); - if (rocket.getStageCount() > 1) { - tabs.add(trans.get("edtmotorconfdlg.lbl.Stagetab"), separationConfigurationPanel); - } - - - //// Close button - JButton close = new JButton(trans.get("dlg.but.close")); - close.addActionListener(new ActionListener() { + tabs.add(trans.get("edtmotorconfdlg.lbl.Stagetab"), separationConfigurationPanel); + + newConfButton = new JButton(trans.get("edtmotorconfdlg.but.Newconfiguration")); + newConfButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - FlightConfigurationDialog.this.dispose(); + addConfiguration(); + configurationChanged(); + } + + }); + + this.add(newConfButton,"skip 1,gapright para"); + + renameConfButton = new JButton(trans.get("edtmotorconfdlg.but.Renameconfiguration")); + renameConfButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + renameConfiguration(); + configurationChanged(); } }); - panel.add(close, "spanx, right"); + this.add(renameConfButton,"gapright para"); - this.add(panel); - this.validate(); - this.pack(); + removeConfButton = new JButton(trans.get("edtmotorconfdlg.but.Removeconfiguration")); + removeConfButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + removeConfiguration(); + configurationChanged(); + } + }); + this.add(removeConfButton,"gapright para"); + copyConfButton = new JButton(trans.get("edtmotorconfdlg.but.Copyconfiguration")); + copyConfButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + copyConfiguration(); + configurationChanged(); + } + }); + this.add(copyConfButton, "wrap"); + updateButtonState(); + + this.add(tabs, "spanx, grow, wrap rel"); + - this.setLocationByPlatform(true); - GUIUtil.setDisposableDialogOptions(this, close); - - // Undo description - final OpenRocketDocument document = BasicFrame.findDocument(rocket); - if (document != null) { - //// Edit motor configurations - document.startUndo(trans.get("edtmotorconfdlg.title.Editmotorconf")); - this.addWindowListener(new WindowAdapter() { - @Override - public void windowClosed(WindowEvent e) { - document.stopUndo(); - } - }); - } - } - - private void configurationChanged() { - motorConfigurationPanel.fireTableDataChanged(); - recoveryConfigurationPanel.fireTableDataChanged(); - separationConfigurationPanel.fireTableDataChanged(); - updateButtonState(); + this.rocket.getDefaultConfiguration().addChangeListener(this); } private void addConfiguration() { @@ -199,6 +147,18 @@ public class FlightConfigurationDialog extends JDialog { configurationChanged(); } + private void renameConfiguration() { + new RenameConfigDialog(SwingUtilities.getWindowAncestor(this), rocket).setVisible(true); + } + + private void removeConfiguration() { + String currentId = rocket.getDefaultConfiguration().getFlightConfigurationID(); + if (currentId == null) + return; + rocket.removeFlightConfigurationID(currentId); + configurationChanged(); + } + /** * prereq - assumes that the new configuration has been set as the default configuration. */ @@ -209,23 +169,19 @@ public class FlightConfigurationDialog extends JDialog { doc.addSimulation(newSim); } - private void renameConfiguration() { - new RenameConfigDialog(this, rocket).setVisible(true); - } - - private void removeConfiguration() { - String currentId = rocket.getDefaultConfiguration().getFlightConfigurationID(); - if (currentId == null) - return; - rocket.removeFlightConfigurationID(currentId); - rocket.getDefaultConfiguration().setFlightConfigurationID(null); - configurationChanged(); + private void configurationChanged() { + motorConfigurationPanel.fireTableDataChanged(); + recoveryConfigurationPanel.fireTableDataChanged(); + separationConfigurationPanel.fireTableDataChanged(); + updateButtonState(); } private void updateButtonState() { String currentId = rocket.getDefaultConfiguration().getFlightConfigurationID(); removeConfButton.setEnabled(currentId != null); renameConfButton.setEnabled(currentId != null); + copyConfButton.setEnabled(currentId != null); + } } diff --git a/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/MotorConfigurationPanel.java b/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/MotorConfigurationPanel.java new file mode 100644 index 000000000..538eb9709 --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/MotorConfigurationPanel.java @@ -0,0 +1,343 @@ +package net.sf.openrocket.gui.main.flightconfigpanel; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.ListSelectionModel; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.border.Border; +import javax.swing.border.EmptyBorder; +import javax.swing.table.TableCellRenderer; + +import net.miginfocom.swing.MigLayout; +import net.sf.openrocket.gui.components.StyledLabel; +import net.sf.openrocket.gui.components.StyledLabel.Style; +import net.sf.openrocket.gui.dialogs.flightconfiguration.IgnitionSelectionDialog; +import net.sf.openrocket.gui.dialogs.flightconfiguration.MotorMountConfigurationPanel; +import net.sf.openrocket.gui.dialogs.motor.MotorChooserDialog; +import net.sf.openrocket.gui.util.GUIUtil; +import net.sf.openrocket.motor.Motor; +import net.sf.openrocket.rocketcomponent.IgnitionConfiguration; +import net.sf.openrocket.rocketcomponent.IgnitionConfiguration.IgnitionEvent; +import net.sf.openrocket.rocketcomponent.MotorConfiguration; +import net.sf.openrocket.rocketcomponent.MotorMount; +import net.sf.openrocket.rocketcomponent.Rocket; +import net.sf.openrocket.rocketcomponent.RocketComponent; +import net.sf.openrocket.unit.UnitGroup; +import net.sf.openrocket.util.Chars; +import net.sf.openrocket.util.Coordinate; +import net.sf.openrocket.util.Pair; + +public class MotorConfigurationPanel extends FlightConfigurablePanel { + + private static final String NONE = trans.get("edtmotorconfdlg.tbl.None"); + + private final JButton selectMotorButton, removeMotorButton, selectIgnitionButton, resetIgnitionButton; + + protected FlightConfigurableTableModel configurationTableModel; + + MotorConfigurationPanel(final FlightConfigurationPanel flightConfigurationPanel, Rocket rocket) { + super(flightConfigurationPanel,rocket); + + { + //// Select motor mounts + JPanel subpanel = new JPanel(new MigLayout("")); + JLabel label = new StyledLabel(trans.get("lbl.motorMounts"), Style.BOLD); + subpanel.add(label, "wrap"); + + MotorMountConfigurationPanel mountConfigPanel = new MotorMountConfigurationPanel(this,rocket) { + @Override + public void onDataChanged() { + MotorConfigurationPanel.this.fireTableDataChanged(); + + } + }; + subpanel.add(mountConfigPanel, "grow"); + this.add(subpanel, "split, w 200lp, growy"); + } + + JScrollPane scroll = new JScrollPane(table); + this.add(scroll, "grow, wrap"); + + //// Select motor + selectMotorButton = new JButton(trans.get("MotorConfigurationPanel.btn.selectMotor")); + selectMotorButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + selectMotor(); + } + }); + this.add(selectMotorButton, "split, align right, sizegroup button"); + + //// Remove motor button + removeMotorButton = new JButton(trans.get("MotorConfigurationPanel.btn.removeMotor")); + removeMotorButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + removeMotor(); + } + }); + this.add(removeMotorButton, "sizegroup button"); + + //// Select Ignition button + selectIgnitionButton = new JButton(trans.get("MotorConfigurationPanel.btn.selectIgnition")); + selectIgnitionButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + selectIgnition(); + } + }); + this.add(selectIgnitionButton, "sizegroup button"); + + //// Reset Ignition button + resetIgnitionButton = new JButton(trans.get("MotorConfigurationPanel.btn.resetIgnition")); + resetIgnitionButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + resetIgnition(); + } + }); + this.add(resetIgnitionButton, "sizegroup button, wrap"); + + updateButtonState(); + + } + + @Override + protected JTable initializeTable() { + //// Motor selection table. + configurationTableModel = new FlightConfigurableTableModel(MotorMount.class,rocket) { + + @Override + protected boolean includeComponent(MotorMount component) { + return component.isMotorMount(); + } + + }; + JTable configurationTable = new JTable(configurationTableModel); + configurationTable.setCellSelectionEnabled(true); + configurationTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + configurationTable.setDefaultRenderer(Object.class, new MotorTableCellRenderer()); + + configurationTable.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + updateButtonState(); + int selectedColumn = table.getSelectedColumn(); + if (e.getClickCount() == 2) { + if (selectedColumn > 0) { + selectMotor(); + } + } + } + }); + return configurationTable; + } + + public void fireTableDataChanged() { + int selected = table.getSelectedRow(); + configurationTableModel.fireTableDataChanged(); + if (selected >= 0) { + selected = Math.min(selected, table.getRowCount() - 1); + table.getSelectionModel().setSelectionInterval(selected, selected); + } + updateButtonState(); + } + + private void updateButtonState() { + String currentID = rocket.getDefaultConfiguration().getFlightConfigurationID(); + MotorMount currentMount = getSelectedComponent(); + selectMotorButton.setEnabled(currentMount != null && currentID != null); + removeMotorButton.setEnabled(currentMount != null && currentID != null); + selectIgnitionButton.setEnabled(currentMount != null && currentID != null); + resetIgnitionButton.setEnabled(currentMount != null && currentID != null); + } + + + private void selectMotor() { + String id = rocket.getDefaultConfiguration().getFlightConfigurationID(); + MotorMount mount = getSelectedComponent(); + if (id == null || mount == null) + return; + + MotorConfiguration config = mount.getMotorConfiguration().get(id); + + MotorChooserDialog dialog = new MotorChooserDialog( + mount, + id, + SwingUtilities.getWindowAncestor(flightConfigurationPanel)); + dialog.setVisible(true); + Motor m = dialog.getSelectedMotor(); + double d = dialog.getSelectedDelay(); + + if (m != null) { + config = new MotorConfiguration(); + config.setMotor(m); + config.setEjectionDelay(d); + mount.getMotorConfiguration().set(id, config); + } + + fireTableDataChanged(); + } + + private void removeMotor() { + String id = rocket.getDefaultConfiguration().getFlightConfigurationID(); + MotorMount mount = getSelectedComponent(); + if (id == null || mount == null) + return; + + mount.getMotorConfiguration().resetDefault(id); + + fireTableDataChanged(); + } + + private void selectIgnition() { + String currentID = rocket.getDefaultConfiguration().getFlightConfigurationID(); + MotorMount currentMount = getSelectedComponent(); + if (currentID == null || currentMount == null) + return; + + IgnitionSelectionDialog dialog = new IgnitionSelectionDialog( + SwingUtilities.getWindowAncestor(this.flightConfigurationPanel), + rocket, + currentMount); + dialog.setVisible(true); + + fireTableDataChanged(); + } + + + private void resetIgnition() { + String currentID = rocket.getDefaultConfiguration().getFlightConfigurationID(); + MotorMount currentMount = getSelectedComponent(); + if (currentID == null || currentMount == null) + return; + + currentMount.getIgnitionConfiguration().resetDefault(currentID); + + fireTableDataChanged(); + } + + + private class MotorTableCellRenderer implements TableCellRenderer { + + private void setSelected( JComponent c, JTable table, boolean isSelected, boolean hasFocus ) { + c.setOpaque(true); + if ( isSelected) { + c.setBackground(table.getSelectionBackground()); + c.setForeground(table.getSelectionForeground()); + } else { + c.setBackground(table.getBackground()); + c.setForeground(table.getForeground()); + } + Border b = null; + if ( hasFocus ) { + if (isSelected) { + b = UIManager.getBorder("Table.focusSelectedCellHighlightBorder"); + } else { + b = UIManager.getBorder("Table.focusCellHighligtBorder"); + } + } else { + b = new EmptyBorder(1,1,1,1); + } + c.setBorder(b); + } + + @Override + public Component getTableCellRendererComponent(JTable table,Object value, boolean isSelected, boolean hasFocus, int row,int column) { + switch (column) { + case 0: { + JLabel label = new JLabel(descriptor.format(rocket, (String) value)); + setSelected(label, table, isSelected, hasFocus); + return label; + } + default: { + Pair v = (Pair) value; + String id = v.getU(); + MotorMount component = v.getV(); + JLabel label = format(component, id); + setSelected(label, table, isSelected, hasFocus); + return label; + } + } + } + + protected JLabel format(MotorMount mount, String configId) { + JLabel label = new JLabel(); + label.setLayout(new BoxLayout(label, BoxLayout.X_AXIS)); + MotorConfiguration motorConfig = mount.getMotorConfiguration().get(configId); + String motorString = getMotorSpecification(mount, motorConfig); + JLabel motorDescriptionLabel = new JLabel(motorString); + label.add(motorDescriptionLabel); + label.add( Box.createRigidArea(new Dimension(10,0))); + JLabel ignitionLabel = getIgnitionEventString(configId, mount); + label.add(ignitionLabel); + label.validate(); + return label; +// label.setText(motorString + " " + ignitionString); + } + + private String getMotorSpecification(MotorMount mount, MotorConfiguration motorConfig) { + Motor motor = motorConfig.getMotor(); + + if (motor == null) + return NONE; + + String str = motor.getDesignation(motorConfig.getEjectionDelay()); + int count = getMountMultiplicity(mount); + if (count > 1) { + str = "" + count + Chars.TIMES + " " + str; + } + return str; + } + + private int getMountMultiplicity(MotorMount mount) { + RocketComponent c = (RocketComponent) mount; + return c.toAbsolute(Coordinate.NUL).length; + } + + protected final void shaded(JLabel label) { + GUIUtil.changeFontStyle(label, Font.ITALIC); + label.setForeground(Color.GRAY); + } + + + private JLabel getIgnitionEventString(String id, MotorMount mount) { + IgnitionConfiguration ignitionConfig = mount.getIgnitionConfiguration().get(id); + IgnitionConfiguration.IgnitionEvent ignitionEvent = ignitionConfig.getIgnitionEvent(); + + Double ignitionDelay = ignitionConfig.getIgnitionDelay(); + boolean isDefault = mount.getIgnitionConfiguration().isDefault(id); + + JLabel label = new JLabel(); + String str = trans.get("MotorMount.IgnitionEvent.short." + ignitionEvent.name()); + if (ignitionEvent != IgnitionEvent.NEVER && ignitionDelay > 0.001) { + str = str + " + " + UnitGroup.UNITS_SHORT_TIME.toStringUnit(ignitionDelay); + } + if (isDefault) { + shaded(label); + String def = trans.get("MotorConfigurationTableModel.table.ignition.default"); + str = def.replace("{0}", str); + } + label.setText(str); + return label; + } + + } + +} diff --git a/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/RecoveryConfigurationPanel.java b/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/RecoveryConfigurationPanel.java new file mode 100644 index 000000000..fc302c3b0 --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/RecoveryConfigurationPanel.java @@ -0,0 +1,160 @@ +package net.sf.openrocket.gui.main.flightconfigpanel; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Font; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.ListSelectionModel; +import javax.swing.SwingUtilities; +import javax.swing.table.DefaultTableCellRenderer; + +import net.sf.openrocket.formatting.RocketDescriptor; +import net.sf.openrocket.gui.dialogs.flightconfiguration.DeploymentSelectionDialog; +import net.sf.openrocket.gui.util.GUIUtil; +import net.sf.openrocket.l10n.Translator; +import net.sf.openrocket.rocketcomponent.DeploymentConfiguration; +import net.sf.openrocket.rocketcomponent.DeploymentConfiguration.DeployEvent; +import net.sf.openrocket.rocketcomponent.MotorMount; +import net.sf.openrocket.rocketcomponent.RecoveryDevice; +import net.sf.openrocket.rocketcomponent.Rocket; +import net.sf.openrocket.startup.Application; +import net.sf.openrocket.unit.UnitGroup; +import net.sf.openrocket.util.Pair; + +public class RecoveryConfigurationPanel extends FlightConfigurablePanel { + + Translator trans = Application.getTranslator(); + private RocketDescriptor descriptor = Application.getInjector().getInstance(RocketDescriptor.class); + + private FlightConfigurableTableModel recoveryTableModel; + private final JButton selectDeploymentButton; + private final JButton resetDeploymentButton; + + + RecoveryConfigurationPanel(FlightConfigurationPanel flightConfigurationPanel, Rocket rocket) { + super(flightConfigurationPanel,rocket); + + JScrollPane scroll = new JScrollPane(table); + this.add(scroll, "span, grow, wrap"); + + //// Select deployment + selectDeploymentButton = new JButton(trans.get("edtmotorconfdlg.but.Selectdeployment")); + selectDeploymentButton.setEnabled(false); + selectDeploymentButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + selectDeployment(); + } + }); + this.add(selectDeploymentButton, "split, align right, sizegroup button"); + + //// Reset deployment + resetDeploymentButton = new JButton(trans.get("edtmotorconfdlg.but.Resetdeployment")); + resetDeploymentButton.setEnabled(false); + resetDeploymentButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + resetDeployment(); + } + }); + this.add(resetDeploymentButton, "sizegroup button, wrap"); + } + + @Override + protected JTable initializeTable() { + //// Recovery selection + recoveryTableModel = new FlightConfigurableTableModel(RecoveryDevice.class, rocket); + JTable recoveryTable = new JTable(recoveryTableModel); + recoveryTable.setCellSelectionEnabled(true); + recoveryTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + recoveryTable.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + updateButtonState(); + + if (e.getClickCount() == 2) { + // Double-click edits + selectDeployment(); + } + } + }); + recoveryTable.setDefaultRenderer(Object.class, new RecoveryTableCellRenderer()); + + return recoveryTable; + } + + public void fireTableDataChanged() { + int selected = table.getSelectedRow(); + recoveryTableModel.fireTableDataChanged(); + if (selected >= 0) { + selected = Math.min(selected, table.getRowCount() - 1); + table.getSelectionModel().setSelectionInterval(selected, selected); + } + updateButtonState(); + } + + private void selectDeployment() { + RecoveryDevice c = getSelectedComponent(); + if (c == null) { + return; + } + JDialog d = new DeploymentSelectionDialog(SwingUtilities.getWindowAncestor(this), rocket, c); + d.setVisible(true); + fireTableDataChanged(); + } + + private void resetDeployment() { + RecoveryDevice c = getSelectedComponent(); + if (c == null) { + return; + } + String id = rocket.getDefaultConfiguration().getFlightConfigurationID(); + c.getDeploymentConfiguration().resetDefault(id); + fireTableDataChanged(); + } + + public void updateButtonState() { + boolean componentSelected = getSelectedComponent() != null; + selectDeploymentButton.setEnabled(componentSelected); + resetDeploymentButton.setEnabled(componentSelected); + } + + class RecoveryTableCellRenderer extends FlightConfigurablePanel.FlightConfigurableCellRenderer { + + @Override + protected void format(RecoveryDevice recovery, String configId, JLabel label) { + DeploymentConfiguration deployConfig = recovery.getDeploymentConfiguration().get(configId); + String spec = getDeploymentSpecification(deployConfig); + label.setText(spec); + if (recovery.getDeploymentConfiguration().isDefault(configId)) { + shaded(label); + } else { + regular(label); + } + } + + private String getDeploymentSpecification( DeploymentConfiguration config ) { + String str; + + str = trans.get("RecoveryDevice.DeployEvent.short." + config.getDeployEvent().name()); + if (config.getDeployEvent() == DeployEvent.ALTITUDE) { + str += " " + UnitGroup.UNITS_DISTANCE.toStringUnit(config.getDeployAltitude()); + } + if (config.getDeployDelay() > 0.001) { + str += " + " + UnitGroup.UNITS_SHORT_TIME.toStringUnit(config.getDeployDelay()); + } + + return str; + } + } + +} diff --git a/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/SeparationConfigurationPanel.java b/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/SeparationConfigurationPanel.java new file mode 100644 index 000000000..57e7e4e46 --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/SeparationConfigurationPanel.java @@ -0,0 +1,165 @@ +package net.sf.openrocket.gui.main.flightconfigpanel; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Font; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.ListSelectionModel; +import javax.swing.SwingUtilities; +import javax.swing.table.DefaultTableCellRenderer; + +import net.sf.openrocket.formatting.RocketDescriptor; +import net.sf.openrocket.gui.dialogs.flightconfiguration.SeparationSelectionDialog; +import net.sf.openrocket.gui.util.GUIUtil; +import net.sf.openrocket.l10n.Translator; +import net.sf.openrocket.rocketcomponent.MotorMount; +import net.sf.openrocket.rocketcomponent.RecoveryDevice; +import net.sf.openrocket.rocketcomponent.Rocket; +import net.sf.openrocket.rocketcomponent.Stage; +import net.sf.openrocket.rocketcomponent.StageSeparationConfiguration; +import net.sf.openrocket.startup.Application; +import net.sf.openrocket.unit.UnitGroup; +import net.sf.openrocket.util.Pair; + +public class SeparationConfigurationPanel extends FlightConfigurablePanel { + + static final Translator trans = Application.getTranslator(); + private RocketDescriptor descriptor = Application.getInjector().getInstance(RocketDescriptor.class); + + private FlightConfigurableTableModel separationTableModel; + private final JButton selectSeparationButton; + private final JButton resetDeploymentButton; + + + SeparationConfigurationPanel(FlightConfigurationPanel flightConfigurationPanel, Rocket rocket) { + super(flightConfigurationPanel,rocket); + + JScrollPane scroll = new JScrollPane(table); + this.add(scroll, "span, grow, wrap"); + + //// Select deployment + selectSeparationButton = new JButton(trans.get("edtmotorconfdlg.but.Selectseparation")); + selectSeparationButton.setEnabled(false); + selectSeparationButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + selectDeployment(); + } + }); + this.add(selectSeparationButton, "split, align right, sizegroup button"); + + //// Reset deployment + resetDeploymentButton = new JButton(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"); + + } + + @Override + protected JTable initializeTable() { + //// Separation selection + separationTableModel = new FlightConfigurableTableModel(Stage.class, rocket) { + @Override + protected boolean includeComponent(Stage component) { + return component.getStageNumber() > 0; + } + + }; + JTable separationTable = new JTable(separationTableModel); + separationTable.setCellSelectionEnabled(true); + separationTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + separationTable.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + updateButtonState(); + if (e.getClickCount() == 2) { + // Double-click edits + selectDeployment(); + } + } + }); + separationTable.setDefaultRenderer(Object.class, new SeparationTableCellRenderer()); + + return separationTable; + } + + public void fireTableDataChanged() { + int selected = table.getSelectedRow(); + separationTableModel.fireTableDataChanged(); + if (selected >= 0) { + selected = Math.min(selected, table.getRowCount() - 1); + table.getSelectionModel().setSelectionInterval(selected, selected); + } + updateButtonState(); + } + + + private void selectDeployment() { + Stage stage = getSelectedComponent(); + if (stage == null) { + return; + } + JDialog d = new SeparationSelectionDialog(SwingUtilities.getWindowAncestor(this), rocket, stage); + d.setVisible(true); + fireTableDataChanged(); + } + + private void resetDeployment() { + Stage stage = getSelectedComponent(); + if (stage == null) { + return; + } + String id = rocket.getDefaultConfiguration().getFlightConfigurationID(); + stage.getStageSeparationConfiguration().resetDefault(id); + fireTableDataChanged(); + } + public void updateButtonState() { + boolean componentSelected = getSelectedComponent() != null; + selectSeparationButton.setEnabled(componentSelected); + resetDeploymentButton.setEnabled(componentSelected); + } + + private class SeparationTableCellRenderer extends FlightConfigurablePanel.FlightConfigurableCellRenderer { + + @Override + protected void format(Stage stage, String configId, JLabel label) { + StageSeparationConfiguration sepConfig = stage.getStageSeparationConfiguration().get(configId); + String spec = getSeparationSpecification(sepConfig); + label.setText(spec); + if (stage.getStageSeparationConfiguration().isDefault(configId)) { + shaded(label); + } else { + regular(label); + } + } + + private String getSeparationSpecification( StageSeparationConfiguration sepConfig ) { + String str; + + str = sepConfig.getSeparationEvent().toString(); + if (sepConfig.getSeparationDelay() > 0.001) { + str += " + " + UnitGroup.UNITS_SHORT_TIME.toStringUnit(sepConfig.getSeparationDelay()); + } + + return str; + + } + } + + +} diff --git a/core/src/net/sf/openrocket/gui/plot/Axis.java b/swing/src/net/sf/openrocket/gui/plot/Axis.java similarity index 100% rename from core/src/net/sf/openrocket/gui/plot/Axis.java rename to swing/src/net/sf/openrocket/gui/plot/Axis.java diff --git a/core/src/net/sf/openrocket/gui/plot/EventGraphics.java b/swing/src/net/sf/openrocket/gui/plot/EventGraphics.java similarity index 100% rename from core/src/net/sf/openrocket/gui/plot/EventGraphics.java rename to swing/src/net/sf/openrocket/gui/plot/EventGraphics.java diff --git a/core/src/net/sf/openrocket/gui/plot/PlotConfiguration.java b/swing/src/net/sf/openrocket/gui/plot/PlotConfiguration.java similarity index 100% rename from core/src/net/sf/openrocket/gui/plot/PlotConfiguration.java rename to swing/src/net/sf/openrocket/gui/plot/PlotConfiguration.java diff --git a/core/src/net/sf/openrocket/gui/plot/SimulationChart.java b/swing/src/net/sf/openrocket/gui/plot/SimulationChart.java similarity index 100% rename from core/src/net/sf/openrocket/gui/plot/SimulationChart.java rename to swing/src/net/sf/openrocket/gui/plot/SimulationChart.java diff --git a/core/src/net/sf/openrocket/gui/plot/SimulationPlot.java b/swing/src/net/sf/openrocket/gui/plot/SimulationPlot.java similarity index 100% rename from core/src/net/sf/openrocket/gui/plot/SimulationPlot.java rename to swing/src/net/sf/openrocket/gui/plot/SimulationPlot.java diff --git a/core/src/net/sf/openrocket/gui/plot/SimulationPlotDialog.java b/swing/src/net/sf/openrocket/gui/plot/SimulationPlotDialog.java similarity index 100% rename from core/src/net/sf/openrocket/gui/plot/SimulationPlotDialog.java rename to swing/src/net/sf/openrocket/gui/plot/SimulationPlotDialog.java diff --git a/core/src/net/sf/openrocket/gui/plot/Util.java b/swing/src/net/sf/openrocket/gui/plot/Util.java similarity index 100% rename from core/src/net/sf/openrocket/gui/plot/Util.java rename to swing/src/net/sf/openrocket/gui/plot/Util.java diff --git a/core/src/net/sf/openrocket/gui/preset/ButtonColumn.java b/swing/src/net/sf/openrocket/gui/preset/ButtonColumn.java similarity index 100% rename from core/src/net/sf/openrocket/gui/preset/ButtonColumn.java rename to swing/src/net/sf/openrocket/gui/preset/ButtonColumn.java diff --git a/core/src/net/sf/openrocket/gui/preset/DeselectableComboBox.java b/swing/src/net/sf/openrocket/gui/preset/DeselectableComboBox.java similarity index 100% rename from core/src/net/sf/openrocket/gui/preset/DeselectableComboBox.java rename to swing/src/net/sf/openrocket/gui/preset/DeselectableComboBox.java diff --git a/core/src/net/sf/openrocket/gui/preset/ImagePreviewPanel.java b/swing/src/net/sf/openrocket/gui/preset/ImagePreviewPanel.java similarity index 100% rename from core/src/net/sf/openrocket/gui/preset/ImagePreviewPanel.java rename to swing/src/net/sf/openrocket/gui/preset/ImagePreviewPanel.java diff --git a/core/src/net/sf/openrocket/gui/preset/MaterialModel.java b/swing/src/net/sf/openrocket/gui/preset/MaterialModel.java similarity index 100% rename from core/src/net/sf/openrocket/gui/preset/MaterialModel.java rename to swing/src/net/sf/openrocket/gui/preset/MaterialModel.java diff --git a/core/src/net/sf/openrocket/gui/preset/PresetEditorDialog.java b/swing/src/net/sf/openrocket/gui/preset/PresetEditorDialog.java similarity index 100% rename from core/src/net/sf/openrocket/gui/preset/PresetEditorDialog.java rename to swing/src/net/sf/openrocket/gui/preset/PresetEditorDialog.java diff --git a/core/src/net/sf/openrocket/gui/preset/PresetResultListener.java b/swing/src/net/sf/openrocket/gui/preset/PresetResultListener.java similarity index 100% rename from core/src/net/sf/openrocket/gui/preset/PresetResultListener.java rename to swing/src/net/sf/openrocket/gui/preset/PresetResultListener.java diff --git a/core/src/net/sf/openrocket/gui/print/AbstractPrintable.java b/swing/src/net/sf/openrocket/gui/print/AbstractPrintable.java similarity index 100% rename from core/src/net/sf/openrocket/gui/print/AbstractPrintable.java rename to swing/src/net/sf/openrocket/gui/print/AbstractPrintable.java diff --git a/core/src/net/sf/openrocket/gui/print/DesignReport.java b/swing/src/net/sf/openrocket/gui/print/DesignReport.java similarity index 100% rename from core/src/net/sf/openrocket/gui/print/DesignReport.java rename to swing/src/net/sf/openrocket/gui/print/DesignReport.java diff --git a/core/src/net/sf/openrocket/gui/print/FinMarkingGuide.java b/swing/src/net/sf/openrocket/gui/print/FinMarkingGuide.java similarity index 100% rename from core/src/net/sf/openrocket/gui/print/FinMarkingGuide.java rename to swing/src/net/sf/openrocket/gui/print/FinMarkingGuide.java diff --git a/core/src/net/sf/openrocket/gui/print/ITextHelper.java b/swing/src/net/sf/openrocket/gui/print/ITextHelper.java similarity index 100% rename from core/src/net/sf/openrocket/gui/print/ITextHelper.java rename to swing/src/net/sf/openrocket/gui/print/ITextHelper.java diff --git a/core/src/net/sf/openrocket/gui/print/OpenRocketPrintable.java b/swing/src/net/sf/openrocket/gui/print/OpenRocketPrintable.java similarity index 100% rename from core/src/net/sf/openrocket/gui/print/OpenRocketPrintable.java rename to swing/src/net/sf/openrocket/gui/print/OpenRocketPrintable.java diff --git a/core/src/net/sf/openrocket/gui/print/PDFPrintStreamDoc.java b/swing/src/net/sf/openrocket/gui/print/PDFPrintStreamDoc.java similarity index 100% rename from core/src/net/sf/openrocket/gui/print/PDFPrintStreamDoc.java rename to swing/src/net/sf/openrocket/gui/print/PDFPrintStreamDoc.java diff --git a/core/src/net/sf/openrocket/gui/print/PaperOrientation.java b/swing/src/net/sf/openrocket/gui/print/PaperOrientation.java similarity index 100% rename from core/src/net/sf/openrocket/gui/print/PaperOrientation.java rename to swing/src/net/sf/openrocket/gui/print/PaperOrientation.java diff --git a/core/src/net/sf/openrocket/gui/print/PaperSize.java b/swing/src/net/sf/openrocket/gui/print/PaperSize.java similarity index 100% rename from core/src/net/sf/openrocket/gui/print/PaperSize.java rename to swing/src/net/sf/openrocket/gui/print/PaperSize.java diff --git a/core/src/net/sf/openrocket/gui/print/PrintController.java b/swing/src/net/sf/openrocket/gui/print/PrintController.java similarity index 100% rename from core/src/net/sf/openrocket/gui/print/PrintController.java rename to swing/src/net/sf/openrocket/gui/print/PrintController.java diff --git a/core/src/net/sf/openrocket/gui/print/PrintFigure.java b/swing/src/net/sf/openrocket/gui/print/PrintFigure.java similarity index 100% rename from core/src/net/sf/openrocket/gui/print/PrintFigure.java rename to swing/src/net/sf/openrocket/gui/print/PrintFigure.java diff --git a/core/src/net/sf/openrocket/gui/print/PrintSettings.java b/swing/src/net/sf/openrocket/gui/print/PrintSettings.java similarity index 100% rename from core/src/net/sf/openrocket/gui/print/PrintSettings.java rename to swing/src/net/sf/openrocket/gui/print/PrintSettings.java diff --git a/core/src/net/sf/openrocket/gui/print/PrintSimulationWorker.java b/swing/src/net/sf/openrocket/gui/print/PrintSimulationWorker.java similarity index 100% rename from core/src/net/sf/openrocket/gui/print/PrintSimulationWorker.java rename to swing/src/net/sf/openrocket/gui/print/PrintSimulationWorker.java diff --git a/core/src/net/sf/openrocket/gui/print/PrintUnit.java b/swing/src/net/sf/openrocket/gui/print/PrintUnit.java similarity index 100% rename from core/src/net/sf/openrocket/gui/print/PrintUnit.java rename to swing/src/net/sf/openrocket/gui/print/PrintUnit.java diff --git a/core/src/net/sf/openrocket/gui/print/PrintUtilities.java b/swing/src/net/sf/openrocket/gui/print/PrintUtilities.java similarity index 100% rename from core/src/net/sf/openrocket/gui/print/PrintUtilities.java rename to swing/src/net/sf/openrocket/gui/print/PrintUtilities.java diff --git a/core/src/net/sf/openrocket/gui/print/PrintableCenteringRing.java b/swing/src/net/sf/openrocket/gui/print/PrintableCenteringRing.java similarity index 100% rename from core/src/net/sf/openrocket/gui/print/PrintableCenteringRing.java rename to swing/src/net/sf/openrocket/gui/print/PrintableCenteringRing.java diff --git a/core/src/net/sf/openrocket/gui/print/PrintableComponent.java b/swing/src/net/sf/openrocket/gui/print/PrintableComponent.java similarity index 100% rename from core/src/net/sf/openrocket/gui/print/PrintableComponent.java rename to swing/src/net/sf/openrocket/gui/print/PrintableComponent.java diff --git a/core/src/net/sf/openrocket/gui/print/PrintableContext.java b/swing/src/net/sf/openrocket/gui/print/PrintableContext.java similarity index 100% rename from core/src/net/sf/openrocket/gui/print/PrintableContext.java rename to swing/src/net/sf/openrocket/gui/print/PrintableContext.java diff --git a/core/src/net/sf/openrocket/gui/print/PrintableFinSet.java b/swing/src/net/sf/openrocket/gui/print/PrintableFinSet.java similarity index 100% rename from core/src/net/sf/openrocket/gui/print/PrintableFinSet.java rename to swing/src/net/sf/openrocket/gui/print/PrintableFinSet.java diff --git a/core/src/net/sf/openrocket/gui/print/PrintableNoseCone.java b/swing/src/net/sf/openrocket/gui/print/PrintableNoseCone.java similarity index 100% rename from core/src/net/sf/openrocket/gui/print/PrintableNoseCone.java rename to swing/src/net/sf/openrocket/gui/print/PrintableNoseCone.java diff --git a/core/src/net/sf/openrocket/gui/print/PrintableTransition.java b/swing/src/net/sf/openrocket/gui/print/PrintableTransition.java similarity index 100% rename from core/src/net/sf/openrocket/gui/print/PrintableTransition.java rename to swing/src/net/sf/openrocket/gui/print/PrintableTransition.java diff --git a/core/src/net/sf/openrocket/gui/print/TemplateProperties.java b/swing/src/net/sf/openrocket/gui/print/TemplateProperties.java similarity index 100% rename from core/src/net/sf/openrocket/gui/print/TemplateProperties.java rename to swing/src/net/sf/openrocket/gui/print/TemplateProperties.java diff --git a/core/src/net/sf/openrocket/gui/print/components/CheckBoxNode.java b/swing/src/net/sf/openrocket/gui/print/components/CheckBoxNode.java similarity index 100% rename from core/src/net/sf/openrocket/gui/print/components/CheckBoxNode.java rename to swing/src/net/sf/openrocket/gui/print/components/CheckBoxNode.java diff --git a/core/src/net/sf/openrocket/gui/print/components/CheckTreeCellRenderer.java b/swing/src/net/sf/openrocket/gui/print/components/CheckTreeCellRenderer.java similarity index 100% rename from core/src/net/sf/openrocket/gui/print/components/CheckTreeCellRenderer.java rename to swing/src/net/sf/openrocket/gui/print/components/CheckTreeCellRenderer.java diff --git a/core/src/net/sf/openrocket/gui/print/components/CheckTreeManager.java b/swing/src/net/sf/openrocket/gui/print/components/CheckTreeManager.java similarity index 100% rename from core/src/net/sf/openrocket/gui/print/components/CheckTreeManager.java rename to swing/src/net/sf/openrocket/gui/print/components/CheckTreeManager.java diff --git a/core/src/net/sf/openrocket/gui/print/components/CheckTreeSelectionModel.java b/swing/src/net/sf/openrocket/gui/print/components/CheckTreeSelectionModel.java similarity index 100% rename from core/src/net/sf/openrocket/gui/print/components/CheckTreeSelectionModel.java rename to swing/src/net/sf/openrocket/gui/print/components/CheckTreeSelectionModel.java diff --git a/core/src/net/sf/openrocket/gui/print/components/RocketPrintTree.java b/swing/src/net/sf/openrocket/gui/print/components/RocketPrintTree.java similarity index 100% rename from core/src/net/sf/openrocket/gui/print/components/RocketPrintTree.java rename to swing/src/net/sf/openrocket/gui/print/components/RocketPrintTree.java diff --git a/core/src/net/sf/openrocket/gui/print/components/Rule.java b/swing/src/net/sf/openrocket/gui/print/components/Rule.java similarity index 100% rename from core/src/net/sf/openrocket/gui/print/components/Rule.java rename to swing/src/net/sf/openrocket/gui/print/components/Rule.java diff --git a/core/src/net/sf/openrocket/gui/print/visitor/AbstractPrintStrategy.java b/swing/src/net/sf/openrocket/gui/print/visitor/AbstractPrintStrategy.java similarity index 100% rename from core/src/net/sf/openrocket/gui/print/visitor/AbstractPrintStrategy.java rename to swing/src/net/sf/openrocket/gui/print/visitor/AbstractPrintStrategy.java diff --git a/core/src/net/sf/openrocket/gui/print/visitor/CenteringRingStrategy.java b/swing/src/net/sf/openrocket/gui/print/visitor/CenteringRingStrategy.java similarity index 100% rename from core/src/net/sf/openrocket/gui/print/visitor/CenteringRingStrategy.java rename to swing/src/net/sf/openrocket/gui/print/visitor/CenteringRingStrategy.java diff --git a/core/src/net/sf/openrocket/gui/print/visitor/Dimension.java b/swing/src/net/sf/openrocket/gui/print/visitor/Dimension.java similarity index 100% rename from core/src/net/sf/openrocket/gui/print/visitor/Dimension.java rename to swing/src/net/sf/openrocket/gui/print/visitor/Dimension.java diff --git a/core/src/net/sf/openrocket/gui/print/visitor/FinMarkingGuideStrategy.java b/swing/src/net/sf/openrocket/gui/print/visitor/FinMarkingGuideStrategy.java similarity index 100% rename from core/src/net/sf/openrocket/gui/print/visitor/FinMarkingGuideStrategy.java rename to swing/src/net/sf/openrocket/gui/print/visitor/FinMarkingGuideStrategy.java diff --git a/core/src/net/sf/openrocket/gui/print/visitor/FinSetPrintStrategy.java b/swing/src/net/sf/openrocket/gui/print/visitor/FinSetPrintStrategy.java similarity index 100% rename from core/src/net/sf/openrocket/gui/print/visitor/FinSetPrintStrategy.java rename to swing/src/net/sf/openrocket/gui/print/visitor/FinSetPrintStrategy.java diff --git a/core/src/net/sf/openrocket/gui/print/visitor/PageFitPrintStrategy.java b/swing/src/net/sf/openrocket/gui/print/visitor/PageFitPrintStrategy.java similarity index 100% rename from core/src/net/sf/openrocket/gui/print/visitor/PageFitPrintStrategy.java rename to swing/src/net/sf/openrocket/gui/print/visitor/PageFitPrintStrategy.java diff --git a/core/src/net/sf/openrocket/gui/print/visitor/PartsDetailVisitorStrategy.java b/swing/src/net/sf/openrocket/gui/print/visitor/PartsDetailVisitorStrategy.java similarity index 100% rename from core/src/net/sf/openrocket/gui/print/visitor/PartsDetailVisitorStrategy.java rename to swing/src/net/sf/openrocket/gui/print/visitor/PartsDetailVisitorStrategy.java diff --git a/core/src/net/sf/openrocket/gui/print/visitor/PartsListVisitorStrategy.java b/swing/src/net/sf/openrocket/gui/print/visitor/PartsListVisitorStrategy.java similarity index 100% rename from core/src/net/sf/openrocket/gui/print/visitor/PartsListVisitorStrategy.java rename to swing/src/net/sf/openrocket/gui/print/visitor/PartsListVisitorStrategy.java diff --git a/core/src/net/sf/openrocket/gui/print/visitor/TransitionStrategy.java b/swing/src/net/sf/openrocket/gui/print/visitor/TransitionStrategy.java similarity index 100% rename from core/src/net/sf/openrocket/gui/print/visitor/TransitionStrategy.java rename to swing/src/net/sf/openrocket/gui/print/visitor/TransitionStrategy.java diff --git a/core/src/net/sf/openrocket/gui/rocketfigure/BodyTubeShapes.java b/swing/src/net/sf/openrocket/gui/rocketfigure/BodyTubeShapes.java similarity index 100% rename from core/src/net/sf/openrocket/gui/rocketfigure/BodyTubeShapes.java rename to swing/src/net/sf/openrocket/gui/rocketfigure/BodyTubeShapes.java diff --git a/core/src/net/sf/openrocket/gui/rocketfigure/FinSetShapes.java b/swing/src/net/sf/openrocket/gui/rocketfigure/FinSetShapes.java similarity index 100% rename from core/src/net/sf/openrocket/gui/rocketfigure/FinSetShapes.java rename to swing/src/net/sf/openrocket/gui/rocketfigure/FinSetShapes.java diff --git a/core/src/net/sf/openrocket/gui/rocketfigure/LaunchLugShapes.java b/swing/src/net/sf/openrocket/gui/rocketfigure/LaunchLugShapes.java similarity index 100% rename from core/src/net/sf/openrocket/gui/rocketfigure/LaunchLugShapes.java rename to swing/src/net/sf/openrocket/gui/rocketfigure/LaunchLugShapes.java diff --git a/core/src/net/sf/openrocket/gui/rocketfigure/MassObjectShapes.java b/swing/src/net/sf/openrocket/gui/rocketfigure/MassObjectShapes.java similarity index 100% rename from core/src/net/sf/openrocket/gui/rocketfigure/MassObjectShapes.java rename to swing/src/net/sf/openrocket/gui/rocketfigure/MassObjectShapes.java diff --git a/core/src/net/sf/openrocket/gui/rocketfigure/RingComponentShapes.java b/swing/src/net/sf/openrocket/gui/rocketfigure/RingComponentShapes.java similarity index 100% rename from core/src/net/sf/openrocket/gui/rocketfigure/RingComponentShapes.java rename to swing/src/net/sf/openrocket/gui/rocketfigure/RingComponentShapes.java diff --git a/core/src/net/sf/openrocket/gui/rocketfigure/RocketComponentShapes.java b/swing/src/net/sf/openrocket/gui/rocketfigure/RocketComponentShapes.java similarity index 100% rename from core/src/net/sf/openrocket/gui/rocketfigure/RocketComponentShapes.java rename to swing/src/net/sf/openrocket/gui/rocketfigure/RocketComponentShapes.java diff --git a/core/src/net/sf/openrocket/gui/rocketfigure/SymmetricComponentShapes.java b/swing/src/net/sf/openrocket/gui/rocketfigure/SymmetricComponentShapes.java similarity index 100% rename from core/src/net/sf/openrocket/gui/rocketfigure/SymmetricComponentShapes.java rename to swing/src/net/sf/openrocket/gui/rocketfigure/SymmetricComponentShapes.java diff --git a/core/src/net/sf/openrocket/gui/rocketfigure/TransitionShapes.java b/swing/src/net/sf/openrocket/gui/rocketfigure/TransitionShapes.java similarity index 100% rename from core/src/net/sf/openrocket/gui/rocketfigure/TransitionShapes.java rename to swing/src/net/sf/openrocket/gui/rocketfigure/TransitionShapes.java diff --git a/core/src/net/sf/openrocket/gui/scalefigure/AbstractScaleFigure.java b/swing/src/net/sf/openrocket/gui/scalefigure/AbstractScaleFigure.java similarity index 100% rename from core/src/net/sf/openrocket/gui/scalefigure/AbstractScaleFigure.java rename to swing/src/net/sf/openrocket/gui/scalefigure/AbstractScaleFigure.java diff --git a/core/src/net/sf/openrocket/gui/scalefigure/FinPointFigure.java b/swing/src/net/sf/openrocket/gui/scalefigure/FinPointFigure.java similarity index 100% rename from core/src/net/sf/openrocket/gui/scalefigure/FinPointFigure.java rename to swing/src/net/sf/openrocket/gui/scalefigure/FinPointFigure.java diff --git a/core/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java b/swing/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java similarity index 100% rename from core/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java rename to swing/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java diff --git a/core/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java b/swing/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java similarity index 97% rename from core/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java rename to swing/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java index 5ae1d1581..c458b8e66 100644 --- a/core/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java +++ b/swing/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java @@ -6,7 +6,6 @@ import java.awt.Dimension; import java.awt.Font; import java.awt.Point; import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import java.awt.event.InputEvent; import java.awt.event.MouseEvent; import java.util.ArrayList; @@ -22,9 +21,7 @@ import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.ComboBoxModel; import javax.swing.DefaultComboBoxModel; -import javax.swing.JButton; import javax.swing.JComboBox; -import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JSlider; @@ -48,7 +45,6 @@ import net.sf.openrocket.gui.components.BasicSlider; import net.sf.openrocket.gui.components.StageSelector; import net.sf.openrocket.gui.components.UnitSelector; import net.sf.openrocket.gui.configdialog.ComponentConfigDialog; -import net.sf.openrocket.gui.dialogs.flightconfiguration.FlightConfigurationDialog; import net.sf.openrocket.gui.figure3d.RocketFigure3d; import net.sf.openrocket.gui.figureelements.CGCaret; import net.sf.openrocket.gui.figureelements.CPCaret; @@ -323,20 +319,7 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change JLabel label = new JLabel(trans.get("RocketPanel.lbl.Flightcfg")); label.setHorizontalAlignment(JLabel.RIGHT); add(label, "growx, right"); - add(new JComboBox(new FlightConfigurationModel(configuration)), ""); - - //// Edit button - JButton button = new JButton(trans.get("RocketPanel.but.FlightcfgEdit")); - button.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - JDialog configDialog = new FlightConfigurationDialog(document.getRocket(), SwingUtilities.windowForComponent(RocketPanel.this)); - configDialog.show(); - } - }); - add(button, "wrap"); - - + add(new JComboBox(new FlightConfigurationModel(configuration)), "wrap"); // Create slider and scroll pane diff --git a/core/src/net/sf/openrocket/gui/scalefigure/ScaleFigure.java b/swing/src/net/sf/openrocket/gui/scalefigure/ScaleFigure.java similarity index 100% rename from core/src/net/sf/openrocket/gui/scalefigure/ScaleFigure.java rename to swing/src/net/sf/openrocket/gui/scalefigure/ScaleFigure.java diff --git a/core/src/net/sf/openrocket/gui/scalefigure/ScaleScrollPane.java b/swing/src/net/sf/openrocket/gui/scalefigure/ScaleScrollPane.java similarity index 100% rename from core/src/net/sf/openrocket/gui/scalefigure/ScaleScrollPane.java rename to swing/src/net/sf/openrocket/gui/scalefigure/ScaleScrollPane.java diff --git a/core/src/net/sf/openrocket/gui/scalefigure/ScaleSelector.java b/swing/src/net/sf/openrocket/gui/scalefigure/ScaleSelector.java similarity index 100% rename from core/src/net/sf/openrocket/gui/scalefigure/ScaleSelector.java rename to swing/src/net/sf/openrocket/gui/scalefigure/ScaleSelector.java diff --git a/core/src/net/sf/openrocket/gui/simulation/SimulationConditionsPanel.java b/swing/src/net/sf/openrocket/gui/simulation/SimulationConditionsPanel.java similarity index 100% rename from core/src/net/sf/openrocket/gui/simulation/SimulationConditionsPanel.java rename to swing/src/net/sf/openrocket/gui/simulation/SimulationConditionsPanel.java diff --git a/core/src/net/sf/openrocket/gui/simulation/SimulationEditDialog.java b/swing/src/net/sf/openrocket/gui/simulation/SimulationEditDialog.java similarity index 93% rename from core/src/net/sf/openrocket/gui/simulation/SimulationEditDialog.java rename to swing/src/net/sf/openrocket/gui/simulation/SimulationEditDialog.java index ae0784c30..53468bb61 100644 --- a/core/src/net/sf/openrocket/gui/simulation/SimulationEditDialog.java +++ b/swing/src/net/sf/openrocket/gui/simulation/SimulationEditDialog.java @@ -13,7 +13,6 @@ import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTabbedPane; import javax.swing.JTextField; -import javax.swing.SwingUtilities; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.event.DocumentEvent; @@ -23,7 +22,6 @@ import net.miginfocom.swing.MigLayout; import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.document.Simulation; import net.sf.openrocket.gui.adaptors.FlightConfigurationModel; -import net.sf.openrocket.gui.dialogs.flightconfiguration.FlightConfigurationDialog; import net.sf.openrocket.gui.util.GUIUtil; import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.rocketcomponent.Configuration; @@ -158,18 +156,7 @@ public class SimulationEditDialog extends JDialog { conditions.setMotorConfigurationID(configuration.getFlightConfigurationID()); } }); - panel.add(combo, "span, split"); - - //// Edit button - JButton button = new JButton(trans.get("simedtdlg.but.FlightcfgEdit")); - button.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - JDialog configDialog = new FlightConfigurationDialog(SimulationEditDialog.this.document.getRocket(), SwingUtilities.windowForComponent(SimulationEditDialog.this)); - configDialog.setVisible(true); - } - }); - panel.add(button, "align left"); + panel.add(combo, "span"); panel.add(new JPanel(), "growx, wrap"); diff --git a/core/src/net/sf/openrocket/gui/simulation/SimulationExportPanel.java b/swing/src/net/sf/openrocket/gui/simulation/SimulationExportPanel.java similarity index 100% rename from core/src/net/sf/openrocket/gui/simulation/SimulationExportPanel.java rename to swing/src/net/sf/openrocket/gui/simulation/SimulationExportPanel.java diff --git a/core/src/net/sf/openrocket/gui/simulation/SimulationOptionsPanel.java b/swing/src/net/sf/openrocket/gui/simulation/SimulationOptionsPanel.java similarity index 100% rename from core/src/net/sf/openrocket/gui/simulation/SimulationOptionsPanel.java rename to swing/src/net/sf/openrocket/gui/simulation/SimulationOptionsPanel.java diff --git a/core/src/net/sf/openrocket/gui/simulation/SimulationPlotPanel.java b/swing/src/net/sf/openrocket/gui/simulation/SimulationPlotPanel.java similarity index 100% rename from core/src/net/sf/openrocket/gui/simulation/SimulationPlotPanel.java rename to swing/src/net/sf/openrocket/gui/simulation/SimulationPlotPanel.java diff --git a/core/src/net/sf/openrocket/gui/simulation/SimulationRunDialog.java b/swing/src/net/sf/openrocket/gui/simulation/SimulationRunDialog.java similarity index 100% rename from core/src/net/sf/openrocket/gui/simulation/SimulationRunDialog.java rename to swing/src/net/sf/openrocket/gui/simulation/SimulationRunDialog.java diff --git a/core/src/net/sf/openrocket/gui/simulation/SimulationWarningDialog.java b/swing/src/net/sf/openrocket/gui/simulation/SimulationWarningDialog.java similarity index 100% rename from core/src/net/sf/openrocket/gui/simulation/SimulationWarningDialog.java rename to swing/src/net/sf/openrocket/gui/simulation/SimulationWarningDialog.java diff --git a/core/src/net/sf/openrocket/gui/simulation/SimulationWorker.java b/swing/src/net/sf/openrocket/gui/simulation/SimulationWorker.java similarity index 100% rename from core/src/net/sf/openrocket/gui/simulation/SimulationWorker.java rename to swing/src/net/sf/openrocket/gui/simulation/SimulationWorker.java diff --git a/swing/src/net/sf/openrocket/gui/util/CheckList.java b/swing/src/net/sf/openrocket/gui/util/CheckList.java new file mode 100644 index 000000000..fa7c17948 --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/util/CheckList.java @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2009-2011, EzWare + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer.Redistributions + * in binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution.Neither the name of the + * EzWare nor the names of its contributors may be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +package net.sf.openrocket.gui.util; + +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseListener; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import javax.swing.AbstractAction; +import javax.swing.JList; +import javax.swing.KeyStroke; +import javax.swing.ListSelectionModel; + +/** + * The decorator for JList which makes it work like check list + * UI can be designed using JList and which can be later decorated to become a check list + * @author Eugene Ryzhikov + * + * @param list item type + */ +public class CheckList { + + private final JList list; + private static final MouseAdapter checkBoxEditor = new CheckListEditor(); + + public static class Builder { + + private JList list; + + public Builder(JList list) { + this.list = list == null ? new JList() : list; + } + + public Builder() { + this(null); + } + + public CheckList build() { + return new CheckList(list); + } + + } + + + /** + * Wraps the standard JList and makes it work like check list + * @param list + */ + private CheckList(final JList list) { + + if (list == null) + throw new NullPointerException(); + this.list = list; + this.list.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + + if (!isEditorAttached()) + list.addMouseListener(checkBoxEditor); + this.list.setCellRenderer(new CheckListRenderer()); + + setupKeyboardActions(list); + + } + + @SuppressWarnings("serial") + private void setupKeyboardActions(final JList list) { + String actionKey = "toggle-check"; + list.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), actionKey); + list.getActionMap().put(actionKey, new AbstractAction() { + + @Override + public void actionPerformed(ActionEvent e) { + toggleIndex(list.getSelectedIndex()); + } + }); + } + + private boolean isEditorAttached() { + + for (MouseListener ml : list.getMouseListeners()) { + if (ml instanceof CheckListEditor) + return true; + } + return false; + + } + + public JList getList() { + return list; + } + + /** + * Sets data to a check list. Simplification for setting new the model + * @param data + */ + public void setData(Collection data) { + setModel(new DefaultCheckListModel(data)); + } + + /** + * Sets the model for check list. + * @param model + */ + public void setModel(DefaultCheckListModel model) { + list.setModel(model); + } + + @SuppressWarnings("unchecked") + public DefaultCheckListModel getModel() { + return (DefaultCheckListModel) list.getModel(); + } + + /** + * Returns a collection of checked items. + * @return collection of checked items. Empty collection if nothing is selected + */ + public Collection getCheckedItems() { + return getModel().getCheckedItems(); + } + + public Collection getUncheckedItems() { + List unchecked = new ArrayList(); + for (int i = getModel().getSize() - 1; i >= 0; i--) { + unchecked.add((T) getModel().getElementAt(i)); + } + unchecked.removeAll(getCheckedItems()); + return unchecked; + } + + public void checkAll() { + getModel().checkAll(); + } + + public void clearAll() { + getModel().clearAll(); + } + + /** + * Resets checked elements + * @param elements + */ + public void setCheckedItems(Collection elements) { + getModel().setCheckedItems(elements); + } + + public void setUncheckedItems( Collection elements ) { + getModel().setUncheckedItems(elements); + } + + public void toggleIndex(int index) { + if (index >= 0 && index < list.getModel().getSize()) { + DefaultCheckListModel model = getModel(); + model.setCheckedIndex(index, !model.isCheckedIndex(index)); + } + } + +} diff --git a/swing/src/net/sf/openrocket/gui/util/CheckListEditor.java b/swing/src/net/sf/openrocket/gui/util/CheckListEditor.java new file mode 100644 index 000000000..68680670f --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/util/CheckListEditor.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2009-2011, EzWare + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer.Redistributions + * in binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution.Neither the name of the + * EzWare nor the names of its contributors may be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +package net.sf.openrocket.gui.util; + +import java.awt.Rectangle; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.Arrays; + +import javax.swing.JList; +import javax.swing.SwingUtilities; + + +/** + * Determines mouse click and + * 1. Toggles the check on selected item if clicked once + * 2. Clears checks and checks selected item if clicked more then once + * + * Created on Feb 4, 2011 + * @author Eugene Ryzhikov + * + */ +final class CheckListEditor extends MouseAdapter { + @Override + public void mouseClicked(MouseEvent e) { + + if (!SwingUtilities.isLeftMouseButton(e)) + return; + + JList list = (JList) e.getSource(); + if (!list.isEnabled() || (!(list.getModel() instanceof DefaultCheckListModel))) + return; + + int index = list.locationToIndex(e.getPoint()); + if (index < 0) + return; + + Rectangle bounds = list.getCellBounds(index, index); + + if (bounds.contains(e.getPoint())) { + + @SuppressWarnings("unchecked") + DefaultCheckListModel model = (DefaultCheckListModel) list.getModel(); + + if (e.getClickCount() > 1) { + // clear all and check selected for more then 1 clicks + // Original implementation had this implementation. I didn't like that behavior. +// model.setCheckedItems(Arrays.asList(model.getElementAt(index))); + } else { + // simple toggle for 1 click + model.setCheckedIndex(index, !model.isCheckedIndex(index)); + } + e.consume(); + } + + } + +} diff --git a/swing/src/net/sf/openrocket/gui/util/CheckListRenderer.java b/swing/src/net/sf/openrocket/gui/util/CheckListRenderer.java new file mode 100644 index 000000000..e0777c4f9 --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/util/CheckListRenderer.java @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2009-2011, EzWare + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer.Redistributions + * in binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution.Neither the name of the + * EzWare nor the names of its contributors may be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +package net.sf.openrocket.gui.util; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Rectangle; +import java.io.Serializable; + +import javax.swing.DefaultListCellRenderer; +import javax.swing.Icon; +import javax.swing.JCheckBox; +import javax.swing.JList; +import javax.swing.ListCellRenderer; +import javax.swing.UIManager; +import javax.swing.border.Border; +import javax.swing.border.EmptyBorder; + +public class CheckListRenderer extends JCheckBox implements ListCellRenderer, Serializable { + + private static final long serialVersionUID = 1L; + + private static final Border NO_FOCUS_BORDER = new EmptyBorder(1, 1, 1, 1); + private static final Border SAFE_NO_FOCUS_BORDER = NO_FOCUS_BORDER; // may change in the feature + + /** + * Constructs a default renderer object for an item in a list. + */ + public CheckListRenderer() { + super(); + setOpaque(true); + setBorder(getNoFocusBorder()); + } + + private static Border getNoFocusBorder() { + if (System.getSecurityManager() != null) { + return SAFE_NO_FOCUS_BORDER; + } else { + return NO_FOCUS_BORDER; + } + } + + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, + boolean cellHasFocus) { + + setComponentOrientation(list.getComponentOrientation()); + + Color bg = null; + Color fg = null; + + JList.DropLocation dropLocation = list.getDropLocation(); + if (dropLocation != null && !dropLocation.isInsert() && dropLocation.getIndex() == index) { + + bg = UIManager.getColor("List.dropCellBackground"); + fg = UIManager.getColor("List.dropCellForeground"); + + isSelected = true; + } + + if (isSelected) { + setBackground(bg == null ? list.getSelectionBackground() : bg); + setForeground(fg == null ? list.getSelectionForeground() : fg); + } else { + setBackground(list.getBackground()); + setForeground(list.getForeground()); + } + + if (value instanceof Icon) { + setIcon((Icon) value); + setText(""); + } else { + setIcon(null); + setText(getObjectAsText(value)); + } + + setSelected(isChecked(list, index)); + + setEnabled(list.isEnabled()); + setFont(list.getFont()); + + Border border = null; + if (cellHasFocus) { + if (isSelected) { + border = UIManager.getBorder("List.focusSelectedCellHighlightBorder"); + } + if (border == null) { + border = UIManager.getBorder("List.focusCellHighlightBorder"); + } + } else { + border = getNoFocusBorder(); + } + setBorder(border); + + return this; + } + + protected String getObjectAsText(Object obj) { + return (obj == null) ? "" : obj.toString(); + } + + private boolean isChecked(JList list, int index) { + + if (list.getModel() instanceof DefaultCheckListModel) { + return ((DefaultCheckListModel) list.getModel()).isCheckedIndex(index); + } else { + return false; + } + + } + + /** + * @return true if the background is opaque and differs from the JList's background; false otherwise + */ + @Override + public boolean isOpaque() { + Color back = getBackground(); + Component p = getParent(); + if (p != null) { + p = p.getParent(); + } + // p should now be the JList. + boolean colorMatch = (back != null) && (p != null) && back.equals(p.getBackground()) && p.isOpaque(); + return !colorMatch && super.isOpaque(); + } + + @Override + protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) { + + if ("text".equals(propertyName) || + (("font".equals(propertyName) || "foreground".equals(propertyName)) && + oldValue != newValue && getClientProperty(javax.swing.plaf.basic.BasicHTML.propertyKey) != null)) { + + super.firePropertyChange(propertyName, oldValue, newValue); + } + } + + // Methods below are overridden for performance reasons. + + @Override + public void validate() { + } + + @Override + public void invalidate() { + } + + @Override + public void repaint() { + } + + @Override + public void revalidate() { + } + + @Override + public void repaint(long tm, int x, int y, int width, int height) { + } + + @Override + public void repaint(Rectangle r) { + } + + @Override + public void firePropertyChange(String propertyName, byte oldValue, byte newValue) { + } + + @Override + public void firePropertyChange(String propertyName, char oldValue, char newValue) { + } + + @Override + public void firePropertyChange(String propertyName, short oldValue, short newValue) { + } + + @Override + public void firePropertyChange(String propertyName, int oldValue, int newValue) { + } + + @Override + public void firePropertyChange(String propertyName, long oldValue, long newValue) { + } + + @Override + public void firePropertyChange(String propertyName, float oldValue, float newValue) { + } + + @Override + public void firePropertyChange(String propertyName, double oldValue, double newValue) { + } + + @Override + public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) { + } + + @SuppressWarnings("serial") + public static class UIResource extends DefaultListCellRenderer implements javax.swing.plaf.UIResource { + } + +} \ No newline at end of file diff --git a/core/src/net/sf/openrocket/gui/util/ColorConversion.java b/swing/src/net/sf/openrocket/gui/util/ColorConversion.java similarity index 100% rename from core/src/net/sf/openrocket/gui/util/ColorConversion.java rename to swing/src/net/sf/openrocket/gui/util/ColorConversion.java diff --git a/core/src/net/sf/openrocket/gui/util/ConcurrentProgressMonitor.java b/swing/src/net/sf/openrocket/gui/util/ConcurrentProgressMonitor.java similarity index 100% rename from core/src/net/sf/openrocket/gui/util/ConcurrentProgressMonitor.java rename to swing/src/net/sf/openrocket/gui/util/ConcurrentProgressMonitor.java diff --git a/core/src/net/sf/openrocket/gui/util/ConcurrentProgressMonitorInputStream.java b/swing/src/net/sf/openrocket/gui/util/ConcurrentProgressMonitorInputStream.java similarity index 100% rename from core/src/net/sf/openrocket/gui/util/ConcurrentProgressMonitorInputStream.java rename to swing/src/net/sf/openrocket/gui/util/ConcurrentProgressMonitorInputStream.java diff --git a/core/src/net/sf/openrocket/gui/util/CustomFinImporter.java b/swing/src/net/sf/openrocket/gui/util/CustomFinImporter.java similarity index 100% rename from core/src/net/sf/openrocket/gui/util/CustomFinImporter.java rename to swing/src/net/sf/openrocket/gui/util/CustomFinImporter.java diff --git a/swing/src/net/sf/openrocket/gui/util/DefaultCheckListModel.java b/swing/src/net/sf/openrocket/gui/util/DefaultCheckListModel.java new file mode 100644 index 000000000..cbb4e5919 --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/util/DefaultCheckListModel.java @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2009-2011, EzWare + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer.Redistributions + * in binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution.Neither the name of the + * EzWare nor the names of its contributors may be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +package net.sf.openrocket.gui.util; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import javax.swing.AbstractListModel; + +/** + * Default model for check list. It is based on the list of items + * Implementation of checks is based on HashSet of checked items + * + * @author Eugene Ryzhikov + * + * @param list element type + */ +public class DefaultCheckListModel extends AbstractListModel { + + private static final long serialVersionUID = 1L; + + private final List data = new ArrayList(); + private final Set checks = new HashSet(); + + public DefaultCheckListModel(Collection data) { + + if (data == null) + return; + for (T object : data) { + this.data.add(object); + checks.clear(); + } + } + + public DefaultCheckListModel(T... data) { + this(Arrays.asList(data)); + } + + /* (non-Javadoc) + * @see org.oxbow.swingbits.list.ICheckListModel#getSize() + */ + @Override + public int getSize() { + return data().size(); + } + + private List data() { + return data; + } + + + @Override + public Object getElementAt(int index) { + return data().get(index); + } + + public boolean isCheckedIndex(int index) { + return checks.contains(data().get(index)); + } + + public void setCheckedIndex(int index, boolean value) { + T o = data().get(index); + if (value) + checks.add(o); + else + checks.remove(o); + fireContentsChanged(this, index, index); + } + + public Collection getCheckedItems() { + List items = new ArrayList(checks); + items.retainAll(data); + return Collections.unmodifiableList(items); + } + + public void clearAll() { + checks.clear(); + fireContentsChanged(this, 0, checks.size() - 1); + } + + public void checkAll() { + checks.addAll(data); + fireContentsChanged(this, 0, checks.size() - 1); + } + + public void setCheckedItems(Collection items) { + + // if ( CollectionUtils.isEmpty(items)) return; + + List correctedItems = new ArrayList(items); + correctedItems.retainAll(data); + + checks.clear(); + checks.addAll(correctedItems); + fireContentsChanged(this, 0, checks.size() - 1); + + + } + + public void setUncheckedItems( Collection items ) { + + List correctedItems = new ArrayList(data); + correctedItems.removeAll(items); + + checks.clear(); + checks.addAll(correctedItems); + fireContentsChanged(this, 0, checks.size() - 1); + + } +} diff --git a/core/src/net/sf/openrocket/gui/util/EditDecalHelper.java b/swing/src/net/sf/openrocket/gui/util/EditDecalHelper.java similarity index 100% rename from core/src/net/sf/openrocket/gui/util/EditDecalHelper.java rename to swing/src/net/sf/openrocket/gui/util/EditDecalHelper.java diff --git a/core/src/net/sf/openrocket/gui/util/FileHelper.java b/swing/src/net/sf/openrocket/gui/util/FileHelper.java similarity index 100% rename from core/src/net/sf/openrocket/gui/util/FileHelper.java rename to swing/src/net/sf/openrocket/gui/util/FileHelper.java diff --git a/core/src/net/sf/openrocket/gui/util/GUIUtil.java b/swing/src/net/sf/openrocket/gui/util/GUIUtil.java similarity index 100% rename from core/src/net/sf/openrocket/gui/util/GUIUtil.java rename to swing/src/net/sf/openrocket/gui/util/GUIUtil.java diff --git a/core/src/net/sf/openrocket/gui/util/Icons.java b/swing/src/net/sf/openrocket/gui/util/Icons.java similarity index 100% rename from core/src/net/sf/openrocket/gui/util/Icons.java rename to swing/src/net/sf/openrocket/gui/util/Icons.java diff --git a/core/src/net/sf/openrocket/gui/util/OpenFileWorker.java b/swing/src/net/sf/openrocket/gui/util/OpenFileWorker.java similarity index 100% rename from core/src/net/sf/openrocket/gui/util/OpenFileWorker.java rename to swing/src/net/sf/openrocket/gui/util/OpenFileWorker.java diff --git a/core/src/net/sf/openrocket/gui/util/ProgressOutputStream.java b/swing/src/net/sf/openrocket/gui/util/ProgressOutputStream.java similarity index 100% rename from core/src/net/sf/openrocket/gui/util/ProgressOutputStream.java rename to swing/src/net/sf/openrocket/gui/util/ProgressOutputStream.java diff --git a/core/src/net/sf/openrocket/gui/util/SaveCSVWorker.java b/swing/src/net/sf/openrocket/gui/util/SaveCSVWorker.java similarity index 100% rename from core/src/net/sf/openrocket/gui/util/SaveCSVWorker.java rename to swing/src/net/sf/openrocket/gui/util/SaveCSVWorker.java diff --git a/core/src/net/sf/openrocket/gui/util/SaveFileWorker.java b/swing/src/net/sf/openrocket/gui/util/SaveFileWorker.java similarity index 100% rename from core/src/net/sf/openrocket/gui/util/SaveFileWorker.java rename to swing/src/net/sf/openrocket/gui/util/SaveFileWorker.java diff --git a/core/src/net/sf/openrocket/gui/util/SwingPreferences.java b/swing/src/net/sf/openrocket/gui/util/SwingPreferences.java similarity index 92% rename from core/src/net/sf/openrocket/gui/util/SwingPreferences.java rename to swing/src/net/sf/openrocket/gui/util/SwingPreferences.java index d752c260a..9bdb5f2e9 100644 --- a/core/src/net/sf/openrocket/gui/util/SwingPreferences.java +++ b/swing/src/net/sf/openrocket/gui/util/SwingPreferences.java @@ -6,6 +6,7 @@ import java.awt.Point; import java.io.File; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; @@ -14,12 +15,10 @@ import java.util.Set; import java.util.prefs.BackingStoreException; import java.util.prefs.Preferences; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import net.sf.openrocket.arch.SystemInfo; import net.sf.openrocket.document.Simulation; import net.sf.openrocket.material.Material; +import net.sf.openrocket.motor.Manufacturer; import net.sf.openrocket.preset.ComponentPreset; import net.sf.openrocket.rocketcomponent.Rocket; import net.sf.openrocket.simulation.FlightDataType; @@ -30,6 +29,9 @@ import net.sf.openrocket.unit.UnitGroup; import net.sf.openrocket.util.BugException; import net.sf.openrocket.util.BuildProperties; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + public class SwingPreferences extends net.sf.openrocket.startup.Preferences { private static final Logger log = LoggerFactory.getLogger(SwingPreferences.class); @@ -575,9 +577,9 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences { return materials; } - + //// Preset Component Favorites - + @Override public void setComponentFavorite(ComponentPreset preset, ComponentPreset.Type type, boolean favorite) { Preferences prefs = PREFNODE.node("favoritePresets").node(type.name()); @@ -599,35 +601,67 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences { } return collection; } - + //// Decal Editor Setting private final static String DECAL_EDITOR_PREFERNCE_NODE = "decalEditorPreference"; private final static String DECAL_EDITOR_USE_SYSTEM_DEFAULT = ""; - public void clearDecalEditorPreference( ) { - putString(DECAL_EDITOR_PREFERNCE_NODE,null); + public void clearDecalEditorPreference() { + putString(DECAL_EDITOR_PREFERNCE_NODE, null); } + public void setDecalEditorPreference(boolean useSystem, String commandLine) { - if ( useSystem ) { - putString(DECAL_EDITOR_PREFERNCE_NODE,DECAL_EDITOR_USE_SYSTEM_DEFAULT); - } else if ( commandLine != null ) { + if (useSystem) { + putString(DECAL_EDITOR_PREFERNCE_NODE, DECAL_EDITOR_USE_SYSTEM_DEFAULT); + } else if (commandLine != null) { putString(DECAL_EDITOR_PREFERNCE_NODE, commandLine); } else { clearDecalEditorPreference(); } } - + public boolean isDecalEditorPreferenceSet() { - String s = getString(DECAL_EDITOR_PREFERNCE_NODE,null); + String s = getString(DECAL_EDITOR_PREFERNCE_NODE, null); return s != null; } public boolean isDecalEditorPreferenceSystem() { - String s = getString(DECAL_EDITOR_PREFERNCE_NODE,null); + String s = getString(DECAL_EDITOR_PREFERNCE_NODE, null); return DECAL_EDITOR_USE_SYSTEM_DEFAULT.equals(s); } + public String getDecalEditorCommandLine() { - return getString(DECAL_EDITOR_PREFERNCE_NODE,null); + return getString(DECAL_EDITOR_PREFERNCE_NODE, null); } + public List getExcludedMotorManufacturers() { + Preferences prefs = PREFNODE.node("excludedMotorManufacturers"); + List collection = new ArrayList(); + try { + String[] manuShortNames = prefs.keys(); + for (String s : manuShortNames) { + Manufacturer m = Manufacturer.getManufacturer(s); + if (m != null) { + collection.add(m); + } + } + } catch (BackingStoreException e) { + } + + return collection; + + } + + public void setExcludedMotorManufacturers(Collection manus) { + Preferences prefs = PREFNODE.node("excludedMotorManufacturers"); + try { + for (String s : prefs.keys()) { + prefs.remove(s); + } + } catch (BackingStoreException e) { + } + for (Manufacturer m : manus) { + prefs.putBoolean(m.getSimpleName(), true); + } + } } diff --git a/core/src/net/sf/openrocket/gui/watcher/FileWatcher.java b/swing/src/net/sf/openrocket/gui/watcher/FileWatcher.java similarity index 100% rename from core/src/net/sf/openrocket/gui/watcher/FileWatcher.java rename to swing/src/net/sf/openrocket/gui/watcher/FileWatcher.java diff --git a/core/src/net/sf/openrocket/gui/watcher/WatchEvent.java b/swing/src/net/sf/openrocket/gui/watcher/WatchEvent.java similarity index 100% rename from core/src/net/sf/openrocket/gui/watcher/WatchEvent.java rename to swing/src/net/sf/openrocket/gui/watcher/WatchEvent.java diff --git a/core/src/net/sf/openrocket/gui/watcher/WatchKey.java b/swing/src/net/sf/openrocket/gui/watcher/WatchKey.java similarity index 100% rename from core/src/net/sf/openrocket/gui/watcher/WatchKey.java rename to swing/src/net/sf/openrocket/gui/watcher/WatchKey.java diff --git a/core/src/net/sf/openrocket/gui/watcher/WatchService.java b/swing/src/net/sf/openrocket/gui/watcher/WatchService.java similarity index 100% rename from core/src/net/sf/openrocket/gui/watcher/WatchService.java rename to swing/src/net/sf/openrocket/gui/watcher/WatchService.java diff --git a/core/src/net/sf/openrocket/gui/watcher/WatchServiceImpl.java b/swing/src/net/sf/openrocket/gui/watcher/WatchServiceImpl.java similarity index 100% rename from core/src/net/sf/openrocket/gui/watcher/WatchServiceImpl.java rename to swing/src/net/sf/openrocket/gui/watcher/WatchServiceImpl.java diff --git a/core/src/net/sf/openrocket/gui/watcher/Watchable.java b/swing/src/net/sf/openrocket/gui/watcher/Watchable.java similarity index 100% rename from core/src/net/sf/openrocket/gui/watcher/Watchable.java rename to swing/src/net/sf/openrocket/gui/watcher/Watchable.java diff --git a/swing/src/net/sf/openrocket/gui/widgets/MultiSlider.java b/swing/src/net/sf/openrocket/gui/widgets/MultiSlider.java new file mode 100644 index 000000000..544b91287 --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/widgets/MultiSlider.java @@ -0,0 +1,572 @@ +package net.sf.openrocket.gui.widgets; +/* ------------------------------------------------------------------- + * GeoVISTA Center (Penn State, Dept. of Geography) + * + * Java source file for the class MultiSlider + * + * Copyright (c), 1999 - 2002, Masahiro Takatsuka and GeoVISTA Center + * All Rights Researved. + * + * Original Author: Masahiro Takatsuka + * $Author: eytanadar $ + * + * $Date: 2005/10/05 20:19:52 $ + * + * + * Reference: Document no: + * ___ ___ + * + * To Do: + * ___ + * + ------------------------------------------------------------------- */ + +/* --------------------------- Package ---------------------------- */ + +import java.awt.Color; + +import javax.accessibility.AccessibleContext; +import javax.accessibility.AccessibleState; +import javax.swing.BoundedRangeModel; +import javax.swing.DefaultBoundedRangeModel; +import javax.swing.JComponent; +import javax.swing.JSlider; +import javax.swing.plaf.SliderUI; + +/*==================================================================== + Implementation of class MultiSlider + ====================================================================*/ +/*** + * A component that lets the user graphically select values by slding + * multiple thumbs within a bounded interval. MultiSlider inherits all + * fields and methods from javax.swing.JSlider. + *

+ * + * @version $Revision: 1.1 $ + * @author Masahiro Takatsuka (masa@jbeans.net) + * @see JSlider + */ + +public class MultiSlider extends JSlider { + /*** + * @see #getUIClassID + * @see #readObject + */ + private static final String uiClassID = "MultiSliderUI"; + + /*** + * An array of data models that handle the numeric maximum values, + * minimum values, and current-position values for the multi slider. + */ + private BoundedRangeModel[] sliderModels; + + /*** + * If it is true, a thumb is bounded by adjacent thumbs. + */ + private boolean bounded = false; + + /*** + * This is a color to paint the current thumb + */ + private Color currentThumbColor = Color.red; + + transient private int valueBeforeStateChange; + + /*** + * Creates a slider with the specified orientation and the + * specified mimimum, maximum, and initial values. + * + * @exception IllegalArgumentException if orientation is not one of VERTICAL, HORIZONTAL + * + * @see #setOrientation + * @see #setMinimum + * @see #setMaximum + * @see #setValue + */ + public MultiSlider(int orientation, int min, int max, + int val1, int val2) { + checkOrientation(orientation); + this.orientation = orientation; + setNumberOfThumbs(min,max,new int[]{val1,val2}); + } + + /*** + * Creates a slider with the specified orientation and the + * specified mimimum, maximum, and the number of thumbs. + * + * @exception IllegalArgumentException if orientation is not one of VERTICAL, HORIZONTAL + * + * @see #setOrientation + * @see #setMinimum + * @see #setMaximum + * @see #setValue + */ + public MultiSlider(int orientation, int min, int max) { + checkOrientation(orientation); + this.orientation = orientation; + setNumberOfThumbs(min, max, 2); + } + + /*** + * Creates a horizontal slider with the range 0 to 100 and + * an intitial value of 50. + */ + public MultiSlider() { + this(HORIZONTAL, 0, 100); + } + + + /*** + * Creates a slider using the specified orientation with the + * range 0 to 100 and an intitial value of 50. + */ + public MultiSlider(int orientation) { + this(orientation, 0, 100); + } + + + /*** + * Creates a horizontal slider using the specified min and max + * with an intitial value of 50. + */ + public MultiSlider(int min, int max) { + this(HORIZONTAL, min, max); + } + + public void setCurrentThumbColor(Color c) { + this.currentThumbColor = c; + } + + public Color getCurrentThumbColor() { + return this.currentThumbColor; + } + + public int getTrackBuffer() { + return ((MultiSliderUI) this.ui).getTrackBuffer(); + } + + /*** + * Validates the orientation parameter. + */ + private void checkOrientation(int orientation) { + switch (orientation) { + case VERTICAL: + case HORIZONTAL: + break; + default: + throw new IllegalArgumentException("orientation must be one of: VERTICAL, HORIZONTAL"); + } + } + + /*** + * Notification from the UIFactory that the L&F has changed. + * Called to replace the UI with the latest version from the + * default UIFactory. + * + * @see JComponent#updateUI + */ + public void updateUI() { + updateLabelUIs(); + MultiSliderUI ui = new MultiSliderUI(); + if (this.sliderModels != null) { + ui.setThumbCount(this.sliderModels.length); + } + setUI((SliderUI) ui); + } + + /*** + * Returns the number of thumbs in the slider. + */ + public int getNumberOfThumbs() { + return this.sliderModels.length; + } + + /*** + * Sets the number of thumbs with the specified parameters. + */ + private void setNumberOfThumbs(int min, int max, int num, boolean useEndPoints) { + int [] values = createDefaultValues(min, max, num, useEndPoints); + setNumberOfThumbs(min, max, values); + } + + /*** + * Sets the number of thumbs with the specified parameters. + */ + private void setNumberOfThumbs(int min, int max, int num) { + setNumberOfThumbs(min, max, num, false); + } + + /*** + * Sets the number of thumbs with the specified parameters. + */ + private void setNumberOfThumbs(int min, int max, int[] values) { + if (values == null || values.length < 1) { + values = new int[] {50}; + } + int num = values.length; + this.sliderModels = new BoundedRangeModel[num]; + for (int i = 0; i < num; i++) { + this.sliderModels[i] = new DefaultBoundedRangeModel(values[i], 0, min, max); + this.sliderModels[i].addChangeListener(changeListener); + } + updateUI(); + } + + /*** + * Sets the number of thumbs. + */ + private void setNumberOfThumbs(int num) { + setNumberOfThumbs(num, false); + } + + /*** + * Sets the number of thumbs. + */ + private void setNumberOfThumbs(int num, boolean useEndPoints) { + if (getNumberOfThumbs() != num) { + setNumberOfThumbs(getMinimum(), getMaximum(), num, useEndPoints); + } + } + + /*** + * Sets the number of thumbs by specifying the initial values. + */ + private void setNumberOfThumbs(int[] values) { + setNumberOfThumbs(getMinimum(), getMaximum(), values); + } + + /*** + * creates evenly spaced values for thumbs. + */ + private int[] createDefaultValues(int min, int max, int num_of_values, boolean useEndPoints) { + int[] values = new int[num_of_values]; + int range = max - min; + + if (!useEndPoints) { + int step = range / (num_of_values + 1); + for (int i = 0; i < num_of_values; i++) { + values[i] = min + (i + 1) * step; + } + } else { + if (num_of_values < 1) { + return new int[0]; + } + values[0] = getMinimum(); + values[num_of_values - 1] = getMaximum(); + int[] def = createDefaultValues(getMinimum(), getMaximum(), num_of_values - 2, false); + for (int i = 0; i < def.length; i++) { + values[i + 1] = def[i]; + } + } + return values; + } + + /*** + * Returns the index number of currently operated thumb. + */ + public int getCurrentThumbIndex() { + return ((MultiSliderUI)ui).getCurrentIndex(); + } + + /*** + * Returns data model that handles the sliders three + * fundamental properties: minimum, maximum, value. + * + * @see #setModel + */ + public BoundedRangeModel getModel() { + return getModelAt(getCurrentThumbIndex()); + } + + /*** + * Returns data model that handles the sliders three + * fundamental properties: minimum, maximum, value. + * + * @see #setModel + */ + public BoundedRangeModel getModelAt(int index) { + if (this.sliderModels == null || index >= this.sliderModels.length) { + return null; + } + return this.sliderModels[index]; + } + + /*** + * Returns data model that handles the sliders three + * fundamental properties: minimum, maximum, value. + * + * @see #setModel + */ + public BoundedRangeModel[] getModels() { + return this.sliderModels; + } + + /*** + * Sets the model that handles the sliders three + * fundamental properties: minimum, maximum, value. + * + * @see #getModel + * @beaninfo + * bound: true + * description: The sliders BoundedRangeModel. + */ + public void setModel(BoundedRangeModel newModel) { + // Hack around jdk 7 problem: http://code.google.com/p/geoviz/issues/detail?id=80 + + try + { + setModelAt(getCurrentThumbIndex(), newModel); + + } + catch (Exception e) + { + this.sliderModel = newModel; + } + } + + /*** + * Sets the model that handles the sliders three + * fundamental properties: minimum, maximum, value. + * + * @see #getModel + * @beaninfo + * bound: true + * description: The sliders BoundedRangeModel. + */ + public void setModelAt(int index, BoundedRangeModel newModel) { + BoundedRangeModel oldModel = getModelAt(index); + + if (oldModel != null) { + oldModel.removeChangeListener(changeListener); + } + + this.sliderModels[index] = newModel; + + if (newModel != null) { + newModel.addChangeListener(changeListener); + + if (accessibleContext != null) { + accessibleContext.firePropertyChange( + AccessibleContext.ACCESSIBLE_VALUE_PROPERTY, + (oldModel == null + ? null : new Integer(oldModel.getValue())), + (newModel == null + ? null : new Integer(newModel.getValue()))); + } + } + + firePropertyChange("model", oldModel, this.sliderModels[index]); + } + + /*** + * Sets the models minimum property. + * + * @see #getMinimum + * @see BoundedRangeModel#setMinimum + * @beaninfo + * bound: true + * preferred: true + * description: The sliders minimum value. + */ + public void setMinimum(int minimum) { + int count = getNumberOfThumbs(); + int oldMin = getModel().getMinimum(); + for (int i = 0; i < count; i++) { + getModelAt(i).setMinimum(minimum); + } + firePropertyChange( "minimum", new Integer( oldMin ), new Integer( minimum ) ); + } + + /*** + * Sets the models maximum property. + * + * @see #getMaximum + * @see BoundedRangeModel#setMaximum + * @beaninfo + * bound: true + * preferred: true + * description: The sliders maximum value. + */ + public void setMaximum(int maximum) { + int count = getNumberOfThumbs(); + int oldMax = getModel().getMaximum(); + for (int i = 0; i < count; i++) { + getModelAt(i).setMaximum(maximum); + } + firePropertyChange( "maximum", new Integer( oldMax ), new Integer( maximum ) ); + } + + /*** + * Returns the sliders value. + * @return the models value property + * @see #setValue + */ + public int getValue() { + // Hack around jdk 7 problem: http://code.google.com/p/geoviz/issues/detail?id=80 + try + { + return getValueAt(getCurrentThumbIndex()); + + } + catch (Exception e) + { + return 0; + } + } + + /*** + * Returns the sliders value. + * @return the models value property + * @see #setValue + */ + public int getValueAt(int index) { + return getModelAt(index).getValue(); + } + + /*** + * Sets the sliders current value. This method just forwards + * the value to the model. + * + * @see #getValue + * @beaninfo + * preferred: true + * description: The sliders current value. + */ + public void setValue(int n) { + setValueAt(getCurrentThumbIndex(), n); + } + + /*** + * Sets the sliders current value. This method just forwards + * the value to the model. + * + * @see #getValue + * @beaninfo + * preferred: true + * description: The sliders current value. + */ + public void setValueAt(int index, int n) { + BoundedRangeModel m = getModelAt(index); + int oldValue = m.getValue(); + m.setValue(n); + + if (accessibleContext != null) { + accessibleContext.firePropertyChange( + AccessibleContext.ACCESSIBLE_VALUE_PROPERTY, + new Integer(oldValue), + new Integer(m.getValue())); + } + } + + /*** + * True if the slider knob is being dragged. + * + * @return the value of the models valueIsAdjusting property + * @see #setValueIsAdjusting + */ + public boolean getValueIsAdjusting() { + boolean result = false; + int count = getNumberOfThumbs(); + for (int i = 0; i < count; i++) { + result = (result || getValueIsAdjustingAt(i)); + } + return result; + } + + /*** + * True if the slider knob is being dragged. + */ + public boolean getValueIsAdjustingAt(int index) { + return getModelAt(index).getValueIsAdjusting(); + } + + /*** + * Sets the models valueIsAdjusting property. Slider look and + * feel implementations should set this property to true when + * a knob drag begins, and to false when the drag ends. The + * slider model will not generate ChangeEvents while + * valueIsAdjusting is true. + * + * @see #getValueIsAdjusting + * @see BoundedRangeModel#setValueIsAdjusting + * @beaninfo + * expert: true + * description: True if the slider knob is being dragged. + */ + public void setValueIsAdjusting(boolean b) { + setValueIsAdjustingAt(getCurrentThumbIndex(), b); + } + + /*** + * Sets the models valueIsAdjusting property. Slider look and + * feel implementations should set this property to true when + * a knob drag begins, and to false when the drag ends. The + * slider model will not generate ChangeEvents while + * valueIsAdjusting is true. + */ + public void setValueIsAdjustingAt(int index, boolean b) { + BoundedRangeModel m = getModelAt(index); + boolean oldValue = m.getValueIsAdjusting(); + m.setValueIsAdjusting(b); + + if ((oldValue != b) && (accessibleContext != null)) { + accessibleContext.firePropertyChange( + AccessibleContext.ACCESSIBLE_STATE_PROPERTY, + ((oldValue) ? AccessibleState.BUSY : null), + ((b) ? AccessibleState.BUSY : null)); + } + } + + /*** + * Sets the size of the range "covered" by the knob. Most look + * and feel implementations will change the value by this amount + * if the user clicks on either side of the knob. + * + * @see #getExtent + * @see BoundedRangeModel#setExtent + * @beaninfo + * expert: true + * description: Size of the range covered by the knob. + */ + public void setExtent(int extent) { + int count = getNumberOfThumbs(); + for (int i = 0; i < count; i++) { + getModelAt(i).setExtent(extent); + } + } + + + /*** + * Sets a bounded attribute of a slider thumb. + *

+	 * 
+ * + * @param b + * @return void + */ + public void setBounded(boolean b) { + this.bounded = b; + } + + /*** + * Returns a bounded attribute of a slider thumb. + *
+	 * 
+ * + * @return boolean + */ + public boolean isBounded() { + return this.bounded; + } + + public int getValueBeforeStateChange() { + return this.valueBeforeStateChange; + } + + void setValueBeforeStateChange(int v) { + this.valueBeforeStateChange = v; + } +} + + + diff --git a/swing/src/net/sf/openrocket/gui/widgets/MultiSliderUI.java b/swing/src/net/sf/openrocket/gui/widgets/MultiSliderUI.java new file mode 100644 index 000000000..5bbfa31d4 --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/widgets/MultiSliderUI.java @@ -0,0 +1,612 @@ +package net.sf.openrocket.gui.widgets; +/* ------------------------------------------------------------------- + * GeoVISTA Center (Penn State, Dept. of Geography) + * + * Java source file for the class MultiSliderUI + * + * Copyright (c), 1999 - 2002, Masahiro Takatsuka and GeoVISTA Center + * All Rights Researved. + * + * Original Author: Masahiro Takatsuka + * $Author: eytanadar $ + * + * $Date: 2005/10/05 20:19:52 $ + * + * + * Reference: Document no: + * ___ ___ + * + * To Do: + * ___ + * +------------------------------------------------------------------- */ + +/* --------------------------- Package ---------------------------- */ +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Rectangle; +import java.awt.event.ActionEvent; +import java.awt.event.MouseEvent; + +import javax.swing.AbstractAction; +import javax.swing.BoundedRangeModel; +import javax.swing.JComponent; +import javax.swing.JSlider; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.basic.BasicSliderUI; +import javax.swing.plaf.metal.MetalSliderUI; + +/*==================================================================== + Implementation of class MultiSliderUI + ====================================================================*/ +/*** + * A Basic L&F implementation of SliderUI. + * + * @version $Revision: 1.1 $ + * @author Masahiro Takatsuka (masa@jbeans.net) + * @see MetalSliderUI + */ + +class MultiSliderUI extends BasicSliderUI { + private Rectangle[] thumbRects = null; + + private int thumbCount; + transient private int currentIndex = 0; + + transient private boolean isDragging; + transient private int[] minmaxIndices = new int[2]; + + /*** + * ComponentUI Interface Implementation methods + */ + public static ComponentUI createUI(JComponent b) { + return new MultiSliderUI(); + } + + /*** + * Construct a new MultiSliderUI object. + */ + public MultiSliderUI() { + super(null); + } + + int getTrackBuffer() { + return this.trackBuffer; + } + + /*** + * Sets the number of Thumbs. + */ + public void setThumbCount(int count) { + this.thumbCount = count; + } + + /*** + * Returns the index number of the thumb currently operated. + */ + protected int getCurrentIndex() { + return this.currentIndex; + } + + public void installUI(JComponent c) { + this.thumbRects = new Rectangle[this.thumbCount]; + for (int i = 0; i < this.thumbCount; i++) { + this.thumbRects[i] = new Rectangle(); + } + this.currentIndex = 0; + if (this.thumbCount > 0) { + thumbRect = this.thumbRects[this.currentIndex]; + } + super.installUI(c); + } + + public void uninstallUI(JComponent c) { + super.uninstallUI(c); + for (int i = 0; i < this.thumbCount; i++) { + this.thumbRects[i] = null; + } + this.thumbRects = null; + } + + protected void installListeners( JSlider slider ) { + slider.addMouseListener(trackListener); + slider.addMouseMotionListener(trackListener); + slider.addFocusListener(focusListener); + slider.addComponentListener(componentListener); + slider.addPropertyChangeListener( propertyChangeListener ); + for (int i = 0; i < this.thumbCount; i++) { + ((MultiSlider)slider).getModelAt(i).addChangeListener(changeListener); + } + } + + protected void uninstallListeners( JSlider slider ) { + slider.removeMouseListener(trackListener); + slider.removeMouseMotionListener(trackListener); + slider.removeFocusListener(focusListener); + slider.removeComponentListener(componentListener); + slider.removePropertyChangeListener( propertyChangeListener ); + for (int i = 0; i < this.thumbCount; i++) { + BoundedRangeModel model = ((MultiSlider)slider).getModelAt(i); + if (model != null) { + model.removeChangeListener(changeListener); + } + } + } + + protected void calculateThumbSize() { + Dimension size = getThumbSize(); + for (int i = 0; i < this.thumbCount; i++) { + this.thumbRects[i].setSize(size.width, size.height); + } + thumbRect.setSize(size.width, size.height); + } + + protected void calculateThumbLocation() { + MultiSlider slider = (MultiSlider) this.slider; + int majorTickSpacing = slider.getMajorTickSpacing(); + int minorTickSpacing = slider.getMinorTickSpacing(); + int tickSpacing = 0; + + if (minorTickSpacing > 0) { + tickSpacing = minorTickSpacing; + } else if (majorTickSpacing > 0) { + tickSpacing = majorTickSpacing; + } + for (int i = 0; i < this.thumbCount; i++) { + if (slider.getSnapToTicks()) { + int sliderValue = slider.getValueAt(i); + int snappedValue = sliderValue; + if (tickSpacing != 0) { + // If it's not on a tick, change the value + if ((sliderValue - slider.getMinimum()) % tickSpacing != 0 ) { + float temp = (float)(sliderValue - slider.getMinimum()) / (float)tickSpacing; + int whichTick = Math.round(temp); + snappedValue = slider.getMinimum() + (whichTick * tickSpacing); + } + + if( snappedValue != sliderValue ) { + slider.setValueAt(i, snappedValue); + } + } + } + + if (slider.getOrientation() == JSlider.HORIZONTAL) { + int valuePosition = xPositionForValue(slider.getValueAt(i)); + this.thumbRects[i].x = valuePosition - (this.thumbRects[i].width / 2); + this.thumbRects[i].y = trackRect.y; + } else { + int valuePosition = yPositionForValue(slider.getValueAt(i)); + this.thumbRects[i].x = trackRect.x; + this.thumbRects[i].y = valuePosition - (this.thumbRects[i].height / 2); + } + } + } + + public void paint(Graphics g, JComponent c) { + recalculateIfInsetsChanged(); + recalculateIfOrientationChanged(); + Rectangle clip = g.getClipBounds(); + + if (slider.getPaintTrack() && clip.intersects(trackRect)) { + paintTrack( g ); + } + if (slider.getPaintTicks() && clip.intersects(tickRect)) { + paintTicks( g ); + } + if (slider.getPaintLabels() && clip.intersects(labelRect)) { + paintLabels( g ); + } + if (slider.hasFocus() && clip.intersects(focusRect)) { + paintFocus( g ); + } + + // first paint unfocused thumbs. + for (int i = 0; i < this.thumbCount; i++) { + if (i != this.currentIndex) { + if (clip.intersects(this.thumbRects[i])) { + thumbRect = this.thumbRects[i]; + paintThumb(g); + } + } + } + // then paint currently focused thumb. + if (clip.intersects(this.thumbRects[this.currentIndex])) { + thumbRect = this.thumbRects[this.currentIndex]; + paintThumb(g); + } + } + + public void paintThumb(Graphics g) { + super.paintThumb(g); + } + + public void paintTrack(Graphics g) { + super.paintTrack(g); + } + + public void scrollByBlock(int direction) { + synchronized(slider) { + int oldValue = ((MultiSlider)slider).getValueAt(this.currentIndex); + int blockIncrement = slider.getMaximum() / 10; + int delta = blockIncrement * ((direction > 0) ? POSITIVE_SCROLL : NEGATIVE_SCROLL); + ((MultiSlider)slider).setValueAt(this.currentIndex, oldValue + delta); + } + } + + public void scrollByUnit(int direction) { + synchronized(slider) { + int oldValue = ((MultiSlider)slider).getValueAt(this.currentIndex); + int delta = 1 * ((direction > 0) ? POSITIVE_SCROLL : NEGATIVE_SCROLL); + ((MultiSlider)slider).setValueAt(this.currentIndex, oldValue + delta); + } + } + + protected TrackListener createTrackListener( JSlider slider ) { + return new MultiTrackListener(); + } + + /*** + * Track Listener Class tracks mouse movements. + */ + class MultiTrackListener extends BasicSliderUI.TrackListener { + int _trackTop; + int _trackBottom; + int _trackLeft; + int _trackRight; + transient private int[] firstXY = new int[2]; + + /*** + * If the mouse is pressed above the "thumb" component + * then reduce the scrollbars value by one page ("page up"), + * otherwise increase it by one page. If there is no + * thumb then page up if the mouse is in the upper half + * of the track. + */ + public void mousePressed(MouseEvent e) { + int[] neighbours = new int[2]; + boolean bounded = ((MultiSlider)slider).isBounded(); + if (!slider.isEnabled()) { + return; + } + + currentMouseX = e.getX(); + currentMouseY = e.getY(); + firstXY[0] = currentMouseX; + firstXY[1] = currentMouseY; + + slider.requestFocus(); + // Clicked in the Thumb area? + minmaxIndices[0] = -1; + minmaxIndices[1] = -1; + for (int i = 0; i < MultiSliderUI.this.thumbCount; i++) { + if (MultiSliderUI.this.thumbRects[i].contains(currentMouseX, currentMouseY)) { + if (minmaxIndices[0] == -1) { + minmaxIndices[0] = i; + MultiSliderUI.this.currentIndex = i; + } + if (minmaxIndices[1] < i) { + minmaxIndices[1] = i; + } + switch (slider.getOrientation()) { + case JSlider.VERTICAL: + offset = currentMouseY - MultiSliderUI.this.thumbRects[i].y; + break; + case JSlider.HORIZONTAL: + offset = currentMouseX - MultiSliderUI.this.thumbRects[i].x; + break; + } + MultiSliderUI.this.isDragging = true; + thumbRect = MultiSliderUI.this.thumbRects[i]; + if (bounded) { + neighbours[0] = ((i - 1) < 0) ? -1 : (i - 1); + neighbours[1] = ((i + 1) >= MultiSliderUI.this.thumbCount) ? -1 : (i + 1); + //findClosest(currentMouseX, currentMouseY, neighbours, i); + } else { + MultiSliderUI.this.currentIndex = i; + ((MultiSlider)slider).setValueIsAdjustingAt(i, true); + neighbours[0] = -1; + neighbours[1] = -1; + } + setThumbBounds(neighbours); + //return; + } + } + if (minmaxIndices[0] > -1) { + return; + } + + MultiSliderUI.this.currentIndex = findClosest(currentMouseX, currentMouseY, neighbours, -1); + thumbRect = MultiSliderUI.this.thumbRects[MultiSliderUI.this.currentIndex]; + MultiSliderUI.this.isDragging = false; + ((MultiSlider)slider).setValueIsAdjustingAt(MultiSliderUI.this.currentIndex, true); + + Dimension sbSize = slider.getSize(); + int direction = POSITIVE_SCROLL; + + switch (slider.getOrientation()) { + case JSlider.VERTICAL: + if (thumbRect.isEmpty()) { + int scrollbarCenter = sbSize.height / 2; + if (!drawInverted()) { + direction = (currentMouseY < scrollbarCenter) ? POSITIVE_SCROLL : NEGATIVE_SCROLL; + } else { + direction = (currentMouseY < scrollbarCenter) ? NEGATIVE_SCROLL : POSITIVE_SCROLL; + } + } else { + int thumbY = thumbRect.y; + if (!drawInverted()) { + direction = (currentMouseY < thumbY) ? POSITIVE_SCROLL : NEGATIVE_SCROLL; + } else { + direction = (currentMouseY < thumbY) ? NEGATIVE_SCROLL : POSITIVE_SCROLL; + } + } + break; + case JSlider.HORIZONTAL: + if (thumbRect.isEmpty() ) { + int scrollbarCenter = sbSize.width / 2; + if (!drawInverted()) { + direction = (currentMouseX < scrollbarCenter) ? NEGATIVE_SCROLL : POSITIVE_SCROLL; + } else { + direction = (currentMouseX < scrollbarCenter) ? POSITIVE_SCROLL : NEGATIVE_SCROLL; + } + } else { + int thumbX = thumbRect.x; + if (!drawInverted()) { + direction = (currentMouseX < thumbX) ? NEGATIVE_SCROLL : POSITIVE_SCROLL; + } else { + direction = (currentMouseX < thumbX) ? POSITIVE_SCROLL : NEGATIVE_SCROLL; + } + } + break; + } + scrollDueToClickInTrack(direction); + Rectangle r = thumbRect; + if ( !r.contains(currentMouseX, currentMouseY) ) { + if (shouldScroll(direction) ) { + scrollTimer.stop(); + scrollListener.setDirection(direction); + scrollTimer.start(); + } + } + } + + /*** + * Sets a track bound for th thumb currently operated. + */ + private void setThumbBounds(int[] neighbours) { + int halfThumbWidth = thumbRect.width / 2; + int halfThumbHeight = thumbRect.height / 2; + + switch (slider.getOrientation()) { + case JSlider.VERTICAL: + _trackTop = (neighbours[1] == -1) ? trackRect.y : MultiSliderUI.this.thumbRects[neighbours[1]].y + halfThumbHeight; + _trackBottom = (neighbours[0] == -1) ? trackRect.y + (trackRect.height - 1) : MultiSliderUI.this.thumbRects[neighbours[0]].y + halfThumbHeight; + break; + case JSlider.HORIZONTAL: + _trackLeft = (neighbours[0] == -1) ? trackRect.x : MultiSliderUI.this.thumbRects[neighbours[0]].x + halfThumbWidth; + _trackRight = (neighbours[1] == -1) ? trackRect.x + (trackRect.width - 1) : MultiSliderUI.this.thumbRects[neighbours[1]].x + halfThumbWidth; + break; + } + } + + /* + * this is a very lazy way to find the closest. One might want to + * implement a much faster algorithm. + */ + private int findClosest(int x, int y, int[] neighbours, int excluded) { + int orientation = slider.getOrientation(); + int rightmin = Integer.MAX_VALUE; // for dxw, dy + int leftmin = -Integer.MAX_VALUE; // for dx, dyh + int dx = 0; + int dxw = 0; + int dy = 0; + int dyh = 0; + neighbours[0] = -1; // left + neighbours[1] = -1; // right + for (int i = 0; i < MultiSliderUI.this.thumbCount; i++) { + if (i == excluded) { + continue; + } + switch (orientation) { + case JSlider.VERTICAL: + dy = MultiSliderUI.this.thumbRects[i].y - y; + dyh = (MultiSliderUI.this.thumbRects[i].y + MultiSliderUI.this.thumbRects[i].height) - y; + if (dyh <= 0) { + if (dyh > leftmin) { // has to be > and not >= + leftmin = dyh; + neighbours[0] = i; + } + } + if (dy >= 0) { + if (dy <= rightmin) { + rightmin = dy; + neighbours[1] = i; + } + } + break; + case JSlider.HORIZONTAL: + dx = MultiSliderUI.this.thumbRects[i].x - x; + dxw = (MultiSliderUI.this.thumbRects[i].x + MultiSliderUI.this.thumbRects[i].width) - x; + if (dxw <= 0) { + if (dxw >= leftmin) { + leftmin = dxw; + neighbours[0] = i; + } + } + if (dx >= 0) { + if (dx < rightmin) { // has to be < and not <= + rightmin = dx; + neighbours[1] = i; + } + } + break; + } + } + //System.out.println("neighbours = " + neighbours[0] + ", " + neighbours[1]); + int closest = (Math.abs(leftmin) <= Math.abs(rightmin)) ? neighbours[0] : neighbours[1]; + return (closest == -1) ? 0 : closest; + } + + /*** + * Set the models value to the position of the top/left + * of the thumb relative to the origin of the track. + */ + public void mouseDragged( MouseEvent e ) { + ((MultiSlider) MultiSliderUI.this.slider).setValueBeforeStateChange(((MultiSlider) MultiSliderUI.this.slider).getValueAt(MultiSliderUI.this.currentIndex)); + int thumbMiddle = 0; + boolean bounded = ((MultiSlider)slider).isBounded(); + + if (!slider.isEnabled()) { + return; + } + + currentMouseX = e.getX(); + currentMouseY = e.getY(); + + if (! MultiSliderUI.this.isDragging) { + return; + } + + switch (slider.getOrientation()) { + case JSlider.VERTICAL: + int halfThumbHeight = thumbRect.height / 2; + int thumbTop = e.getY() - offset; + if (bounded) { + int[] neighbours = new int[2]; + int idx = -1; + int diff = e.getY() - firstXY[1]; + //System.out.println("diff = " + diff); + if (e.getY() - firstXY[1] > 0) { + idx = minmaxIndices[0]; + } else { + idx = minmaxIndices[1]; + } + minmaxIndices[0] = minmaxIndices[1] = idx; + //System.out.println("idx = " + idx); + if (idx == -1) { + break; + } + + //System.out.println("thumbTop = " + thumbTop); + neighbours[0] = ((idx - 1) < 0) ? -1 : (idx - 1); + neighbours[1] = ((idx + 1) >= MultiSliderUI.this.thumbCount) ? -1 : (idx + 1); + thumbRect = MultiSliderUI.this.thumbRects[idx]; + MultiSliderUI.this.currentIndex = idx; + ((MultiSlider)slider).setValueIsAdjustingAt(idx, true); + setThumbBounds(neighbours); + } + + thumbTop = Math.max(thumbTop, _trackTop - halfThumbHeight); + thumbTop = Math.min(thumbTop, _trackBottom - halfThumbHeight); + + setThumbLocation(thumbRect.x, thumbTop); + + thumbMiddle = thumbTop + halfThumbHeight; + ((MultiSlider)slider).setValueAt(MultiSliderUI.this.currentIndex, valueForYPosition(thumbMiddle) ); + break; + case JSlider.HORIZONTAL: + int halfThumbWidth = thumbRect.width / 2; + int thumbLeft = e.getX() - offset; + if (bounded) { + int[] neighbours = new int[2]; + int idx = -1; + if (e.getX() - firstXY[0] <= 0) { + idx = minmaxIndices[0]; + } else { + idx = minmaxIndices[1]; + } + minmaxIndices[0] = minmaxIndices[1] = idx; + //System.out.println("idx = " + idx); + if (idx == -1) { + break; + } + //System.out.println("thumbLeft = " + thumbLeft); + neighbours[0] = ((idx - 1) < 0) ? -1 : (idx - 1); + neighbours[1] = ((idx + 1) >= MultiSliderUI.this.thumbCount) ? -1 : (idx + 1); + thumbRect = MultiSliderUI.this.thumbRects[idx]; + MultiSliderUI.this.currentIndex = idx; + ((MultiSlider)slider).setValueIsAdjustingAt(idx, true); + setThumbBounds(neighbours); + } + + thumbLeft = Math.max(thumbLeft, _trackLeft - halfThumbWidth); + thumbLeft = Math.min(thumbLeft, _trackRight - halfThumbWidth); + + setThumbLocation(thumbLeft, thumbRect.y); + + thumbMiddle = thumbLeft + halfThumbWidth; + + ((MultiSlider)slider).setValueAt(MultiSliderUI.this.currentIndex, valueForXPosition(thumbMiddle)); + break; + default: + return; + } + } + + public void mouseReleased(MouseEvent e) { + if (!slider.isEnabled()) { + return; + } + + offset = 0; + scrollTimer.stop(); + + if (slider.getSnapToTicks()) { + MultiSliderUI.this.isDragging = false; + ((MultiSlider)slider).setValueIsAdjustingAt(MultiSliderUI.this.currentIndex, false); + } else { + ((MultiSlider)slider).setValueIsAdjustingAt(MultiSliderUI.this.currentIndex, false); + MultiSliderUI.this.isDragging = false; + } + + slider.repaint(); + } + } + + /*** + * A static version of the above. + */ + static class SharedActionScroller extends AbstractAction { + int _dir; + boolean _block; + + public SharedActionScroller(int dir, boolean block) { + _dir = dir; + _block = block; + } + + public void actionPerformed(ActionEvent e) { + JSlider slider = (JSlider)e.getSource(); + MultiSliderUI ui = (MultiSliderUI)slider.getUI(); + if ( _dir == NEGATIVE_SCROLL || _dir == POSITIVE_SCROLL ) { + int realDir = _dir; + if (slider.getInverted()) { + realDir = _dir == NEGATIVE_SCROLL ? POSITIVE_SCROLL : NEGATIVE_SCROLL; + } + if (_block) { + ui.scrollByBlock(realDir); + } else { + ui.scrollByUnit(realDir); + } + } else { + if (slider.getInverted()) { + if (_dir == MIN_SCROLL) { + ((MultiSlider)slider).setValueAt(ui.currentIndex, + slider.getMaximum()); + } else if (_dir == MAX_SCROLL) { + ((MultiSlider)slider).setValueAt(ui.currentIndex, + slider.getMinimum()); + } + } else { + if (_dir == MIN_SCROLL) { + ((MultiSlider)slider).setValueAt(ui.currentIndex, + slider.getMinimum()); + } else if (_dir == MAX_SCROLL) { + ((MultiSlider)slider).setValueAt(ui.currentIndex, + slider.getMaximum()); + } + } + } + } + } +} diff --git a/core/src/net/sf/openrocket/logging/BufferLogger.java b/swing/src/net/sf/openrocket/logging/BufferLogger.java similarity index 100% rename from core/src/net/sf/openrocket/logging/BufferLogger.java rename to swing/src/net/sf/openrocket/logging/BufferLogger.java diff --git a/core/src/net/sf/openrocket/logging/CyclicBuffer.java b/swing/src/net/sf/openrocket/logging/CyclicBuffer.java similarity index 100% rename from core/src/net/sf/openrocket/logging/CyclicBuffer.java rename to swing/src/net/sf/openrocket/logging/CyclicBuffer.java diff --git a/core/src/net/sf/openrocket/logging/DelegatorLogger.java b/swing/src/net/sf/openrocket/logging/DelegatorLogger.java similarity index 100% rename from core/src/net/sf/openrocket/logging/DelegatorLogger.java rename to swing/src/net/sf/openrocket/logging/DelegatorLogger.java diff --git a/core/src/net/sf/openrocket/logging/LogHelper.java b/swing/src/net/sf/openrocket/logging/LogHelper.java similarity index 100% rename from core/src/net/sf/openrocket/logging/LogHelper.java rename to swing/src/net/sf/openrocket/logging/LogHelper.java diff --git a/core/src/net/sf/openrocket/logging/LogLevel.java b/swing/src/net/sf/openrocket/logging/LogLevel.java similarity index 100% rename from core/src/net/sf/openrocket/logging/LogLevel.java rename to swing/src/net/sf/openrocket/logging/LogLevel.java diff --git a/core/src/net/sf/openrocket/logging/LogLevelBufferLogger.java b/swing/src/net/sf/openrocket/logging/LogLevelBufferLogger.java similarity index 100% rename from core/src/net/sf/openrocket/logging/LogLevelBufferLogger.java rename to swing/src/net/sf/openrocket/logging/LogLevelBufferLogger.java diff --git a/core/src/net/sf/openrocket/logging/LogLine.java b/swing/src/net/sf/openrocket/logging/LogLine.java similarity index 100% rename from core/src/net/sf/openrocket/logging/LogLine.java rename to swing/src/net/sf/openrocket/logging/LogLine.java diff --git a/core/src/net/sf/openrocket/logging/LogbackBufferLoggerAdaptor.java b/swing/src/net/sf/openrocket/logging/LogbackBufferLoggerAdaptor.java similarity index 100% rename from core/src/net/sf/openrocket/logging/LogbackBufferLoggerAdaptor.java rename to swing/src/net/sf/openrocket/logging/LogbackBufferLoggerAdaptor.java diff --git a/core/src/net/sf/openrocket/logging/LoggingSystemSetup.java b/swing/src/net/sf/openrocket/logging/LoggingSystemSetup.java similarity index 100% rename from core/src/net/sf/openrocket/logging/LoggingSystemSetup.java rename to swing/src/net/sf/openrocket/logging/LoggingSystemSetup.java diff --git a/core/src/net/sf/openrocket/logging/PrintStreamLogger.java b/swing/src/net/sf/openrocket/logging/PrintStreamLogger.java similarity index 100% rename from core/src/net/sf/openrocket/logging/PrintStreamLogger.java rename to swing/src/net/sf/openrocket/logging/PrintStreamLogger.java diff --git a/core/src/net/sf/openrocket/logging/PrintStreamToSLF4J.java b/swing/src/net/sf/openrocket/logging/PrintStreamToSLF4J.java similarity index 100% rename from core/src/net/sf/openrocket/logging/PrintStreamToSLF4J.java rename to swing/src/net/sf/openrocket/logging/PrintStreamToSLF4J.java diff --git a/core/src/net/sf/openrocket/logging/StackTraceWriter.java b/swing/src/net/sf/openrocket/logging/StackTraceWriter.java similarity index 100% rename from core/src/net/sf/openrocket/logging/StackTraceWriter.java rename to swing/src/net/sf/openrocket/logging/StackTraceWriter.java diff --git a/core/src/net/sf/openrocket/logging/TraceException.java b/swing/src/net/sf/openrocket/logging/TraceException.java similarity index 100% rename from core/src/net/sf/openrocket/logging/TraceException.java rename to swing/src/net/sf/openrocket/logging/TraceException.java diff --git a/core/src/net/sf/openrocket/startup/GuiModule.java b/swing/src/net/sf/openrocket/startup/GuiModule.java similarity index 100% rename from core/src/net/sf/openrocket/startup/GuiModule.java rename to swing/src/net/sf/openrocket/startup/GuiModule.java diff --git a/core/src/net/sf/openrocket/startup/OSXSetup.java b/swing/src/net/sf/openrocket/startup/OSXSetup.java similarity index 100% rename from core/src/net/sf/openrocket/startup/OSXSetup.java rename to swing/src/net/sf/openrocket/startup/OSXSetup.java diff --git a/core/src/net/sf/openrocket/startup/Startup.java b/swing/src/net/sf/openrocket/startup/Startup.java similarity index 100% rename from core/src/net/sf/openrocket/startup/Startup.java rename to swing/src/net/sf/openrocket/startup/Startup.java diff --git a/core/src/net/sf/openrocket/startup/SwingStartup.java b/swing/src/net/sf/openrocket/startup/SwingStartup.java similarity index 100% rename from core/src/net/sf/openrocket/startup/SwingStartup.java rename to swing/src/net/sf/openrocket/startup/SwingStartup.java diff --git a/core/src/net/sf/openrocket/startup/jij/ClasspathProvider.java b/swing/src/net/sf/openrocket/startup/jij/ClasspathProvider.java similarity index 100% rename from core/src/net/sf/openrocket/startup/jij/ClasspathProvider.java rename to swing/src/net/sf/openrocket/startup/jij/ClasspathProvider.java diff --git a/core/src/net/sf/openrocket/startup/jij/ClasspathUrlStreamHandler.java b/swing/src/net/sf/openrocket/startup/jij/ClasspathUrlStreamHandler.java similarity index 100% rename from core/src/net/sf/openrocket/startup/jij/ClasspathUrlStreamHandler.java rename to swing/src/net/sf/openrocket/startup/jij/ClasspathUrlStreamHandler.java diff --git a/core/src/net/sf/openrocket/startup/jij/ConfigurableStreamHandlerFactory.java b/swing/src/net/sf/openrocket/startup/jij/ConfigurableStreamHandlerFactory.java similarity index 100% rename from core/src/net/sf/openrocket/startup/jij/ConfigurableStreamHandlerFactory.java rename to swing/src/net/sf/openrocket/startup/jij/ConfigurableStreamHandlerFactory.java diff --git a/core/src/net/sf/openrocket/startup/jij/CurrentClasspathProvider.java b/swing/src/net/sf/openrocket/startup/jij/CurrentClasspathProvider.java similarity index 100% rename from core/src/net/sf/openrocket/startup/jij/CurrentClasspathProvider.java rename to swing/src/net/sf/openrocket/startup/jij/CurrentClasspathProvider.java diff --git a/core/src/net/sf/openrocket/startup/jij/JarInJarStarter.java b/swing/src/net/sf/openrocket/startup/jij/JarInJarStarter.java similarity index 100% rename from core/src/net/sf/openrocket/startup/jij/JarInJarStarter.java rename to swing/src/net/sf/openrocket/startup/jij/JarInJarStarter.java diff --git a/core/src/net/sf/openrocket/startup/jij/ManifestClasspathProvider.java b/swing/src/net/sf/openrocket/startup/jij/ManifestClasspathProvider.java similarity index 100% rename from core/src/net/sf/openrocket/startup/jij/ManifestClasspathProvider.java rename to swing/src/net/sf/openrocket/startup/jij/ManifestClasspathProvider.java diff --git a/core/src/net/sf/openrocket/startup/jij/PluginClasspathProvider.java b/swing/src/net/sf/openrocket/startup/jij/PluginClasspathProvider.java similarity index 100% rename from core/src/net/sf/openrocket/startup/jij/PluginClasspathProvider.java rename to swing/src/net/sf/openrocket/startup/jij/PluginClasspathProvider.java diff --git a/core/src/net/sf/openrocket/startup/providers/BlockingComponentPresetDatabaseProvider.java b/swing/src/net/sf/openrocket/startup/providers/BlockingComponentPresetDatabaseProvider.java similarity index 100% rename from core/src/net/sf/openrocket/startup/providers/BlockingComponentPresetDatabaseProvider.java rename to swing/src/net/sf/openrocket/startup/providers/BlockingComponentPresetDatabaseProvider.java diff --git a/core/src/net/sf/openrocket/startup/providers/BlockingMotorDatabaseProvider.java b/swing/src/net/sf/openrocket/startup/providers/BlockingMotorDatabaseProvider.java similarity index 100% rename from core/src/net/sf/openrocket/startup/providers/BlockingMotorDatabaseProvider.java rename to swing/src/net/sf/openrocket/startup/providers/BlockingMotorDatabaseProvider.java diff --git a/core/src/net/sf/openrocket/startup/providers/TranslatorProvider.java b/swing/src/net/sf/openrocket/startup/providers/TranslatorProvider.java similarity index 100% rename from core/src/net/sf/openrocket/startup/providers/TranslatorProvider.java rename to swing/src/net/sf/openrocket/startup/providers/TranslatorProvider.java diff --git a/core/src/net/sf/openrocket/utils/BasicApplication.java b/swing/src/net/sf/openrocket/utils/BasicApplication.java similarity index 100% rename from core/src/net/sf/openrocket/utils/BasicApplication.java rename to swing/src/net/sf/openrocket/utils/BasicApplication.java diff --git a/core/src/net/sf/openrocket/utils/ComponentPresetEditor.java b/swing/src/net/sf/openrocket/utils/ComponentPresetEditor.java similarity index 100% rename from core/src/net/sf/openrocket/utils/ComponentPresetEditor.java rename to swing/src/net/sf/openrocket/utils/ComponentPresetEditor.java diff --git a/core/src/net/sf/openrocket/utils/CoreServicesModule.java b/swing/src/net/sf/openrocket/utils/CoreServicesModule.java similarity index 100% rename from core/src/net/sf/openrocket/utils/CoreServicesModule.java rename to swing/src/net/sf/openrocket/utils/CoreServicesModule.java diff --git a/core/src/net/sf/openrocket/utils/GraphicalMotorSelector.java b/swing/src/net/sf/openrocket/utils/GraphicalMotorSelector.java similarity index 100% rename from core/src/net/sf/openrocket/utils/GraphicalMotorSelector.java rename to swing/src/net/sf/openrocket/utils/GraphicalMotorSelector.java diff --git a/core/src/net/sf/openrocket/utils/MotorPlot.java b/swing/src/net/sf/openrocket/utils/MotorPlot.java similarity index 100% rename from core/src/net/sf/openrocket/utils/MotorPlot.java rename to swing/src/net/sf/openrocket/utils/MotorPlot.java diff --git a/core/src/net/sf/openrocket/utils/RocksimComponentFileTranslator.java b/swing/src/net/sf/openrocket/utils/RocksimComponentFileTranslator.java similarity index 100% rename from core/src/net/sf/openrocket/utils/RocksimComponentFileTranslator.java rename to swing/src/net/sf/openrocket/utils/RocksimComponentFileTranslator.java diff --git a/core/src/net/sf/openrocket/utils/RocksimConverter.java b/swing/src/net/sf/openrocket/utils/RocksimConverter.java similarity index 100% rename from core/src/net/sf/openrocket/utils/RocksimConverter.java rename to swing/src/net/sf/openrocket/utils/RocksimConverter.java diff --git a/core/src/net/sf/openrocket/utils/SerializePresets.java b/swing/src/net/sf/openrocket/utils/SerializePresets.java similarity index 100% rename from core/src/net/sf/openrocket/utils/SerializePresets.java rename to swing/src/net/sf/openrocket/utils/SerializePresets.java diff --git a/swing/test/net/sf/openrocket/Estes_A8.rse b/swing/test/net/sf/openrocket/Estes_A8.rse new file mode 100644 index 000000000..1098ffe10 --- /dev/null +++ b/swing/test/net/sf/openrocket/Estes_A8.rse @@ -0,0 +1,40 @@ + + + +Estes A8 RASP.ENG file made from NAR published data +File produced October 3, 2000 +The total impulse, peak thrust, average thrust and burn time are +the same as the averaged static test data on the NAR web site in +the certification file. The curve drawn with these data points is as +close to the certification curve as can be with such a limited +number of points (32) allowed with wRASP up to v1.6. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/test/net/sf/openrocket/IntegrationTest.java b/swing/test/net/sf/openrocket/IntegrationTest.java similarity index 100% rename from core/test/net/sf/openrocket/IntegrationTest.java rename to swing/test/net/sf/openrocket/IntegrationTest.java diff --git a/core/test/net/sf/openrocket/gui/TestGUI.java b/swing/test/net/sf/openrocket/gui/TestGUI.java similarity index 100% rename from core/test/net/sf/openrocket/gui/TestGUI.java rename to swing/test/net/sf/openrocket/gui/TestGUI.java diff --git a/core/test/net/sf/openrocket/gui/configdialog/FinSetConfigTest.java b/swing/test/net/sf/openrocket/gui/configdialog/FinSetConfigTest.java similarity index 100% rename from core/test/net/sf/openrocket/gui/configdialog/FinSetConfigTest.java rename to swing/test/net/sf/openrocket/gui/configdialog/FinSetConfigTest.java diff --git a/core/test/net/sf/openrocket/gui/print/PrintUnitTest.java b/swing/test/net/sf/openrocket/gui/print/PrintUnitTest.java similarity index 100% rename from core/test/net/sf/openrocket/gui/print/PrintUnitTest.java rename to swing/test/net/sf/openrocket/gui/print/PrintUnitTest.java diff --git a/core/test/net/sf/openrocket/gui/print/TestPaperSize.java b/swing/test/net/sf/openrocket/gui/print/TestPaperSize.java similarity index 100% rename from core/test/net/sf/openrocket/gui/print/TestPaperSize.java rename to swing/test/net/sf/openrocket/gui/print/TestPaperSize.java diff --git a/core/test/net/sf/openrocket/logging/CyclicBufferTest.java b/swing/test/net/sf/openrocket/logging/CyclicBufferTest.java similarity index 100% rename from core/test/net/sf/openrocket/logging/CyclicBufferTest.java rename to swing/test/net/sf/openrocket/logging/CyclicBufferTest.java diff --git a/core/test/net/sf/openrocket/logging/LogLevelBufferLoggerTest.java b/swing/test/net/sf/openrocket/logging/LogLevelBufferLoggerTest.java similarity index 100% rename from core/test/net/sf/openrocket/logging/LogLevelBufferLoggerTest.java rename to swing/test/net/sf/openrocket/logging/LogLevelBufferLoggerTest.java diff --git a/core/test/net/sf/openrocket/logging/LogLevelTest.java b/swing/test/net/sf/openrocket/logging/LogLevelTest.java similarity index 100% rename from core/test/net/sf/openrocket/logging/LogLevelTest.java rename to swing/test/net/sf/openrocket/logging/LogLevelTest.java diff --git a/core/test/net/sf/openrocket/simplerocket.ork b/swing/test/net/sf/openrocket/simplerocket.ork similarity index 100% rename from core/test/net/sf/openrocket/simplerocket.ork rename to swing/test/net/sf/openrocket/simplerocket.ork