component config refactoring, localization fixes
authorplaa <plaa@180e2498-e6e9-4542-8430-84ac67f01cd8>
Tue, 11 Oct 2011 19:46:02 +0000 (19:46 +0000)
committerplaa <plaa@180e2498-e6e9-4542-8430-84ac67f01cd8>
Tue, 11 Oct 2011 19:46:02 +0000 (19:46 +0000)
git-svn-id: https://openrocket.svn.sourceforge.net/svnroot/openrocket/trunk@178 180e2498-e6e9-4542-8430-84ac67f01cd8

28 files changed:
ChangeLog
l10n/messages.properties
src/net/sf/openrocket/gui/configdialog/BodyTubeConfig.java
src/net/sf/openrocket/gui/configdialog/BulkheadConfig.java
src/net/sf/openrocket/gui/configdialog/CenteringRingConfig.java
src/net/sf/openrocket/gui/configdialog/ComponentConfigDialog.java
src/net/sf/openrocket/gui/configdialog/EllipticalFinSetConfig.java
src/net/sf/openrocket/gui/configdialog/FinSetConfig.java
src/net/sf/openrocket/gui/configdialog/FreeformFinSetConfig.java
src/net/sf/openrocket/gui/configdialog/InnerTubeConfig.java
src/net/sf/openrocket/gui/configdialog/LaunchLugConfig.java
src/net/sf/openrocket/gui/configdialog/MassComponentConfig.java
src/net/sf/openrocket/gui/configdialog/NoseConeConfig.java
src/net/sf/openrocket/gui/configdialog/ParachuteConfig.java
src/net/sf/openrocket/gui/configdialog/RecoveryDeviceConfig.java
src/net/sf/openrocket/gui/configdialog/RingComponentConfig.java
src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java
src/net/sf/openrocket/gui/configdialog/RocketConfig.java
src/net/sf/openrocket/gui/configdialog/ShockCordConfig.java
src/net/sf/openrocket/gui/configdialog/SleeveConfig.java
src/net/sf/openrocket/gui/configdialog/StreamerConfig.java
src/net/sf/openrocket/gui/configdialog/ThicknessRingComponentConfig.java
src/net/sf/openrocket/gui/configdialog/TransitionConfig.java
src/net/sf/openrocket/gui/configdialog/TrapezoidFinSetConfig.java
src/net/sf/openrocket/startup/Startup.java
src/net/sf/openrocket/startup/Startup2.java [new file with mode: 0644]
src/net/sf/openrocket/startup/VersionHelper.java
src/net/sf/openrocket/util/LineStyle.java

index 11b8fd246d8f67a2025c168f8be86efc028e7e49..84038e12272a901f6f6f3f2722496e19a3358687 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2011-10-11  Sampo Niskanen
+
+       * [BUG] Translators fetched before initialization
+
+2011-10-05  Doug Pedrick
+
+       * Fin tab autocalculation
+
 2011-09-26  Sampo Niskanen
 
        * [BUG] Thrust was computed from dropped stages
index 73d0a9b751fe16076209f35e246ff8a4312bec46..f9a55ae8261006ee902abe1c9ec59f66fa0d5143 100644 (file)
@@ -583,7 +583,7 @@ FinSetConfig.but.Converttofreeform.ttip = Convert this fin set into a freeform f
 FinSetConfig.Convertfinset = Convert fin set
 FinSetConfig.but.Splitfins = Split fins
 FinSetConfig.but.Splitfins.ttip = Split the fin set into separate fins
-FinSetConfig.but.Calcheight = Calculate Height
+FinSetConfig.but.AutoCalc = Calculate automatically
 FinSetConfig.lbl.Through-the-wall  = Through-the-wall fin tabs:
 FinSetConfig.lbl.Tablength = Tab length:
 FinSetConfig.ttip.Tablength = The length of the fin tab.
index f876d6fa40e9aef62c002562bd7670a77c8e6bf6..af272a0d88b50a2f6836ef6874b42d12e4cac5a1 100644 (file)
@@ -1,7 +1,13 @@
 package net.sf.openrocket.gui.configdialog;
 
 
+import javax.swing.JCheckBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JSpinner;
+
 import net.miginfocom.swing.MigLayout;
+import net.sf.openrocket.document.OpenRocketDocument;
 import net.sf.openrocket.gui.SpinnerEditor;
 import net.sf.openrocket.gui.adaptors.BooleanModel;
 import net.sf.openrocket.gui.adaptors.DoubleModel;
@@ -14,96 +20,91 @@ import net.sf.openrocket.rocketcomponent.RocketComponent;
 import net.sf.openrocket.startup.Application;
 import net.sf.openrocket.unit.UnitGroup;
 
-import javax.swing.JCheckBox;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.JSpinner;
-
 public class BodyTubeConfig extends RocketComponentConfig {
-
+       
        private MotorConfig motorConfigPane = null;
        private static final Translator trans = Application.getTranslator();
-
-       public BodyTubeConfig(RocketComponent c) {
-               super(c);
+       
+       public BodyTubeConfig(OpenRocketDocument d, RocketComponent c) {
+               super(d, c);
                
-               JPanel panel = new JPanel(new MigLayout("gap rel unrel","[][65lp::][30lp::][]",""));
+               JPanel panel = new JPanel(new MigLayout("gap rel unrel", "[][65lp::][30lp::][]", ""));
                
                ////  Body tube length
                panel.add(new JLabel(trans.get("BodyTubecfg.lbl.Bodytubelength")));
                
-               DoubleModel m = new DoubleModel(component,"Length",UnitGroup.UNITS_LENGTH,0);
+               DoubleModel m = new DoubleModel(component, "Length", UnitGroup.UNITS_LENGTH, 0);
                
                JSpinner 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.5, 2.0)),"w 100lp, wrap");
+               panel.add(spin, "growx");
                
+               panel.add(new UnitSelector(m), "growx");
+               panel.add(new BasicSlider(m.getSliderModel(0, 0.5, 2.0)), "w 100lp, wrap");
                
+
                //// Body tube diameter
                panel.add(new JLabel(trans.get("BodyTubecfg.lbl.Outerdiameter")));
-
-               DoubleModel od  = new DoubleModel(component,"OuterRadius",2,UnitGroup.UNITS_LENGTH,0);
+               
+               DoubleModel 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(spin, "growx");
+               
+               panel.add(new UnitSelector(od), "growx");
+               panel.add(new BasicSlider(od.getSliderModel(0, 0.04, 0.2)), "w 100lp, wrap 0px");
                
-               panel.add(new UnitSelector(od),"growx");
-               panel.add(new BasicSlider(od.getSliderModel(0, 0.04, 0.2)),"w 100lp, wrap 0px");
-
                JCheckBox check = new JCheckBox(od.getAutomaticAction());
                //// Automatic
                check.setText(trans.get("BodyTubecfg.checkbox.Automatic"));
-               panel.add(check,"skip, span 2, wrap");
-               
+               panel.add(check, "skip, span 2, wrap");
                
+
                ////  Inner diameter
                panel.add(new JLabel(trans.get("BodyTubecfg.lbl.Innerdiameter")));
-
+               
                // Diameter = 2*Radius
-               m = new DoubleModel(component,"InnerRadius",2,UnitGroup.UNITS_LENGTH,0);
+               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(spin, "growx");
                
-               panel.add(new UnitSelector(m),"growx");
-               panel.add(new BasicSlider(m.getSliderModel(new DoubleModel(0), od)),"w 100lp, wrap");
-
+               panel.add(new UnitSelector(m), "growx");
+               panel.add(new BasicSlider(m.getSliderModel(new DoubleModel(0), od)), "w 100lp, wrap");
                
+
                ////  Wall thickness
                panel.add(new JLabel(trans.get("BodyTubecfg.lbl.Wallthickness")));
                
-               m = new DoubleModel(component,"Thickness",UnitGroup.UNITS_LENGTH,0);
+               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(spin, "growx");
                
-               panel.add(new UnitSelector(m),"growx");
-               panel.add(new BasicSlider(m.getSliderModel(0,0.01)),"w 100lp, wrap 0px");
+               panel.add(new UnitSelector(m), "growx");
+               panel.add(new BasicSlider(m.getSliderModel(0, 0.01)), "w 100lp, wrap 0px");
                
                //// Filled
-               check = new JCheckBox(new BooleanModel(component,"Filled"));
+               check = new JCheckBox(new BooleanModel(component, "Filled"));
                check.setText(trans.get("BodyTubecfg.checkbox.Filled"));
-               panel.add(check,"skip, span 2, wrap");
-               
+               panel.add(check, "skip, span 2, wrap");
                
+
                //// Material
                panel.add(materialPanel(new JPanel(new MigLayout()), Material.Type.BULK),
                                "cell 4 0, gapleft paragraph, aligny 0%, spany");
                
                //// General and General properties
-               tabbedPane.insertTab(trans.get("BodyTubecfg.tab.General"), null, panel, 
+               tabbedPane.insertTab(trans.get("BodyTubecfg.tab.General"), null, panel,
                                trans.get("BodyTubecfg.tab.Generalproperties"), 0);
-               motorConfigPane = new MotorConfig((BodyTube)c);
+               motorConfigPane = new MotorConfig((BodyTube) c);
                //// Motor and Motor mount configuration
-               tabbedPane.insertTab(trans.get("BodyTubecfg.tab.Motor"), null, motorConfigPane, 
+               tabbedPane.insertTab(trans.get("BodyTubecfg.tab.Motor"), null, motorConfigPane,
                                trans.get("BodyTubecfg.tab.Motormountconf"), 1);
                tabbedPane.setSelectedIndex(0);
        }
index bc48b8b1d76f37562d79abc4c87c500bebf6bf4f..135ec94e631ea3c922fb4ebf579c3561e4d7f9eb 100644 (file)
@@ -3,6 +3,7 @@ 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;
@@ -12,8 +13,8 @@ import net.sf.openrocket.startup.Application;
 public class BulkheadConfig extends RingComponentConfig {
        private static final Translator trans = Application.getTranslator();
        
-       public BulkheadConfig(RocketComponent c) {
-               super(c);
+       public BulkheadConfig(OpenRocketDocument d, RocketComponent c) {
+               super(d, c);
                
                JPanel tab;
                
index 7d336b88f51888af6f60ec14e8e4af65b9a509f9..dfe6a3526404899b4d0458275d2e93a53a5d4c25 100644 (file)
@@ -3,6 +3,7 @@ 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;
@@ -11,18 +12,18 @@ import net.sf.openrocket.startup.Application;
 
 public class CenteringRingConfig extends RingComponentConfig {
        private static final Translator trans = Application.getTranslator();
-
-       public CenteringRingConfig(RocketComponent c) {
-               super(c);
+       
+       public CenteringRingConfig(OpenRocketDocument d, RocketComponent c) {
+               super(d, c);
                
                JPanel tab;
                
                //// Outer diameter: and Inner diameter: and Thickness:
-               tab = generalTab(trans.get("CenteringRingCfg.tab.Outerdiam"), 
-                               trans.get("CenteringRingCfg.tab.Innerdiam"), null, 
+               tab = generalTab(trans.get("CenteringRingCfg.tab.Outerdiam"),
+                               trans.get("CenteringRingCfg.tab.Innerdiam"), null,
                                trans.get("CenteringRingCfg.tab.Thickness"));
                //// General and General properties
-               tabbedPane.insertTab(trans.get("CenteringRingCfg.tab.General"), null, tab, 
+               tabbedPane.insertTab(trans.get("CenteringRingCfg.tab.General"), null, tab,
                                trans.get("CenteringRingCfg.tab.Generalproperties"), 0);
                tabbedPane.setSelectedIndex(0);
        }
index 0f9f11597f95892b0d78c519d241d66570ffb233..5bb3448bc5f8d0f698bc5b2925d2c28ec107ea46 100644 (file)
@@ -80,9 +80,6 @@ public class ComponentConfigDialog extends JDialog implements ComponentChangeLis
                //// configuration
                setTitle(trans.get("ComponentCfgDlg.configuration1") + " " + component.getComponentName() + " " + trans.get("ComponentCfgDlg.configuration"));
                
-               //              Dimension pref = getPreferredSize();
-               //              Dimension real = getSize();
-               //              if (pref.width > real.width || pref.height > real.height)
                this.pack();
        }
        
@@ -94,7 +91,7 @@ public class ComponentConfigDialog extends JDialog implements ComponentChangeLis
                                findDialogContentsConstructor(component);
                if (c != null) {
                        try {
-                               return c.newInstance(component);
+                               return c.newInstance(document, component);
                        } catch (InstantiationException e) {
                                throw new BugException("BUG in constructor reflection", e);
                        } catch (IllegalAccessException e) {
@@ -162,7 +159,7 @@ public class ComponentConfigDialog extends JDialog implements ComponentChangeLis
                        try {
                                configclass = Class.forName(configclassname);
                                c = (Constructor<? extends RocketComponentConfig>)
-                                               configclass.getConstructor(RocketComponent.class);
+                                               configclass.getConstructor(OpenRocketDocument.class, RocketComponent.class);
                                return c;
                        } catch (Exception ignore) {
                        }
@@ -212,27 +209,6 @@ public class ComponentConfigDialog extends JDialog implements ComponentChangeLis
        }
        
        
-       /**
-        * Add an undo position for the current document.  This is intended for use only
-        * by the currently open dialog.
-        * 
-        * @param description  Description of the undoable action
-        */
-       /*package*/static void addUndoPosition(String description) {
-               if (dialog == null) {
-                       throw new IllegalStateException("Dialog not open, report bug!");
-               }
-               dialog.document.addUndoPosition(description);
-       }
-       
-       /*package*/
-       static String getUndoDescription() {
-               if (dialog == null) {
-                       throw new IllegalStateException("Dialog not open, report bug!");
-               }
-               return dialog.document.getUndoDescription();
-       }
-       
        /**
         * Returns whether the singleton configuration dialog is currently visible or not.
         */
index cfb70b35f95f8cc0869d0ec269a1ee328f2c335c..321ef6c42047a80050b46fdd96fab875bb4218d1 100644 (file)
@@ -9,6 +9,7 @@ import javax.swing.JSpinner;
 import javax.swing.SwingConstants;
 
 import net.miginfocom.swing.MigLayout;
+import net.sf.openrocket.document.OpenRocketDocument;
 import net.sf.openrocket.gui.SpinnerEditor;
 import net.sf.openrocket.gui.adaptors.DoubleModel;
 import net.sf.openrocket.gui.adaptors.EnumModel;
@@ -24,43 +25,43 @@ import net.sf.openrocket.unit.UnitGroup;
 
 public class EllipticalFinSetConfig extends FinSetConfig {
        private static final Translator trans = Application.getTranslator();
-
-       public EllipticalFinSetConfig(final RocketComponent component) {
-               super(component);
-
+       
+       public EllipticalFinSetConfig(OpenRocketDocument d, final RocketComponent component) {
+               super(d, component);
+               
                DoubleModel m;
                JSpinner spin;
                JComboBox combo;
                
                JPanel mainPanel = new JPanel(new MigLayout());
                
-               
-               
-               JPanel panel = new JPanel(new MigLayout("gap rel unrel","[][65lp::][30lp::]",""));
+
+
+               JPanel panel = new JPanel(new MigLayout("gap rel unrel", "[][65lp::][30lp::]", ""));
                
                ////  Number of fins
                panel.add(new JLabel(trans.get("EllipticalFinSetCfg.Nbroffins")));
                
-               IntegerModel im = new IntegerModel(component,"FinCount",1,8);
+               IntegerModel im = new IntegerModel(component, "FinCount", 1, 8);
                
                spin = new JSpinner(im.getSpinnerModel());
                spin.setEditor(new SpinnerEditor(spin));
-               panel.add(spin,"growx, wrap");
-               
+               panel.add(spin, "growx, wrap");
                
+
                ////  Base rotation
                panel.add(new JLabel(trans.get("EllipticalFinSetCfg.Rotation")));
                
-               m = new DoubleModel(component, "BaseRotation", UnitGroup.UNITS_ANGLE,-Math.PI,Math.PI);
+               m = new DoubleModel(component, "BaseRotation", UnitGroup.UNITS_ANGLE, -Math.PI, Math.PI);
                
                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(-Math.PI,Math.PI)),"w 100lp, wrap");
+               panel.add(spin, "growx");
                
+               panel.add(new UnitSelector(m), "growx");
+               panel.add(new BasicSlider(m.getSliderModel(-Math.PI, Math.PI)), "w 100lp, wrap");
                
+
                ////  Fin cant
                JLabel label = new JLabel(trans.get("EllipticalFinSetCfg.Fincant"));
                //// "The angle that the fins are canted with respect to the rocket
@@ -72,117 +73,117 @@ public class EllipticalFinSetConfig extends FinSetConfig {
                
                spin = new JSpinner(m.getSpinnerModel());
                spin.setEditor(new SpinnerEditor(spin));
-               panel.add(spin,"growx");
+               panel.add(spin, "growx");
                
-               panel.add(new UnitSelector(m),"growx");
-               panel.add(new BasicSlider(m.getSliderModel(-FinSet.MAX_CANT,FinSet.MAX_CANT)),
+               panel.add(new UnitSelector(m), "growx");
+               panel.add(new BasicSlider(m.getSliderModel(-FinSet.MAX_CANT, FinSet.MAX_CANT)),
                                "w 100lp, wrap");
                
 
-               
+
                ////  Root chord
                panel.add(new JLabel(trans.get("EllipticalFinSetCfg.Rootchord")));
                
-               m  = new DoubleModel(component,"Length",UnitGroup.UNITS_LENGTH,0);
+               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(spin, "growx");
+               
+               panel.add(new UnitSelector(m), "growx");
+               panel.add(new BasicSlider(m.getSliderModel(0, 0.05, 0.2)), "w 100lp, wrap");
                
-               panel.add(new UnitSelector(m),"growx");
-               panel.add(new BasicSlider(m.getSliderModel(0,0.05,0.2)),"w 100lp, wrap");
-
 
                ////  Height
                panel.add(new JLabel(trans.get("EllipticalFinSetCfg.Height")));
                
-               m = new DoubleModel(component,"Height",UnitGroup.UNITS_LENGTH,0);
+               m = new DoubleModel(component, "Height", UnitGroup.UNITS_LENGTH, 0);
                
                spin = new JSpinner(m.getSpinnerModel());
                spin.setEditor(new SpinnerEditor(spin));
-               panel.add(spin,"growx");
+               panel.add(spin, "growx");
                
-               panel.add(new UnitSelector(m),"growx");
-               panel.add(new BasicSlider(m.getSliderModel(0,0.05,0.2)),"w 100lp, wrap");
-       
+               panel.add(new UnitSelector(m), "growx");
+               panel.add(new BasicSlider(m.getSliderModel(0, 0.05, 0.2)), "w 100lp, wrap");
                
+
                ////  Position
                //// Position relative to:
                panel.add(new JLabel(trans.get("EllipticalFinSetCfg.Positionrelativeto")));
-
+               
                combo = new JComboBox(
                                new EnumModel<RocketComponent.Position>(component, "RelativePosition",
                                                new RocketComponent.Position[] {
-                                               RocketComponent.Position.TOP,
-                                               RocketComponent.Position.MIDDLE,
-                                               RocketComponent.Position.BOTTOM,
-                                               RocketComponent.Position.ABSOLUTE
+                                                               RocketComponent.Position.TOP,
+                                                               RocketComponent.Position.MIDDLE,
+                                                               RocketComponent.Position.BOTTOM,
+                                                               RocketComponent.Position.ABSOLUTE
                                }));
-               panel.add(combo,"spanx, growx, wrap");
+               panel.add(combo, "spanx, growx, wrap");
                
                //// plus
-               panel.add(new JLabel(trans.get("EllipticalFinSetCfg.plus")),"right");
-
-               m = new DoubleModel(component,"PositionValue",UnitGroup.UNITS_LENGTH);
+               panel.add(new JLabel(trans.get("EllipticalFinSetCfg.plus")), "right");
+               
+               m = new DoubleModel(component, "PositionValue", UnitGroup.UNITS_LENGTH);
                spin = new JSpinner(m.getSpinnerModel());
                spin.setEditor(new SpinnerEditor(spin));
-               panel.add(spin,"growx");
+               panel.add(spin, "growx");
                
-               panel.add(new UnitSelector(m),"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");
+               
 
 
-               
                //// Right portion
-               mainPanel.add(panel,"aligny 20%");
+               mainPanel.add(panel, "aligny 20%");
                
-               mainPanel.add(new JSeparator(SwingConstants.VERTICAL),"growy");
+               mainPanel.add(new JSeparator(SwingConstants.VERTICAL), "growy");
                
-               
-               
-               panel = new JPanel(new MigLayout("gap rel unrel","[][65lp::][30lp::]",""));
 
 
+               panel = new JPanel(new MigLayout("gap rel unrel", "[][65lp::][30lp::]", ""));
+               
+
                ////  Cross section
                //// Fin cross section:
-               panel.add(new JLabel(trans.get("EllipticalFinSetCfg.FincrossSection")),"span, split");
+               panel.add(new JLabel(trans.get("EllipticalFinSetCfg.FincrossSection")), "span, split");
                combo = new JComboBox(
-                               new EnumModel<FinSet.CrossSection>(component,"CrossSection"));
-               panel.add(combo,"growx, wrap unrel");
+                               new EnumModel<FinSet.CrossSection>(component, "CrossSection"));
+               panel.add(combo, "growx, wrap unrel");
                
 
                ////  Thickness:
                panel.add(new JLabel(trans.get("EllipticalFinSetCfg.Thickness")));
                
-               m = new DoubleModel(component,"Thickness",UnitGroup.UNITS_LENGTH,0);
+               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 30lp");
+               panel.add(spin, "growx");
                
+               panel.add(new UnitSelector(m), "growx");
+               panel.add(new BasicSlider(m.getSliderModel(0, 0.01)), "w 100lp, wrap 30lp");
                
 
+
                //// Material
                materialPanel(panel, Material.Type.BULK);
                
-               
-               
-               
-               
-               mainPanel.add(panel,"aligny 20%");
+
+
+
+
+               mainPanel.add(panel, "aligny 20%");
                
                addFinSetButtons();
-
+               
                //// General and General properties
-               tabbedPane.insertTab(trans.get("EllipticalFinSetCfg.General"), null, mainPanel, 
+               tabbedPane.insertTab(trans.get("EllipticalFinSetCfg.General"), null, mainPanel,
                                trans.get("EllipticalFinSetCfg.Generalproperties"), 0);
                tabbedPane.setSelectedIndex(0);
        }
-
+       
 }
index b1037a1d8f14303d670924e5c79e00ede32cc8ec..b949b2de0a540038610f989aa5d33d1cdfe6fb48 100644 (file)
@@ -1,6 +1,21 @@
 package net.sf.openrocket.gui.configdialog;
 
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JSpinner;
+import javax.swing.SwingUtilities;
+
 import net.miginfocom.swing.MigLayout;
+import net.sf.openrocket.document.OpenRocketDocument;
 import net.sf.openrocket.gui.SpinnerEditor;
 import net.sf.openrocket.gui.adaptors.DoubleModel;
 import net.sf.openrocket.gui.adaptors.EnumModel;
@@ -19,416 +34,409 @@ import net.sf.openrocket.rocketcomponent.RocketComponent;
 import net.sf.openrocket.startup.Application;
 import net.sf.openrocket.unit.UnitGroup;
 
-import javax.swing.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
 
 public abstract class FinSetConfig extends RocketComponentConfig {
-    private static final LogHelper log = Application.getLogger();
-    private static final Translator trans = Application.getTranslator();
-
-    private JButton split = null;
-
-    public FinSetConfig(RocketComponent component) {
-        super(component);
-
-        //// Fin tabs and Through-the-wall fin tabs
-        tabbedPane.insertTab(trans.get("FinSetConfig.tab.Fintabs"), null, finTabPanel(),
-                trans.get("FinSetConfig.tab.Through-the-wall"), 0);
-    }
-
-
-    protected void addFinSetButtons() {
-        JButton convert = null;
-
-        //// Convert buttons
-        if (!(component instanceof FreeformFinSet)) {
-            //// Convert to freeform
-            convert = new JButton(trans.get("FinSetConfig.but.Converttofreeform"));
-            //// Convert this fin set into a freeform fin set
-            convert.setToolTipText(trans.get("FinSetConfig.but.Converttofreeform.ttip"));
-            convert.addActionListener(new ActionListener() {
-                @Override
-                public void actionPerformed(ActionEvent e) {
-                    log.user("Converting " + component.getComponentName() + " into freeform fin set");
-
-                    // Do change in future for overall safety
-                    SwingUtilities.invokeLater(new Runnable() {
-                        @Override
-                        public void run() {
-                            //// Convert fin set
-                            ComponentConfigDialog.addUndoPosition(trans.get("FinSetConfig.Convertfinset"));
-                            RocketComponent freeform =
-                                    FreeformFinSet.convertFinSet((FinSet) component);
-                            ComponentConfigDialog.showDialog(freeform);
-                        }
-                    });
-
-                    ComponentConfigDialog.hideDialog();
-                }
-            });
-        }
-
-        //// Split fins
-        split = new JButton(trans.get("FinSetConfig.but.Splitfins"));
-        //// Split the fin set into separate fins
-        split.setToolTipText(trans.get("FinSetConfig.but.Splitfins.ttip"));
-        split.addActionListener(new ActionListener() {
-            @Override
-            public void actionPerformed(ActionEvent e) {
-                log.user("Splitting " + component.getComponentName() + " into separate fins, fin count=" +
-                        ((FinSet) component).getFinCount());
-
-                // Do change in future for overall safety
-                SwingUtilities.invokeLater(new Runnable() {
-                    @Override
-                    public void run() {
-                        RocketComponent parent = component.getParent();
-                        int index = parent.getChildPosition(component);
-                        int count = ((FinSet) component).getFinCount();
-                        double base = ((FinSet) component).getBaseRotation();
-                        if (count <= 1)
-                            return;
-
-                        ComponentConfigDialog.addUndoPosition("Split fin set");
-                        parent.removeChild(index);
-                        for (int i = 0; i < count; i++) {
-                            FinSet copy = (FinSet) component.copy();
-                            copy.setFinCount(1);
-                            copy.setBaseRotation(base + i * 2 * Math.PI / count);
-                            copy.setName(copy.getName() + " #" + (i + 1));
-                            parent.addChild(copy, index + i);
-                        }
-                    }
-                });
-
-                ComponentConfigDialog.hideDialog();
-            }
-        });
-        split.setEnabled(((FinSet) component).getFinCount() > 1);
-
-        if (convert == null)
-            addButtons(split);
-        else
-            addButtons(split, convert);
-
-    }
-
-    public JPanel finTabPanel() {
-        JPanel panel = new JPanel(
-                new MigLayout("align 50% 20%, fillx, gap rel unrel, ins 20lp 10% 20lp 10%",
-                        "[150lp::][65lp::][30lp::][200lp::]", ""));
-        //             JPanel panel = new JPanel(new MigLayout("fillx, align 20% 20%, gap rel unrel",
-        //                             "[40lp][80lp::][30lp::][100lp::]",""));
-
-        //// Through-the-wall fin tabs:
-        panel.add(new StyledLabel(trans.get("FinSetConfig.lbl.Through-the-wall"), Style.BOLD),
-                "spanx, wrap 30lp");
-
-        JLabel label;
-        DoubleModel length;
-        DoubleModel length2;
-        DoubleModel length_2;
-        JSpinner spin;
-        JButton calcHeight;
-
-        length = new DoubleModel(component, "Length", UnitGroup.UNITS_LENGTH, 0);
-        length2 = new DoubleModel(component, "Length", 0.5, UnitGroup.UNITS_LENGTH, 0);
-        length_2 = new DoubleModel(component, "Length", -0.5, UnitGroup.UNITS_LENGTH, 0);
-
-        register(length);
-        register(length2);
-        register(length_2);
-
-        ////  Tab length
-        //// Tab length:
-        label = new JLabel(trans.get("FinSetConfig.lbl.Tablength"));
-        //// The length of the fin tab.
-        label.setToolTipText(trans.get("FinSetConfig.ttip.Tablength"));
-        panel.add(label, "gapleft para, gapright 40lp, growx 1");
-
-        final DoubleModel mtl = new DoubleModel(component, "TabLength", UnitGroup.UNITS_LENGTH, 0);
-
-        spin = new JSpinner(mtl.getSpinnerModel());
-        spin.setEditor(new SpinnerEditor(spin));
-        panel.add(spin, "growx 1");
-
-        panel.add(new UnitSelector(mtl), "growx 1");
-        panel.add(new BasicSlider(mtl.getSliderModel(DoubleModel.ZERO, length)),
-                "w 100lp, growx 5, wrap");
-
-
-        ////  Tab length
-        //// Tab height:
-        label = new JLabel(trans.get("FinSetConfig.lbl.Tabheight"));
-        //// The spanwise height of the fin tab.
-        label.setToolTipText(trans.get("FinSetConfig.ttip.Tabheight"));
-        panel.add(label, "gapleft para");
-
-        final DoubleModel mth = new DoubleModel(component, "TabHeight", UnitGroup.UNITS_LENGTH, 0);
-
-        spin = new JSpinner(mth.getSpinnerModel());
-        spin.setEditor(new SpinnerEditor(spin));
-        panel.add(spin, "growx");
-
-        panel.add(new UnitSelector(mth), "growx");
-        panel.add(new BasicSlider(mth.getSliderModel(DoubleModel.ZERO, length2)),
-                "w 100lp, growx 5, wrap para");
-
-        ////  Tab position:
-        label = new JLabel(trans.get("FinSetConfig.lbl.Tabposition"));
-        //// The position of the fin tab.
-        label.setToolTipText(trans.get("FinSetConfig.ttip.Tabposition"));
-        panel.add(label, "gapleft para");
-
-        final DoubleModel mts = new DoubleModel(component, "TabShift", UnitGroup.UNITS_LENGTH);
-
-        spin = new JSpinner(mts.getSpinnerModel());
-        spin.setEditor(new SpinnerEditor(spin));
-        panel.add(spin, "growx");
-
-        panel.add(new UnitSelector(mts), "growx");
-        panel.add(new BasicSlider(mts.getSliderModel(length_2, length2)), "w 100lp, growx 5, wrap");
-
-
-        //// relative to
-        label = new JLabel(trans.get("FinSetConfig.lbl.relativeto"));
-        panel.add(label, "right, gapright unrel");
-
-        final EnumModel<FinSet.TabRelativePosition> em =
-                new EnumModel<FinSet.TabRelativePosition>(component, "TabRelativePosition");
-
-        panel.add(new JComboBox(em), "spanx 3, growx");
-
-        calcHeight = new JButton(trans.get("FinSetConfig.but.Calcheight"));
-
-        // Calculate fin tab height, length, and position
-        calcHeight.addActionListener(new ActionListener() {
-            @Override
-            public void actionPerformed(ActionEvent e) {
-                log.user("Computing " + component.getComponentName() + " tab height.");
-
-                // Do change in future for overall safety
-                SwingUtilities.invokeLater(new Runnable() {
-                    @Override
-                    public void run() {
-                        RocketComponent parent = component.getParent();
-                        if (parent instanceof Coaxial) {
-                            List<RocketComponent> children = parent.getChildren();
-                            List<CenteringRing> rings = new ArrayList<CenteringRing>();
-
-                            ComponentConfigDialog.addUndoPosition("Compute fin tab height");
-                            for (int i = 0; i < children.size(); i++) {
-                                RocketComponent rocketComponent = children.get(i);
-                                if (rocketComponent instanceof InnerTube) {
-                                    InnerTube it = (InnerTube) rocketComponent;
-                                    if (it.isMotorMount()) {
-                                        double depth = ((Coaxial) parent).getOuterRadius() - it.getOuterRadius();
-                                        //Set fin tab depth
-                                        if (depth >= 0.0d) {
-                                            mth.setValue(depth);
-                                            mth.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit());
-                                        }
-                                    }
-                                } else if (rocketComponent instanceof CenteringRing) {
-                                    rings.add((CenteringRing) rocketComponent);
-                                }
-                            }
-                            //Figure out position and length of the fin tab
-                            if (!rings.isEmpty()) {
-                                FinSet.TabRelativePosition temp = (FinSet.TabRelativePosition) em.getSelectedItem();
-                                em.setSelectedItem(FinSet.TabRelativePosition.FRONT);
-                                double len = computeFinTabLength(rings, component.asPositionValue(RocketComponent.Position.TOP),
-                                        component.getLength(), mts);
-                                mtl.setValue(len);
-                                //Be nice to the user and set the tab relative position enum back the way they had it.
-                                em.setSelectedItem(temp);
-                            }
-                        }
-                    }
-                });
-            }
-        });
-        panel.add(calcHeight, "right, gapright unrel");
-
-        return panel;
-    }
-
-    /**
-     * Scenarios:
-     * <p/>
-     * 1. All rings ahead of start of fin.
-     * 2. First ring ahead of start of fin.  Second ring ahead of end of fin.
-     * 3. First ring ahead of start of fin.  Second ring behind end of fin.
-     * 4. First ring equal or behind start of fin.  Second ring ahead of, or equal to, end of fin.
-     * 5. First ring equal or behind start of fin. Second ring behind end of fin.
-     * 6. All rings behind end of fin.
-     *
-     * @param rings              an unordered list of centering rings attached to the parent of the fin set
-     * @param finPositionFromTop the position from the top of the parent of the start of the fin set root
-     * @param finLength          the length of the root chord
-     * @param mts                the model for the tab shift (position); the model's value is modified as a result of this method call
-     * @return the length of the fin tab
-     */
-    private static double computeFinTabLength(List<CenteringRing> rings, Double finPositionFromTop, Double finLength, DoubleModel mts) {
-        List<SortableRing> positionsFromTop = new ArrayList<SortableRing>();
-
-        //Fin tabs will be computed between the last two rings that meet the criteria, represented by top and bottom here.
-        SortableRing top = null;
-        SortableRing bottom = null;
-
-        if (rings != null) {
-            //Sort rings from top of parent to bottom
-            Collections.sort(rings, new Comparator<CenteringRing>() {
-                @Override
-                public int compare(CenteringRing centeringRing, CenteringRing centeringRing1) {
-                    return (int) (1000d * (centeringRing.asPositionValue(RocketComponent.Position.TOP) -
-                            centeringRing1.asPositionValue(RocketComponent.Position.TOP)));
-                }
-            });
-
-            for (int i = 0; i < rings.size(); i++) {
-                CenteringRing centeringRing = rings.get(i);
-                //Handle centering rings that overlap or are adjacent by synthetically merging them into one virtual ring.
-                if (!positionsFromTop.isEmpty() &&
-                        positionsFromTop.get(positionsFromTop.size() - 1).bottomSidePositionFromTop() >= centeringRing.asPositionValue(RocketComponent.Position.TOP)) {
-                    SortableRing adjacent = positionsFromTop.get(positionsFromTop.size() - 1);
-                    adjacent.merge(centeringRing);
-                } else {
-                    positionsFromTop.add(new SortableRing(centeringRing));
-                }
-            }
-
-            for (int i = 0; i < positionsFromTop.size(); i++) {
-                SortableRing sortableRing = positionsFromTop.get(i);
-                if (top == null) {
-                    top = sortableRing;
-                } else if (sortableRing.bottomSidePositionFromTop() <= finPositionFromTop) {
-                    top = sortableRing;
-                    bottom = null;
-                } else if (top.bottomSidePositionFromTop() <= finPositionFromTop) {
-                    if (bottom == null) {
-                        //If the current ring is in the upper half of the root chord, make it the top ring
-                        if (sortableRing.bottomSidePositionFromTop() < finPositionFromTop + finLength / 2d) {
-                            top = sortableRing;
-                        } else {
-                            bottom = sortableRing;
-                        }
-                    }
-                    //Is the ring even with or above the end of the root chord? If so, make the existing bottom the top ring,
-                    //and the current ring the bottom
-                    else if (sortableRing.positionFromTop() <= finPositionFromTop + finLength) {
-                        top = bottom;
-                        bottom = sortableRing;
-                    }
-                } else {
-                    if (bottom == null) {
-                        bottom = sortableRing;
-                    }
-                }
-            }
-        }
-
-        // Edge case where there are no centering rings or for some odd reason top and bottom are identical.
-        if (top == null || top == bottom) {
-            mts.setValue(0);
-            return finLength;
-        }
-
-        if (bottom == null) {
-            // If there is no bottom ring and the top ring's bottom edge is within the span of the root chord, then
-            // set the position of the fin tab starting at the bottom side of the top ring.
-            if (top.bottomSidePositionFromTop() >= finPositionFromTop) {
-                mts.setValue(top.bottomSidePositionFromTop() - finPositionFromTop);
-                return (finPositionFromTop + finLength - top.bottomSidePositionFromTop());
-            } else {
-                // Otherwise the top ring is outside the span of the root chord so set the tab length to be the entire
-                // root chord.
-                mts.setValue(0);
-                return finLength;
-            }
-        }
-        // If the bottom edge of the top centering ring is above the start of the fin's root chord, then make the
-        // fin tab align with the start of the root chord.
-        if (top.bottomSidePositionFromTop() < finPositionFromTop) {
-            mts.setValue(0);
-            return bottom.positionFromTop - finPositionFromTop;
-        } else {
-            // Otherwise the rings are within the span of the root chord.  Place the tab between them.
-            mts.setValue(top.bottomSidePositionFromTop() - finPositionFromTop);
-            return (bottom.positionFromTop() - top.bottomSidePositionFromTop());
-        }
-    }
-
-    @Override
-    public void updateFields() {
-        super.updateFields();
-        if (split != null)
-            split.setEnabled(((FinSet) component).getFinCount() > 1);
-    }
-
-    /**
-     * A container class to store pertinent info about centering rings.  This is used in the computation to figure
-     * out tab length and position.
-     */
-    static class SortableRing {
-
-        /**
-         * The length of the ring (more commonly called the thickness).
-         */
-        private double thickness;
-        /**
-         * The position of the ring from the top of the parent.
-         */
-        private double positionFromTop;
-
-        /**
-         * Constructor.
-         *
-         * @param r the source centering ring
-         */
-        SortableRing(CenteringRing r) {
-            thickness = r.getLength();
-            positionFromTop = r.asPositionValue(RocketComponent.Position.TOP);
-        }
-
-        /**
-         * Merge an adjacent ring.
-         *
-         * @param adjacent the adjacent ring
-         */
-        public void merge(CenteringRing adjacent) {
-            double v = adjacent.asPositionValue(RocketComponent.Position.TOP);
-            if (positionFromTop < v) {
-                thickness = (v + adjacent.getLength()) - positionFromTop;
-            } else {
-                double tmp = positionFromTop + thickness;
-                positionFromTop = v;
-                thickness = tmp - v;
-            }
-        }
-
-        /**
-         * Compute the position of the bottom edge of the ring, relative to the top of the parent.
-         *
-         * @return the distance from the top of the parent to the bottom edge of the ring
-         */
-        public double bottomSidePositionFromTop() {
-            return positionFromTop + thickness;
-        }
-
-        /**
-         * Compute the position of the top edge of the ring, relative to the top of the parent.
-         *
-         * @return the distance from the top of the parent to the top edge of the ring
-         */
-        public double positionFromTop() {
-            return positionFromTop;
-        }
-    }
+       private static final LogHelper log = Application.getLogger();
+       private static final Translator trans = Application.getTranslator();
+       
+       private JButton split = null;
+       
+       public FinSetConfig(OpenRocketDocument d, RocketComponent component) {
+               super(d, component);
+               
+               //// Fin tabs and Through-the-wall fin tabs
+               tabbedPane.insertTab(trans.get("FinSetConfig.tab.Fintabs"), null, finTabPanel(),
+                               trans.get("FinSetConfig.tab.Through-the-wall"), 0);
+       }
+       
+       
+       protected void addFinSetButtons() {
+               JButton convert = null;
+               
+               //// Convert buttons
+               if (!(component instanceof FreeformFinSet)) {
+                       //// Convert to freeform
+                       convert = new JButton(trans.get("FinSetConfig.but.Converttofreeform"));
+                       //// Convert this fin set into a freeform fin set
+                       convert.setToolTipText(trans.get("FinSetConfig.but.Converttofreeform.ttip"));
+                       convert.addActionListener(new ActionListener() {
+                               @Override
+                               public void actionPerformed(ActionEvent e) {
+                                       log.user("Converting " + component.getComponentName() + " into freeform fin set");
+                                       
+                                       // Do change in future for overall safety
+                                       SwingUtilities.invokeLater(new Runnable() {
+                                               @Override
+                                               public void run() {
+                                                       //// Convert fin set
+                                                       document.addUndoPosition(trans.get("FinSetConfig.Convertfinset"));
+                                                       RocketComponent freeform =
+                                                                       FreeformFinSet.convertFinSet((FinSet) component);
+                                                       ComponentConfigDialog.showDialog(freeform);
+                                               }
+                                       });
+                                       
+                                       ComponentConfigDialog.hideDialog();
+                               }
+                       });
+               }
+               
+               //// Split fins
+               split = new JButton(trans.get("FinSetConfig.but.Splitfins"));
+               //// Split the fin set into separate fins
+               split.setToolTipText(trans.get("FinSetConfig.but.Splitfins.ttip"));
+               split.addActionListener(new ActionListener() {
+                       @Override
+                       public void actionPerformed(ActionEvent e) {
+                               log.user("Splitting " + component.getComponentName() + " into separate fins, fin count=" +
+                                               ((FinSet) component).getFinCount());
+                               
+                               // Do change in future for overall safety
+                               SwingUtilities.invokeLater(new Runnable() {
+                                       @Override
+                                       public void run() {
+                                               RocketComponent parent = component.getParent();
+                                               int index = parent.getChildPosition(component);
+                                               int count = ((FinSet) component).getFinCount();
+                                               double base = ((FinSet) component).getBaseRotation();
+                                               if (count <= 1)
+                                                       return;
+                                               
+                                               document.addUndoPosition("Split fin set");
+                                               parent.removeChild(index);
+                                               for (int i = 0; i < count; i++) {
+                                                       FinSet copy = (FinSet) component.copy();
+                                                       copy.setFinCount(1);
+                                                       copy.setBaseRotation(base + i * 2 * Math.PI / count);
+                                                       copy.setName(copy.getName() + " #" + (i + 1));
+                                                       parent.addChild(copy, index + i);
+                                               }
+                                       }
+                               });
+                               
+                               ComponentConfigDialog.hideDialog();
+                       }
+               });
+               split.setEnabled(((FinSet) component).getFinCount() > 1);
+               
+               if (convert == null)
+                       addButtons(split);
+               else
+                       addButtons(split, convert);
+               
+       }
+       
+       public JPanel finTabPanel() {
+               JPanel panel = new JPanel(
+                               new MigLayout("align 50% 20%, fillx, gap rel unrel, ins 20lp 10% 20lp 10%",
+                                               "[150lp::][65lp::][30lp::][200lp::]", ""));
+               //              JPanel panel = new JPanel(new MigLayout("fillx, align 20% 20%, gap rel unrel",
+               //                              "[40lp][80lp::][30lp::][100lp::]",""));
+               
+               //// Through-the-wall fin tabs:
+               panel.add(new StyledLabel(trans.get("FinSetConfig.lbl.Through-the-wall"), Style.BOLD),
+                               "spanx, wrap 30lp");
+               
+               JLabel label;
+               DoubleModel length;
+               DoubleModel length2;
+               DoubleModel length_2;
+               JSpinner spin;
+               JButton autoCalc;
+               
+               length = new DoubleModel(component, "Length", UnitGroup.UNITS_LENGTH, 0);
+               length2 = new DoubleModel(component, "Length", 0.5, UnitGroup.UNITS_LENGTH, 0);
+               length_2 = new DoubleModel(component, "Length", -0.5, UnitGroup.UNITS_LENGTH, 0);
+               
+               register(length);
+               register(length2);
+               register(length_2);
+               
+               ////  Tab length
+               //// Tab length:
+               label = new JLabel(trans.get("FinSetConfig.lbl.Tablength"));
+               //// The length of the fin tab.
+               label.setToolTipText(trans.get("FinSetConfig.ttip.Tablength"));
+               panel.add(label, "gapleft para, gapright 40lp, growx 1");
+               
+               final DoubleModel mtl = new DoubleModel(component, "TabLength", UnitGroup.UNITS_LENGTH, 0);
+               
+               spin = new JSpinner(mtl.getSpinnerModel());
+               spin.setEditor(new SpinnerEditor(spin));
+               panel.add(spin, "growx 1");
+               
+               panel.add(new UnitSelector(mtl), "growx 1");
+               panel.add(new BasicSlider(mtl.getSliderModel(DoubleModel.ZERO, length)),
+                               "w 100lp, growx 5, wrap");
+               
+
+               ////  Tab length
+               //// Tab height:
+               label = new JLabel(trans.get("FinSetConfig.lbl.Tabheight"));
+               //// The spanwise height of the fin tab.
+               label.setToolTipText(trans.get("FinSetConfig.ttip.Tabheight"));
+               panel.add(label, "gapleft para");
+               
+               final DoubleModel mth = new DoubleModel(component, "TabHeight", UnitGroup.UNITS_LENGTH, 0);
+               
+               spin = new JSpinner(mth.getSpinnerModel());
+               spin.setEditor(new SpinnerEditor(spin));
+               panel.add(spin, "growx");
+               
+               panel.add(new UnitSelector(mth), "growx");
+               panel.add(new BasicSlider(mth.getSliderModel(DoubleModel.ZERO, length2)),
+                               "w 100lp, growx 5, wrap");
+               
+               ////  Tab position:
+               label = new JLabel(trans.get("FinSetConfig.lbl.Tabposition"));
+               //// The position of the fin tab.
+               label.setToolTipText(trans.get("FinSetConfig.ttip.Tabposition"));
+               panel.add(label, "gapleft para");
+               
+               final DoubleModel mts = new DoubleModel(component, "TabShift", UnitGroup.UNITS_LENGTH);
+               
+               spin = new JSpinner(mts.getSpinnerModel());
+               spin.setEditor(new SpinnerEditor(spin));
+               panel.add(spin, "growx");
+               
+               panel.add(new UnitSelector(mts), "growx");
+               panel.add(new BasicSlider(mts.getSliderModel(length_2, length2)), "w 100lp, growx 5, wrap");
+               
+
+               //// relative to
+               label = new JLabel(trans.get("FinSetConfig.lbl.relativeto"));
+               panel.add(label, "right, gapright unrel");
+               
+               final EnumModel<FinSet.TabRelativePosition> em =
+                               new EnumModel<FinSet.TabRelativePosition>(component, "TabRelativePosition");
+               
+               panel.add(new JComboBox(em), "spanx 3, growx, wrap para");
+               
+
+               // Calculate fin tab height, length, and position
+               autoCalc = new JButton(trans.get("FinSetConfig.but.AutoCalc"));
+               
+               autoCalc.addActionListener(new ActionListener() {
+                       @Override
+                       public void actionPerformed(ActionEvent e) {
+                               log.user("Computing " + component.getComponentName() + " tab height.");
+                               
+                               RocketComponent parent = component.getParent();
+                               if (parent instanceof Coaxial) {
+                                       try {
+                                               document.startUndo("Compute fin tabs");
+                                               
+                                               List<RocketComponent> children = parent.getChildren();
+                                               List<CenteringRing> rings = new ArrayList<CenteringRing>();
+                                               
+                                               for (int i = 0; i < children.size(); i++) {
+                                                       RocketComponent rocketComponent = children.get(i);
+                                                       if (rocketComponent instanceof InnerTube) {
+                                                               InnerTube it = (InnerTube) rocketComponent;
+                                                               if (it.isMotorMount()) {
+                                                                       double depth = ((Coaxial) parent).getOuterRadius() - it.getOuterRadius();
+                                                                       //Set fin tab depth
+                                                                       if (depth >= 0.0d) {
+                                                                               mth.setValue(depth);
+                                                                               mth.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit());
+                                                                       }
+                                                               }
+                                                       } else if (rocketComponent instanceof CenteringRing) {
+                                                               rings.add((CenteringRing) rocketComponent);
+                                                       }
+                                               }
+                                               //Figure out position and length of the fin tab
+                                               if (!rings.isEmpty()) {
+                                                       FinSet.TabRelativePosition temp = (FinSet.TabRelativePosition) em.getSelectedItem();
+                                                       em.setSelectedItem(FinSet.TabRelativePosition.FRONT);
+                                                       double len = computeFinTabLength(rings, component.asPositionValue(RocketComponent.Position.TOP),
+                                                                               component.getLength(), mts);
+                                                       mtl.setValue(len);
+                                                       //Be nice to the user and set the tab relative position enum back the way they had it.
+                                                       em.setSelectedItem(temp);
+                                               }
+                                               
+                                       } finally {
+                                               document.stopUndo();
+                                       }
+                               }
+                       }
+               });
+               panel.add(autoCalc, "skip 1, spanx");
+               
+               return panel;
+       }
+       
+       /**
+        * Scenarios:
+        * <p/>
+        * 1. All rings ahead of start of fin.
+        * 2. First ring ahead of start of fin.  Second ring ahead of end of fin.
+        * 3. First ring ahead of start of fin.  Second ring behind end of fin.
+        * 4. First ring equal or behind start of fin.  Second ring ahead of, or equal to, end of fin.
+        * 5. First ring equal or behind start of fin. Second ring behind end of fin.
+        * 6. All rings behind end of fin.
+        *
+        * @param rings              an unordered list of centering rings attached to the parent of the fin set
+        * @param finPositionFromTop the position from the top of the parent of the start of the fin set root
+        * @param finLength          the length of the root chord
+        * @param mts                the model for the tab shift (position); the model's value is modified as a result of this method call
+        * @return the length of the fin tab
+        */
+       private static double computeFinTabLength(List<CenteringRing> rings, Double finPositionFromTop, Double finLength, DoubleModel mts) {
+               List<SortableRing> positionsFromTop = new ArrayList<SortableRing>();
+               
+               //Fin tabs will be computed between the last two rings that meet the criteria, represented by top and bottom here.
+               SortableRing top = null;
+               SortableRing bottom = null;
+               
+               if (rings != null) {
+                       //Sort rings from top of parent to bottom
+                       Collections.sort(rings, new Comparator<CenteringRing>() {
+                               @Override
+                               public int compare(CenteringRing centeringRing, CenteringRing centeringRing1) {
+                                       return (int) (1000d * (centeringRing.asPositionValue(RocketComponent.Position.TOP) -
+                                                       centeringRing1.asPositionValue(RocketComponent.Position.TOP)));
+                                               }
+                       });
+                       
+                       for (int i = 0; i < rings.size(); i++) {
+                               CenteringRing centeringRing = rings.get(i);
+                               //Handle centering rings that overlap or are adjacent by synthetically merging them into one virtual ring.
+                               if (!positionsFromTop.isEmpty() &&
+                                               positionsFromTop.get(positionsFromTop.size() - 1).bottomSidePositionFromTop() >= centeringRing.asPositionValue(RocketComponent.Position.TOP)) {
+                                       SortableRing adjacent = positionsFromTop.get(positionsFromTop.size() - 1);
+                                       adjacent.merge(centeringRing);
+                               } else {
+                                       positionsFromTop.add(new SortableRing(centeringRing));
+                               }
+                       }
+                       
+                       for (int i = 0; i < positionsFromTop.size(); i++) {
+                               SortableRing sortableRing = positionsFromTop.get(i);
+                               if (top == null) {
+                                       top = sortableRing;
+                               } else if (sortableRing.bottomSidePositionFromTop() <= finPositionFromTop) {
+                                       top = sortableRing;
+                                       bottom = null;
+                               } else if (top.bottomSidePositionFromTop() <= finPositionFromTop) {
+                                       if (bottom == null) {
+                                               //If the current ring is in the upper half of the root chord, make it the top ring
+                                               if (sortableRing.bottomSidePositionFromTop() < finPositionFromTop + finLength / 2d) {
+                                                       top = sortableRing;
+                                               } else {
+                                                       bottom = sortableRing;
+                                               }
+                                       }
+                                       //Is the ring even with or above the end of the root chord? If so, make the existing bottom the top ring,
+                                       //and the current ring the bottom
+                                       else if (sortableRing.positionFromTop() <= finPositionFromTop + finLength) {
+                                               top = bottom;
+                                               bottom = sortableRing;
+                                       }
+                               } else {
+                                       if (bottom == null) {
+                                               bottom = sortableRing;
+                                       }
+                               }
+                       }
+               }
+               
+               // Edge case where there are no centering rings or for some odd reason top and bottom are identical.
+               if (top == null || top == bottom) {
+                       mts.setValue(0);
+                       return finLength;
+               }
+               
+               if (bottom == null) {
+                       // If there is no bottom ring and the top ring's bottom edge is within the span of the root chord, then
+                       // set the position of the fin tab starting at the bottom side of the top ring.
+                       if (top.bottomSidePositionFromTop() >= finPositionFromTop) {
+                               mts.setValue(top.bottomSidePositionFromTop() - finPositionFromTop);
+                               return (finPositionFromTop + finLength - top.bottomSidePositionFromTop());
+                       } else {
+                               // Otherwise the top ring is outside the span of the root chord so set the tab length to be the entire
+                               // root chord.
+                               mts.setValue(0);
+                               return finLength;
+                       }
+               }
+               // If the bottom edge of the top centering ring is above the start of the fin's root chord, then make the
+               // fin tab align with the start of the root chord.
+               if (top.bottomSidePositionFromTop() < finPositionFromTop) {
+                       mts.setValue(0);
+                       return bottom.positionFromTop - finPositionFromTop;
+               } else {
+                       // Otherwise the rings are within the span of the root chord.  Place the tab between them.
+                       mts.setValue(top.bottomSidePositionFromTop() - finPositionFromTop);
+                       return (bottom.positionFromTop() - top.bottomSidePositionFromTop());
+               }
+       }
+       
+       @Override
+       public void updateFields() {
+               super.updateFields();
+               if (split != null)
+                       split.setEnabled(((FinSet) component).getFinCount() > 1);
+       }
+       
+       /**
+        * A container class to store pertinent info about centering rings.  This is used in the computation to figure
+        * out tab length and position.
+        */
+       static class SortableRing {
+               
+               /**
+                * The length of the ring (more commonly called the thickness).
+                */
+               private double thickness;
+               /**
+                * The position of the ring from the top of the parent.
+                */
+               private double positionFromTop;
+               
+               /**
+                * Constructor.
+                *
+                * @param r the source centering ring
+                */
+               SortableRing(CenteringRing r) {
+                       thickness = r.getLength();
+                       positionFromTop = r.asPositionValue(RocketComponent.Position.TOP);
+               }
+               
+               /**
+                * Merge an adjacent ring.
+                *
+                * @param adjacent the adjacent ring
+                */
+               public void merge(CenteringRing adjacent) {
+                       double v = adjacent.asPositionValue(RocketComponent.Position.TOP);
+                       if (positionFromTop < v) {
+                               thickness = (v + adjacent.getLength()) - positionFromTop;
+                       } else {
+                               double tmp = positionFromTop + thickness;
+                               positionFromTop = v;
+                               thickness = tmp - v;
+                       }
+               }
+               
+               /**
+                * Compute the position of the bottom edge of the ring, relative to the top of the parent.
+                *
+                * @return the distance from the top of the parent to the bottom edge of the ring
+                */
+               public double bottomSidePositionFromTop() {
+                       return positionFromTop + thickness;
+               }
+               
+               /**
+                * Compute the position of the top edge of the ring, relative to the top of the parent.
+                *
+                * @return the distance from the top of the parent to the top edge of the ring
+                */
+               public double positionFromTop() {
+                       return positionFromTop;
+               }
+       }
 }
index 06c877c7fa94810f31866d711b5bdce19777d78c..56609bcf555a0f678b7ee192d2d64d46cf373ded 100644 (file)
@@ -17,6 +17,7 @@ import javax.swing.SwingConstants;
 import javax.swing.table.AbstractTableModel;
 
 import net.miginfocom.swing.MigLayout;
+import net.sf.openrocket.document.OpenRocketDocument;
 import net.sf.openrocket.gui.SpinnerEditor;
 import net.sf.openrocket.gui.adaptors.DoubleModel;
 import net.sf.openrocket.gui.adaptors.EnumModel;
@@ -50,8 +51,8 @@ public class FreeformFinSetConfig extends FinSetConfig {
        private FinPointFigure figure = null;
        
        
-       public FreeformFinSetConfig(RocketComponent component) {
-               super(component);
+       public FreeformFinSetConfig(OpenRocketDocument d, RocketComponent component) {
+               super(d, component);
                this.finset = (FreeformFinSet) component;
                
                //// General and General properties
index 35347fd3b6c4b112c0f4947e68345e71e6b27d0f..a1c6993814fc9eee9e7148cb12bec9414a925e46 100644 (file)
@@ -27,6 +27,7 @@ import javax.swing.event.ChangeEvent;
 import javax.swing.event.ChangeListener;
 
 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;
@@ -47,25 +48,25 @@ import net.sf.openrocket.util.Coordinate;
 public class InnerTubeConfig extends ThicknessRingComponentConfig {
        private static final Translator trans = Application.getTranslator();
        
-
-       public InnerTubeConfig(RocketComponent c) {
-               super(c);
+       
+       public InnerTubeConfig(OpenRocketDocument d, RocketComponent c) {
+               super(d, c);
                
                JPanel tab;
                
                tab = new MotorConfig((MotorMount) c);
                //// Motor and Motor mount configuration
-               tabbedPane.insertTab(trans.get("InnerTubeCfg.tab.Motor"), null, tab, 
+               tabbedPane.insertTab(trans.get("InnerTubeCfg.tab.Motor"), null, tab,
                                trans.get("InnerTubeCfg.tab.ttip.Motor"), 1);
                
                tab = clusterTab();
                //// Cluster and Cluster configuration
-               tabbedPane.insertTab(trans.get("InnerTubeCfg.tab.Cluster"), null, tab, 
+               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, 
+               tabbedPane.insertTab(trans.get("InnerTubeCfg.tab.Radialpos"), null, tab,
                                trans.get("InnerTubeCfg.tab.ttip.Radialpos"), 3);
                
                tabbedPane.setSelectedIndex(0);
@@ -156,7 +157,7 @@ public class InnerTubeConfig extends ThicknessRingComponentConfig {
                                                if (tube.getClusterCount() <= 1)
                                                        return;
                                                
-                                               ComponentConfigDialog.addUndoPosition("Split cluster");
+                                               document.addUndoPosition("Split cluster");
                                                
                                                Coordinate[] coords = { Coordinate.NUL };
                                                coords = component.shiftCoordinates(coords);
index 56f1231f9b1e114543394c7eb1c479945e8a9b2d..947b205aea42c3287fb370f5dd2687647ecd415c 100644 (file)
@@ -1,7 +1,13 @@
 package net.sf.openrocket.gui.configdialog;
 
 
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JSpinner;
+
 import net.miginfocom.swing.MigLayout;
+import net.sf.openrocket.document.OpenRocketDocument;
 import net.sf.openrocket.gui.SpinnerEditor;
 import net.sf.openrocket.gui.adaptors.DoubleModel;
 import net.sf.openrocket.gui.adaptors.EnumModel;
@@ -13,140 +19,135 @@ import net.sf.openrocket.rocketcomponent.RocketComponent;
 import net.sf.openrocket.startup.Application;
 import net.sf.openrocket.unit.UnitGroup;
 
-import javax.swing.JComboBox;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.JSpinner;
-
 public class LaunchLugConfig extends RocketComponentConfig {
-
+       
        private MotorConfig motorConfigPane = null;
        private static final Translator trans = Application.getTranslator();
-
-       public LaunchLugConfig(RocketComponent c) {
-               super(c);
+       
+       public LaunchLugConfig(OpenRocketDocument d, RocketComponent c) {
+               super(d, c);
                
                JPanel primary = new JPanel(new MigLayout("fill"));
                
-               
-               JPanel panel = new JPanel(new MigLayout("gap rel unrel","[][65lp::][30lp::][]",""));
+
+               JPanel panel = new JPanel(new MigLayout("gap rel unrel", "[][65lp::][30lp::][]", ""));
                
                ////  Body tube length
                //// Length:
                panel.add(new JLabel(trans.get("LaunchLugCfg.lbl.Length")));
                
-               DoubleModel m = new DoubleModel(component,"Length",UnitGroup.UNITS_LENGTH,0);
+               DoubleModel m = new DoubleModel(component, "Length", UnitGroup.UNITS_LENGTH, 0);
                
                JSpinner 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.02, 0.1)),"w 100lp, wrap para");
+               panel.add(spin, "growx");
                
+               panel.add(new UnitSelector(m), "growx");
+               panel.add(new BasicSlider(m.getSliderModel(0, 0.02, 0.1)), "w 100lp, wrap para");
                
+
                //// Body tube diameter
                //// Outer diameter:
                panel.add(new JLabel(trans.get("LaunchLugCfg.lbl.Outerdiam")));
-
-               DoubleModel od  = new DoubleModel(component,"OuterRadius",2,UnitGroup.UNITS_LENGTH,0);
+               
+               DoubleModel 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(spin, "growx");
                
-               panel.add(new UnitSelector(od),"growx");
-               panel.add(new BasicSlider(od.getSliderModel(0, 0.04, 0.2)),"w 100lp, wrap rel");
-
+               panel.add(new UnitSelector(od), "growx");
+               panel.add(new BasicSlider(od.getSliderModel(0, 0.04, 0.2)), "w 100lp, wrap rel");
                
+
                ////  Inner diameter:
                panel.add(new JLabel(trans.get("LaunchLugCfg.lbl.Innerdiam")));
-
+               
                // Diameter = 2*Radius
-               m = new DoubleModel(component,"InnerRadius",2,UnitGroup.UNITS_LENGTH,0);
+               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(spin, "growx");
                
-               panel.add(new UnitSelector(m),"growx");
-               panel.add(new BasicSlider(m.getSliderModel(new DoubleModel(0), od)),"w 100lp, wrap rel");
-
+               panel.add(new UnitSelector(m), "growx");
+               panel.add(new BasicSlider(m.getSliderModel(new DoubleModel(0), od)), "w 100lp, wrap rel");
                
+
                ////  Wall thickness
                //// Thickness:
                panel.add(new JLabel(trans.get("LaunchLugCfg.lbl.Thickness")));
                
-               m = new DoubleModel(component,"Thickness",UnitGroup.UNITS_LENGTH,0);
+               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(spin, "growx");
                
-               panel.add(new UnitSelector(m),"growx");
-               panel.add(new BasicSlider(m.getSliderModel(0,0.01)),"w 100lp, wrap 20lp");
+               panel.add(new UnitSelector(m), "growx");
+               panel.add(new BasicSlider(m.getSliderModel(0, 0.01)), "w 100lp, wrap 20lp");
                
 
                ////  Radial position:
                panel.add(new JLabel(trans.get("LaunchLugCfg.lbl.Radialpos")));
                
-               m = new DoubleModel(component,"RadialDirection",UnitGroup.UNITS_ANGLE,
+               m = new DoubleModel(component, "RadialDirection", UnitGroup.UNITS_ANGLE,
                                -Math.PI, Math.PI);
                
                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(-Math.PI, Math.PI)),"w 100lp, wrap");
-               
-               
+               panel.add(spin, "growx");
                
+               panel.add(new UnitSelector(m), "growx");
+               panel.add(new BasicSlider(m.getSliderModel(-Math.PI, Math.PI)), "w 100lp, wrap");
                
+
+
+
                primary.add(panel, "grow, gapright 20lp");
-               panel = new JPanel(new MigLayout("gap rel unrel","[][65lp::][30lp::][]",""));
-               
-               
+               panel = new JPanel(new MigLayout("gap rel unrel", "[][65lp::][30lp::][]", ""));
                
+
+
                //// Position relative to:
                panel.add(new JLabel(trans.get("LaunchLugCfg.lbl.Posrelativeto")));
-
+               
                JComboBox combo = new JComboBox(
                                new EnumModel<RocketComponent.Position>(component, "RelativePosition",
                                                new RocketComponent.Position[] {
-                                               RocketComponent.Position.TOP,
-                                               RocketComponent.Position.MIDDLE,
-                                               RocketComponent.Position.BOTTOM,
-                                               RocketComponent.Position.ABSOLUTE
+                                                               RocketComponent.Position.TOP,
+                                                               RocketComponent.Position.MIDDLE,
+                                                               RocketComponent.Position.BOTTOM,
+                                                               RocketComponent.Position.ABSOLUTE
                                }));
-               panel.add(combo,"spanx, growx, wrap");
+               panel.add(combo, "spanx, growx, wrap");
                
                //// plus
-               panel.add(new JLabel(trans.get("LaunchLugCfg.lbl.plus")),"right");
-
-               m = new DoubleModel(component,"PositionValue",UnitGroup.UNITS_LENGTH);
+               panel.add(new JLabel(trans.get("LaunchLugCfg.lbl.plus")), "right");
+               
+               m = new DoubleModel(component, "PositionValue", UnitGroup.UNITS_LENGTH);
                spin = new JSpinner(m.getSpinnerModel());
                spin.setEditor(new SpinnerEditor(spin));
-               panel.add(spin,"growx");
+               panel.add(spin, "growx");
                
-               panel.add(new UnitSelector(m),"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 para");
-
-               
                
+
+
                //// Material
                materialPanel(panel, Material.Type.BULK);
                
-               
-               primary.add(panel,"grow");
+
+               primary.add(panel, "grow");
                
                //// General and General properties
-               tabbedPane.insertTab(trans.get("LaunchLugCfg.tab.General"), null, primary, 
+               tabbedPane.insertTab(trans.get("LaunchLugCfg.tab.General"), null, primary,
                                trans.get("LaunchLugCfg.tab.Generalprop"), 0);
                tabbedPane.setSelectedIndex(0);
        }
index 659714f46043f001514c4d6aa36b2e92d49ffc1f..b199d20965e28a41adec5702a4c19c79365f22d0 100644 (file)
@@ -3,7 +3,6 @@ package net.sf.openrocket.gui.configdialog;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 
-
 import javax.swing.JButton;
 import javax.swing.JComboBox;
 import javax.swing.JLabel;
@@ -11,6 +10,7 @@ import javax.swing.JPanel;
 import javax.swing.JSpinner;
 
 import net.miginfocom.swing.MigLayout;
+import net.sf.openrocket.document.OpenRocketDocument;
 import net.sf.openrocket.gui.SpinnerEditor;
 import net.sf.openrocket.gui.adaptors.DoubleModel;
 import net.sf.openrocket.gui.adaptors.EnumModel;
@@ -25,125 +25,125 @@ import net.sf.openrocket.unit.UnitGroup;
 
 public class MassComponentConfig extends RocketComponentConfig {
        private static final Translator trans = Application.getTranslator();
-
-       public MassComponentConfig(RocketComponent component) {
-               super(component);
-               
-               
-               JPanel panel = new JPanel(new MigLayout("gap rel unrel","[][65lp::][30lp::]",""));
-               
+       
+       public MassComponentConfig(OpenRocketDocument d, RocketComponent component) {
+               super(d, component);
                
+
+               JPanel panel = new JPanel(new MigLayout("gap rel unrel", "[][65lp::][30lp::]", ""));
                
+
+
                ////  Mass
                panel.add(new JLabel(trans.get("MassComponentCfg.lbl.Mass")));
                
-               DoubleModel m = new DoubleModel(component,"ComponentMass",UnitGroup.UNITS_MASS,0);
+               DoubleModel m = new DoubleModel(component, "ComponentMass", UnitGroup.UNITS_MASS, 0);
                
                JSpinner 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.05, 0.5)),"w 100lp, wrap");
-               
+               panel.add(spin, "growx");
                
+               panel.add(new UnitSelector(m), "growx");
+               panel.add(new BasicSlider(m.getSliderModel(0, 0.05, 0.5)), "w 100lp, wrap");
                
+
+
                ////  Mass length
                //// Length
                panel.add(new JLabel(trans.get("MassComponentCfg.lbl.Length")));
                
-               m = new DoubleModel(component,"Length",UnitGroup.UNITS_LENGTH,0);
+               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, 0.5)),"w 100lp, wrap");
+               panel.add(spin, "growx");
                
+               panel.add(new UnitSelector(m), "growx");
+               panel.add(new BasicSlider(m.getSliderModel(0, 0.1, 0.5)), "w 100lp, wrap");
                
+
                //// Tube diameter
                //// Diameter:
                panel.add(new JLabel(trans.get("MassComponentCfg.lbl.Diameter")));
-
-               DoubleModel od  = new DoubleModel(component,"Radius",2,UnitGroup.UNITS_LENGTH,0);
+               
+               DoubleModel od = new DoubleModel(component, "Radius", 2, UnitGroup.UNITS_LENGTH, 0);
                // Diameter = 2*Radius
-
+               
                spin = new JSpinner(od.getSpinnerModel());
                spin.setEditor(new SpinnerEditor(spin));
-               panel.add(spin,"growx");
+               panel.add(spin, "growx");
                
-               panel.add(new UnitSelector(od),"growx");
-               panel.add(new BasicSlider(od.getSliderModel(0, 0.04, 0.2)),"w 100lp, wrap");
-
+               panel.add(new UnitSelector(od), "growx");
+               panel.add(new BasicSlider(od.getSliderModel(0, 0.04, 0.2)), "w 100lp, wrap");
                
+
                ////  Position
                //// Position relative to:
                panel.add(new JLabel(trans.get("MassComponentCfg.lbl.PosRelativeto")));
-
+               
                JComboBox combo = new JComboBox(
                                new EnumModel<RocketComponent.Position>(component, "RelativePosition",
                                                new RocketComponent.Position[] {
-                                               RocketComponent.Position.TOP,
-                                               RocketComponent.Position.MIDDLE,
-                                               RocketComponent.Position.BOTTOM,
-                                               RocketComponent.Position.ABSOLUTE
+                                                               RocketComponent.Position.TOP,
+                                                               RocketComponent.Position.MIDDLE,
+                                                               RocketComponent.Position.BOTTOM,
+                                                               RocketComponent.Position.ABSOLUTE
                                }));
-               panel.add(combo,"spanx, growx, wrap");
+               panel.add(combo, "spanx, growx, wrap");
                //// plus
-               panel.add(new JLabel(trans.get("MassComponentCfg.lbl.plus")),"right");
-
-               m = new DoubleModel(component,"PositionValue",UnitGroup.UNITS_LENGTH);
+               panel.add(new JLabel(trans.get("MassComponentCfg.lbl.plus")), "right");
+               
+               m = new DoubleModel(component, "PositionValue", UnitGroup.UNITS_LENGTH);
                spin = new JSpinner(m.getSpinnerModel());
                spin.setEditor(new SpinnerEditor(spin));
-               panel.add(spin,"growx");
+               panel.add(spin, "growx");
                
-               panel.add(new UnitSelector(m),"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");
-
+               
                //// General and General properties
-               tabbedPane.insertTab(trans.get("MassComponentCfg.tab.General"), null, panel, 
+               tabbedPane.insertTab(trans.get("MassComponentCfg.tab.General"), null, panel,
                                trans.get("MassComponentCfg.tab.ttip.General"), 0);
                //// Radial position and Radial position configuration
-               tabbedPane.insertTab(trans.get("MassComponentCfg.tab.Radialpos"), null, positionTab(), 
+               tabbedPane.insertTab(trans.get("MassComponentCfg.tab.Radialpos"), null, positionTab(),
                                trans.get("MassComponentCfg.tab.ttip.Radialpos"), 1);
                tabbedPane.setSelectedIndex(0);
        }
        
        
        protected JPanel positionTab() {
-               JPanel panel = new JPanel(new MigLayout("gap rel unrel","[][65lp::][30lp::]",""));
+               JPanel panel = new JPanel(new MigLayout("gap rel unrel", "[][65lp::][30lp::]", ""));
                
                ////  Radial position
                //// Radial distance:
                panel.add(new JLabel(trans.get("MassComponentCfg.lbl.Radialdistance")));
                
-               DoubleModel m = new DoubleModel(component,"RadialPosition",UnitGroup.UNITS_LENGTH,0);
+               DoubleModel m = new DoubleModel(component, "RadialPosition", UnitGroup.UNITS_LENGTH, 0);
                
                JSpinner 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");
+               panel.add(spin, "growx");
                
+               panel.add(new UnitSelector(m), "growx");
+               panel.add(new BasicSlider(m.getSliderModel(0, 0.1, 1.0)), "w 100lp, wrap");
                
+
                //// Radial direction:
                panel.add(new JLabel(trans.get("MassComponentCfg.lbl.Radialdirection")));
                
-               m = new DoubleModel(component,"RadialDirection",UnitGroup.UNITS_ANGLE,0);
+               m = new DoubleModel(component, "RadialDirection", UnitGroup.UNITS_ANGLE, 0);
                
                spin = new JSpinner(m.getSpinnerModel());
                spin.setEditor(new SpinnerEditor(spin));
-               panel.add(spin,"growx");
+               panel.add(spin, "growx");
                
-               panel.add(new UnitSelector(m),"growx");
-               panel.add(new BasicSlider(m.getSliderModel(-Math.PI, Math.PI)),"w 100lp, wrap");
-
+               panel.add(new UnitSelector(m), "growx");
+               panel.add(new BasicSlider(m.getSliderModel(-Math.PI, Math.PI)), "w 100lp, wrap");
                
+
                //// Reset button
                JButton button = new JButton(trans.get("MassComponentCfg.but.Reset"));
                button.addActionListener(new ActionListener() {
@@ -153,7 +153,7 @@ public class MassComponentConfig extends RocketComponentConfig {
                                ((MassComponent) component).setRadialPosition(0.0);
                        }
                });
-               panel.add(button,"spanx, right");
+               panel.add(button, "spanx, right");
                
                return panel;
        }
index a9d4f61ad440a5a20804fb369808c69c1a16e118..682f6d3507b44b30229481791037bb4a0037e798 100644 (file)
@@ -12,6 +12,7 @@ import javax.swing.JSlider;
 import javax.swing.JSpinner;
 
 import net.miginfocom.swing.MigLayout;
+import net.sf.openrocket.document.OpenRocketDocument;
 import net.sf.openrocket.gui.SpinnerEditor;
 import net.sf.openrocket.gui.adaptors.BooleanModel;
 import net.sf.openrocket.gui.adaptors.DoubleModel;
@@ -27,7 +28,7 @@ import net.sf.openrocket.startup.Application;
 import net.sf.openrocket.unit.UnitGroup;
 
 public class NoseConeConfig extends RocketComponentConfig {
-
+       
        private JComboBox typeBox;
        
        private DescriptionArea description;
@@ -36,146 +37,147 @@ public class NoseConeConfig extends RocketComponentConfig {
        private JSpinner shapeSpinner;
        private JSlider shapeSlider;
        private static final Translator trans = Application.getTranslator();
-
+       
        // Prepended to the description from NoseCone.DESCRIPTIONS
        private static final String PREDESC = "<html>";
        
-       public NoseConeConfig(RocketComponent c) {
-               super(c);
+       public NoseConeConfig(OpenRocketDocument d, RocketComponent c) {
+               super(d, c);
                
                DoubleModel m;
-               JPanel panel = new JPanel(new MigLayout("","[][65lp::][30lp::]"));
-
-               
+               JPanel panel = new JPanel(new MigLayout("", "[][65lp::][30lp::]"));
                
 
+
+
                ////  Shape selection
                //// Nose cone shape:
                panel.add(new JLabel(trans.get("NoseConeCfg.lbl.Noseconeshape")));
-
-               Transition.Shape selected = ((NoseCone)component).getType();
+               
+               Transition.Shape selected = ((NoseCone) component).getType();
                Transition.Shape[] typeList = Transition.Shape.values();
                
                typeBox = new JComboBox(typeList);
                typeBox.setEditable(false);
                typeBox.setSelectedItem(selected);
                typeBox.addActionListener(new ActionListener() {
+                       @Override
                        public void actionPerformed(ActionEvent e) {
-                               Transition.Shape s = (Transition.Shape)typeBox.getSelectedItem();
-                               ((NoseCone)component).setType(s);
+                               Transition.Shape s = (Transition.Shape) typeBox.getSelectedItem();
+                               ((NoseCone) component).setType(s);
                                description.setText(PREDESC + s.getNoseConeDescription());
                                updateEnabled();
                        }
                });
-               panel.add(typeBox,"span, wrap rel");
-
-               
+               panel.add(typeBox, "span, wrap rel");
                
 
+
+
                ////  Shape parameter
                ////  Shape parameter:
                shapeLabel = new JLabel(trans.get("NoseConeCfg.lbl.Shapeparam"));
                panel.add(shapeLabel);
                
-               m = new DoubleModel(component,"ShapeParameter");
+               m = new DoubleModel(component, "ShapeParameter");
                
                shapeSpinner = new JSpinner(m.getSpinnerModel());
                shapeSpinner.setEditor(new SpinnerEditor(shapeSpinner));
-               panel.add(shapeSpinner,"growx");
+               panel.add(shapeSpinner, "growx");
                
-               DoubleModel min = new DoubleModel(component,"ShapeParameterMin");
-               DoubleModel max = new DoubleModel(component,"ShapeParameterMax");
-               shapeSlider = new BasicSlider(m.getSliderModel(min,max)); 
-               panel.add(shapeSlider,"skip, w 100lp, wrap para");
+               DoubleModel min = new DoubleModel(component, "ShapeParameterMin");
+               DoubleModel max = new DoubleModel(component, "ShapeParameterMax");
+               shapeSlider = new BasicSlider(m.getSliderModel(min, max));
+               panel.add(shapeSlider, "skip, w 100lp, wrap para");
                
                updateEnabled();
-
                
+
                ////  Length
                //// Nose cone length:
                panel.add(new JLabel(trans.get("NoseConeCfg.lbl.Noseconelength")));
-
-               m = new DoubleModel(component,"Length",UnitGroup.UNITS_LENGTH,0);
+               
+               m = new DoubleModel(component, "Length", UnitGroup.UNITS_LENGTH, 0);
                JSpinner spin = new JSpinner(m.getSpinnerModel());
                spin.setEditor(new SpinnerEditor(spin));
-               panel.add(spin,"growx");
+               panel.add(spin, "growx");
                
-               panel.add(new UnitSelector(m),"growx");
-               panel.add(new BasicSlider(m.getSliderModel(0, 0.1, 0.7)),"w 100lp, wrap");
+               panel.add(new UnitSelector(m), "growx");
+               panel.add(new BasicSlider(m.getSliderModel(0, 0.1, 0.7)), "w 100lp, wrap");
                
                ////  Diameter
                //// Base diameter:
                panel.add(new JLabel(trans.get("NoseConeCfg.lbl.Basediam")));
-
-               m = new DoubleModel(component,"AftRadius",2.0,UnitGroup.UNITS_LENGTH,0);  // Diameter = 2*Radius
+               
+               m = new DoubleModel(component, "AftRadius", 2.0, UnitGroup.UNITS_LENGTH, 0); // Diameter = 2*Radius
                spin = new JSpinner(m.getSpinnerModel());
                spin.setEditor(new SpinnerEditor(spin));
-               panel.add(spin,"growx");
+               panel.add(spin, "growx");
                
-               panel.add(new UnitSelector(m),"growx");
-               panel.add(new BasicSlider(m.getSliderModel(0, 0.04, 0.2)),"w 100lp, wrap 0px");
+               panel.add(new UnitSelector(m), "growx");
+               panel.add(new BasicSlider(m.getSliderModel(0, 0.04, 0.2)), "w 100lp, wrap 0px");
                
                JCheckBox check = new JCheckBox(m.getAutomaticAction());
                //// Automatic
                check.setText(trans.get("NoseConeCfg.checkbox.Automatic"));
-               panel.add(check,"skip, span 2, wrap");
+               panel.add(check, "skip, span 2, wrap");
                
 
                ////  Wall thickness:
                panel.add(new JLabel(trans.get("NoseConeCfg.lbl.Wallthickness")));
                
-               m = new DoubleModel(component,"Thickness",UnitGroup.UNITS_LENGTH,0);
+               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(spin, "growx");
                
-               panel.add(new UnitSelector(m),"growx");
-               panel.add(new BasicSlider(m.getSliderModel(0,0.01)),"w 100lp, wrap 0px");
+               panel.add(new UnitSelector(m), "growx");
+               panel.add(new BasicSlider(m.getSliderModel(0, 0.01)), "w 100lp, wrap 0px");
                
 
-               check = new JCheckBox(new BooleanModel(component,"Filled"));
+               check = new JCheckBox(new BooleanModel(component, "Filled"));
                //// Filled
                check.setText(trans.get("NoseConeCfg.checkbox.Filled"));
-               panel.add(check,"skip, span 2, wrap");
-
+               panel.add(check, "skip, span 2, wrap");
                
+
                panel.add(new JLabel(""), "growy");
                
-               
-               
+
+
                ////  Description
                
                JPanel panel2 = new JPanel(new MigLayout("ins 0"));
                
                description = new DescriptionArea(5);
-               description.setText(PREDESC + ((NoseCone)component).getType().getNoseConeDescription());
+               description.setText(PREDESC + ((NoseCone) component).getType().getNoseConeDescription());
                panel2.add(description, "wmin 250lp, spanx, growx, wrap para");
                
 
                //// Material
                
-               
+
                materialPanel(panel2, Material.Type.BULK);
                panel.add(panel2, "cell 4 0, gapleft paragraph, aligny 0%, spany");
                
 
                //// General and General properties
-               tabbedPane.insertTab(trans.get("NoseConeCfg.tab.General"), null, panel, 
+               tabbedPane.insertTab(trans.get("NoseConeCfg.tab.General"), null, panel,
                                trans.get("NoseConeCfg.tab.ttip.General"), 0);
                //// Shoulder and Shoulder properties
-               tabbedPane.insertTab(trans.get("NoseConeCfg.tab.Shoulder"), null, shoulderTab(), 
+               tabbedPane.insertTab(trans.get("NoseConeCfg.tab.Shoulder"), null, shoulderTab(),
                                trans.get("NoseConeCfg.tab.ttip.Shoulder"), 1);
                tabbedPane.setSelectedIndex(0);
        }
        
-
+       
        private void updateEnabled() {
-               boolean e = ((NoseCone)component).getType().usesParameter();
+               boolean e = ((NoseCone) component).getType().usesParameter();
                shapeLabel.setEnabled(e);
                shapeSpinner.setEnabled(e);
                shapeSlider.setEnabled(e);
        }
-
        
+
 }
index 4dcd5104efca3efe026963ce1a3ed1fc8117f8b0..311b42afeb4b2e6333eb233a9c4262784d9ff525 100644 (file)
@@ -11,6 +11,7 @@ import javax.swing.JPanel;
 import javax.swing.JSpinner;
 
 import net.miginfocom.swing.MigLayout;
+import net.sf.openrocket.document.OpenRocketDocument;
 import net.sf.openrocket.gui.SpinnerEditor;
 import net.sf.openrocket.gui.adaptors.DoubleModel;
 import net.sf.openrocket.gui.adaptors.EnumModel;
@@ -19,263 +20,263 @@ import net.sf.openrocket.gui.adaptors.MaterialModel;
 import net.sf.openrocket.gui.components.BasicSlider;
 import net.sf.openrocket.gui.components.HtmlLabel;
 import net.sf.openrocket.gui.components.StyledLabel;
-import net.sf.openrocket.gui.components.UnitSelector;
 import net.sf.openrocket.gui.components.StyledLabel.Style;
+import net.sf.openrocket.gui.components.UnitSelector;
 import net.sf.openrocket.l10n.Translator;
 import net.sf.openrocket.material.Material;
 import net.sf.openrocket.rocketcomponent.MassObject;
+import net.sf.openrocket.rocketcomponent.MotorMount.IgnitionEvent;
 import net.sf.openrocket.rocketcomponent.Parachute;
 import net.sf.openrocket.rocketcomponent.RocketComponent;
-import net.sf.openrocket.rocketcomponent.MotorMount.IgnitionEvent;
 import net.sf.openrocket.startup.Application;
 import net.sf.openrocket.unit.UnitGroup;
 
 public class ParachuteConfig extends RecoveryDeviceConfig {
        private static final Translator trans = Application.getTranslator();
-
-       public ParachuteConfig(final RocketComponent component) {
-               super(component);
-
-               JPanel primary = new JPanel(new MigLayout());
+       
+       public ParachuteConfig(OpenRocketDocument d, final RocketComponent component) {
+               super(d, component);
                
-               JPanel panel = new JPanel(new MigLayout("gap rel unrel","[][65lp::][30lp::][]",""));
+               JPanel primary = new JPanel(new MigLayout());
                
+               JPanel panel = new JPanel(new MigLayout("gap rel unrel", "[][65lp::][30lp::][]", ""));
                
+
                //// Canopy
                panel.add(new StyledLabel(trans.get("ParachuteCfg.lbl.Canopy"), Style.BOLD), "wrap unrel");
                
                //// Diameter:
                panel.add(new JLabel(trans.get("ParachuteCfg.lbl.Diameter")));
                
-               DoubleModel m = new DoubleModel(component,"Diameter",UnitGroup.UNITS_LENGTH,0);
+               DoubleModel m = new DoubleModel(component, "Diameter", UnitGroup.UNITS_LENGTH, 0);
                
                JSpinner 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.4, 1.5)),"w 100lp, wrap");
-
+               panel.add(spin, "growx");
+               panel.add(new UnitSelector(m), "growx");
+               panel.add(new BasicSlider(m.getSliderModel(0, 0.4, 1.5)), "w 100lp, wrap");
+               
                //// Material:
                panel.add(new JLabel(trans.get("ParachuteCfg.lbl.Material")));
                
-               JComboBox combo = new JComboBox(new MaterialModel(panel, component, 
+               JComboBox combo = new JComboBox(new MaterialModel(panel, component,
                                Material.Type.SURFACE));
                //// The component material affects the weight of the component.
                combo.setToolTipText(trans.get("ParachuteCfg.combo.MaterialModel"));
-               panel.add(combo,"spanx 3, growx, wrap paragraph");
-
-//             materialPanel(panel, Material.Type.SURFACE, "Material:", null);
-               
+               panel.add(combo, "spanx 3, growx, wrap paragraph");
                
+               //              materialPanel(panel, Material.Type.SURFACE, "Material:", null);
                
+
+
                // CD
                //// <html>Drag coefficient C<sub>D</sub>:
                JLabel label = new HtmlLabel(trans.get("ParachuteCfg.lbl.longA1"));
                String tip = trans.get("ParachuteCfg.lbl.longB1") +
-               trans.get("ParachuteCfg.lbl.longB2") + "  " +
-               trans.get("ParachuteCfg.lbl.longB3");
+                               trans.get("ParachuteCfg.lbl.longB2") + "  " +
+                               trans.get("ParachuteCfg.lbl.longB3");
                label.setToolTipText(tip);
                panel.add(label);
                
-               m = new DoubleModel(component,"CD",UnitGroup.UNITS_COEFFICIENT,0);
+               m = new DoubleModel(component, "CD", UnitGroup.UNITS_COEFFICIENT, 0);
                
                spin = new JSpinner(m.getSpinnerModel());
                spin.setToolTipText(tip);
                spin.setEditor(new SpinnerEditor(spin));
-               panel.add(spin,"growx");
+               panel.add(spin, "growx");
                
                //// Reset button
                JButton button = new JButton(trans.get("ParachuteCfg.but.Reset"));
                button.addActionListener(new ActionListener() {
                        @Override
                        public void actionPerformed(ActionEvent e) {
-                               Parachute p = (Parachute)component;
+                               Parachute p = (Parachute) component;
                                p.setCD(Parachute.DEFAULT_CD);
                        }
                });
-               panel.add(button,"spanx, wrap 30lp");
-
-               
+               panel.add(button, "spanx, wrap 30lp");
                
+
+
                ////  Shroud lines
                panel.add(new StyledLabel(trans.get("ParachuteCfg.lbl.Shroudlines"), Style.BOLD), "wrap unrel");
-
+               
                //// Number of lines:
                panel.add(new JLabel(trans.get("ParachuteCfg.lbl.Numberoflines")));
-               IntegerModel im = new IntegerModel(component,"LineCount",0);
+               IntegerModel im = new IntegerModel(component, "LineCount", 0);
                
                spin = new JSpinner(im.getSpinnerModel());
                spin.setEditor(new SpinnerEditor(spin));
-               panel.add(spin,"growx, wrap");
+               panel.add(spin, "growx, wrap");
                
                //// Line length:
                panel.add(new JLabel(trans.get("ParachuteCfg.lbl.Linelength")));
-
-               m = new DoubleModel(component,"LineLength",UnitGroup.UNITS_LENGTH,0);
+               
+               m = new DoubleModel(component, "LineLength", 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.4, 1.5)),"w 100lp, wrap");
-
+               panel.add(spin, "growx");
+               panel.add(new UnitSelector(m), "growx");
+               panel.add(new BasicSlider(m.getSliderModel(0, 0.4, 1.5)), "w 100lp, wrap");
+               
                //// Material:
                panel.add(new JLabel(trans.get("ParachuteCfg.lbl.Material")));
                
-               combo = new JComboBox(new MaterialModel(panel, component, Material.Type.LINE, 
+               combo = new JComboBox(new MaterialModel(panel, component, Material.Type.LINE,
                                "LineMaterial"));
-               panel.add(combo,"spanx 3, growx, wrap");
-
-               
+               panel.add(combo, "spanx 3, growx, wrap");
                
-               primary.add(panel, "grow, gapright 20lp");
-               panel = new JPanel(new MigLayout("gap rel unrel","[][65lp::][30lp::][]",""));
 
+
+               primary.add(panel, "grow, gapright 20lp");
+               panel = new JPanel(new MigLayout("gap rel unrel", "[][65lp::][30lp::][]", ""));
                
-               
-               
+
+
+
                //// Position
                //// Position relative to:
                panel.add(new JLabel(trans.get("ParachuteCfg.lbl.Posrelativeto")));
-
+               
                combo = new JComboBox(
                                new EnumModel<RocketComponent.Position>(component, "RelativePosition",
                                                new RocketComponent.Position[] {
-                                               RocketComponent.Position.TOP,
-                                               RocketComponent.Position.MIDDLE,
-                                               RocketComponent.Position.BOTTOM,
-                                               RocketComponent.Position.ABSOLUTE
+                                                               RocketComponent.Position.TOP,
+                                                               RocketComponent.Position.MIDDLE,
+                                                               RocketComponent.Position.BOTTOM,
+                                                               RocketComponent.Position.ABSOLUTE
                                }));
-               panel.add(combo,"spanx, growx, wrap");
+               panel.add(combo, "spanx, growx, wrap");
                
                //// plus
-               panel.add(new JLabel(trans.get("ParachuteCfg.lbl.plus")),"right");
-
-               m = new DoubleModel(component,"PositionValue",UnitGroup.UNITS_LENGTH);
+               panel.add(new JLabel(trans.get("ParachuteCfg.lbl.plus")), "right");
+               
+               m = new DoubleModel(component, "PositionValue", UnitGroup.UNITS_LENGTH);
                spin = new JSpinner(m.getSpinnerModel());
                spin.setEditor(new SpinnerEditor(spin));
-               panel.add(spin,"growx");
+               panel.add(spin, "growx");
                
-               panel.add(new UnitSelector(m),"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");
-
+               
 
                ////  Spatial length
                //// Packed length:
                panel.add(new JLabel(trans.get("ParachuteCfg.lbl.Packedlength")));
                
-               m = new DoubleModel(component,"Length",UnitGroup.UNITS_LENGTH,0);
+               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, 0.5)),"w 100lp, wrap");
+               panel.add(spin, "growx");
                
+               panel.add(new UnitSelector(m), "growx");
+               panel.add(new BasicSlider(m.getSliderModel(0, 0.1, 0.5)), "w 100lp, wrap");
                
+
                //// Tube diameter
                //// Packed diameter:
                panel.add(new JLabel(trans.get("ParachuteCfg.lbl.Packeddiam")));
-
-               DoubleModel od  = new DoubleModel(component,"Radius",2,UnitGroup.UNITS_LENGTH,0);
+               
+               DoubleModel od = new DoubleModel(component, "Radius", 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 30lp");
+               panel.add(spin, "growx");
                
+               panel.add(new UnitSelector(od), "growx");
+               panel.add(new BasicSlider(od.getSliderModel(0, 0.04, 0.2)), "w 100lp, wrap 30lp");
                
+
                //// Deployment
                //// Deploys at:
-               panel.add(new JLabel(trans.get("ParachuteCfg.lbl.Deploysat")),"");
+               panel.add(new JLabel(trans.get("ParachuteCfg.lbl.Deploysat")), "");
                
                combo = new JComboBox(new EnumModel<IgnitionEvent>(component, "DeployEvent"));
-               panel.add(combo,"spanx 3, growx, wrap");
+               panel.add(combo, "spanx 3, growx, wrap");
                
                // ... and delay
                //// plus
-               panel.add(new JLabel(trans.get("ParachuteCfg.lbl.plusdelay")),"right");
+               panel.add(new JLabel(trans.get("ParachuteCfg.lbl.plusdelay")), "right");
                
-               m = new DoubleModel(component,"DeployDelay",0);
+               m = new DoubleModel(component, "DeployDelay", 0);
                spin = new JSpinner(m.getSpinnerModel());
                spin.setEditor(new SpinnerEditor(spin));
-               panel.add(spin,"spanx, split");
+               panel.add(spin, "spanx, split");
                
                //// seconds
-               panel.add(new JLabel(trans.get("ParachuteCfg.lbl.seconds")),"wrap paragraph");
-
+               panel.add(new JLabel(trans.get("ParachuteCfg.lbl.seconds")), "wrap paragraph");
+               
                // Altitude:
                label = new JLabel(trans.get("ParachuteCfg.lbl.Altitude"));
                altitudeComponents.add(label);
                panel.add(label);
                
-               m = new DoubleModel(component,"DeployAltitude",UnitGroup.UNITS_DISTANCE,0);
+               m = new DoubleModel(component, "DeployAltitude", UnitGroup.UNITS_DISTANCE, 0);
                
                spin = new JSpinner(m.getSpinnerModel());
                spin.setEditor(new SpinnerEditor(spin));
                altitudeComponents.add(spin);
-               panel.add(spin,"growx");
+               panel.add(spin, "growx");
                UnitSelector unit = new UnitSelector(m);
                altitudeComponents.add(unit);
-               panel.add(unit,"growx");
+               panel.add(unit, "growx");
                BasicSlider slider = new BasicSlider(m.getSliderModel(100, 1000));
                altitudeComponents.add(slider);
-               panel.add(slider,"w 100lp, wrap");
-
+               panel.add(slider, "w 100lp, wrap");
                
+
                primary.add(panel, "grow");
                
                updateFields();
-
+               
                //// General and General properties
                tabbedPane.insertTab(trans.get("ParachuteCfg.tab.General"), null, primary, trans.get("ParachuteCfg.tab.ttip.General"), 0);
                //// Radial position and Radial position configuration
-               tabbedPane.insertTab(trans.get("ParachuteCfg.tab.Radialpos"), null, positionTab(), 
+               tabbedPane.insertTab(trans.get("ParachuteCfg.tab.Radialpos"), null, positionTab(),
                                trans.get("ParachuteCfg.tab.ttip.Radialpos"), 1);
                tabbedPane.setSelectedIndex(0);
        }
        
        
-       
+
 
 
        protected JPanel positionTab() {
-               JPanel panel = new JPanel(new MigLayout("gap rel unrel","[][65lp::][30lp::]",""));
+               JPanel panel = new JPanel(new MigLayout("gap rel unrel", "[][65lp::][30lp::]", ""));
                
                ////  Radial position
                //// Radial distance:
                panel.add(new JLabel(trans.get("ParachuteCfg.lbl.Radialdistance")));
                
-               DoubleModel m = new DoubleModel(component,"RadialPosition",UnitGroup.UNITS_LENGTH,0);
+               DoubleModel m = new DoubleModel(component, "RadialPosition", UnitGroup.UNITS_LENGTH, 0);
                
                JSpinner 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");
+               panel.add(spin, "growx");
                
+               panel.add(new UnitSelector(m), "growx");
+               panel.add(new BasicSlider(m.getSliderModel(0, 0.1, 1.0)), "w 100lp, wrap");
                
+
                //// Radial direction:
                panel.add(new JLabel(trans.get("ParachuteCfg.lbl.Radialdirection")));
                
-               m = new DoubleModel(component,"RadialDirection",UnitGroup.UNITS_ANGLE,0);
+               m = new DoubleModel(component, "RadialDirection", UnitGroup.UNITS_ANGLE, 0);
                
                spin = new JSpinner(m.getSpinnerModel());
                spin.setEditor(new SpinnerEditor(spin));
-               panel.add(spin,"growx");
+               panel.add(spin, "growx");
                
-               panel.add(new UnitSelector(m),"growx");
-               panel.add(new BasicSlider(m.getSliderModel(-Math.PI, Math.PI)),"w 100lp, wrap");
-
+               panel.add(new UnitSelector(m), "growx");
+               panel.add(new BasicSlider(m.getSliderModel(-Math.PI, Math.PI)), "w 100lp, wrap");
                
+
                //// Reset button
                JButton button = new JButton(trans.get("ParachuteCfg.but.Reset"));
                button.addActionListener(new ActionListener() {
@@ -285,7 +286,7 @@ public class ParachuteConfig extends RecoveryDeviceConfig {
                                ((MassObject) component).setRadialPosition(0.0);
                        }
                });
-               panel.add(button,"spanx, right");
+               panel.add(button, "spanx, right");
                
                return panel;
        }
index a6b2ef8ac4cd91b438eaa1c662aa05c4f8e521bf..f93613c96c46dfa37b883194c1825b7150b61cf2 100644 (file)
@@ -5,20 +5,21 @@ import java.util.List;
 
 import javax.swing.JComponent;
 
+import net.sf.openrocket.document.OpenRocketDocument;
 import net.sf.openrocket.rocketcomponent.RecoveryDevice;
 import net.sf.openrocket.rocketcomponent.RocketComponent;
 
 
 public abstract class RecoveryDeviceConfig extends RocketComponentConfig {
-
+       
        protected final List<JComponent> altitudeComponents = new ArrayList<JComponent>();
        
-       public RecoveryDeviceConfig(RocketComponent component) {
-               super(component);
+       public RecoveryDeviceConfig(OpenRocketDocument d, RocketComponent component) {
+               super(d, component);
        }
-
        
        
+
        @Override
        public void updateFields() {
                super.updateFields();
@@ -26,10 +27,10 @@ public abstract class RecoveryDeviceConfig extends RocketComponentConfig {
                if (altitudeComponents == null)
                        return;
                
-               boolean enabled = (((RecoveryDevice)component).getDeployEvent() 
-                               == RecoveryDevice.DeployEvent.ALTITUDE); 
+               boolean enabled = (((RecoveryDevice) component).getDeployEvent()
+                               == RecoveryDevice.DeployEvent.ALTITUDE);
                
-               for (JComponent c: altitudeComponents) {
+               for (JComponent c : altitudeComponents) {
                        c.setEnabled(enabled);
                }
        }
index c520e66a91d46e0899cac3f7d89eee010727c2f4..23906d6fd2970e3cce5f2897c9c36377eaeba6af 100644 (file)
@@ -12,6 +12,7 @@ import javax.swing.JPanel;
 import javax.swing.JSpinner;
 
 import net.miginfocom.swing.MigLayout;
+import net.sf.openrocket.document.OpenRocketDocument;
 import net.sf.openrocket.gui.SpinnerEditor;
 import net.sf.openrocket.gui.adaptors.DoubleModel;
 import net.sf.openrocket.gui.adaptors.EnumModel;
@@ -29,8 +30,8 @@ import net.sf.openrocket.unit.UnitGroup;
 public class RingComponentConfig extends RocketComponentConfig {
        private static final Translator trans = Application.getTranslator();
        
-       public RingComponentConfig(RocketComponent component) {
-               super(component);
+       public RingComponentConfig(OpenRocketDocument d, RocketComponent component) {
+               super(d, component);
        }
        
        
index 3779f5483876eda4cef9309dc882146f908b6cb6..802434d76d2748001688823485068ed32e4a7e68 100644 (file)
@@ -24,6 +24,7 @@ import javax.swing.JTextArea;
 import javax.swing.JTextField;
 
 import net.miginfocom.swing.MigLayout;
+import net.sf.openrocket.document.OpenRocketDocument;
 import net.sf.openrocket.gui.SpinnerEditor;
 import net.sf.openrocket.gui.adaptors.BooleanModel;
 import net.sf.openrocket.gui.adaptors.DoubleModel;
@@ -40,7 +41,6 @@ import net.sf.openrocket.rocketcomponent.ComponentAssembly;
 import net.sf.openrocket.rocketcomponent.ExternalComponent;
 import net.sf.openrocket.rocketcomponent.ExternalComponent.Finish;
 import net.sf.openrocket.rocketcomponent.NoseCone;
-import net.sf.openrocket.rocketcomponent.Rocket;
 import net.sf.openrocket.rocketcomponent.RocketComponent;
 import net.sf.openrocket.startup.Application;
 import net.sf.openrocket.unit.UnitGroup;
@@ -53,6 +53,7 @@ public class RocketComponentConfig extends JPanel {
        
        private static final Translator trans = Application.getTranslator();
        
+       protected final OpenRocketDocument document;
        protected final RocketComponent component;
        protected final JTabbedPane tabbedPane;
        
@@ -69,8 +70,9 @@ public class RocketComponentConfig extends JPanel {
        private JLabel massLabel;
        
        
-       public RocketComponentConfig(RocketComponent component) {
+       public RocketComponentConfig(OpenRocketDocument document, RocketComponent component) {
                setLayout(new MigLayout("fill", "[grow, fill]"));
+               this.document = document;
                this.component = component;
                
                //// Component name:
@@ -92,14 +94,14 @@ public class RocketComponentConfig extends JPanel {
                this.add(tabbedPane, "growx, growy 1, wrap");
                
                //// Override and Mass and CG override options
-               tabbedPane.addTab(trans.get("RocketCompCfg.tab.Override"), null, overrideTab(), 
+               tabbedPane.addTab(trans.get("RocketCompCfg.tab.Override"), null, overrideTab(),
                                trans.get("RocketCompCfg.tab.MassandCGoverride"));
                if (component.isMassive())
                        //// Figure and Figure style options
-                       tabbedPane.addTab(trans.get("RocketCompCfg.tab.Figure"), null, figureTab(), 
+                       tabbedPane.addTab(trans.get("RocketCompCfg.tab.Figure"), null, figureTab(),
                                        trans.get("RocketCompCfg.tab.Figstyleopt"));
                //// Comment and Specify a comment for the component
-               tabbedPane.addTab(trans.get("RocketCompCfg.tab.Comment"), null, commentTab(), 
+               tabbedPane.addTab(trans.get("RocketCompCfg.tab.Comment"), null, commentTab(),
                                trans.get("RocketCompCfg.tab.Specifyacomment"));
                
                addButtons();
@@ -165,14 +167,14 @@ public class RocketComponentConfig extends JPanel {
                        String overridetext = null;
                        if (component.isMassOverridden()) {
                                //// (overridden to 
-                               overridetext = trans.get("RocketCompCfg.lbl.overriddento")+" " + UnitGroup.UNITS_MASS.getDefaultUnit().
+                               overridetext = trans.get("RocketCompCfg.lbl.overriddento") + " " + UnitGroup.UNITS_MASS.getDefaultUnit().
                                                toStringUnit(component.getOverrideMass()) + ")";
                        }
                        
                        for (RocketComponent c = component.getParent(); c != null; c = c.getParent()) {
                                if (c.isMassOverridden() && c.getOverrideSubcomponents()) {
                                        ///// (overridden by
-                                       overridetext = trans.get("RocketCompCfg.lbl.overriddenby")+" " + c.getName() + ")";
+                                       overridetext = trans.get("RocketCompCfg.lbl.overriddenby") + " " + c.getName() + ")";
                                }
                        }
                        
@@ -226,24 +228,19 @@ public class RocketComponentConfig extends JPanel {
                                @Override
                                public void actionPerformed(ActionEvent e) {
                                        Finish f = ((ExternalComponent) component).getFinish();
-                                       Rocket rocket = component.getRocket();
                                        try {
-                                               rocket.freeze();
-                                               // Store previous undo description
-                                               String desc = ComponentConfigDialog.getUndoDescription();
-                                               ComponentConfigDialog.addUndoPosition("Set rocket finish");
+                                               document.startUndo("Set rocket finish");
+                                               
                                                // Do changes
-                                               Iterator<RocketComponent> iter = rocket.iterator();
+                                               Iterator<RocketComponent> iter = component.getRoot().iterator();
                                                while (iter.hasNext()) {
                                                        RocketComponent c = iter.next();
                                                        if (c instanceof ExternalComponent) {
                                                                ((ExternalComponent) c).setFinish(f);
                                                        }
                                                }
-                                               // Restore undo description
-                                               ComponentConfigDialog.addUndoPosition(desc);
                                        } finally {
-                                               rocket.thaw();
+                                               document.stopUndo();
                                        }
                                }
                        });
@@ -337,7 +334,7 @@ public class RocketComponentConfig extends JPanel {
                //// <html>The overridden mass does not include motors.<br>
                panel.add(new StyledLabel(trans.get("RocketCompCfg.lbl.longB1") +
                                //// The center of gravity is measured from the front end of the
-                               trans.get("RocketCompCfg.lbl.longB2") +" " +
+                               trans.get("RocketCompCfg.lbl.longB2") + " " +
                                component.getComponentName().toLowerCase() + ".", -1),
                                "spanx, wrap, gap para, height 0::30lp");
                
@@ -349,7 +346,7 @@ public class RocketComponentConfig extends JPanel {
                JPanel panel = new JPanel(new MigLayout("fill"));
                
                //// Comments on the
-               panel.add(new StyledLabel(trans.get("RocketCompCfg.lbl.Commentsonthe") +" " + component.getComponentName() + ":",
+               panel.add(new StyledLabel(trans.get("RocketCompCfg.lbl.Commentsonthe") + " " + component.getComponentName() + ":",
                                Style.BOLD), "wrap");
                
                // TODO: LOW:  Changes in comment from other sources not reflected in component
index 07be2395ad131b1d569e194c0fdbddd660c6907d..701295c2473d3ecfd9b4e447952a31d3eb3af5a2 100644 (file)
@@ -11,6 +11,7 @@ import javax.swing.JScrollPane;
 import javax.swing.JTextArea;
 
 import net.miginfocom.swing.MigLayout;
+import net.sf.openrocket.document.OpenRocketDocument;
 import net.sf.openrocket.l10n.Translator;
 import net.sf.openrocket.rocketcomponent.Rocket;
 import net.sf.openrocket.rocketcomponent.RocketComponent;
@@ -27,8 +28,8 @@ public class RocketConfig extends RocketComponentConfig {
        
        private final Rocket rocket;
        
-       public RocketConfig(RocketComponent c) {
-               super(c);
+       public RocketConfig(OpenRocketDocument d, RocketComponent c) {
+               super(d, c);
                
                rocket = (Rocket) c;
                
index 0a21fc4c797a504e257b73e47f64734f69bc010a..fbc99f853d44941011681e0f78c2f948ca2098ca 100644 (file)
@@ -7,6 +7,7 @@ import javax.swing.JPanel;
 import javax.swing.JSpinner;
 
 import net.miginfocom.swing.MigLayout;
+import net.sf.openrocket.document.OpenRocketDocument;
 import net.sf.openrocket.gui.SpinnerEditor;
 import net.sf.openrocket.gui.adaptors.DoubleModel;
 import net.sf.openrocket.gui.adaptors.EnumModel;
@@ -20,17 +21,17 @@ import net.sf.openrocket.unit.UnitGroup;
 
 public class ShockCordConfig extends RocketComponentConfig {
        private static final Translator trans = Application.getTranslator();
-
-       public ShockCordConfig(RocketComponent component) {
-               super(component);
+       
+       public ShockCordConfig(OpenRocketDocument d, RocketComponent component) {
+               super(d, component);
                
-               JPanel panel = new JPanel(new MigLayout("gap rel unrel","[][65lp::][30lp::]",""));
+               JPanel panel = new JPanel(new MigLayout("gap rel unrel", "[][65lp::][30lp::]", ""));
                JLabel label;
                DoubleModel m;
                JSpinner spin;
                String tip;
                
-               
+
                //////  Left side
                
                // Cord length
@@ -38,14 +39,14 @@ public class ShockCordConfig extends RocketComponentConfig {
                label = new JLabel(trans.get("ShockCordCfg.lbl.Shockcordlength"));
                panel.add(label);
                
-               m = new DoubleModel(component,"CordLength",UnitGroup.UNITS_LENGTH,0);
+               m = new DoubleModel(component, "CordLength", UnitGroup.UNITS_LENGTH, 0);
                
                spin = new JSpinner(m.getSpinnerModel());
                spin.setEditor(new SpinnerEditor(spin));
-               panel.add(spin,"growx");
+               panel.add(spin, "growx");
                
-               panel.add(new UnitSelector(m),"growx");
-               panel.add(new BasicSlider(m.getSliderModel(0, 1, 10)),"w 100lp, wrap");
+               panel.add(new UnitSelector(m), "growx");
+               panel.add(new BasicSlider(m.getSliderModel(0, 1, 10)), "w 100lp, wrap");
                
 
                // Material
@@ -53,77 +54,77 @@ public class ShockCordConfig extends RocketComponentConfig {
                materialPanel(panel, Material.Type.LINE, trans.get("ShockCordCfg.lbl.Shockcordmaterial"), null);
                
 
-               
+
                /////  Right side
-               JPanel panel2 = new JPanel(new MigLayout("gap rel unrel","[][65lp::][30lp::]",""));
+               JPanel panel2 = new JPanel(new MigLayout("gap rel unrel", "[][65lp::][30lp::]", ""));
                panel.add(panel2, "cell 4 0, gapleft paragraph, aligny 0%, spany");
                
-               
+
                ////  Position
                //// Position relative to:
                panel2.add(new JLabel(trans.get("ShockCordCfg.lbl.Posrelativeto")));
-
+               
                JComboBox combo = new JComboBox(
                                new EnumModel<RocketComponent.Position>(component, "RelativePosition",
                                                new RocketComponent.Position[] {
-                                               RocketComponent.Position.TOP,
-                                               RocketComponent.Position.MIDDLE,
-                                               RocketComponent.Position.BOTTOM,
-                                               RocketComponent.Position.ABSOLUTE
+                                                               RocketComponent.Position.TOP,
+                                                               RocketComponent.Position.MIDDLE,
+                                                               RocketComponent.Position.BOTTOM,
+                                                               RocketComponent.Position.ABSOLUTE
                                }));
-               panel2.add(combo,"spanx, growx, wrap");
+               panel2.add(combo, "spanx, growx, wrap");
                
                //// plus
-               panel2.add(new JLabel(trans.get("ShockCordCfg.lbl.plus")),"right");
-
-               m = new DoubleModel(component,"PositionValue",UnitGroup.UNITS_LENGTH);
+               panel2.add(new JLabel(trans.get("ShockCordCfg.lbl.plus")), "right");
+               
+               m = new DoubleModel(component, "PositionValue", UnitGroup.UNITS_LENGTH);
                spin = new JSpinner(m.getSpinnerModel());
                spin.setEditor(new SpinnerEditor(spin));
-               panel2.add(spin,"growx");
+               panel2.add(spin, "growx");
                
-               panel2.add(new UnitSelector(m),"growx");
+               panel2.add(new UnitSelector(m), "growx");
                panel2.add(new BasicSlider(m.getSliderModel(
                                new DoubleModel(component.getParent(), "Length", -1.0, UnitGroup.UNITS_NONE),
                                new DoubleModel(component.getParent(), "Length"))),
                                "w 100lp, wrap");
-
+               
 
                ////  Spatial length
                //// Packed length:
                panel2.add(new JLabel(trans.get("ShockCordCfg.lbl.Packedlength")));
                
-               m = new DoubleModel(component,"Length",UnitGroup.UNITS_LENGTH,0);
+               m = new DoubleModel(component, "Length", UnitGroup.UNITS_LENGTH, 0);
                
                spin = new JSpinner(m.getSpinnerModel());
                spin.setEditor(new SpinnerEditor(spin));
-               panel2.add(spin,"growx");
-               
-               panel2.add(new UnitSelector(m),"growx");
-               panel2.add(new BasicSlider(m.getSliderModel(0, 0.1, 0.5)),"w 100lp, wrap");
+               panel2.add(spin, "growx");
                
+               panel2.add(new UnitSelector(m), "growx");
+               panel2.add(new BasicSlider(m.getSliderModel(0, 0.1, 0.5)), "w 100lp, wrap");
                
+
                //// Tube diameter
                //// Packed diameter:
                panel2.add(new JLabel(trans.get("ShockCordCfg.lbl.Packeddiam")));
-
-               DoubleModel od  = new DoubleModel(component,"Radius",2,UnitGroup.UNITS_LENGTH,0);
+               
+               DoubleModel od = new DoubleModel(component, "Radius", 2, UnitGroup.UNITS_LENGTH, 0);
                // Diameter = 2*Radius
-
+               
                spin = new JSpinner(od.getSpinnerModel());
                spin.setEditor(new SpinnerEditor(spin));
-               panel2.add(spin,"growx");
-               
-               panel2.add(new UnitSelector(od),"growx");
-               panel2.add(new BasicSlider(od.getSliderModel(0, 0.04, 0.2)),"w 100lp, wrap");
-
+               panel2.add(spin, "growx");
                
+               panel2.add(new UnitSelector(od), "growx");
+               panel2.add(new BasicSlider(od.getSliderModel(0, 0.04, 0.2)), "w 100lp, wrap");
                
+
+
                //// General and General properties
                tabbedPane.insertTab(trans.get("ShockCordCfg.tab.General"), null, panel, trans.get("ShockCordCfg.tab.ttip.General"), 0);
-//             tabbedPane.insertTab("Radial position", null, positionTab(), 
-//                             "Radial position configuration", 1);
+               //              tabbedPane.insertTab("Radial position", null, positionTab(), 
+               //                              "Radial position configuration", 1);
                tabbedPane.setSelectedIndex(0);
        }
        
-       
+
 }
index 67160b8168ba3eed87d4ff186bca4c4d4adf4e88..32192765ff02f8ca4927ad9bfa60f01979035177 100644 (file)
@@ -3,6 +3,7 @@ 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;
@@ -12,18 +13,18 @@ import net.sf.openrocket.startup.Application;
 public class SleeveConfig extends RingComponentConfig {
        private static final Translator trans = Application.getTranslator();
        
-       public SleeveConfig(RocketComponent c) {
-               super(c);
+       public SleeveConfig(OpenRocketDocument d, RocketComponent c) {
+               super(d, c);
                
                JPanel tab;
                //// Outer diameter:
                //// Inner diameter:
                //// Wall thickness:
                //// Length:
-               tab = generalTab(trans.get("SleeveCfg.tab.Outerdiam"), trans.get("SleeveCfg.tab.Innerdiam"), 
+               tab = generalTab(trans.get("SleeveCfg.tab.Outerdiam"), trans.get("SleeveCfg.tab.Innerdiam"),
                                trans.get("SleeveCfg.tab.Wallthickness"), trans.get("SleeveCfg.tab.Length"));
                //// General and General properties
-               tabbedPane.insertTab(trans.get("SleeveCfg.tab.General"), null, tab, 
+               tabbedPane.insertTab(trans.get("SleeveCfg.tab.General"), null, tab,
                                trans.get("SleeveCfg.tab.Generalproperties"), 0);
                tabbedPane.setSelectedIndex(0);
        }
index 3aef4acc021b73c66ad8cebd3161dc142476ec86..8d7be3049e1d4ac2a9380713762174eb6580a1f6 100644 (file)
@@ -12,6 +12,7 @@ import javax.swing.JPanel;
 import javax.swing.JSpinner;
 
 import net.miginfocom.swing.MigLayout;
+import net.sf.openrocket.document.OpenRocketDocument;
 import net.sf.openrocket.gui.SpinnerEditor;
 import net.sf.openrocket.gui.adaptors.DoubleModel;
 import net.sf.openrocket.gui.adaptors.EnumModel;
@@ -31,8 +32,8 @@ import net.sf.openrocket.unit.UnitGroup;
 public class StreamerConfig extends RecoveryDeviceConfig {
        private static final Translator trans = Application.getTranslator();
        
-       public StreamerConfig(final RocketComponent component) {
-               super(component);
+       public StreamerConfig(OpenRocketDocument d, final RocketComponent component) {
+               super(d, component);
                
                JPanel primary = new JPanel(new MigLayout());
                
index 2b1bb6f32158076ecf8f46612c89f5a2d2c71ad1..3013b7c9721cd28be18ff1c5a7d816069e46d90a 100644 (file)
@@ -3,6 +3,7 @@ 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;
@@ -12,8 +13,8 @@ import net.sf.openrocket.startup.Application;
 public class ThicknessRingComponentConfig extends RingComponentConfig {
        private static final Translator trans = Application.getTranslator();
        
-       public ThicknessRingComponentConfig(RocketComponent c) {
-               super(c);
+       public ThicknessRingComponentConfig(OpenRocketDocument d, RocketComponent c) {
+               super(d, c);
                
                JPanel tab;
                
@@ -21,11 +22,11 @@ public class ThicknessRingComponentConfig extends RingComponentConfig {
                //// Inner diameter:
                //// Wall thickness:
                //// Length:
-               tab = generalTab(trans.get("ThicknessRingCompCfg.tab.Outerdiam"), 
+               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, 
+               tabbedPane.insertTab(trans.get("ThicknessRingCompCfg.tab.General"), null, tab,
                                trans.get("ThicknessRingCompCfg.tab.Generalprop"), 0);
                tabbedPane.setSelectedIndex(0);
        }
index 513c49eb849bf01a032f78e2a01036f6347fddb7..5e0286d8946447a450e048caba95730bd48a4ed1 100644 (file)
@@ -11,6 +11,7 @@ import javax.swing.JPanel;
 import javax.swing.JSpinner;
 
 import net.miginfocom.swing.MigLayout;
+import net.sf.openrocket.document.OpenRocketDocument;
 import net.sf.openrocket.gui.SpinnerEditor;
 import net.sf.openrocket.gui.adaptors.BooleanModel;
 import net.sf.openrocket.gui.adaptors.DoubleModel;
@@ -25,7 +26,7 @@ import net.sf.openrocket.startup.Application;
 import net.sf.openrocket.unit.UnitGroup;
 
 public class TransitionConfig extends RocketComponentConfig {
-
+       
        private static final Translator trans = Application.getTranslator();
        private JComboBox typeBox;
        //private JLabel description;
@@ -40,168 +41,169 @@ public class TransitionConfig extends RocketComponentConfig {
        private static final String PREDESC = "<html>";
        
        
-       public TransitionConfig(RocketComponent c) {
-               super(c);
+       public TransitionConfig(OpenRocketDocument d, RocketComponent c) {
+               super(d, c);
                
                DoubleModel m;
                JSpinner spin;
                JCheckBox checkbox;
-
-               JPanel panel = new JPanel(new MigLayout("gap rel unrel","[][65lp::][30lp::]",""));
+               
+               JPanel panel = new JPanel(new MigLayout("gap rel unrel", "[][65lp::][30lp::]", ""));
                
 
 
                ////  Shape selection
                //// Transition shape:
                panel.add(new JLabel(trans.get("TransitionCfg.lbl.Transitionshape")));
-
-               Transition.Shape selected = ((Transition)component).getType();
+               
+               Transition.Shape selected = ((Transition) component).getType();
                Transition.Shape[] typeList = Transition.Shape.values();
                
                typeBox = new JComboBox(typeList);
                typeBox.setEditable(false);
                typeBox.setSelectedItem(selected);
                typeBox.addActionListener(new ActionListener() {
+                       @Override
                        public void actionPerformed(ActionEvent e) {
-                               Transition.Shape s = (Transition.Shape)typeBox.getSelectedItem();
-                               ((Transition)component).setType(s);
+                               Transition.Shape s = (Transition.Shape) typeBox.getSelectedItem();
+                               ((Transition) component).setType(s);
                                description.setText(PREDESC + s.getTransitionDescription());
                                updateEnabled();
                        }
                });
-               panel.add(typeBox,"span, split 2");
-
+               panel.add(typeBox, "span, split 2");
+               
                //// Clipped
-               checkbox = new JCheckBox(new BooleanModel(component,"Clipped"));
+               checkbox = new JCheckBox(new BooleanModel(component, "Clipped"));
                //// Clipped
                checkbox.setText(trans.get("TransitionCfg.checkbox.Clipped"));
-               panel.add(checkbox,"wrap");
-               
+               panel.add(checkbox, "wrap");
                
+
                ////  Shape parameter:
                shapeLabel = new JLabel(trans.get("TransitionCfg.lbl.Shapeparam"));
                panel.add(shapeLabel);
                
-               m = new DoubleModel(component,"ShapeParameter");
+               m = new DoubleModel(component, "ShapeParameter");
                
                shapeSpinner = new JSpinner(m.getSpinnerModel());
                shapeSpinner.setEditor(new SpinnerEditor(shapeSpinner));
-               panel.add(shapeSpinner,"growx");
+               panel.add(shapeSpinner, "growx");
                
-               DoubleModel min = new DoubleModel(component,"ShapeParameterMin");
-               DoubleModel max = new DoubleModel(component,"ShapeParameterMax");
-               shapeSlider = new BasicSlider(m.getSliderModel(min,max)); 
-               panel.add(shapeSlider,"skip, w 100lp, wrap");
+               DoubleModel min = new DoubleModel(component, "ShapeParameterMin");
+               DoubleModel max = new DoubleModel(component, "ShapeParameterMax");
+               shapeSlider = new BasicSlider(m.getSliderModel(min, max));
+               panel.add(shapeSlider, "skip, w 100lp, wrap");
                
                updateEnabled();
                
-               
+
                ////  Length
                //// Transition length:
                panel.add(new JLabel(trans.get("TransitionCfg.lbl.Transitionlength")));
                
-               m = new DoubleModel(component,"Length",UnitGroup.UNITS_LENGTH,0);
+               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.05, 0.3)),"w 100lp, wrap");
+               panel.add(spin, "growx");
                
+               panel.add(new UnitSelector(m), "growx");
+               panel.add(new BasicSlider(m.getSliderModel(0, 0.05, 0.3)), "w 100lp, wrap");
                
+
                //// Transition diameter 1
                //// Fore diameter:
                panel.add(new JLabel(trans.get("TransitionCfg.lbl.Forediam")));
-
-               DoubleModel od  = new DoubleModel(component,"ForeRadius",2,UnitGroup.UNITS_LENGTH,0);
+               
+               DoubleModel od = new DoubleModel(component, "ForeRadius", 2, UnitGroup.UNITS_LENGTH, 0);
                // Diameter = 2*Radius
-
+               
                spin = new JSpinner(od.getSpinnerModel());
                spin.setEditor(new SpinnerEditor(spin));
-               panel.add(spin,"growx");
+               panel.add(spin, "growx");
+               
+               panel.add(new UnitSelector(od), "growx");
+               panel.add(new BasicSlider(od.getSliderModel(0, 0.04, 0.2)), "w 100lp, wrap 0px");
                
-               panel.add(new UnitSelector(od),"growx");
-               panel.add(new BasicSlider(od.getSliderModel(0, 0.04, 0.2)),"w 100lp, wrap 0px");
-
                checkbox = new JCheckBox(od.getAutomaticAction());
                //// Automatic
                checkbox.setText(trans.get("TransitionCfg.checkbox.Automatic"));
-               panel.add(checkbox,"skip, span 2, wrap");
-               
+               panel.add(checkbox, "skip, span 2, wrap");
                
+
                //// Transition diameter 2
                //// Aft diameter:
                panel.add(new JLabel(trans.get("TransitionCfg.lbl.Aftdiam")));
-
-               od  = new DoubleModel(component,"AftRadius",2,UnitGroup.UNITS_LENGTH,0);
+               
+               od = new DoubleModel(component, "AftRadius", 2, UnitGroup.UNITS_LENGTH, 0);
                // Diameter = 2*Radius
-
+               
                spin = new JSpinner(od.getSpinnerModel());
                spin.setEditor(new SpinnerEditor(spin));
-               panel.add(spin,"growx");
+               panel.add(spin, "growx");
+               
+               panel.add(new UnitSelector(od), "growx");
+               panel.add(new BasicSlider(od.getSliderModel(0, 0.04, 0.2)), "w 100lp, wrap 0px");
                
-               panel.add(new UnitSelector(od),"growx");
-               panel.add(new BasicSlider(od.getSliderModel(0, 0.04, 0.2)),"w 100lp, wrap 0px");
-
                checkbox = new JCheckBox(od.getAutomaticAction());
                //// Automatic
                checkbox.setText(trans.get("TransitionCfg.checkbox.Automatic"));
-               panel.add(checkbox,"skip, span 2, wrap");
-               
+               panel.add(checkbox, "skip, span 2, wrap");
                
+
                ////  Wall thickness:
                panel.add(new JLabel(trans.get("TransitionCfg.lbl.Wallthickness")));
                
-               m = new DoubleModel(component,"Thickness",UnitGroup.UNITS_LENGTH,0);
+               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(spin, "growx");
                
-               panel.add(new UnitSelector(m),"growx");
-               panel.add(new BasicSlider(m.getSliderModel(0,0.01)),"w 100lp, wrap 0px");
+               panel.add(new UnitSelector(m), "growx");
+               panel.add(new BasicSlider(m.getSliderModel(0, 0.01)), "w 100lp, wrap 0px");
                
                //// Filled
-               checkbox = new JCheckBox(new BooleanModel(component,"Filled"));
+               checkbox = new JCheckBox(new BooleanModel(component, "Filled"));
                //// Filled
                checkbox.setText(trans.get("TransitionCfg.checkbox.Filled"));
-               panel.add(checkbox,"skip, span 2, wrap");
-
-               
+               panel.add(checkbox, "skip, span 2, wrap");
                
+
+
                ////  Description
                
                JPanel panel2 = new JPanel(new MigLayout("ins 0"));
                
                description = new DescriptionArea(5);
-               description.setText(PREDESC + ((Transition)component).getType().
+               description.setText(PREDESC + ((Transition) component).getType().
                                getTransitionDescription());
                panel2.add(description, "wmin 250lp, spanx, growx, wrap para");
                
 
                //// Material
                
-               
+
                materialPanel(panel2, Material.Type.BULK);
                panel.add(panel2, "cell 4 0, gapleft paragraph, aligny 0%, spany");
                
                //// General and General properties
-               tabbedPane.insertTab(trans.get("TransitionCfg.tab.General"), null, panel, 
+               tabbedPane.insertTab(trans.get("TransitionCfg.tab.General"), null, panel,
                                trans.get("TransitionCfg.tab.Generalproperties"), 0);
                //// Shoulder and Shoulder properties
-               tabbedPane.insertTab(trans.get("TransitionCfg.tab.Shoulder"), null, shoulderTab(), 
+               tabbedPane.insertTab(trans.get("TransitionCfg.tab.Shoulder"), null, shoulderTab(),
                                trans.get("TransitionCfg.tab.Shoulderproperties"), 1);
                tabbedPane.setSelectedIndex(0);
        }
        
        
-       
+
        private void updateEnabled() {
-               boolean e = ((Transition)component).getType().usesParameter();
+               boolean e = ((Transition) component).getType().usesParameter();
                shapeLabel.setEnabled(e);
                shapeSpinner.setEnabled(e);
                shapeSlider.setEnabled(e);
        }
-
+       
 }
index d4482de14b67569cca82a40f6abef6ed02bb0530..47650ffda2a5cdab29da1f982d522261283d929d 100644 (file)
@@ -9,6 +9,7 @@ import javax.swing.JSpinner;
 import javax.swing.SwingConstants;
 
 import net.miginfocom.swing.MigLayout;
+import net.sf.openrocket.document.OpenRocketDocument;
 import net.sf.openrocket.gui.SpinnerEditor;
 import net.sf.openrocket.gui.adaptors.DoubleModel;
 import net.sf.openrocket.gui.adaptors.EnumModel;
@@ -27,8 +28,8 @@ import net.sf.openrocket.unit.UnitGroup;
 public class TrapezoidFinSetConfig extends FinSetConfig {
        private static final Translator trans = Application.getTranslator();
        
-       public TrapezoidFinSetConfig(final RocketComponent component) {
-               super(component);
+       public TrapezoidFinSetConfig(OpenRocketDocument d, final RocketComponent component) {
+               super(d, component);
                
                DoubleModel m;
                JSpinner spin;
@@ -36,8 +37,8 @@ public class TrapezoidFinSetConfig extends FinSetConfig {
                
                JPanel mainPanel = new JPanel(new MigLayout());
                
-               
-               JPanel panel = new JPanel(new MigLayout("gap rel unrel","[][65lp::][30lp::]",""));
+
+               JPanel panel = new JPanel(new MigLayout("gap rel unrel", "[][65lp::][30lp::]", ""));
                
                ////  Number of fins:
                JLabel label = new JLabel(trans.get("TrapezoidFinSetCfg.lbl.Nbroffins"));
@@ -45,15 +46,15 @@ public class TrapezoidFinSetConfig extends FinSetConfig {
                label.setToolTipText(trans.get("TrapezoidFinSetCfg.lbl.ttip.Nbroffins"));
                panel.add(label);
                
-               IntegerModel im = new IntegerModel(component,"FinCount",1,8);
+               IntegerModel im = new IntegerModel(component, "FinCount", 1, 8);
                
                spin = new JSpinner(im.getSpinnerModel());
                spin.setEditor(new SpinnerEditor(spin));
                //// The number of fins in the fin set.
                spin.setToolTipText(trans.get("TrapezoidFinSetCfg.lbl.ttip.Nbroffins"));
-               panel.add(spin,"growx, wrap");
-               
+               panel.add(spin, "growx, wrap");
                
+
                ////  Base rotation
                //// Fin rotation:
                label = new JLabel(trans.get("TrapezoidFinSetCfg.lbl.Finrotation"));
@@ -61,16 +62,16 @@ public class TrapezoidFinSetConfig extends FinSetConfig {
                label.setToolTipText(trans.get("TrapezoidFinSetCfg.lbl.ttip.Finrotation"));
                panel.add(label);
                
-               m = new DoubleModel(component, "BaseRotation", UnitGroup.UNITS_ANGLE,-Math.PI,Math.PI);
+               m = new DoubleModel(component, "BaseRotation", UnitGroup.UNITS_ANGLE, -Math.PI, Math.PI);
                
                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(-Math.PI,Math.PI)),"w 100lp, wrap");
+               panel.add(spin, "growx");
                
+               panel.add(new UnitSelector(m), "growx");
+               panel.add(new BasicSlider(m.getSliderModel(-Math.PI, Math.PI)), "w 100lp, wrap");
                
+
                ////  Fin cant:
                label = new JLabel(trans.get("TrapezoidFinSetCfg.lbl.Fincant"));
                //// The angle that the fins are canted with respect to the rocket 
@@ -82,158 +83,158 @@ public class TrapezoidFinSetConfig extends FinSetConfig {
                
                spin = new JSpinner(m.getSpinnerModel());
                spin.setEditor(new SpinnerEditor(spin));
-               panel.add(spin,"growx");
+               panel.add(spin, "growx");
                
-               panel.add(new UnitSelector(m),"growx");
-               panel.add(new BasicSlider(m.getSliderModel(-FinSet.MAX_CANT,FinSet.MAX_CANT)),
+               panel.add(new UnitSelector(m), "growx");
+               panel.add(new BasicSlider(m.getSliderModel(-FinSet.MAX_CANT, FinSet.MAX_CANT)),
                                "w 100lp, wrap");
                
-               
+
                ////  Root chord:
                panel.add(new JLabel(trans.get("TrapezoidFinSetCfg.lbl.Rootchord")));
                
-               m  = new DoubleModel(component,"RootChord",UnitGroup.UNITS_LENGTH,0);
+               m = new DoubleModel(component, "RootChord", UnitGroup.UNITS_LENGTH, 0);
                
                spin = new JSpinner(m.getSpinnerModel());
                spin.setEditor(new SpinnerEditor(spin));
-               panel.add(spin,"growx");
+               panel.add(spin, "growx");
+               
+               panel.add(new UnitSelector(m), "growx");
+               panel.add(new BasicSlider(m.getSliderModel(0, 0.05, 0.2)), "w 100lp, wrap");
                
-               panel.add(new UnitSelector(m),"growx");
-               panel.add(new BasicSlider(m.getSliderModel(0,0.05,0.2)),"w 100lp, wrap");
 
 
-               
                ////  Tip chord:
                panel.add(new JLabel(trans.get("TrapezoidFinSetCfg.lbl.Tipchord")));
                
-               m = new DoubleModel(component,"TipChord",UnitGroup.UNITS_LENGTH,0);
+               m = new DoubleModel(component, "TipChord", UnitGroup.UNITS_LENGTH, 0);
                
                spin = new JSpinner(m.getSpinnerModel());
                spin.setEditor(new SpinnerEditor(spin));
-               panel.add(spin,"growx");
+               panel.add(spin, "growx");
                
-               panel.add(new UnitSelector(m),"growx");
-               panel.add(new BasicSlider(m.getSliderModel(0,0.05,0.2)),"w 100lp, wrap");
-
+               panel.add(new UnitSelector(m), "growx");
+               panel.add(new BasicSlider(m.getSliderModel(0, 0.05, 0.2)), "w 100lp, wrap");
                
+
                ////  Height:
                panel.add(new JLabel(trans.get("TrapezoidFinSetCfg.lbl.Height")));
                
-               m = new DoubleModel(component,"Height",UnitGroup.UNITS_LENGTH,0);
+               m = new DoubleModel(component, "Height", 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.05,0.2)),"w 100lp, wrap");
-       
+               panel.add(spin, "growx");
                
+               panel.add(new UnitSelector(m), "growx");
+               panel.add(new BasicSlider(m.getSliderModel(0, 0.05, 0.2)), "w 100lp, wrap");
                
+
+
                ////  Sweep length:
                panel.add(new JLabel(trans.get("TrapezoidFinSetCfg.lbl.Sweeplength")));
                
-               m = new DoubleModel(component,"Sweep",UnitGroup.UNITS_LENGTH);
+               m = new DoubleModel(component, "Sweep", UnitGroup.UNITS_LENGTH);
                
                spin = new JSpinner(m.getSpinnerModel());
                spin.setEditor(new SpinnerEditor(spin));
-               panel.add(spin,"growx");
+               panel.add(spin, "growx");
+               
+               panel.add(new UnitSelector(m), "growx");
                
-               panel.add(new UnitSelector(m),"growx");
-
                // sweep slider from -1.1*TipChord to 1.1*RootChord
-               DoubleModel tc = new DoubleModel(component,"TipChord",-1.1,UnitGroup.UNITS_LENGTH);
-               DoubleModel rc = new DoubleModel(component,"RootChord",1.1,UnitGroup.UNITS_LENGTH);
-               panel.add(new BasicSlider(m.getSliderModel(tc,rc)),"w 100lp, wrap");
-
+               DoubleModel tc = new DoubleModel(component, "TipChord", -1.1, UnitGroup.UNITS_LENGTH);
+               DoubleModel rc = new DoubleModel(component, "RootChord", 1.1, UnitGroup.UNITS_LENGTH);
+               panel.add(new BasicSlider(m.getSliderModel(tc, rc)), "w 100lp, wrap");
                
+
                ////  Sweep angle:
                panel.add(new JLabel(trans.get("TrapezoidFinSetCfg.lbl.Sweepangle")));
                
-               m = new DoubleModel(component, "SweepAngle",UnitGroup.UNITS_ANGLE,
-                               -TrapezoidFinSet.MAX_SWEEP_ANGLE,TrapezoidFinSet.MAX_SWEEP_ANGLE);
+               m = new DoubleModel(component, "SweepAngle", UnitGroup.UNITS_ANGLE,
+                               -TrapezoidFinSet.MAX_SWEEP_ANGLE, TrapezoidFinSet.MAX_SWEEP_ANGLE);
                
                spin = new JSpinner(m.getSpinnerModel());
                spin.setEditor(new SpinnerEditor(spin));
-               panel.add(spin,"growx");
+               panel.add(spin, "growx");
                
-               panel.add(new UnitSelector(m),"growx");
-               panel.add(new BasicSlider(m.getSliderModel(-Math.PI/4,Math.PI/4)),
+               panel.add(new UnitSelector(m), "growx");
+               panel.add(new BasicSlider(m.getSliderModel(-Math.PI / 4, Math.PI / 4)),
                                "w 100lp, wrap paragraph");
-
                
 
-               
 
-               mainPanel.add(panel,"aligny 20%");
-               
-               mainPanel.add(new JSeparator(SwingConstants.VERTICAL),"growy");
-               
+
+
+               mainPanel.add(panel, "aligny 20%");
                
+               mainPanel.add(new JSeparator(SwingConstants.VERTICAL), "growy");
                
-               panel = new JPanel(new MigLayout("gap rel unrel","[][65lp::][30lp::]",""));
 
+
+               panel = new JPanel(new MigLayout("gap rel unrel", "[][65lp::][30lp::]", ""));
                
-               
+
+
                ////  Fin cross section:
                panel.add(new JLabel(trans.get("TrapezoidFinSetCfg.lbl.FincrossSection")));
                combo = new JComboBox(
-                               new EnumModel<FinSet.CrossSection>(component,"CrossSection"));
-               panel.add(combo,"span, growx, wrap");
+                               new EnumModel<FinSet.CrossSection>(component, "CrossSection"));
+               panel.add(combo, "span, growx, wrap");
                
 
                ////  Thickness:
                panel.add(new JLabel(trans.get("TrapezoidFinSetCfg.lbl.Thickness")));
                
-               m = new DoubleModel(component,"Thickness",UnitGroup.UNITS_LENGTH,0);
+               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 para");
+               panel.add(spin, "growx");
                
+               panel.add(new UnitSelector(m), "growx");
+               panel.add(new BasicSlider(m.getSliderModel(0, 0.01)), "w 100lp, wrap para");
                
+
                ////  Position
                //// Position relative to:
                panel.add(new JLabel(trans.get("TrapezoidFinSetCfg.lbl.Posrelativeto")));
-
+               
                combo = new JComboBox(
                                new EnumModel<RocketComponent.Position>(component, "RelativePosition",
                                                new RocketComponent.Position[] {
-                                               RocketComponent.Position.TOP,
-                                               RocketComponent.Position.MIDDLE,
-                                               RocketComponent.Position.BOTTOM,
-                                               RocketComponent.Position.ABSOLUTE
+                                                               RocketComponent.Position.TOP,
+                                                               RocketComponent.Position.MIDDLE,
+                                                               RocketComponent.Position.BOTTOM,
+                                                               RocketComponent.Position.ABSOLUTE
                                }));
-               panel.add(combo,"spanx, growx, wrap");
+               panel.add(combo, "spanx, growx, wrap");
                //// plus
-               panel.add(new JLabel(trans.get("TrapezoidFinSetCfg.lbl.plus")),"right");
-
-               m = new DoubleModel(component,"PositionValue",UnitGroup.UNITS_LENGTH);
+               panel.add(new JLabel(trans.get("TrapezoidFinSetCfg.lbl.plus")), "right");
+               
+               m = new DoubleModel(component, "PositionValue", UnitGroup.UNITS_LENGTH);
                spin = new JSpinner(m.getSpinnerModel());
                spin.setEditor(new SpinnerEditor(spin));
-               panel.add(spin,"growx");
+               panel.add(spin, "growx");
                
-               panel.add(new UnitSelector(m),"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 para");
-
+               
 
 
                //// Material
                materialPanel(panel, Material.Type.BULK);
                
-               
-               
-               
-               mainPanel.add(panel,"aligny 20%");
+
+
+
+               mainPanel.add(panel, "aligny 20%");
                
                //// General and General properties
-               tabbedPane.insertTab(trans.get("TrapezoidFinSetCfg.tab.General"), null, mainPanel, 
+               tabbedPane.insertTab(trans.get("TrapezoidFinSetCfg.tab.General"), null, mainPanel,
                                trans.get("TrapezoidFinSetCfg.tab.Generalproperties"), 0);
                tabbedPane.setSelectedIndex(0);
                
index a975894ca84daac37fb0ed6de875d2b3402743a6..361e53f1ff2c44e343f98f7239f335aebe844e2f 100644 (file)
@@ -1,31 +1,9 @@
 package net.sf.openrocket.startup;
 
-import java.awt.GraphicsEnvironment;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.io.File;
 import java.io.PrintStream;
-import java.util.List;
 import java.util.Locale;
-import java.util.concurrent.atomic.AtomicInteger;
+import java.util.prefs.Preferences;
 
-import javax.swing.JOptionPane;
-import javax.swing.SwingUtilities;
-import javax.swing.Timer;
-import javax.swing.ToolTipManager;
-
-import net.sf.openrocket.communication.UpdateInfo;
-import net.sf.openrocket.communication.UpdateInfoRetriever;
-import net.sf.openrocket.database.Databases;
-import net.sf.openrocket.database.ThrustCurveMotorSet;
-import net.sf.openrocket.database.ThrustCurveMotorSetDatabase;
-import net.sf.openrocket.file.iterator.DirectoryIterator;
-import net.sf.openrocket.file.iterator.FileIterator;
-import net.sf.openrocket.file.motor.MotorLoaderHelper;
-import net.sf.openrocket.gui.dialogs.UpdateInfoDialog;
-import net.sf.openrocket.gui.main.BasicFrame;
-import net.sf.openrocket.gui.main.ExceptionHandler;
-import net.sf.openrocket.gui.main.Splash;
 import net.sf.openrocket.l10n.DebugTranslator;
 import net.sf.openrocket.l10n.L10N;
 import net.sf.openrocket.l10n.ResourceBundleTranslator;
@@ -35,36 +13,34 @@ import net.sf.openrocket.logging.LogHelper;
 import net.sf.openrocket.logging.LogLevel;
 import net.sf.openrocket.logging.LogLevelBufferLogger;
 import net.sf.openrocket.logging.PrintStreamLogger;
-import net.sf.openrocket.motor.Motor;
-import net.sf.openrocket.motor.ThrustCurveMotor;
-import net.sf.openrocket.util.GUIUtil;
-import net.sf.openrocket.util.Prefs;
-import net.sf.openrocket.util.SimpleFileFilter;
 
 
 /**
- * A startup class that checks that a suitable JRE environment is being run.
- * If the environment is too old the execution is canceled, and if OpenJDK is being
- * used warns the user of problems and confirms whether to continue.
+ * The first class in the OpenRocket startup sequence.  This class is responsible
+ * for setting up the Application class with the statically used subsystems
+ * (logging and translation) and then delegating to Startup2 class.
+ * <p>
+ * This class must be very cautious about what classes it calls.  This is because
+ * the loggers/translators for classes are initialized as static final members during
+ * class initialization.  For example, this class MUST NOT use the Prefs class, because
+ * using it will cause LineStyle to be initialized, which then receives an invalid
+ * (not-yet-initialized) translator.
  * 
  * @author Sampo Niskanen <sampo.niskanen@iki.fi>
  */
 public class Startup {
        
-       private static LogHelper log;
+       static LogHelper log;
        
        private static final String LOG_STDERR_PROPERTY = "openrocket.log.stderr";
        private static final String LOG_STDOUT_PROPERTY = "openrocket.log.stdout";
        
        private static final int LOG_BUFFER_LENGTH = 50;
        
-       private static final String THRUSTCURVE_DIRECTORY = "datafiles/thrustcurves/";
-       
-
-       /** Block motor loading for this many milliseconds */
-       private static AtomicInteger blockLoading = new AtomicInteger(Integer.MAX_VALUE);
-       
        
+       /**
+        * OpenRocket startup main method.
+        */
        public static void main(final String[] args) throws Exception {
                
                // Check for "openrocket.debug" property before anything else
@@ -76,33 +52,16 @@ public class Startup {
                // Setup the translations
                initializeL10n();
                
-               // Check that we have a head
-               checkHead();
-               
-               // Check that we're running a good version of a JRE
-               log.info("Checking JRE compatibility");
-               VersionHelper.checkVersion();
-               VersionHelper.checkOpenJDK();
-               
-               // Run the actual startup method in the EDT since it can use progress dialogs etc.
-               log.info("Running main");
-               SwingUtilities.invokeAndWait(new Runnable() {
-                       @Override
-                       public void run() {
-                               runMain(args);
-                       }
-               });
+               // Continue startup in Startup2 class (where Application is already set up)
+               Startup2.runMain(args);
                
-               log.info("Startup complete");
-               
-               // Block motor loading for 1.5 seconds to allow window painting
-               blockLoading.set(1500);
        }
        
        
 
-
-
+       /**
+        * Set proper system properties if openrocket.debug is defined.
+        */
        private static void checkDebugStatus() {
                if (System.getProperty("openrocket.debug") != null) {
                        setPropertyIfNotSet("openrocket.log.stdout", "VBOSE");
@@ -120,252 +79,10 @@ public class Startup {
        }
        
        
-       /**
-        * Initializes the localization system.
-        */
-       private static void initializeL10n() {
-               
-               String langcode = System.getProperty("openrocket.locale");
-               if (langcode != null) {
-                       Locale l = L10N.toLocale(langcode);
-                       log.info("Setting custom locale " + l);
-                       Locale.setDefault(l);
-               } else {
-                       Locale l = Prefs.getUserLocale();
-                       if (l != null) {
-                               log.info("Setting user-selected locale " + l);
-                               Locale.setDefault(l);
-                       } else {
-                               log.info("Using default locale " + Locale.getDefault());
-                       }
-               }
-               
-               Translator t;
-               t = new ResourceBundleTranslator("l10n.messages");
-               if (Locale.getDefault().getLanguage().equals("xx")) {
-                       t = new DebugTranslator(t);
-               }
-               
-               log.info("Set up translation for locale " + Locale.getDefault() +
-                               ", debug.currentFile=" + t.get("debug.currentFile"));
-               
-               Application.setBaseTranslator(t);
-       }
-       
-       
-       private static void runMain(String[] args) {
-               
-               // Initialize the splash screen with version info
-               log.info("Initializing the splash screen");
-               Splash.init();
-               
-               // Setup the uncaught exception handler
-               log.info("Registering exception handler");
-               ExceptionHandler.registerExceptionHandler();
-               
-               // Start update info fetching
-               final UpdateInfoRetriever updateInfo;
-               if (Prefs.getCheckUpdates()) {
-                       log.info("Starting update check");
-                       updateInfo = new UpdateInfoRetriever();
-                       updateInfo.start();
-               } else {
-                       log.info("Update check disabled");
-                       updateInfo = null;
-               }
-               
-               // Set the best available look-and-feel
-               log.info("Setting best LAF");
-               GUIUtil.setBestLAF();
-               
-               // Set tooltip delay time.  Tooltips are used in MotorChooserDialog extensively.
-               ToolTipManager.sharedInstance().setDismissDelay(30000);
-               
-               // Load defaults
-               Prefs.loadDefaultUnits();
-               
-               // Load motors etc.
-               log.info("Loading databases");
-               loadMotor();
-               Databases.fakeMethod();
-               
-               // Starting action (load files or open new document)
-               log.info("Opening main application window");
-               if (!handleCommandLine(args)) {
-                       BasicFrame.newAction();
-               }
-               
-               // Check whether update info has been fetched or whether it needs more time
-               log.info("Checking update status");
-               checkUpdateStatus(updateInfo);
-       }
-       
-       
-
-       private static void loadMotor() {
-               
-               log.info("Starting motor loading from " + THRUSTCURVE_DIRECTORY + " in background thread.");
-               ThrustCurveMotorSetDatabase db = new ThrustCurveMotorSetDatabase(true) {
-                       
-                       @Override
-                       protected void loadMotors() {
-                               
-                               // Block loading until timeout occurs or database is taken into use
-                               log.info("Blocking motor loading while starting up");
-                               while (!inUse && blockLoading.addAndGet(-100) > 0) {
-                                       try {
-                                               Thread.sleep(100);
-                                       } catch (InterruptedException e) {
-                                       }
-                               }
-                               log.info("Blocking ended, inUse=" + inUse + " slowLoadingCount=" + blockLoading.get());
-                               
-                               // Start loading
-                               log.info("Loading motors from " + THRUSTCURVE_DIRECTORY);
-                               long t0 = System.currentTimeMillis();
-                               int fileCount;
-                               int thrustCurveCount;
-                               
-                               // Load the packaged thrust curves
-                               List<Motor> list;
-                               FileIterator iterator = DirectoryIterator.findDirectory(THRUSTCURVE_DIRECTORY,
-                                                               new SimpleFileFilter("", false, "eng", "rse"));
-                               if (iterator == null) {
-                                       throw new IllegalStateException("Thrust curve directory " + THRUSTCURVE_DIRECTORY +
-                                                       "not found, distribution built wrong");
-                               }
-                               list = MotorLoaderHelper.load(iterator);
-                               for (Motor m : list) {
-                                       this.addMotor((ThrustCurveMotor) m);
-                               }
-                               fileCount = iterator.getFileCount();
-                               
-                               thrustCurveCount = list.size();
-                               
-                               // Load the user-defined thrust curves
-                               for (File file : Prefs.getUserThrustCurveFiles()) {
-                                       // TODO: LOW: This counts a directory as one file
-                                       log.info("Loading motors from " + file);
-                                       list = MotorLoaderHelper.load(file);
-                                       for (Motor m : list) {
-                                               this.addMotor((ThrustCurveMotor) m);
-                                       }
-                                       fileCount++;
-                                       thrustCurveCount += list.size();
-                               }
-                               
-                               long t1 = System.currentTimeMillis();
-                               
-                               // Count statistics
-                               int distinctMotorCount = 0;
-                               int distinctThrustCurveCount = 0;
-                               distinctMotorCount = motorSets.size();
-                               for (ThrustCurveMotorSet set : motorSets) {
-                                       distinctThrustCurveCount += set.getMotorCount();
-                               }
-                               log.info("Motor loading done, took " + (t1 - t0) + " ms to load "
-                                               + fileCount + " files/directories containing "
-                                               + thrustCurveCount + " thrust curves which contained "
-                                               + distinctMotorCount + " distinct motors with "
-                                               + distinctThrustCurveCount + " distinct thrust curves.");
-                       }
-                       
-               };
-               db.startLoading();
-               Application.setMotorSetDatabase(db);
-       }
-       
-       
-
-       private static void checkUpdateStatus(final UpdateInfoRetriever updateInfo) {
-               if (updateInfo == null)
-                       return;
-               
-               int delay = 1000;
-               if (!updateInfo.isRunning())
-                       delay = 100;
-               
-               final Timer timer = new Timer(delay, null);
-               
-               ActionListener listener = new ActionListener() {
-                       private int count = 5;
-                       
-                       @Override
-                       public void actionPerformed(ActionEvent e) {
-                               if (!updateInfo.isRunning()) {
-                                       timer.stop();
-                                       
-                                       String current = Prefs.getVersion();
-                                       String last = Prefs.getString(Prefs.LAST_UPDATE, "");
-                                       
-                                       UpdateInfo info = updateInfo.getUpdateInfo();
-                                       if (info != null && info.getLatestVersion() != null &&
-                                                       !current.equals(info.getLatestVersion()) &&
-                                                       !last.equals(info.getLatestVersion())) {
-                                               
-                                               UpdateInfoDialog infoDialog = new UpdateInfoDialog(info);
-                                               infoDialog.setVisible(true);
-                                               if (infoDialog.isReminderSelected()) {
-                                                       Prefs.putString(Prefs.LAST_UPDATE, "");
-                                               } else {
-                                                       Prefs.putString(Prefs.LAST_UPDATE, info.getLatestVersion());
-                                               }
-                                       }
-                               }
-                               count--;
-                               if (count <= 0)
-                                       timer.stop();
-                       }
-               };
-               timer.addActionListener(listener);
-               timer.start();
-       }
-       
-       
-       /**
-        * Handles arguments passed from the command line.  This may be used either
-        * when starting the first instance of OpenRocket or later when OpenRocket is
-        * executed again while running.
-        * 
-        * @param args  the command-line arguments.
-        * @return              whether a new frame was opened or similar user desired action was
-        *                              performed as a result.
-        */
-       public static boolean handleCommandLine(String[] args) {
-               
-               // Check command-line for files
-               boolean opened = false;
-               for (String file : args) {
-                       if (BasicFrame.open(new File(file), null)) {
-                               opened = true;
-                       }
-               }
-               return opened;
-       }
-       
-       
 
        /**
-        * Check that the JRE is not running headless.
+        * Initializes the loggins system.
         */
-       private static void checkHead() {
-               
-               log.info("Checking for graphics head");
-               
-               if (GraphicsEnvironment.isHeadless()) {
-                       log.error("Application is headless.");
-                       System.err.println();
-                       System.err.println("OpenRocket cannot currently be run without the graphical " +
-                                       "user interface.");
-                       System.err.println();
-                       System.exit(1);
-               }
-               
-       }
-       
-       
-       ///////////  Logging  ///////////
-       
        private static void initializeLogging() {
                DelegatorLogger delegator = new DelegatorLogger();
                
@@ -387,7 +104,7 @@ public class Startup {
                
                // Initialize the log for this class
                log = Application.getLogger();
-               log.info("Logging subsystem initialized for OpenRocket " + Prefs.getVersion());
+               log.info("Logging subsystem initialized");
                String str = "Console logging output:";
                for (LogLevel l : LogLevel.values()) {
                        PrintStream ps = printer.getOutput(l);
@@ -420,50 +137,64 @@ public class Startup {
        }
        
        
-       ///////////  Helper methods  //////////
-       
+
+
        /**
-        * Presents an error message to the user and exits the application.
-        * 
-        * @param message       an array of messages to present.
+        * Initializes the localization system.
         */
-       static void error(String[] message) {
+       private static void initializeL10n() {
                
-               System.err.println();
-               System.err.println("Error starting OpenRocket:");
-               System.err.println();
-               for (int i = 0; i < message.length; i++) {
-                       System.err.println(message[i]);
-               }
-               System.err.println();
+               // Check for locale propery
+               String langcode = System.getProperty("openrocket.locale");
                
-
-               if (!GraphicsEnvironment.isHeadless()) {
+               if (langcode != null) {
                        
-                       JOptionPane.showMessageDialog(null, message, "Error starting OpenRocket",
-                                       JOptionPane.ERROR_MESSAGE);
+                       Locale l = L10N.toLocale(langcode);
+                       log.info("Setting custom locale " + l);
+                       Locale.setDefault(l);
+                       
+               } else {
+                       
+                       // Check user-configured locale
+                       Locale l = getUserLocale();
+                       if (l != null) {
+                               log.info("Setting user-selected locale " + l);
+                               Locale.setDefault(l);
+                       } else {
+                               log.info("Using default locale " + Locale.getDefault());
+                       }
                        
                }
                
-               System.exit(1);
+               // Setup the translator
+               Translator t;
+               t = new ResourceBundleTranslator("l10n.messages");
+               if (Locale.getDefault().getLanguage().equals("xx")) {
+                       t = new DebugTranslator(t);
+               }
+               
+               log.info("Set up translation for locale " + Locale.getDefault() +
+                               ", debug.currentFile=" + t.get("debug.currentFile"));
+               
+               Application.setBaseTranslator(t);
        }
        
        
-       /**
-        * Presents the user with a message dialog and asks whether to continue.
-        * If the user does not select "Yes" the the application exits.
-        * 
-        * @param message       the message Strings to show.
-        */
-       static void confirm(String[] message) {
-               
-               if (!GraphicsEnvironment.isHeadless()) {
-                       
-                       if (JOptionPane.showConfirmDialog(null, message, "Error starting OpenRocket",
-                                       JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION) {
-                               System.exit(1);
-                       }
+
+
+       private static Locale getUserLocale() {
+               /*
+                * This method MUST NOT use the Prefs class, since is causes a multitude
+                * of classes to be initialized.  Therefore this duplicates the functionality
+                * of the Prefs class locally.
+                */
+
+               if (System.getProperty("openrocket.debug.prefs") != null) {
+                       return null;
                }
+               
+               return L10N.toLocale(Preferences.userRoot().node("OpenRocket").get("locale", null));
        }
        
+
 }
diff --git a/src/net/sf/openrocket/startup/Startup2.java b/src/net/sf/openrocket/startup/Startup2.java
new file mode 100644 (file)
index 0000000..4371fc3
--- /dev/null
@@ -0,0 +1,291 @@
+package net.sf.openrocket.startup;
+
+import java.awt.GraphicsEnvironment;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.swing.SwingUtilities;
+import javax.swing.Timer;
+import javax.swing.ToolTipManager;
+
+import net.sf.openrocket.communication.UpdateInfo;
+import net.sf.openrocket.communication.UpdateInfoRetriever;
+import net.sf.openrocket.database.Databases;
+import net.sf.openrocket.database.ThrustCurveMotorSet;
+import net.sf.openrocket.database.ThrustCurveMotorSetDatabase;
+import net.sf.openrocket.file.iterator.DirectoryIterator;
+import net.sf.openrocket.file.iterator.FileIterator;
+import net.sf.openrocket.file.motor.MotorLoaderHelper;
+import net.sf.openrocket.gui.dialogs.UpdateInfoDialog;
+import net.sf.openrocket.gui.main.BasicFrame;
+import net.sf.openrocket.gui.main.ExceptionHandler;
+import net.sf.openrocket.gui.main.Splash;
+import net.sf.openrocket.logging.LogHelper;
+import net.sf.openrocket.motor.Motor;
+import net.sf.openrocket.motor.ThrustCurveMotor;
+import net.sf.openrocket.util.GUIUtil;
+import net.sf.openrocket.util.Prefs;
+import net.sf.openrocket.util.SimpleFileFilter;
+
+/**
+ * The second class in the OpenRocket startup sequence.  This class can assume the
+ * Application class to be properly set up, and can use any classes safely.
+ * 
+ * @author Sampo Niskanen <sampo.niskanen@iki.fi>
+ */
+public class Startup2 {
+       private static final LogHelper log = Application.getLogger();
+       
+
+       private static final String THRUSTCURVE_DIRECTORY = "datafiles/thrustcurves/";
+       
+       /** Block motor loading for this many milliseconds */
+       private static AtomicInteger blockLoading = new AtomicInteger(Integer.MAX_VALUE);
+       
+       
+
+       /**
+        * Run when starting up OpenRocket after Application has been set up.
+        * 
+        * @param args  command line arguments
+        */
+       static void runMain(final String[] args) throws Exception {
+               
+               log.info("Starting up OpenRocket version " + Prefs.getVersion());
+               
+               // Check that we're not running headless
+               log.info("Checking for graphics head");
+               checkHead();
+               
+               // Check that we're running a good version of a JRE
+               log.info("Checking JRE compatibility");
+               VersionHelper.checkVersion();
+               VersionHelper.checkOpenJDK();
+               
+               // Run the actual startup method in the EDT since it can use progress dialogs etc.
+               log.info("Moving startup to EDT");
+               SwingUtilities.invokeAndWait(new Runnable() {
+                       @Override
+                       public void run() {
+                               runInEDT(args);
+                       }
+               });
+               
+               log.info("Startup complete");
+       }
+       
+       
+       /**
+        * Run in the EDT when starting up OpenRocket.
+        * 
+        * @param args  command line arguments
+        */
+       private static void runInEDT(String[] args) {
+               
+               // Initialize the splash screen with version info
+               log.info("Initializing the splash screen");
+               Splash.init();
+               
+               // Setup the uncaught exception handler
+               log.info("Registering exception handler");
+               ExceptionHandler.registerExceptionHandler();
+               
+               // Start update info fetching
+               final UpdateInfoRetriever updateInfo;
+               if (Prefs.getCheckUpdates()) {
+                       log.info("Starting update check");
+                       updateInfo = new UpdateInfoRetriever();
+                       updateInfo.start();
+               } else {
+                       log.info("Update check disabled");
+                       updateInfo = null;
+               }
+               
+               // Set the best available look-and-feel
+               log.info("Setting best LAF");
+               GUIUtil.setBestLAF();
+               
+               // Set tooltip delay time.  Tooltips are used in MotorChooserDialog extensively.
+               ToolTipManager.sharedInstance().setDismissDelay(30000);
+               
+               // Load defaults
+               Prefs.loadDefaultUnits();
+               
+               // Load motors etc.
+               log.info("Loading databases");
+               loadMotor();
+               Databases.fakeMethod();
+               
+               // Starting action (load files or open new document)
+               log.info("Opening main application window");
+               if (!handleCommandLine(args)) {
+                       BasicFrame.newAction();
+               }
+               
+               // Check whether update info has been fetched or whether it needs more time
+               log.info("Checking update status");
+               checkUpdateStatus(updateInfo);
+               
+               // Block motor loading for 1.5 seconds to allow window painting to be faster
+               blockLoading.set(1500);
+       }
+       
+       
+       /**
+        * Check that the JRE is not running headless.
+        */
+       private static void checkHead() {
+               
+               if (GraphicsEnvironment.isHeadless()) {
+                       log.error("Application is headless.");
+                       System.err.println();
+                       System.err.println("OpenRocket cannot currently be run without the graphical " +
+                                       "user interface.");
+                       System.err.println();
+                       System.exit(1);
+               }
+               
+       }
+       
+       
+       private static void loadMotor() {
+               
+               log.info("Starting motor loading from " + THRUSTCURVE_DIRECTORY + " in background thread.");
+               ThrustCurveMotorSetDatabase db = new ThrustCurveMotorSetDatabase(true) {
+                       
+                       @Override
+                       protected void loadMotors() {
+                               
+                               // Block loading until timeout occurs or database is taken into use
+                               log.info("Blocking motor loading while starting up");
+                               while (!inUse && blockLoading.addAndGet(-100) > 0) {
+                                       try {
+                                               Thread.sleep(100);
+                                       } catch (InterruptedException e) {
+                                       }
+                               }
+                               log.info("Blocking ended, inUse=" + inUse + " blockLoading=" + blockLoading.get());
+                               
+                               // Start loading
+                               log.info("Loading motors from " + THRUSTCURVE_DIRECTORY);
+                               long t0 = System.currentTimeMillis();
+                               int fileCount;
+                               int thrustCurveCount;
+                               
+                               // Load the packaged thrust curves
+                               List<Motor> list;
+                               FileIterator iterator = DirectoryIterator.findDirectory(THRUSTCURVE_DIRECTORY,
+                                                               new SimpleFileFilter("", false, "eng", "rse"));
+                               if (iterator == null) {
+                                       throw new IllegalStateException("Thrust curve directory " + THRUSTCURVE_DIRECTORY +
+                                                       "not found, distribution built wrong");
+                               }
+                               list = MotorLoaderHelper.load(iterator);
+                               for (Motor m : list) {
+                                       this.addMotor((ThrustCurveMotor) m);
+                               }
+                               fileCount = iterator.getFileCount();
+                               
+                               thrustCurveCount = list.size();
+                               
+                               // Load the user-defined thrust curves
+                               for (File file : Prefs.getUserThrustCurveFiles()) {
+                                       log.info("Loading motors from " + file);
+                                       list = MotorLoaderHelper.load(file);
+                                       for (Motor m : list) {
+                                               this.addMotor((ThrustCurveMotor) m);
+                                       }
+                                       fileCount++;
+                                       thrustCurveCount += list.size();
+                               }
+                               
+                               long t1 = System.currentTimeMillis();
+                               
+                               // Count statistics
+                               int distinctMotorCount = 0;
+                               int distinctThrustCurveCount = 0;
+                               distinctMotorCount = motorSets.size();
+                               for (ThrustCurveMotorSet set : motorSets) {
+                                       distinctThrustCurveCount += set.getMotorCount();
+                               }
+                               log.info("Motor loading done, took " + (t1 - t0) + " ms to load "
+                                               + fileCount + " files/directories containing "
+                                               + thrustCurveCount + " thrust curves which contained "
+                                               + distinctMotorCount + " distinct motors with "
+                                               + distinctThrustCurveCount + " distinct thrust curves.");
+                       }
+                       
+               };
+               db.startLoading();
+               Application.setMotorSetDatabase(db);
+       }
+       
+       private static void checkUpdateStatus(final UpdateInfoRetriever updateInfo) {
+               if (updateInfo == null)
+                       return;
+               
+               int delay = 1000;
+               if (!updateInfo.isRunning())
+                       delay = 100;
+               
+               final Timer timer = new Timer(delay, null);
+               
+               ActionListener listener = new ActionListener() {
+                       private int count = 5;
+                       
+                       @Override
+                       public void actionPerformed(ActionEvent e) {
+                               if (!updateInfo.isRunning()) {
+                                       timer.stop();
+                                       
+                                       String current = Prefs.getVersion();
+                                       String last = Prefs.getString(Prefs.LAST_UPDATE, "");
+                                       
+                                       UpdateInfo info = updateInfo.getUpdateInfo();
+                                       if (info != null && info.getLatestVersion() != null &&
+                                                       !current.equals(info.getLatestVersion()) &&
+                                                       !last.equals(info.getLatestVersion())) {
+                                               
+                                               UpdateInfoDialog infoDialog = new UpdateInfoDialog(info);
+                                               infoDialog.setVisible(true);
+                                               if (infoDialog.isReminderSelected()) {
+                                                       Prefs.putString(Prefs.LAST_UPDATE, "");
+                                               } else {
+                                                       Prefs.putString(Prefs.LAST_UPDATE, info.getLatestVersion());
+                                               }
+                                       }
+                               }
+                               count--;
+                               if (count <= 0)
+                                       timer.stop();
+                       }
+               };
+               timer.addActionListener(listener);
+               timer.start();
+       }
+       
+       /**
+        * Handles arguments passed from the command line.  This may be used either
+        * when starting the first instance of OpenRocket or later when OpenRocket is
+        * executed again while running.
+        * 
+        * @param args  the command-line arguments.
+        * @return              whether a new frame was opened or similar user desired action was
+        *                              performed as a result.
+        */
+       private static boolean handleCommandLine(String[] args) {
+               
+               // Check command-line for files
+               boolean opened = false;
+               for (String file : args) {
+                       if (BasicFrame.open(new File(file), null)) {
+                               opened = true;
+                       }
+               }
+               return opened;
+       }
+       
+}
index 3d90d3e9d67d34ac4231ebb277e52568ee5ababc..097f1dc43c2d64ce6f16ced5dff95e04ce89cb25 100644 (file)
@@ -1,5 +1,9 @@
 package net.sf.openrocket.startup;
 
+import java.awt.GraphicsEnvironment;
+
+import javax.swing.JOptionPane;
+
 import net.sf.openrocket.logging.LogHelper;
 
 public class VersionHelper {
@@ -34,14 +38,14 @@ public class VersionHelper {
                        
                        if (major < REQUIRED_MAJOR_VERSION ||
                                        (major == REQUIRED_MAJOR_VERSION && minor < REQUIRED_MINOR_VERSION)) {
-                               Startup.error(new String[] { "Java SE version 6 is required to run OpenRocket.",
+                               error(new String[] { "Java SE version 6 is required to run OpenRocket.",
                                                "You are currently running " + jreName + " version " +
                                                                jreVersion + " by " + jreVendor });
                        }
                        
                } catch (RuntimeException e) {
                        
-                       Startup.confirm(new String[] { "The Java version in use could not be detected.",
+                       confirm(new String[] { "The Java version in use could not be detected.",
                                        "OpenRocket requires at least Java SE 6.",
                                        "Continue anyway?" });
                        
@@ -64,7 +68,7 @@ public class VersionHelper {
                        
                        if (jreVersion.matches(BAD_OPENJDK_VERSION)) {
                                
-                               Startup.confirm(new String[] { "Old versions of OpenJDK are known to have problems " +
+                               confirm(new String[] { "Old versions of OpenJDK are known to have problems " +
                                                "running OpenRocket.",
                                                " ",
                                                "You are currently running " + jreName + " version " +
@@ -74,4 +78,51 @@ public class VersionHelper {
                }
        }
        
+       
+
+       ///////////  Helper methods  //////////
+       
+       /**
+        * Presents an error message to the user and exits the application.
+        * 
+        * @param message       an array of messages to present.
+        */
+       private static void error(String[] message) {
+               
+               System.err.println();
+               System.err.println("Error starting OpenRocket:");
+               System.err.println();
+               for (int i = 0; i < message.length; i++) {
+                       System.err.println(message[i]);
+               }
+               System.err.println();
+               
+
+               if (!GraphicsEnvironment.isHeadless()) {
+                       
+                       JOptionPane.showMessageDialog(null, message, "Error starting OpenRocket",
+                                       JOptionPane.ERROR_MESSAGE);
+                       
+               }
+               
+               System.exit(1);
+       }
+       
+       
+       /**
+        * Presents the user with a message dialog and asks whether to continue.
+        * If the user does not select "Yes" the the application exits.
+        * 
+        * @param message       the message Strings to show.
+        */
+       private static void confirm(String[] message) {
+               
+               if (!GraphicsEnvironment.isHeadless()) {
+                       
+                       if (JOptionPane.showConfirmDialog(null, message, "Error starting OpenRocket",
+                                       JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION) {
+                               System.exit(1);
+                       }
+               }
+       }
 }
index 73df2b7381172129b2b144848eec41148477bfa6..2bb3af6d1765b294afe37458aeebe51f856b8421 100644 (file)
@@ -14,6 +14,7 @@ import net.sf.openrocket.startup.Application;
 
 public enum LineStyle {
        
+
        //// Solid
        SOLID("LineStyle.Solid", new float[] { 10f, 0f }),
        //// Dashed
@@ -24,6 +25,10 @@ public enum LineStyle {
        DASHDOT("LineStyle.Dash-dotted", new float[] { 8f, 3f, 2f, 3f });
        
        private static final Translator trans = Application.getTranslator();
+       static {
+               System.out.println("*** LineStyle initialized trans:" + trans + " ***");
+               System.err.println("*** LineStyle initialized ***");
+       }
        private final String name;
        private final float[] dashes;