diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties index 7c0b8385e..d41dd4841 100644 --- a/core/resources/l10n/messages.properties +++ b/core/resources/l10n/messages.properties @@ -894,6 +894,7 @@ StageConfig.tab.Separation.ttip = Stage separation options StageConfig.separation.lbl.title = Select when this stage separates: StageConfig.separation.lbl.plus = plus StageConfig.separation.lbl.seconds = seconds +StageConfig.parallel.autoradius = Enable Automatic Positioning StageConfig.parallel.radius = Radial Distance StageConfig.parallel.angle = Angle StageConfig.parallel.count = Number of Copies diff --git a/core/src/net/sf/openrocket/file/openrocket/OpenRocketSaver.java b/core/src/net/sf/openrocket/file/openrocket/OpenRocketSaver.java index 27a4361fb..508e3e274 100644 --- a/core/src/net/sf/openrocket/file/openrocket/OpenRocketSaver.java +++ b/core/src/net/sf/openrocket/file/openrocket/OpenRocketSaver.java @@ -19,7 +19,7 @@ import net.sf.openrocket.document.Simulation; import net.sf.openrocket.document.StorageOptions; import net.sf.openrocket.file.RocketSaver; import net.sf.openrocket.rocketcomponent.AxialStage; -import net.sf.openrocket.rocketcomponent.BoosterSet; +import net.sf.openrocket.rocketcomponent.ParallelStage; import net.sf.openrocket.rocketcomponent.DeploymentConfiguration.DeployEvent; import net.sf.openrocket.rocketcomponent.FinSet; import net.sf.openrocket.rocketcomponent.FlightConfigurableComponent; @@ -259,7 +259,7 @@ public class OpenRocketSaver extends RocketSaver { ///////////////// // Search the rocket for any Boosters or Pods (version 1.8) for (RocketComponent c : document.getRocket()) { - if ((c instanceof BoosterSet) || (c instanceof PodSet)) { + if ((c instanceof ParallelStage) || (c instanceof PodSet)) { return FILE_VERSION_DIVISOR + 8; } } diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java b/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java index 5012694a7..44701df23 100644 --- a/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java +++ b/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java @@ -9,7 +9,7 @@ import net.sf.openrocket.preset.ComponentPreset; import net.sf.openrocket.rocketcomponent.AxialStage; import net.sf.openrocket.rocketcomponent.BodyComponent; import net.sf.openrocket.rocketcomponent.BodyTube; -import net.sf.openrocket.rocketcomponent.BoosterSet; +import net.sf.openrocket.rocketcomponent.ParallelStage; import net.sf.openrocket.rocketcomponent.Bulkhead; import net.sf.openrocket.rocketcomponent.CenteringRing; import net.sf.openrocket.rocketcomponent.DeploymentConfiguration; @@ -90,7 +90,7 @@ class DocumentConfig { // Other constructors.put("stage", AxialStage.class.getConstructor(new Class[0])); - constructors.put("boosterset", BoosterSet.class.getConstructor(new Class[0])); + constructors.put("boosterset", ParallelStage.class.getConstructor(new Class[0])); constructors.put("podset", PodSet.class.getConstructor(new Class[0])); } catch (NoSuchMethodException e) { @@ -150,11 +150,11 @@ class DocumentConfig { // BoosterSet setters.put("BoosterSet:instancecount", new IntSetter( - Reflection.findMethod(BoosterSet.class, "setInstanceCount",int.class))); + Reflection.findMethod(ParallelStage.class, "setInstanceCount",int.class))); setters.put("BoosterSet:radialoffset", new DoubleSetter( - Reflection.findMethod(BoosterSet.class, "setRadialOffset", double.class))); + Reflection.findMethod(ParallelStage.class, "setRadialOffset", double.class))); setters.put("BoosterSet:angleoffset", new DoubleSetter( - Reflection.findMethod(BoosterSet.class, "setAngularOffset", double.class))); + Reflection.findMethod(ParallelStage.class, "setAngularOffset", double.class))); // SymmetricComponent setters.put("SymmetricComponent:thickness", new DoubleSetter( diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/PositionSetter.java b/core/src/net/sf/openrocket/file/openrocket/importt/PositionSetter.java index 0a206cafb..a9c470824 100644 --- a/core/src/net/sf/openrocket/file/openrocket/importt/PositionSetter.java +++ b/core/src/net/sf/openrocket/file/openrocket/importt/PositionSetter.java @@ -4,7 +4,7 @@ import java.util.HashMap; import net.sf.openrocket.aerodynamics.Warning; import net.sf.openrocket.aerodynamics.WarningSet; -import net.sf.openrocket.rocketcomponent.BoosterSet; +import net.sf.openrocket.rocketcomponent.ParallelStage; import net.sf.openrocket.rocketcomponent.FinSet; import net.sf.openrocket.rocketcomponent.InternalComponent; import net.sf.openrocket.rocketcomponent.LaunchLug; @@ -46,8 +46,8 @@ class PositionSetter implements Setter { } else if (c instanceof TubeFinSet) { ((TubeFinSet) c).setRelativePosition(type); c.setAxialOffset(pos); - } else if (c instanceof BoosterSet) { - ((BoosterSet) c).setRelativePositionMethod(type); + } else if (c instanceof ParallelStage) { + ((ParallelStage) c).setRelativePositionMethod(type); c.setAxialOffset(pos); } else if (c instanceof PodSet) { ((PodSet) c).setRelativePositionMethod(type); diff --git a/core/src/net/sf/openrocket/file/openrocket/savers/AxialStageSaver.java b/core/src/net/sf/openrocket/file/openrocket/savers/AxialStageSaver.java index 013ad6636..b3115c749 100644 --- a/core/src/net/sf/openrocket/file/openrocket/savers/AxialStageSaver.java +++ b/core/src/net/sf/openrocket/file/openrocket/savers/AxialStageSaver.java @@ -5,7 +5,7 @@ import java.util.List; import java.util.Locale; import net.sf.openrocket.rocketcomponent.AxialStage; -import net.sf.openrocket.rocketcomponent.BoosterSet; +import net.sf.openrocket.rocketcomponent.ParallelStage; import net.sf.openrocket.rocketcomponent.FlightConfiguration; import net.sf.openrocket.rocketcomponent.FlightConfigurationID; import net.sf.openrocket.rocketcomponent.Rocket; @@ -28,7 +28,7 @@ public class AxialStageSaver extends ComponentAssemblySaver { list.add(""); } } else { - if (c instanceof BoosterSet) { + if (c instanceof ParallelStage) { list.add(""); instance.addParams(c, list); list.add(""); diff --git a/core/src/net/sf/openrocket/file/openrocket/savers/ComponentAssemblySaver.java b/core/src/net/sf/openrocket/file/openrocket/savers/ComponentAssemblySaver.java index ef624e2c4..c9facdc38 100644 --- a/core/src/net/sf/openrocket/file/openrocket/savers/ComponentAssemblySaver.java +++ b/core/src/net/sf/openrocket/file/openrocket/savers/ComponentAssemblySaver.java @@ -4,7 +4,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; -import net.sf.openrocket.rocketcomponent.BoosterSet; +import net.sf.openrocket.rocketcomponent.ParallelStage; import net.sf.openrocket.rocketcomponent.ComponentAssembly; import net.sf.openrocket.rocketcomponent.Instanceable; import net.sf.openrocket.rocketcomponent.PodSet; @@ -24,7 +24,7 @@ public class ComponentAssemblySaver extends RocketComponentSaver { list.add(""); instance.addParams(c, list); list.add(""); - } else if (c instanceof BoosterSet) { + } else if (c instanceof ParallelStage) { list.add(""); instance.addParams(c, list); list.add(""); diff --git a/core/src/net/sf/openrocket/masscalc/MassCalculator.java b/core/src/net/sf/openrocket/masscalc/MassCalculator.java index 98bb13198..86ab2af3c 100644 --- a/core/src/net/sf/openrocket/masscalc/MassCalculator.java +++ b/core/src/net/sf/openrocket/masscalc/MassCalculator.java @@ -13,7 +13,7 @@ import net.sf.openrocket.motor.MotorInstanceConfiguration; import net.sf.openrocket.motor.MotorInstanceId; import net.sf.openrocket.motor.ThrustCurveMotor; import net.sf.openrocket.rocketcomponent.AxialStage; -import net.sf.openrocket.rocketcomponent.BoosterSet; +import net.sf.openrocket.rocketcomponent.ParallelStage; import net.sf.openrocket.rocketcomponent.ComponentAssembly; import net.sf.openrocket.rocketcomponent.FlightConfiguration; import net.sf.openrocket.rocketcomponent.Instanceable; @@ -345,7 +345,7 @@ public class MassCalculator implements Monitorable { MassData childrenData = MassData.ZERO_DATA; // Combine data for subcomponents for (RocketComponent child : component.getChildren()) { - if( child instanceof BoosterSet ){ + if( child instanceof ParallelStage ){ // this stage will be tallied separately... skip. continue; } @@ -401,7 +401,7 @@ public class MassCalculator implements Monitorable { // move to parent's reference point resultantData = resultantData.move( component.getOffset() ); - if( component instanceof BoosterSet ){ + if( component instanceof ParallelStage ){ // hacky correction for the fact Booster Stages aren't direct subchildren to the rocket resultantData = resultantData.move( component.getParent().getOffset() ); } diff --git a/core/src/net/sf/openrocket/rocketcomponent/AxialStage.java b/core/src/net/sf/openrocket/rocketcomponent/AxialStage.java index 918fb196f..5288ce692 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/AxialStage.java +++ b/core/src/net/sf/openrocket/rocketcomponent/AxialStage.java @@ -63,7 +63,7 @@ public class AxialStage extends ComponentAssembly implements FlightConfigurableC */ @Override public boolean isCompatible(Class type) { - if (BoosterSet.class.isAssignableFrom(type)) { + if (ParallelStage.class.isAssignableFrom(type)) { return true; } else if (PodSet.class.isAssignableFrom(type)) { return true; diff --git a/core/src/net/sf/openrocket/rocketcomponent/ComponentAssembly.java b/core/src/net/sf/openrocket/rocketcomponent/ComponentAssembly.java index 043aeef54..f12d270e8 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/ComponentAssembly.java +++ b/core/src/net/sf/openrocket/rocketcomponent/ComponentAssembly.java @@ -81,6 +81,22 @@ public abstract class ComponentAssembly extends RocketComponent { return 0; } + public double getOuterRadius(){ + double outerRadius=0; + for( RocketComponent comp : children ){ + double thisRadius=0; + if( comp instanceof BodyTube ){ + thisRadius = ((BodyTube)comp).getOuterRadius(); + }else if( comp instanceof Transition ){ + Transition trans = (Transition)comp; + thisRadius = Math.max( trans.getForeRadius(), trans.getAftRadius()); + } + + outerRadius = Math.max( outerRadius, thisRadius); + } + return outerRadius; + } + /** * Components have no aerodynamic effect, so return false. */ @@ -113,7 +129,7 @@ public abstract class ComponentAssembly extends RocketComponent { if (null == this.parent) { throw new NullPointerException(" a Stage requires a parent before any positioning! "); } - if ((this instanceof BoosterSet ) || ( this instanceof PodSet )){ + if ((this instanceof ParallelStage ) || ( this instanceof PodSet )){ if (Position.AFTER == _newPosition) { log.warn("Stages (or Pods) cannot be relative to other stages via AFTER! Ignoring."); super.setRelativePosition(Position.TOP); diff --git a/core/src/net/sf/openrocket/rocketcomponent/BoosterSet.java b/core/src/net/sf/openrocket/rocketcomponent/ParallelStage.java similarity index 85% rename from core/src/net/sf/openrocket/rocketcomponent/BoosterSet.java rename to core/src/net/sf/openrocket/rocketcomponent/ParallelStage.java index 5154384b3..02a36fdfe 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/BoosterSet.java +++ b/core/src/net/sf/openrocket/rocketcomponent/ParallelStage.java @@ -11,7 +11,7 @@ import net.sf.openrocket.startup.Application; import net.sf.openrocket.util.BugException; import net.sf.openrocket.util.Coordinate; -public class BoosterSet extends AxialStage implements FlightConfigurableComponent, RingInstanceable { +public class ParallelStage extends AxialStage implements FlightConfigurableComponent, RingInstanceable { private static final Translator trans = Application.getTranslator(); //private static final Logger log = LoggerFactory.getLogger(BoosterSet.class); @@ -20,15 +20,16 @@ public class BoosterSet extends AxialStage implements FlightConfigurableComponen protected double angularSeparation = Math.PI; protected double angularPosition_rad = 0; + protected boolean autoRadialPosition = true; protected double radialPosition_m = 0; - public BoosterSet() { + public ParallelStage() { this.count = 2; this.relativePosition = Position.BOTTOM; this.angularSeparation = Math.PI * 2 / this.count; } - public BoosterSet( final int _count ){ + public ParallelStage( final int _count ){ this(); this.count = _count; @@ -88,7 +89,7 @@ public class BoosterSet extends AxialStage implements FlightConfigurableComponen @Override protected RocketComponent copyWithOriginalID() { - BoosterSet copy = (BoosterSet) (super.copyWithOriginalID()); + ParallelStage copy = (ParallelStage) (super.copyWithOriginalID()); return copy; } @@ -192,6 +193,15 @@ public class BoosterSet extends AxialStage implements FlightConfigurableComponen return this.getAxialOffset(); } + public boolean getAutoRadialOffset(){ + return this.autoRadialPosition; + } + + public void setAutoRadialOffset( final boolean enabled ){ + this.autoRadialPosition = enabled; + fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + } + @Override public void setRadialOffset(final double radius) { mutex.verify(); @@ -206,32 +216,6 @@ public class BoosterSet extends AxialStage implements FlightConfigurableComponen fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); } -// @Override -// protected Coordinate[] shiftCoordinates(Coordinate[] c) { -// checkState(); -// -// if (1 < c.length) { -// throw new BugException("implementation of 'shiftCoordinates' assumes the coordinate array has len == 1; The length here is "+c.length+"! "); -// } -// -// double radius = this.radialPosition_m; -// double angle0 = this.angularPosition_rad; -// double angleIncr = this.angularSeparation; -// Coordinate center = c[0]; -// Coordinate[] toReturn = new Coordinate[this.count]; -// //Coordinate thisOffset; -// double thisAngle = angle0; -// for (int instanceNumber = 0; instanceNumber < this.count; instanceNumber++) { -// toReturn[instanceNumber] = center.add(0, radius * Math.cos(thisAngle), radius * Math.sin(thisAngle)); -// -// thisAngle += angleIncr; -// } -// -// return toReturn; -// } -// - - @Override public void toDebugTreeNode(final StringBuilder buffer, final String prefix) { buffer.append(String.format("%s %-24s (stage: %d)", prefix, this.getName(), this.getStageNumber())); @@ -248,5 +232,20 @@ public class BoosterSet extends AxialStage implements FlightConfigurableComponen } + @Override + protected void update() { + super.update(); + + if( this.autoRadialPosition ){ + AxialStage parentStage = (AxialStage)this.parent; + if( null == parentStage ){ + this.radialPosition_m = this.getOuterRadius(); + }else{ + this.radialPosition_m = this.getOuterRadius() + parentStage.getOuterRadius(); + } + } + } + + } diff --git a/core/src/net/sf/openrocket/util/TestRockets.java b/core/src/net/sf/openrocket/util/TestRockets.java index 8f63b03e6..73d8ba3c8 100644 --- a/core/src/net/sf/openrocket/util/TestRockets.java +++ b/core/src/net/sf/openrocket/util/TestRockets.java @@ -21,7 +21,7 @@ import net.sf.openrocket.preset.InvalidComponentPresetException; import net.sf.openrocket.preset.TypedPropertyMap; import net.sf.openrocket.rocketcomponent.AxialStage; import net.sf.openrocket.rocketcomponent.BodyTube; -import net.sf.openrocket.rocketcomponent.BoosterSet; +import net.sf.openrocket.rocketcomponent.ParallelStage; import net.sf.openrocket.rocketcomponent.Bulkhead; import net.sf.openrocket.rocketcomponent.CenteringRing; import net.sf.openrocket.rocketcomponent.ClusterConfiguration; @@ -829,7 +829,7 @@ public class TestRockets { // ====== Booster Stage Set ====== // ====== ====== ====== ====== - BoosterSet boosterStage = new BoosterSet(); + ParallelStage boosterStage = new ParallelStage(); boosterStage.setName("Booster Stage"); coreStage.addChild( boosterStage); boosterStage.setRelativePositionMethod(Position.BOTTOM); diff --git a/core/test/net/sf/openrocket/masscalc/MassCalculatorTest.java b/core/test/net/sf/openrocket/masscalc/MassCalculatorTest.java index 2e55fc9b4..74382d111 100644 --- a/core/test/net/sf/openrocket/masscalc/MassCalculatorTest.java +++ b/core/test/net/sf/openrocket/masscalc/MassCalculatorTest.java @@ -8,7 +8,7 @@ import org.junit.Test; import net.sf.openrocket.masscalc.MassCalculator.MassCalcType; import net.sf.openrocket.motor.MotorInstance; -import net.sf.openrocket.rocketcomponent.BoosterSet; +import net.sf.openrocket.rocketcomponent.ParallelStage; import net.sf.openrocket.rocketcomponent.FlightConfiguration; import net.sf.openrocket.rocketcomponent.FlightConfigurationID; import net.sf.openrocket.rocketcomponent.InnerTube; @@ -119,7 +119,7 @@ public class MassCalculatorTest extends BaseTestCase { // ====== Booster Set Stage ====== // ====== ====== ====== - BoosterSet boosters = (BoosterSet) rkt.getChild(1).getChild(1); + ParallelStage boosters = (ParallelStage) rkt.getChild(1).getChild(1); { expMass = 0.01530561538; cc= boosters.getChild(0); @@ -232,7 +232,7 @@ public class MassCalculatorTest extends BaseTestCase { // ====== Booster Set Stage ====== // ====== ====== ====== - BoosterSet boosters = (BoosterSet) rkt.getChild(1).getChild(1); + ParallelStage boosters = (ParallelStage) rkt.getChild(1).getChild(1); { cc= boosters.getChild(0); expInertia = 5.20107e-6; @@ -264,7 +264,7 @@ public class MassCalculatorTest extends BaseTestCase { Rocket rocket = TestRockets.makeFalcon9Heavy(); rocket.setName("TestRocket."+Thread.currentThread().getStackTrace()[1].getMethodName()); - BoosterSet boosters = (BoosterSet) rocket.getChild(1).getChild(1); + ParallelStage boosters = (ParallelStage) rocket.getChild(1).getChild(1); int boostNum = boosters.getStageNumber(); rocket.getDefaultConfiguration().setAllStages(false); @@ -293,7 +293,7 @@ public class MassCalculatorTest extends BaseTestCase { Rocket rocket = TestRockets.makeFalcon9Heavy(); rocket.setName("TestRocket."+Thread.currentThread().getStackTrace()[1].getMethodName()); - BoosterSet boosters = (BoosterSet) rocket.getChild(1).getChild(1); + ParallelStage boosters = (ParallelStage) rocket.getChild(1).getChild(1); int boostNum = boosters.getStageNumber(); rocket.getDefaultConfiguration().setAllStages(false); rocket.getDefaultConfiguration().setOnlyStage( boostNum); @@ -339,7 +339,7 @@ public class MassCalculatorTest extends BaseTestCase { rocket.setName("TestRocket."+Thread.currentThread().getStackTrace()[1].getMethodName()); FlightConfiguration defaultConfig = rocket.getDefaultConfiguration(); - BoosterSet boosters = (BoosterSet) rocket.getChild(1).getChild(1); + ParallelStage boosters = (ParallelStage) rocket.getChild(1).getChild(1); int boostNum = boosters.getStageNumber(); rocket.getDefaultConfiguration().setAllStages(false); @@ -365,7 +365,7 @@ public class MassCalculatorTest extends BaseTestCase { FlightConfiguration defaultConfig = rocket.getDefaultConfiguration(); rocket.setName("TestRocket."+Thread.currentThread().getStackTrace()[1].getMethodName()); - BoosterSet boosters = (BoosterSet) rocket.getChild(1).getChild(1); + ParallelStage boosters = (ParallelStage) rocket.getChild(1).getChild(1); int boostNum = boosters.getStageNumber(); rocket.getDefaultConfiguration().setAllStages(false); @@ -393,7 +393,7 @@ public class MassCalculatorTest extends BaseTestCase { FlightConfiguration config = rocket.getDefaultConfiguration(); rocket.setName("TestRocket."+Thread.currentThread().getStackTrace()[1].getMethodName()); - BoosterSet boosters = (BoosterSet) rocket.getChild(1).getChild(1); + ParallelStage boosters = (ParallelStage) rocket.getChild(1).getChild(1); int boostNum = boosters.getStageNumber(); config.setAllStages(false); config.setOnlyStage( boostNum); @@ -444,7 +444,7 @@ public class MassCalculatorTest extends BaseTestCase { FlightConfiguration config = rocket.getDefaultConfiguration(); rocket.setName("TestRocket."+Thread.currentThread().getStackTrace()[1].getMethodName()); - BoosterSet boosters = (BoosterSet) rocket.getChild(1).getChild(1); + ParallelStage boosters = (ParallelStage) rocket.getChild(1).getChild(1); int boostNum = boosters.getStageNumber(); config.setAllStages(false); config.setOnlyStage( boostNum); diff --git a/core/test/net/sf/openrocket/rocketcomponent/BoosterSetTest.java b/core/test/net/sf/openrocket/rocketcomponent/BoosterSetTest.java index 3ba03ed49..042ab61ee 100644 --- a/core/test/net/sf/openrocket/rocketcomponent/BoosterSetTest.java +++ b/core/test/net/sf/openrocket/rocketcomponent/BoosterSetTest.java @@ -23,7 +23,7 @@ public class BoosterSetTest extends BaseTestCase { } public Rocket createTestRocket() { - double tubeRadius = 1; + double tubeRadius = 1.2; // setup Rocket rocket = new Rocket(); rocket.setName("Rocket"); @@ -53,28 +53,29 @@ public class BoosterSetTest extends BaseTestCase { return rocket; } - public BoosterSet createBooster() { + public ParallelStage createBooster() { double tubeRadius = 0.8; - BoosterSet booster = new BoosterSet(); - booster.setName("Booster Stage"); + ParallelStage strapon = new ParallelStage(); + strapon.setName("Booster Stage"); + strapon.setAutoRadialOffset(true); RocketComponent boosterNose = new NoseCone(Transition.Shape.CONICAL, 2.0, tubeRadius); boosterNose.setName("Booster Nosecone"); - booster.addChild(boosterNose); + strapon.addChild(boosterNose); RocketComponent boosterBody = new BodyTube(2.0, tubeRadius, 0.01); boosterBody.setName("Booster Body "); - booster.addChild(boosterBody); + strapon.addChild(boosterBody); Transition boosterTail = new Transition(); boosterTail.setName("Booster Tail"); boosterTail.setForeRadius(1.0); boosterTail.setAftRadius(0.5); boosterTail.setLength(1.0); - booster.addChild(boosterTail); + strapon.addChild(boosterTail); - booster.setInstanceCount(3); - booster.setRadialOffset(1.8); + strapon.setInstanceCount(3); + strapon.setRadialOffset(1.8); - return booster; + return strapon; } /* From OpenRocket Technical Documentation @@ -104,7 +105,7 @@ public class BoosterSetTest extends BaseTestCase { } @Test - public void testAddSustainerStage() { + public void testCreateSustainer() { RocketComponent rocket = createTestRocket(); // Sustainer Stage @@ -200,7 +201,7 @@ public class BoosterSetTest extends BaseTestCase { assertEquals(" createTestRocket failed:\n" + rocketTree + " core Fins abs X: ", expectedX, resultantX, EPSILON); } - + @Test public void testSetStagePosition_topOfStack() { // setup @@ -233,15 +234,17 @@ public class BoosterSetTest extends BaseTestCase { // setup RocketComponent rocket = createTestRocket(); AxialStage core = (AxialStage) rocket.getChild(1); - BoosterSet set0 = createBooster(); + ParallelStage set0 = createBooster(); core.addChild(set0); double targetOffset = 0; set0.setAxialOffset(Position.BOTTOM, targetOffset); // vv function under test + set0.setAutoRadialOffset(true); set0.setInstanceCount(2); set0.setRadialOffset(4.0); set0.setAngularOffset(Math.PI / 2); + // ^^ function under test String treeDump = rocket.toDebugTree(); @@ -262,6 +265,49 @@ public class BoosterSetTest extends BaseTestCase { assertEquals(" 'setAngularOffset(double)' failed:\n" + treeDump + " angular offset: ", expectedAngularOffset, angularOffset, EPSILON); } + + @Test + public void testAddStraponAuto() { + // setup + RocketComponent rocket = createTestRocket(); + AxialStage core = (AxialStage) rocket.getChild(1); + ParallelStage strapons = createBooster(); + core.addChild( strapons); + + double targetXOffset = +1.0; + strapons.setAxialOffset(Position.BOTTOM, targetXOffset); + double targetRadialOffset = 0.01; + // vv function under test + strapons.setRadialOffset(targetRadialOffset); + strapons.setAutoRadialOffset(true); + // ^^ function under test + String treeDump = rocket.toDebugTree(); + + double expectedRadialOffset = core.getOuterRadius() + strapons.getOuterRadius(); + double actualRadialOffset = strapons.getRadialOffset(); + assertEquals(" 'setAutoRadialOffset()' failed:\n" + treeDump , expectedRadialOffset, actualRadialOffset, EPSILON); + +// Coordinate[] instanceAbsoluteCoords = set0.getLocations(); +// // Coordinate[] instanceRelativeCoords = new Coordinate[] { componentAbsolutePosition }; +// // instanceRelativeCoords = boosterSet.shiftCoordinates(instanceRelativeCoords); +// +// int inst = 0; +// Coordinate expectedPosition0 = new Coordinate(expectedX, radius * Math.cos(angle * inst), radius * Math.sin(angle * inst)); +// Coordinate resultantPosition0 = instanceAbsoluteCoords[inst]; +// assertEquals(" 'setAngularOffset(double)' failed:\n" + treeDump + " angular offset: ", resultantPosition0, equalTo(expectedPosition0)); +// +// inst = 1; +// Coordinate expectedPosition1 = new Coordinate(expectedX, radius * Math.cos(angle * inst), radius * Math.sin(angle * inst)); +// Coordinate resultantPosition1 = instanceAbsoluteCoords[inst]; +// assertThat(treeDump + "\n>> Failed to generate Parallel Stage instances correctly: ", resultantPosition1, equalTo(expectedPosition1)); +// +// inst = 2; +// Coordinate expectedPosition2 = new Coordinate(expectedX, radius * Math.cos(angle * inst), radius * Math.sin(angle * inst)); +// Coordinate resultantPosition2 = instanceAbsoluteCoords[inst]; +// assertThat(treeDump + "\n>> Failed to generate Parallel Stage instances correctly: ", resultantPosition2, equalTo(expectedPosition2)); +// + } + // because even though this is an "outside" stage, it's relative to itself -- i.e. an error. // also an error with a well-defined failure result (i.e. just failover to AFTER placement as the first stage of a rocket. @Test @@ -269,7 +315,7 @@ public class BoosterSetTest extends BaseTestCase { // setup RocketComponent rocket = createTestRocket(); AxialStage core = (AxialStage) rocket.getChild(1); - BoosterSet set0 = createBooster(); + ParallelStage set0 = createBooster(); core.addChild(set0); double targetOffset = 0; @@ -314,7 +360,7 @@ public class BoosterSetTest extends BaseTestCase { // setup RocketComponent rocket = createTestRocket(); AxialStage core = (AxialStage) rocket.getChild(1); - BoosterSet booster = createBooster(); + ParallelStage booster = createBooster(); core.addChild(booster); double targetX = +17.0; @@ -376,7 +422,7 @@ public class BoosterSetTest extends BaseTestCase { public void testSetStagePosition_outsideTOP() { Rocket rocket = this.createTestRocket(); AxialStage core = (AxialStage) rocket.getChild(1); - BoosterSet booster = createBooster(); + ParallelStage booster = createBooster(); core.addChild(booster); double targetOffset = +2.0; @@ -406,7 +452,7 @@ public class BoosterSetTest extends BaseTestCase { // setup RocketComponent rocket = createTestRocket(); AxialStage core = (AxialStage) rocket.getChild(1); - BoosterSet booster = createBooster(); + ParallelStage booster = createBooster(); core.addChild(booster); // when 'external' the stage should be freely movable @@ -436,7 +482,7 @@ public class BoosterSetTest extends BaseTestCase { // setup RocketComponent rocket = createTestRocket(); AxialStage core = (AxialStage) rocket.getChild(1); - BoosterSet booster = createBooster(); + ParallelStage booster = createBooster(); core.addChild(booster); // vv function under test @@ -465,7 +511,7 @@ public class BoosterSetTest extends BaseTestCase { // setup RocketComponent rocket = createTestRocket(); AxialStage core = (AxialStage) rocket.getChild(1); - BoosterSet booster = createBooster(); + ParallelStage booster = createBooster(); core.addChild(booster); double targetOffset = +4.50; @@ -489,7 +535,7 @@ public class BoosterSetTest extends BaseTestCase { // setup RocketComponent rocket = createTestRocket(); AxialStage core = (AxialStage) rocket.getChild(1); - BoosterSet booster = createBooster(); + ParallelStage booster = createBooster(); core.addChild(booster); double targetOffset = +4.50; @@ -513,7 +559,7 @@ public class BoosterSetTest extends BaseTestCase { // setup RocketComponent rocket = createTestRocket(); AxialStage core = (AxialStage) rocket.getChild(1); - BoosterSet booster = createBooster(); + ParallelStage booster = createBooster(); core.addChild(booster); double targetOffset = +4.50; @@ -538,7 +584,7 @@ public class BoosterSetTest extends BaseTestCase { // setup RocketComponent rocket = createTestRocket(); AxialStage core = (AxialStage) rocket.getChild(1); - BoosterSet booster = createBooster(); + ParallelStage booster = createBooster(); core.addChild(booster); @@ -563,7 +609,7 @@ public class BoosterSetTest extends BaseTestCase { // setup RocketComponent rocket = createTestRocket(); AxialStage core = (AxialStage) rocket.getChild(1); - BoosterSet booster = createBooster(); + ParallelStage booster = createBooster(); core.addChild(booster); double targetOffset = +4.50; @@ -587,7 +633,7 @@ public class BoosterSetTest extends BaseTestCase { Rocket rocket = createTestRocket(); AxialStage core = (AxialStage) rocket.getChild(1); - BoosterSet booster = new BoosterSet(); + ParallelStage booster = new ParallelStage(); booster.setName("Booster Stage"); core.addChild(booster); final double targetOffset = +2.50; @@ -623,10 +669,10 @@ public class BoosterSetTest extends BaseTestCase { public void testStageInitializationMethodValueOrder() { Rocket rocket = createTestRocket(); AxialStage core = (AxialStage) rocket.getChild(1); - BoosterSet boosterA = createBooster(); + ParallelStage boosterA = createBooster(); boosterA.setName("Booster A Stage"); core.addChild(boosterA); - BoosterSet boosterB = createBooster(); + ParallelStage boosterB = createBooster(); boosterB.setName("Booster B Stage"); core.addChild(boosterB); @@ -653,11 +699,11 @@ public class BoosterSetTest extends BaseTestCase { Rocket rocket = createTestRocket(); AxialStage sustainer = (AxialStage) rocket.getChild(0); AxialStage core = (AxialStage) rocket.getChild(1); - BoosterSet boosterA = createBooster(); + ParallelStage boosterA = createBooster(); boosterA.setName("Booster A Stage"); core.addChild(boosterA); boosterA.setAxialOffset(Position.BOTTOM, 0.0); - BoosterSet boosterB = createBooster(); + ParallelStage boosterB = createBooster(); boosterB.setName("Booster B Stage"); core.addChild(boosterB); boosterB.setAxialOffset(Position.BOTTOM, 0); @@ -691,7 +737,7 @@ public class BoosterSetTest extends BaseTestCase { actualStageCount = rocket.getDefaultConfiguration().getStageCount(); assertEquals(" Stage tracking error: removed booster A, but configuration not updated: " + treedump, expectedStageCount, actualStageCount); - BoosterSet boosterC = createBooster(); + ParallelStage boosterC = createBooster(); boosterC.setName("Booster C Stage"); core.addChild(boosterC); boosterC.setAxialOffset(Position.BOTTOM, 0); diff --git a/swing/src/net/sf/openrocket/gui/configdialog/ComponentAssemblyConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/ComponentAssemblyConfig.java index ac3ce259e..7d54fbb09 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/ComponentAssemblyConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/ComponentAssemblyConfig.java @@ -27,82 +27,6 @@ public class ComponentAssemblyConfig extends RocketComponentConfig { public ComponentAssemblyConfig(OpenRocketDocument document, RocketComponent component) { super(document, component); - // For DEBUG purposes - if( component instanceof AxialStage ){ - System.err.println(" Dumping AxialStage tree info for devel / debugging."); - System.err.println(component.toDebugTree()); - } - - // only stages which are actually off-centerline will get the dialog here: - if(( component instanceof ComponentAssembly )&&( 1 < component.getInstanceCount() )){ - tabbedPane.insertTab( trans.get("RocketCompCfg.tab.Parallel"), null, parallelTab( (ComponentAssembly) component ), trans.get("RocketCompCfg.tab.ParallelComment"), 1); - } - } - - private JPanel parallelTab( final ComponentAssembly assembly ){ - JPanel motherPanel = new JPanel( new MigLayout("fill")); - - // set radial distance - JLabel radiusLabel = new JLabel(trans.get("StageConfig.parallel.radius")); - motherPanel.add( radiusLabel , "align left"); - DoubleModel radiusModel = new DoubleModel( assembly, "RadialOffset", UnitGroup.UNITS_LENGTH, 0); - //radiusModel.setCurrentUnit( UnitGroup.UNITS_LENGTH.getUnit("cm")); - JSpinner radiusSpinner = new JSpinner( radiusModel.getSpinnerModel()); - radiusSpinner.setEditor(new SpinnerEditor(radiusSpinner )); - motherPanel.add(radiusSpinner , "growx 1, align right"); - UnitSelector radiusUnitSelector = new UnitSelector(radiusModel); - motherPanel.add(radiusUnitSelector, "growx 1, wrap"); - - // set location angle around the primary stage - JLabel angleLabel = new JLabel(trans.get("StageConfig.parallel.angle")); - motherPanel.add( angleLabel, "align left"); - DoubleModel angleModel = new DoubleModel( assembly, "AngularOffset", 1.0, UnitGroup.UNITS_ANGLE, 0.0, Math.PI*2); - angleModel.setCurrentUnit( UnitGroup.UNITS_ANGLE.getUnit("rad")); - JSpinner angleSpinner = new JSpinner(angleModel.getSpinnerModel()); - angleSpinner.setEditor(new SpinnerEditor(angleSpinner)); - motherPanel.add(angleSpinner, "growx 1"); - UnitSelector angleUnitSelector = new UnitSelector(angleModel); - motherPanel.add( angleUnitSelector, "growx 1, wrap"); - - // set multiplicity - JLabel countLabel = new JLabel(trans.get("StageConfig.parallel.count")); - motherPanel.add( countLabel, "align left"); - - IntegerModel countModel = new IntegerModel( assembly, "InstanceCount", 2); - JSpinner countSpinner = new JSpinner(countModel.getSpinnerModel()); - countSpinner.setEditor(new SpinnerEditor(countSpinner)); - motherPanel.add(countSpinner, "growx 1, wrap"); - - // setPositions relative to parent component - JLabel positionLabel = new JLabel(trans.get("LaunchLugCfg.lbl.Posrelativeto")); - motherPanel.add( positionLabel); - - // EnumModel(ChangeSource source, String valueName, Enum[] values) { - ComboBoxModel relativePositionMethodModel = new EnumModel(component, "RelativePositionMethod", - new RocketComponent.Position[] { - RocketComponent.Position.TOP, - RocketComponent.Position.MIDDLE, - RocketComponent.Position.BOTTOM, - RocketComponent.Position.ABSOLUTE - }); - JComboBox positionMethodCombo = new JComboBox( relativePositionMethodModel ); - motherPanel.add(positionMethodCombo, "spanx 2, growx, wrap"); - - // relative offset labels - JLabel positionPlusLabel = new JLabel(trans.get("StageConfig.parallel.offset")); - motherPanel.add( positionPlusLabel ); - DoubleModel axialOffsetModel = new DoubleModel( assembly, "AxialOffset", UnitGroup.UNITS_LENGTH); - axialOffsetModel.setCurrentUnit(UnitGroup.UNITS_LENGTH.getUnit("cm")); - JSpinner axPosSpin= new JSpinner( axialOffsetModel.getSpinnerModel()); - axPosSpin.setEditor(new SpinnerEditor(axPosSpin)); - motherPanel.add(axPosSpin, "growx"); - UnitSelector axialOffsetUnitSelector = new UnitSelector(axialOffsetModel); - motherPanel.add(axialOffsetUnitSelector, "growx 1, wrap"); - - // For DEBUG purposes - //System.err.println(assembly.getRocket().toDebugTree()); - - return motherPanel; } } diff --git a/swing/src/net/sf/openrocket/gui/configdialog/ParallelStageConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/ParallelStageConfig.java new file mode 100644 index 000000000..21286436d --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/configdialog/ParallelStageConfig.java @@ -0,0 +1,118 @@ +package net.sf.openrocket.gui.configdialog; + +import javax.swing.ComboBoxModel; +import javax.swing.JCheckBox; +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.BooleanModel; +import net.sf.openrocket.gui.adaptors.DoubleModel; +import net.sf.openrocket.gui.adaptors.EnumModel; +import net.sf.openrocket.gui.adaptors.IntegerModel; +import net.sf.openrocket.gui.components.UnitSelector; +import net.sf.openrocket.l10n.Translator; +import net.sf.openrocket.rocketcomponent.AxialStage; +import net.sf.openrocket.rocketcomponent.ParallelStage; +import net.sf.openrocket.rocketcomponent.ComponentAssembly; +import net.sf.openrocket.rocketcomponent.RocketComponent; +import net.sf.openrocket.startup.Application; +import net.sf.openrocket.unit.UnitGroup; +import net.sf.openrocket.util.ChangeSource; + +public class ParallelStageConfig extends RocketComponentConfig { + private static final long serialVersionUID = -944969957186522471L; + private static final Translator trans = Application.getTranslator(); + + public ParallelStageConfig(OpenRocketDocument document, RocketComponent component) { + super(document, component); + + // For DEBUG purposes + if( component instanceof AxialStage ){ + System.err.println(" Dumping AxialStage tree info for devel / debugging."); + System.err.println(component.toDebugTree()); + } + + // only stages which are actually off-centerline will get the dialog here: + tabbedPane.insertTab( trans.get("RocketCompCfg.tab.Parallel"), null, parallelTab( (ParallelStage)component ), trans.get("RocketCompCfg.tab.ParallelComment"), 1); + } + + private JPanel parallelTab( final ParallelStage boosters ){ + JPanel motherPanel = new JPanel( new MigLayout("fill")); + + // auto radial distance + BooleanModel autoRadOffsModel = new BooleanModel( boosters, "AutoRadialOffset"); + JCheckBox autoRadCheckBox = new JCheckBox( autoRadOffsModel ); + autoRadCheckBox.setText( trans.get("StageConfig.parallel.autoradius")); + motherPanel.add( autoRadCheckBox, "align left, wrap"); + // set radial distance + JLabel radiusLabel = new JLabel(trans.get("StageConfig.parallel.radius")); + motherPanel.add( radiusLabel , "align left"); + autoRadOffsModel.addEnableComponent(radiusLabel, false); + DoubleModel radiusModel = new DoubleModel( boosters, "RadialOffset", UnitGroup.UNITS_LENGTH, 0); + //radiusModel.setCurrentUnit( UnitGroup.UNITS_LENGTH.getUnit("cm")); + JSpinner radiusSpinner = new JSpinner( radiusModel.getSpinnerModel()); + radiusSpinner.setEditor(new SpinnerEditor(radiusSpinner )); + motherPanel.add(radiusSpinner , "growx 1, align right"); + autoRadOffsModel.addEnableComponent(radiusSpinner, false); + UnitSelector radiusUnitSelector = new UnitSelector(radiusModel); + motherPanel.add(radiusUnitSelector, "growx 1, wrap"); + autoRadOffsModel.addEnableComponent(radiusUnitSelector, false); + + // set location angle around the primary stage + JLabel angleLabel = new JLabel(trans.get("StageConfig.parallel.angle")); + motherPanel.add( angleLabel, "align left"); + DoubleModel angleModel = new DoubleModel( boosters, "AngularOffset", 1.0, UnitGroup.UNITS_ANGLE, 0.0, Math.PI*2); + angleModel.setCurrentUnit( UnitGroup.UNITS_ANGLE.getUnit("rad")); + JSpinner angleSpinner = new JSpinner(angleModel.getSpinnerModel()); + angleSpinner.setEditor(new SpinnerEditor(angleSpinner)); + motherPanel.add(angleSpinner, "growx 1"); + UnitSelector angleUnitSelector = new UnitSelector(angleModel); + motherPanel.add( angleUnitSelector, "growx 1, wrap"); + + // set multiplicity + JLabel countLabel = new JLabel(trans.get("StageConfig.parallel.count")); + motherPanel.add( countLabel, "align left"); + + IntegerModel countModel = new IntegerModel( boosters, "InstanceCount", 2); + JSpinner countSpinner = new JSpinner(countModel.getSpinnerModel()); + countSpinner.setEditor(new SpinnerEditor(countSpinner)); + motherPanel.add(countSpinner, "growx 1, wrap"); + + // setPositions relative to parent component + JLabel positionLabel = new JLabel(trans.get("LaunchLugCfg.lbl.Posrelativeto")); + motherPanel.add( positionLabel); + + // EnumModel(ChangeSource source, String valueName, Enum[] values) { + ComboBoxModel relativePositionMethodModel = new EnumModel(component, "RelativePositionMethod", + new RocketComponent.Position[] { + RocketComponent.Position.TOP, + RocketComponent.Position.MIDDLE, + RocketComponent.Position.BOTTOM, + RocketComponent.Position.ABSOLUTE + }); + JComboBox positionMethodCombo = new JComboBox( relativePositionMethodModel ); + motherPanel.add(positionMethodCombo, "spanx 2, growx, wrap"); + + // relative offset labels + JLabel positionPlusLabel = new JLabel(trans.get("StageConfig.parallel.offset")); + motherPanel.add( positionPlusLabel ); + DoubleModel axialOffsetModel = new DoubleModel( boosters, "AxialOffset", UnitGroup.UNITS_LENGTH); + axialOffsetModel.setCurrentUnit(UnitGroup.UNITS_LENGTH.getUnit("cm")); + JSpinner axPosSpin= new JSpinner( axialOffsetModel.getSpinnerModel()); + axPosSpin.setEditor(new SpinnerEditor(axPosSpin)); + motherPanel.add(axPosSpin, "growx"); + UnitSelector axialOffsetUnitSelector = new UnitSelector(axialOffsetModel); + motherPanel.add(axialOffsetUnitSelector, "growx 1, wrap"); + + // For DEBUG purposes + //System.err.println(assembly.getRocket().toDebugTree()); + + return motherPanel; + } + +} diff --git a/swing/src/net/sf/openrocket/gui/configdialog/PodSetConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/PodSetConfig.java new file mode 100644 index 000000000..664912e02 --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/configdialog/PodSetConfig.java @@ -0,0 +1,100 @@ +package net.sf.openrocket.gui.configdialog; + +import javax.swing.ComboBoxModel; +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; +import net.sf.openrocket.gui.adaptors.IntegerModel; +import net.sf.openrocket.gui.components.UnitSelector; +import net.sf.openrocket.l10n.Translator; +import net.sf.openrocket.rocketcomponent.AxialStage; +import net.sf.openrocket.rocketcomponent.ComponentAssembly; +import net.sf.openrocket.rocketcomponent.RocketComponent; +import net.sf.openrocket.startup.Application; +import net.sf.openrocket.unit.UnitGroup; + +public class PodSetConfig extends RocketComponentConfig { + private static final long serialVersionUID = -944969957186522471L; + private static final Translator trans = Application.getTranslator(); + + public PodSetConfig(OpenRocketDocument document, RocketComponent component) { + super(document, component); + + // only stages which are actually off-centerline will get the dialog here: + tabbedPane.insertTab( trans.get("RocketCompCfg.tab.Parallel"), null, parallelTab( (ComponentAssembly) component ), trans.get("RocketCompCfg.tab.ParallelComment"), 1); + } + + private JPanel parallelTab( final ComponentAssembly assembly ){ + JPanel motherPanel = new JPanel( new MigLayout("fill")); + + // set radial distance + JLabel radiusLabel = new JLabel(trans.get("StageConfig.parallel.radius")); + motherPanel.add( radiusLabel , "align left"); + DoubleModel radiusModel = new DoubleModel( assembly, "RadialOffset", UnitGroup.UNITS_LENGTH, 0); + //radiusModel.setCurrentUnit( UnitGroup.UNITS_LENGTH.getUnit("cm")); + JSpinner radiusSpinner = new JSpinner( radiusModel.getSpinnerModel()); + radiusSpinner.setEditor(new SpinnerEditor(radiusSpinner )); + motherPanel.add(radiusSpinner , "growx 1, align right"); + UnitSelector radiusUnitSelector = new UnitSelector(radiusModel); + motherPanel.add(radiusUnitSelector, "growx 1, wrap"); + + // set location angle around the primary stage + JLabel angleLabel = new JLabel(trans.get("StageConfig.parallel.angle")); + motherPanel.add( angleLabel, "align left"); + DoubleModel angleModel = new DoubleModel( assembly, "AngularOffset", 1.0, UnitGroup.UNITS_ANGLE, 0.0, Math.PI*2); + angleModel.setCurrentUnit( UnitGroup.UNITS_ANGLE.getUnit("rad")); + JSpinner angleSpinner = new JSpinner(angleModel.getSpinnerModel()); + angleSpinner.setEditor(new SpinnerEditor(angleSpinner)); + motherPanel.add(angleSpinner, "growx 1"); + UnitSelector angleUnitSelector = new UnitSelector(angleModel); + motherPanel.add( angleUnitSelector, "growx 1, wrap"); + + // set multiplicity + JLabel countLabel = new JLabel(trans.get("StageConfig.parallel.count")); + motherPanel.add( countLabel, "align left"); + + IntegerModel countModel = new IntegerModel( assembly, "InstanceCount", 2); + JSpinner countSpinner = new JSpinner(countModel.getSpinnerModel()); + countSpinner.setEditor(new SpinnerEditor(countSpinner)); + motherPanel.add(countSpinner, "growx 1, wrap"); + + // setPositions relative to parent component + JLabel positionLabel = new JLabel(trans.get("LaunchLugCfg.lbl.Posrelativeto")); + motherPanel.add( positionLabel); + + // EnumModel(ChangeSource source, String valueName, Enum[] values) { + ComboBoxModel relativePositionMethodModel = new EnumModel(component, "RelativePositionMethod", + new RocketComponent.Position[] { + RocketComponent.Position.TOP, + RocketComponent.Position.MIDDLE, + RocketComponent.Position.BOTTOM, + RocketComponent.Position.ABSOLUTE + }); + JComboBox positionMethodCombo = new JComboBox( relativePositionMethodModel ); + motherPanel.add(positionMethodCombo, "spanx 2, growx, wrap"); + + // relative offset labels + JLabel positionPlusLabel = new JLabel(trans.get("StageConfig.parallel.offset")); + motherPanel.add( positionPlusLabel ); + DoubleModel axialOffsetModel = new DoubleModel( assembly, "AxialOffset", UnitGroup.UNITS_LENGTH); + axialOffsetModel.setCurrentUnit(UnitGroup.UNITS_LENGTH.getUnit("cm")); + JSpinner axPosSpin= new JSpinner( axialOffsetModel.getSpinnerModel()); + axPosSpin.setEditor(new SpinnerEditor(axPosSpin)); + motherPanel.add(axPosSpin, "growx"); + UnitSelector axialOffsetUnitSelector = new UnitSelector(axialOffsetModel); + motherPanel.add(axialOffsetUnitSelector, "growx 1, wrap"); + + // For DEBUG purposes + //System.err.println(assembly.getRocket().toDebugTree()); + + return motherPanel; + } + +} diff --git a/swing/src/net/sf/openrocket/gui/main/ComponentAddButtons.java b/swing/src/net/sf/openrocket/gui/main/ComponentAddButtons.java index ea3e2fa6f..05381aa71 100644 --- a/swing/src/net/sf/openrocket/gui/main/ComponentAddButtons.java +++ b/swing/src/net/sf/openrocket/gui/main/ComponentAddButtons.java @@ -34,7 +34,7 @@ import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.logging.Markers; import net.sf.openrocket.rocketcomponent.BodyComponent; import net.sf.openrocket.rocketcomponent.BodyTube; -import net.sf.openrocket.rocketcomponent.BoosterSet; +import net.sf.openrocket.rocketcomponent.ParallelStage; import net.sf.openrocket.rocketcomponent.Bulkhead; import net.sf.openrocket.rocketcomponent.CenteringRing; import net.sf.openrocket.rocketcomponent.EllipticalFinSet; @@ -167,7 +167,7 @@ public class ComponentAddButtons extends JPanel implements Scrollable { //// Component Assembly Components: ComponentButton[] buttonsToAdd = { new ComponentButton(AxialStage.class, trans.get("RocketActions.NewStageAct.Newstage")), - new ComponentButton(BoosterSet.class, trans.get("compaddbuttons.newBooster.lbl")), + new ComponentButton(ParallelStage.class, trans.get("compaddbuttons.newBooster.lbl")), new ComponentButton(PodSet.class, trans.get("compaddbuttons.newPods.lbl"))}; addButtonGroup(row, buttonsToAdd); diff --git a/swing/src/net/sf/openrocket/gui/main/ComponentIcons.java b/swing/src/net/sf/openrocket/gui/main/ComponentIcons.java index 0d846fd8d..0874c54fa 100644 --- a/swing/src/net/sf/openrocket/gui/main/ComponentIcons.java +++ b/swing/src/net/sf/openrocket/gui/main/ComponentIcons.java @@ -12,7 +12,7 @@ import javax.swing.ImageIcon; import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.rocketcomponent.AxialStage; import net.sf.openrocket.rocketcomponent.BodyTube; -import net.sf.openrocket.rocketcomponent.BoosterSet; +import net.sf.openrocket.rocketcomponent.ParallelStage; import net.sf.openrocket.rocketcomponent.Bulkhead; import net.sf.openrocket.rocketcomponent.CenteringRing; import net.sf.openrocket.rocketcomponent.EllipticalFinSet; @@ -86,7 +86,7 @@ public class ComponentIcons { load("stage", trans.get("ComponentIcons.Stage"), AxialStage.class); load("boosters", trans.get("ComponentIcons.Boosters"), - BoosterSet.class); + ParallelStage.class); load("pods", trans.get("ComponentIcons.Pods"), PodSet.class); // // Mass components