From 8ce90d2bb52437866f4482325506e7fe4b396fea Mon Sep 17 00:00:00 2001 From: SiboVG Date: Thu, 17 Feb 2022 00:33:15 +0100 Subject: [PATCH] [fixes #358] Implement multi-component editing --- .../rocketcomponent/BodyComponent.java | 6 ++ .../openrocket/rocketcomponent/BodyTube.java | 39 +++++++- .../rocketcomponent/ComponentAssembly.java | 6 ++ .../rocketcomponent/EllipticalFinSet.java | 12 +++ .../rocketcomponent/ExternalComponent.java | 12 +++ .../sf/openrocket/rocketcomponent/FinSet.java | 83 +++++++++++++++++ .../rocketcomponent/FreeformFinSet.java | 12 +++ .../openrocket/rocketcomponent/InnerTube.java | 37 +++++++- .../InsideColorComponentHandler.java | 24 +++++ .../openrocket/rocketcomponent/LaunchLug.java | 42 +++++++++ .../rocketcomponent/MassComponent.java | 18 ++++ .../rocketcomponent/MassObject.java | 24 +++++ .../openrocket/rocketcomponent/Parachute.java | 30 +++++++ .../rocketcomponent/ParallelStage.java | 46 +++++++++- .../sf/openrocket/rocketcomponent/PodSet.java | 38 +++++++- .../rocketcomponent/RadiusRingComponent.java | 30 +++++++ .../rocketcomponent/RailButton.java | 64 +++++++++++-- .../rocketcomponent/RecoveryDevice.java | 18 ++++ .../rocketcomponent/RingComponent.java | 36 ++++++++ .../rocketcomponent/RocketComponent.java | 88 ++++++++++++++++++ .../openrocket/rocketcomponent/ShockCord.java | 12 +++ .../sf/openrocket/rocketcomponent/Sleeve.java | 18 ++++ .../openrocket/rocketcomponent/Streamer.java | 30 +++++++ .../rocketcomponent/StructuralComponent.java | 6 ++ .../rocketcomponent/SymmetricComponent.java | 12 +++ .../ThicknessRingComponent.java | 18 ++++ .../rocketcomponent/Transition.java | 90 +++++++++++++++++++ .../rocketcomponent/TrapezoidFinSet.java | 36 ++++++++ .../rocketcomponent/TubeFinSet.java | 60 +++++++++++++ .../configdialog/ComponentConfigDialog.java | 3 + .../configdialog/RocketComponentConfig.java | 1 + .../sf/openrocket/gui/main/RocketActions.java | 34 +++++-- 32 files changed, 961 insertions(+), 24 deletions(-) diff --git a/core/src/net/sf/openrocket/rocketcomponent/BodyComponent.java b/core/src/net/sf/openrocket/rocketcomponent/BodyComponent.java index 62f1dab0f..e9712e133 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/BodyComponent.java +++ b/core/src/net/sf/openrocket/rocketcomponent/BodyComponent.java @@ -69,6 +69,12 @@ public abstract class BodyComponent extends ExternalComponent { return; this.length = Math.max(length, 0); fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof BodyComponent) { + ((BodyComponent) listener).setLength(length); + } + } } @Override diff --git a/core/src/net/sf/openrocket/rocketcomponent/BodyTube.java b/core/src/net/sf/openrocket/rocketcomponent/BodyTube.java index eb3b6d3d6..01bb7ca66 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/BodyTube.java +++ b/core/src/net/sf/openrocket/rocketcomponent/BodyTube.java @@ -125,6 +125,12 @@ public class BodyTube extends SymmetricComponent implements BoxBounded, MotorMou this.thickness = this.outerRadius; fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); clearPreset(); + + for (RocketComponent listener : configListeners) { + if (listener instanceof BodyTube) { + ((BodyTube) listener).setOuterRadius(radius); + } + } } @@ -146,6 +152,12 @@ public class BodyTube extends SymmetricComponent implements BoxBounded, MotorMou autoRadius = auto; fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); clearPreset(); + + for (RocketComponent listener : configListeners) { + if (listener instanceof BodyTube) { + ((BodyTube) listener).setOuterRadiusAutomatic(auto); + } + } } @Override @@ -239,6 +251,12 @@ public class BodyTube extends SymmetricComponent implements BoxBounded, MotorMou @Override public void setInnerRadius(double r) { setThickness(getOuterRadius() - r); + + for (RocketComponent listener : configListeners) { + if (listener instanceof BodyTube) { + ((BodyTube) listener).setInnerRadius(r); + } + } } @@ -384,9 +402,12 @@ public class BodyTube extends SymmetricComponent implements BoxBounded, MotorMou } this.isActingMount=true; - - // this is done automatically in the motorSet - //fireComponentChangeEvent(ComponentChangeEvent.MOTOR_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof BodyTube) { + ((BodyTube) listener).setMotorConfig(newMotorConfig, fcid); + } + } } @@ -411,6 +432,12 @@ public class BodyTube extends SymmetricComponent implements BoxBounded, MotorMou return; this.isActingMount = _active; fireComponentChangeEvent(ComponentChangeEvent.MOTOR_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof BodyTube) { + ((BodyTube) listener).setMotorMount(_active); + } + } } @Override @@ -447,6 +474,12 @@ public class BodyTube extends SymmetricComponent implements BoxBounded, MotorMou return; this.overhang = overhang; fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof BodyTube) { + ((BodyTube) listener).setMotorOverhang(overhang); + } + } } diff --git a/core/src/net/sf/openrocket/rocketcomponent/ComponentAssembly.java b/core/src/net/sf/openrocket/rocketcomponent/ComponentAssembly.java index 55db91984..e70bd026e 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/ComponentAssembly.java +++ b/core/src/net/sf/openrocket/rocketcomponent/ComponentAssembly.java @@ -159,6 +159,12 @@ public abstract class ComponentAssembly extends RocketComponent implements Axial throw new BugException("Unrecognized subclass of Component Assembly. Please update this method."); } fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof ComponentAssembly) { + ((ComponentAssembly) listener).setAxialMethod(newMethod); + } + } } @Override diff --git a/core/src/net/sf/openrocket/rocketcomponent/EllipticalFinSet.java b/core/src/net/sf/openrocket/rocketcomponent/EllipticalFinSet.java index 7d6ed096f..2dcc9a4fc 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/EllipticalFinSet.java +++ b/core/src/net/sf/openrocket/rocketcomponent/EllipticalFinSet.java @@ -64,6 +64,12 @@ public class EllipticalFinSet extends FinSet { return; this.height = height; fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof EllipticalFinSet) { + ((EllipticalFinSet) listener).setHeight(height); + } + } } @@ -73,6 +79,12 @@ public class EllipticalFinSet extends FinSet { this.length = length; validateFinTabLength(); fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof EllipticalFinSet) { + ((EllipticalFinSet) listener).setLength(length); + } + } } diff --git a/core/src/net/sf/openrocket/rocketcomponent/ExternalComponent.java b/core/src/net/sf/openrocket/rocketcomponent/ExternalComponent.java index 9d34f7519..764853c09 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/ExternalComponent.java +++ b/core/src/net/sf/openrocket/rocketcomponent/ExternalComponent.java @@ -114,6 +114,12 @@ public abstract class ExternalComponent extends RocketComponent { material = mat; clearPreset(); fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof ExternalComponent) { + ((ExternalComponent) listener).setMaterial(mat); + } + } } public Finish getFinish() { @@ -125,6 +131,12 @@ public abstract class ExternalComponent extends RocketComponent { return; this.finish = finish; fireComponentChangeEvent(ComponentChangeEvent.AERODYNAMIC_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof ExternalComponent) { + ((ExternalComponent) listener).setFinish(finish); + } + } } diff --git a/core/src/net/sf/openrocket/rocketcomponent/FinSet.java b/core/src/net/sf/openrocket/rocketcomponent/FinSet.java index 2ff54bab0..be6018edd 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/FinSet.java +++ b/core/src/net/sf/openrocket/rocketcomponent/FinSet.java @@ -163,6 +163,12 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona finRotationIncrement = Transformation.rotate_x(2 * Math.PI / finCount); fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof FinSet) { + ((FinSet) listener).setFinCount(n); + } + } } public Transformation getFinRotationTransformation() { @@ -188,6 +194,12 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona */ public void setBaseRotation(double r) { setAngleOffset(r); + + for (RocketComponent listener : configListeners) { + if (listener instanceof FinSet) { + ((FinSet) listener).setBaseRotation(r); + } + } } /** @@ -208,6 +220,12 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona this.cantRadians = clampedCant; fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof FinSet) { + ((FinSet) listener).setCantAngle(newCantRadians); + } + } } public Transformation getCantRotation() { @@ -230,6 +248,12 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona return; thickness = Math.max(r, 0); fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof FinSet) { + ((FinSet) listener).setThickness(r); + } + } } @@ -242,6 +266,12 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona return; crossSection = cs; fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof FinSet) { + ((FinSet) listener).setCrossSection(cs); + } + } } public double getTabHeight() { @@ -272,6 +302,12 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona tabHeight = newTabHeight; validateFinTabHeight(); fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof FinSet) { + ((FinSet) listener).setTabHeight(newTabHeight); + } + } } @@ -292,6 +328,12 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona updateTabPosition(); fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof FinSet) { + ((FinSet) listener).setTabLength(lengthRequest); + } + } } public void updateTabPosition(){ @@ -308,6 +350,12 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona updateTabPosition(); fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof FinSet) { + ((FinSet) listener).setTabOffset(offsetRequest); + } + } } public AxialMethod getTabOffsetMethod() { @@ -323,6 +371,12 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona this.tabOffset = this.tabOffsetMethod.getAsOffset(tabPosition, tabLength, length); fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof FinSet) { + ((FinSet) listener).setTabOffsetMethod(newPositionMethod); + } + } } /** @@ -974,6 +1028,12 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona } fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof FinSet) { + ((FinSet) listener).setAngleOffset(angleRadians); + } + } } @Override @@ -1003,6 +1063,12 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona mutex.verify(); this.angleMethod = newAngleMethod; fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof FinSet) { + ((FinSet) listener).setAngleMethod(newAngleMethod); + } + } } @Override @@ -1029,6 +1095,11 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona @Override public void setInstanceCount(int newCount) { setFinCount(newCount); + for (RocketComponent listener : configListeners) { + if (listener instanceof FinSet) { + ((FinSet) listener).setInstanceCount(newCount); + } + } } @Override @@ -1085,6 +1156,12 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona filletMaterial = mat; clearPreset(); fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof FinSet) { + ((FinSet) listener).setFilletMaterial(mat); + } + } } public double getFilletRadius() { @@ -1097,6 +1174,12 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona filletRadius = r; clearPreset(); fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof FinSet) { + ((FinSet) listener).setFilletRadius(r); + } + } } /** diff --git a/core/src/net/sf/openrocket/rocketcomponent/FreeformFinSet.java b/core/src/net/sf/openrocket/rocketcomponent/FreeformFinSet.java index 14e4e6d40..81512ca8b 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/FreeformFinSet.java +++ b/core/src/net/sf/openrocket/rocketcomponent/FreeformFinSet.java @@ -153,6 +153,12 @@ public class FreeformFinSet extends FinSet { */ public void setPoints(Coordinate[] newPoints) { setPoints(new ArrayList<>(Arrays.asList(newPoints))); + + for (RocketComponent listener : configListeners) { + if (listener instanceof FreeformFinSet) { + ((FreeformFinSet) listener).setPoints(newPoints); + } + } } /** @@ -192,6 +198,12 @@ public class FreeformFinSet extends FinSet { } fireComponentChangeEvent(ComponentChangeEvent.AEROMASS_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof FreeformFinSet) { + ((FreeformFinSet) listener).setPoints(newPoints); + } + } } /** diff --git a/core/src/net/sf/openrocket/rocketcomponent/InnerTube.java b/core/src/net/sf/openrocket/rocketcomponent/InnerTube.java index bd7cfcd42..f1bd573dc 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/InnerTube.java +++ b/core/src/net/sf/openrocket/rocketcomponent/InnerTube.java @@ -137,6 +137,12 @@ public class InnerTube extends ThicknessRingComponent implements AxialPositionab this.cluster = cluster; fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); } + + for (RocketComponent listener : configListeners) { + if (listener instanceof InnerTube) { + ((InnerTube) listener).setClusterConfiguration(cluster); + } + } } public BoundingBox getInstanceBoundingBox(){ @@ -187,6 +193,12 @@ public class InnerTube extends ThicknessRingComponent implements AxialPositionab return; clusterScale = scale; fireComponentChangeEvent(new ComponentChangeEvent(this, ComponentChangeEvent.MASS_CHANGE)); + + for (RocketComponent listener : configListeners) { + if (listener instanceof InnerTube) { + ((InnerTube) listener).setClusterScale(scale); + } + } } @@ -208,6 +220,12 @@ public class InnerTube extends ThicknessRingComponent implements AxialPositionab return; this.clusterRotation = rotation; fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof InnerTube) { + ((InnerTube) listener).setClusterRotation(rotation); + } + } } @@ -298,8 +316,11 @@ public class InnerTube extends ThicknessRingComponent implements AxialPositionab this.isActingMount = true; - // this is done automatically in the motorSet - //fireComponentChangeEvent(ComponentChangeEvent.MOTOR_CHANGE); + for (RocketComponent listener : configListeners) { + if (listener instanceof InnerTube) { + ((InnerTube) listener).setMotorConfig(newMotorConfig, fcid); + } + } } @Override @@ -323,6 +344,12 @@ public class InnerTube extends ThicknessRingComponent implements AxialPositionab return; this.isActingMount = _active; fireComponentChangeEvent(ComponentChangeEvent.MOTOR_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof InnerTube) { + ((InnerTube) listener).setMotorMount(_active); + } + } } @Override @@ -358,6 +385,12 @@ public class InnerTube extends ThicknessRingComponent implements AxialPositionab return; this.overhang = overhang; fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof InnerTube) { + ((InnerTube) listener).setMotorOverhang(overhang); + } + } } @Override diff --git a/core/src/net/sf/openrocket/rocketcomponent/InsideColorComponentHandler.java b/core/src/net/sf/openrocket/rocketcomponent/InsideColorComponentHandler.java index fdd2a9556..19d5705dd 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/InsideColorComponentHandler.java +++ b/core/src/net/sf/openrocket/rocketcomponent/InsideColorComponentHandler.java @@ -53,6 +53,12 @@ public class InsideColorComponentHandler { } } component.fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE); + + for (RocketComponent listener : component.configListeners) { + if (listener instanceof InsideColorComponent) { + ((InsideColorComponent) listener).getInsideColorComponentHandler().setInsideAppearance(appearance); + } + } } /** @@ -73,6 +79,12 @@ public class InsideColorComponentHandler { */ public void setEdgesSameAsInside(boolean newState) { this.edgesSameAsInside = newState; + + for (RocketComponent listener : component.configListeners) { + if (listener instanceof InsideColorComponent) { + ((InsideColorComponent) listener).getInsideColorComponentHandler().setEdgesSameAsInside(newState); + } + } } /** @@ -92,5 +104,17 @@ public class InsideColorComponentHandler { */ public void setSeparateInsideOutside(boolean newState) { this.separateInsideOutside = newState; + + for (RocketComponent listener : component.configListeners) { + if (listener instanceof InsideColorComponent) { + ((InsideColorComponent) listener).getInsideColorComponentHandler().setSeparateInsideOutside(newState); + } + } + } + + public void copyFrom(InsideColorComponentHandler src) { + this.insideAppearance = src.insideAppearance; + this.separateInsideOutside = src.separateInsideOutside; + this.edgesSameAsInside = src.edgesSameAsInside; } } diff --git a/core/src/net/sf/openrocket/rocketcomponent/LaunchLug.java b/core/src/net/sf/openrocket/rocketcomponent/LaunchLug.java index bf90d26e6..c314a3566 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/LaunchLug.java +++ b/core/src/net/sf/openrocket/rocketcomponent/LaunchLug.java @@ -55,6 +55,12 @@ public class LaunchLug extends ExternalComponent implements AnglePositionable, B this.thickness = Math.min(this.thickness, this.radius); clearPreset(); fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof LaunchLug) { + ((LaunchLug) listener).setOuterRadius(radius); + } + } } @Override @@ -65,6 +71,12 @@ public class LaunchLug extends ExternalComponent implements AnglePositionable, B @Override public void setInnerRadius(double innerRadius) { setOuterRadius(innerRadius + thickness); + + for (RocketComponent listener : configListeners) { + if (listener instanceof LaunchLug) { + ((LaunchLug) listener).setInnerRadius(innerRadius); + } + } } @Override @@ -78,6 +90,12 @@ public class LaunchLug extends ExternalComponent implements AnglePositionable, B this.thickness = MathUtil.clamp(thickness, 0, radius); clearPreset(); fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof LaunchLug) { + ((LaunchLug) listener).setThickness(thickness); + } + } } @Override @@ -92,6 +110,12 @@ public class LaunchLug extends ExternalComponent implements AnglePositionable, B return; this.angleOffsetRadians = clamped_rad; fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof LaunchLug) { + ((LaunchLug) listener).setAngleOffset(newAngleRadians); + } + } } public void setLength(double length) { @@ -99,6 +123,12 @@ public class LaunchLug extends ExternalComponent implements AnglePositionable, B return; this.length = length; fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof LaunchLug) { + ((LaunchLug) listener).setLength(length); + } + } } @Override @@ -243,6 +273,12 @@ public class LaunchLug extends ExternalComponent implements AnglePositionable, B @Override public void setInstanceSeparation(final double _separation){ this.instanceSeparation = _separation; + + for (RocketComponent listener : configListeners) { + if (listener instanceof LaunchLug) { + ((LaunchLug) listener).setInstanceSeparation(_separation); + } + } } @Override @@ -250,6 +286,12 @@ public class LaunchLug extends ExternalComponent implements AnglePositionable, B if( 0 < newCount ){ this.instanceCount = newCount; } + + for (RocketComponent listener : configListeners) { + if (listener instanceof LaunchLug) { + ((LaunchLug) listener).setInstanceCount(newCount); + } + } } @Override diff --git a/core/src/net/sf/openrocket/rocketcomponent/MassComponent.java b/core/src/net/sf/openrocket/rocketcomponent/MassComponent.java index 67091f1cf..4c8e2accc 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/MassComponent.java +++ b/core/src/net/sf/openrocket/rocketcomponent/MassComponent.java @@ -64,6 +64,12 @@ public class MassComponent extends MassObject { return; this.mass = mass; fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof MassComponent) { + ((MassComponent) listener).setComponentMass(mass); + } + } } @@ -80,6 +86,12 @@ public class MassComponent extends MassObject { if (Double.isNaN(m)) m = 0; setComponentMass(m); + + for (RocketComponent listener : configListeners) { + if (listener instanceof MassComponent) { + ((MassComponent) listener).setDensity(density); + } + } } @@ -107,6 +119,12 @@ public class MassComponent extends MassObject { checkState(); this.massComponentType = compType; fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof MassComponent) { + ((MassComponent) listener).setMassComponentType(compType); + } + } } @Override diff --git a/core/src/net/sf/openrocket/rocketcomponent/MassObject.java b/core/src/net/sf/openrocket/rocketcomponent/MassObject.java index 9999fee70..6830af80a 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/MassObject.java +++ b/core/src/net/sf/openrocket/rocketcomponent/MassObject.java @@ -57,6 +57,12 @@ public abstract class MassObject extends InternalComponent { } this.length = length; fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof MassObject) { + ((MassObject) listener).setLength(length); + } + } } @@ -72,6 +78,12 @@ public abstract class MassObject extends InternalComponent { } this.radius = radius; fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof MassObject) { + ((MassObject) listener).setRadius(radius); + } + } } @@ -89,6 +101,12 @@ public abstract class MassObject extends InternalComponent { shiftY = radialPosition * Math.cos(radialDirection); shiftZ = radialPosition * Math.sin(radialDirection); fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof MassObject) { + ((MassObject) listener).setRadialPosition(radialPosition); + } + } } public final double getRadialDirection() { @@ -104,6 +122,12 @@ public abstract class MassObject extends InternalComponent { shiftY = radialPosition * Math.cos(radialDirection); shiftZ = radialPosition * Math.sin(radialDirection); fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof MassObject) { + ((MassObject) listener).setRadialDirection(radialDirection); + } + } } diff --git a/core/src/net/sf/openrocket/rocketcomponent/Parachute.java b/core/src/net/sf/openrocket/rocketcomponent/Parachute.java index 721d5fab3..a371fb863 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/Parachute.java +++ b/core/src/net/sf/openrocket/rocketcomponent/Parachute.java @@ -38,6 +38,12 @@ public class Parachute extends RecoveryDevice { this.diameter = d; clearPreset(); fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof Parachute) { + ((Parachute) listener).setDiameter(d); + } + } } @@ -56,6 +62,12 @@ public class Parachute extends RecoveryDevice { fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); else fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof Parachute) { + ((Parachute) listener).setLineMaterial(mat); + } + } } @@ -69,6 +81,12 @@ public class Parachute extends RecoveryDevice { this.lineCount = n; clearPreset(); fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof Parachute) { + ((Parachute) listener).setLineCount(n); + } + } } public final double getLineLength() { @@ -83,6 +101,12 @@ public class Parachute extends RecoveryDevice { fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); else fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof Parachute) { + ((Parachute) listener).setLineLength(length); + } + } } @@ -102,6 +126,12 @@ public class Parachute extends RecoveryDevice { diameter = MathUtil.safeSqrt(area / Math.PI) * 2; clearPreset(); fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof Parachute) { + ((Parachute) listener).setArea(area); + } + } } @Override diff --git a/core/src/net/sf/openrocket/rocketcomponent/ParallelStage.java b/core/src/net/sf/openrocket/rocketcomponent/ParallelStage.java index 7a1fabe7b..3da070d34 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/ParallelStage.java +++ b/core/src/net/sf/openrocket/rocketcomponent/ParallelStage.java @@ -126,6 +126,12 @@ public class ParallelStage extends AxialStage implements FlightConfigurableCompo this.instanceCount = newCount; this.angleSeparation = Math.PI * 2 / this.instanceCount; fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof ParallelStage) { + ((ParallelStage) listener).setInstanceCount(newCount); + } + } } @Override @@ -182,11 +188,23 @@ public class ParallelStage extends AxialStage implements FlightConfigurableCompo super.setAxialMethod(_newPosition); fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof ParallelStage) { + ((ParallelStage) listener).setAxialMethod(_newPosition); + } + } } @Override public void setRadiusOffset(final double radius_m) { - setRadius( radiusMethod, radius_m ); + setRadius( radiusMethod, radius_m ); + + for (RocketComponent listener : configListeners) { + if (listener instanceof ParallelStage) { + ((ParallelStage) listener).setRadiusOffset(radius_m); + } + } } @Override @@ -194,10 +212,16 @@ public class ParallelStage extends AxialStage implements FlightConfigurableCompo mutex.verify(); this.angleOffset_rad = MathUtil.reducePi( angle_rad); fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof ParallelStage) { + ((ParallelStage) listener).setAngleOffset(angle_rad); + } + } } @Override - public void setRadius( final RadiusMethod requestedMethod, final double requestedRadius ) { + public void setRadius(RadiusMethod requestedMethod, double requestedRadius ) { mutex.verify(); RadiusMethod newMethod = requestedMethod; @@ -211,6 +235,12 @@ public class ParallelStage extends AxialStage implements FlightConfigurableCompo this.radiusOffset_m = newRadius; fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof ParallelStage) { + ((ParallelStage) listener).setRadius(requestedMethod, requestedRadius); + } + } } @Override @@ -223,6 +253,12 @@ public class ParallelStage extends AxialStage implements FlightConfigurableCompo mutex.verify(); this.angleMethod = newAngleMethod; fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof ParallelStage) { + ((ParallelStage) listener).setAngleMethod(newAngleMethod); + } + } } @Override @@ -233,6 +269,12 @@ public class ParallelStage extends AxialStage implements FlightConfigurableCompo @Override public void setRadiusMethod(RadiusMethod newRadiusMethod) { setRadius( newRadiusMethod, this.radiusOffset_m ); + + for (RocketComponent listener : configListeners) { + if (listener instanceof ParallelStage) { + ((ParallelStage) listener).setRadiusMethod(newRadiusMethod); + } + } } diff --git a/core/src/net/sf/openrocket/rocketcomponent/PodSet.java b/core/src/net/sf/openrocket/rocketcomponent/PodSet.java index f0cdaaa76..daf93b421 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/PodSet.java +++ b/core/src/net/sf/openrocket/rocketcomponent/PodSet.java @@ -162,7 +162,7 @@ public class PodSet extends ComponentAssembly implements RingInstanceable { @Override - public void setInstanceCount( final int newCount ){ + public void setInstanceCount(int newCount ){ mutex.verify(); if ( newCount < 1) { // there must be at least one instance.... @@ -172,6 +172,12 @@ public class PodSet extends ComponentAssembly implements RingInstanceable { this.instanceCount = newCount; this.angleSeparation = Math.PI * 2 / this.instanceCount; fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof PodSet) { + ((PodSet) listener).setInstanceCount(newCount); + } + } } @Override @@ -192,7 +198,13 @@ public class PodSet extends ComponentAssembly implements RingInstanceable { public void setAngleOffset(double angle_rad) { mutex.verify(); this.angleOffset_rad = angle_rad; - fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof PodSet) { + ((PodSet) listener).setAngleOffset(angle_rad); + } + } } @Override @@ -213,6 +225,12 @@ public class PodSet extends ComponentAssembly implements RingInstanceable { this.radiusOffset_m = radius_m; } fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof PodSet) { + ((PodSet) listener).setRadiusOffset(radius_m); + } + } } @Override @@ -221,14 +239,20 @@ public class PodSet extends ComponentAssembly implements RingInstanceable { } @Override - public void setRadiusMethod( final RadiusMethod newMethod ) { + public void setRadiusMethod(RadiusMethod newMethod ) { mutex.verify(); this.radiusMethod = newMethod; fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof PodSet) { + ((PodSet) listener).setRadiusMethod(newMethod); + } + } } @Override - public void setRadius( final RadiusMethod requestMethod, final double requestRadius ) { + public void setRadius(RadiusMethod requestMethod, double requestRadius ) { mutex.verify(); RadiusMethod newMethod = requestMethod; @@ -241,6 +265,12 @@ public class PodSet extends ComponentAssembly implements RingInstanceable { this.radiusMethod = newMethod; this.radiusOffset_m = newRadius; fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof PodSet) { + ((PodSet) listener).setRadius(requestMethod, requestRadius); + } + } } } diff --git a/core/src/net/sf/openrocket/rocketcomponent/RadiusRingComponent.java b/core/src/net/sf/openrocket/rocketcomponent/RadiusRingComponent.java index 0c0da4d19..5c81026d0 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/RadiusRingComponent.java +++ b/core/src/net/sf/openrocket/rocketcomponent/RadiusRingComponent.java @@ -63,6 +63,12 @@ public abstract class RadiusRingComponent extends RingComponent implements Coaxi clearPreset(); fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof RadiusRingComponent) { + ((RadiusRingComponent) listener).setOuterRadius(r); + } + } } @@ -85,6 +91,12 @@ public abstract class RadiusRingComponent extends RingComponent implements Coaxi clearPreset(); fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof RadiusRingComponent) { + ((RadiusRingComponent) listener).setInnerRadius(r); + } + } } @@ -98,6 +110,12 @@ public abstract class RadiusRingComponent extends RingComponent implements Coaxi thickness = MathUtil.clamp(thickness, 0, outer); setInnerRadius(outer - thickness); + + for (RocketComponent listener : configListeners) { + if (listener instanceof RadiusRingComponent) { + ((RadiusRingComponent) listener).setThickness(thickness); + } + } } @@ -109,6 +127,12 @@ public abstract class RadiusRingComponent extends RingComponent implements Coaxi @Override public void setInstanceSeparation(final double _separation){ this.instanceSeparation = _separation; + + for (RocketComponent listener : configListeners) { + if (listener instanceof RadiusRingComponent) { + ((RadiusRingComponent) listener).setInstanceSeparation(_separation); + } + } } @Override @@ -116,6 +140,12 @@ public abstract class RadiusRingComponent extends RingComponent implements Coaxi if( 0 < newCount ){ this.instanceCount = newCount; } + + for (RocketComponent listener : configListeners) { + if (listener instanceof RadiusRingComponent) { + ((RadiusRingComponent) listener).setInstanceCount(newCount); + } + } } @Override diff --git a/core/src/net/sf/openrocket/rocketcomponent/RailButton.java b/core/src/net/sf/openrocket/rocketcomponent/RailButton.java index 9a7a637bf..311c76aed 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/RailButton.java +++ b/core/src/net/sf/openrocket/rocketcomponent/RailButton.java @@ -151,31 +151,61 @@ public class RailButton extends ExternalComponent implements AnglePositionable, } - public void setStandoff( final double newStandoff){ + public void setStandoff(double newStandoff){ this.standoff_m = Math.max( newStandoff, RailButton.MINIMUM_STANDOFF ); + + for (RocketComponent listener : configListeners) { + if (listener instanceof RailButton) { + ((RailButton) listener).setStandoff(newStandoff); + } + } } - public void setInnerDiameter( final double newID ){ + public void setInnerDiameter(double newID ){ this.innerDiameter_m = newID; fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof RailButton) { + ((RailButton) listener).setInnerDiameter(newID); + } + } } - public void setOuterDiameter( final double newOD ){ + public void setOuterDiameter(double newOD ){ this.outerDiameter_m = newOD; fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof RailButton) { + ((RailButton) listener).setOuterDiameter(newOD); + } + } } - public void setTotalHeight( final double newHeight ) { + public void setTotalHeight(double newHeight ) { this.totalHeight_m = newHeight; fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof RailButton) { + ((RailButton) listener).setTotalHeight(newHeight); + } + } } - public void setThickness( final double newThickness ) { + public void setThickness(double newThickness ) { this.flangeHeight_m = newThickness; fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof RailButton) { + ((RailButton) listener).setThickness(newThickness); + } + } } @Override @@ -201,13 +231,19 @@ public class RailButton extends ExternalComponent implements AnglePositionable, @Override - public void setAngleOffset(final double angle_rad){ + public void setAngleOffset(double angle_rad){ double clamped_rad = MathUtil.clamp(angle_rad, -Math.PI, Math.PI); if (MathUtil.equals(this.angle_rad, clamped_rad)) return; this.angle_rad = clamped_rad; fireComponentChangeEvent(ComponentChangeEvent.AERODYNAMIC_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof RailButton) { + ((RailButton) listener).setAngleOffset(angle_rad); + } + } } @@ -282,17 +318,29 @@ public class RailButton extends ExternalComponent implements AnglePositionable, } @Override - public void setInstanceSeparation(final double _separation){ + public void setInstanceSeparation(double _separation){ this.instanceSeparation = _separation; fireComponentChangeEvent(ComponentChangeEvent.AERODYNAMIC_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof RailButton) { + ((RailButton) listener).setInstanceSeparation(_separation); + } + } } @Override - public void setInstanceCount( final int newCount ){ + public void setInstanceCount(int newCount ){ if( 0 < newCount ){ this.instanceCount = newCount; } fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof RailButton) { + ((RailButton) listener).setInstanceCount(newCount); + } + } } @Override diff --git a/core/src/net/sf/openrocket/rocketcomponent/RecoveryDevice.java b/core/src/net/sf/openrocket/rocketcomponent/RecoveryDevice.java index a0e783a70..a2785c551 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/RecoveryDevice.java +++ b/core/src/net/sf/openrocket/rocketcomponent/RecoveryDevice.java @@ -54,6 +54,12 @@ public abstract class RecoveryDevice extends MassObject implements FlightConfigu this.cd = cd; this.cdAutomatic = false; fireComponentChangeEvent(ComponentChangeEvent.AERODYNAMIC_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof RecoveryDevice) { + ((RecoveryDevice) listener).setCD(cd); + } + } } @@ -66,6 +72,12 @@ public abstract class RecoveryDevice extends MassObject implements FlightConfigu return; this.cdAutomatic = auto; fireComponentChangeEvent(ComponentChangeEvent.AERODYNAMIC_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof RecoveryDevice) { + ((RecoveryDevice) listener).setCDAutomatic(auto); + } + } } @@ -83,6 +95,12 @@ public abstract class RecoveryDevice extends MassObject implements FlightConfigu this.material = (Material.Surface) mat; clearPreset(); fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof RecoveryDevice) { + ((RecoveryDevice) listener).setMaterial(mat); + } + } } public FlightConfigurableParameterSet getDeploymentConfigurations() { diff --git a/core/src/net/sf/openrocket/rocketcomponent/RingComponent.java b/core/src/net/sf/openrocket/rocketcomponent/RingComponent.java index 1b9655e6d..3d0b0d379 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/RingComponent.java +++ b/core/src/net/sf/openrocket/rocketcomponent/RingComponent.java @@ -58,6 +58,12 @@ public abstract class RingComponent extends StructuralComponent implements BoxBo return; outerRadiusAutomatic = auto; fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof RingComponent) { + ((RingComponent) listener).setOuterRadiusAutomatic(auto); + } + } } @@ -71,6 +77,12 @@ public abstract class RingComponent extends StructuralComponent implements BoxBo return; innerRadiusAutomatic = auto; fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof RingComponent) { + ((RingComponent) listener).setInnerRadiusAutomatic(auto); + } + } } @@ -83,6 +95,12 @@ public abstract class RingComponent extends StructuralComponent implements BoxBo this.length = l; fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof RingComponent) { + ((RingComponent) listener).setLength(length); + } + } } @@ -110,6 +128,12 @@ public abstract class RingComponent extends StructuralComponent implements BoxBo shiftY = radialPosition * Math.cos(radialDirection); shiftZ = radialPosition * Math.sin(radialDirection); fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof RingComponent) { + ((RingComponent) listener).setRadialDirection(dir); + } + } } public BoundingBox getInstanceBoundingBox(){ @@ -148,6 +172,12 @@ public abstract class RingComponent extends StructuralComponent implements BoxBo shiftY = radialPosition * Math.cos(radialDirection); shiftZ = radialPosition * Math.sin(radialDirection); fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof RingComponent) { + ((RingComponent) listener).setRadialPosition(pos); + } + } } @@ -170,6 +200,12 @@ public abstract class RingComponent extends StructuralComponent implements BoxBo assert (MathUtil.equals(z, shiftZ)); fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof RingComponent) { + ((RingComponent) listener).setRadialShift(y, z); + } + } } @Override diff --git a/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java b/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java index 4391770c0..29f2f8538 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java +++ b/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java @@ -5,6 +5,7 @@ import java.util.Collection; import java.util.Deque; import java.util.EventObject; import java.util.Iterator; +import java.util.LinkedList; import java.util.List; import java.util.NoSuchElementException; @@ -127,6 +128,11 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab */ private final Invalidator invalidator = new Invalidator(this); + /** + * List of components that will set their properties to the same as the current component + */ + protected final List configListeners = new LinkedList<>(); + /** * This is for determining the order in which the component should be drawn in the 2D views, both @@ -458,6 +464,10 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab } // CHECK - should this be a TEXTURE_CHANGE and not NONFUNCTIONAL_CHANGE? fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE); + + for (RocketComponent listener : configListeners) { + listener.setAppearance(appearance); + } } /** @@ -480,6 +490,10 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab checkState(); this.color = c; fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE); + + for (RocketComponent listener : configListeners) { + listener.setColor(c); + } } @@ -494,6 +508,10 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab checkState(); this.lineStyle = style; fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE); + + for (RocketComponent listener : configListeners) { + listener.setLineStyle(style); + } } @@ -523,6 +541,10 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab overrideMass = Math.max(m, 0); if (massOverridden) fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + listener.setOverrideMass(m); + } } /** @@ -548,6 +570,10 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab checkState(); massOverridden = o; fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + listener.setMassOverridden(o); + } } @@ -588,6 +614,10 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); else fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE); + + for (RocketComponent listener : configListeners) { + listener.setOverrideCGX(x); + } } /** @@ -612,6 +642,10 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab checkState(); cgOverridden = o; fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + listener.setCGOverridden(o); + } } @@ -639,6 +673,10 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); else fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE); + + for (RocketComponent listener : configListeners) { + listener.setOverrideCD(x); + } } @@ -666,6 +704,10 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab checkState(); cdOverridden = o; fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + listener.setCDOverridden(o); + } } @@ -699,6 +741,10 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab checkState(); overrideSubcomponents = override; fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + listener.setOverrideSubcomponents(override); + } } /** @@ -747,6 +793,10 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab else this.name = name; fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE); + + for (RocketComponent listener : configListeners) { + listener.setName(name); + } } @@ -775,6 +825,10 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab else this.comment = comment; fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE); + + for (RocketComponent listener : configListeners) { + listener.setComment(comment); + } } @@ -845,6 +899,10 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab rocket.thaw(); } } + + for (RocketComponent listener : configListeners) { + listener.loadPreset(preset); + } } @@ -876,6 +934,10 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab return; presetComponent = null; fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE); + + for (RocketComponent listener : configListeners) { + listener.clearPreset(); + } } @@ -951,6 +1013,10 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab // // this doesn't cause any physical change-- just how it's described. // fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + listener.setAxialMethod(newAxialMethod); + } } /** @@ -1784,6 +1850,28 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab public void fireComponentChangeEvent(int type) { fireComponentChangeEvent(new ComponentChangeEvent(this, type)); } + + /** + * Add a new config listener that will undergo the same configuration changes as this.component. Listener must be + * of the same class as this.component. + * @param listener new config listener + * @return true if listener was successfully added, false if not + */ + public boolean addConfigListener(RocketComponent listener) { + if (listener == null || !this.getClass().equals(listener.getClass())) { + return false; + } + configListeners.add(listener); + return true; + } + + public void removeConfigListener(RocketComponent listener) { + configListeners.remove(listener); + } + + public void clearConfigListeners() { + configListeners.clear(); + } /** diff --git a/core/src/net/sf/openrocket/rocketcomponent/ShockCord.java b/core/src/net/sf/openrocket/rocketcomponent/ShockCord.java index d2f9cc7fa..fe03b3da3 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/ShockCord.java +++ b/core/src/net/sf/openrocket/rocketcomponent/ShockCord.java @@ -32,6 +32,12 @@ public class ShockCord extends MassObject { return; this.material = m; fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof ShockCord) { + ((ShockCord) listener).setMaterial(m); + } + } } @@ -45,6 +51,12 @@ public class ShockCord extends MassObject { return; this.cordLength = length; fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof ShockCord) { + ((ShockCord) listener).setCordLength(length); + } + } } diff --git a/core/src/net/sf/openrocket/rocketcomponent/Sleeve.java b/core/src/net/sf/openrocket/rocketcomponent/Sleeve.java index aafff5422..515b91236 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/Sleeve.java +++ b/core/src/net/sf/openrocket/rocketcomponent/Sleeve.java @@ -42,6 +42,12 @@ public class Sleeve extends RingComponent { if (thickness > r) thickness = r; fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof Sleeve) { + ((Sleeve) listener).setOuterRadius(r); + } + } } @@ -67,6 +73,12 @@ public class Sleeve extends RingComponent { return; innerRadius = r; fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof Sleeve) { + ((Sleeve) listener).setInnerRadius(r); + } + } } @Override @@ -81,6 +93,12 @@ public class Sleeve extends RingComponent { return; thickness = t; fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof Sleeve) { + ((Sleeve) listener).setThickness(t); + } + } } diff --git a/core/src/net/sf/openrocket/rocketcomponent/Streamer.java b/core/src/net/sf/openrocket/rocketcomponent/Streamer.java index 33352590e..58f367dcc 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/Streamer.java +++ b/core/src/net/sf/openrocket/rocketcomponent/Streamer.java @@ -36,6 +36,12 @@ public class Streamer extends RecoveryDevice { this.stripLength = stripLength; clearPreset(); fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof Streamer) { + ((Streamer) listener).setStripLength(stripLength); + } + } } public double getStripWidth() { @@ -49,11 +55,23 @@ public class Streamer extends RecoveryDevice { this.length = stripWidth; clearPreset(); fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof Streamer) { + ((Streamer) listener).setStripWidth(stripWidth); + } + } } @Override public void setLength(double length) { setStripWidth(length); + + for (RocketComponent listener : configListeners) { + if (listener instanceof Streamer) { + ((Streamer) listener).setStripWidth(length); + } + } } @@ -72,6 +90,12 @@ public class Streamer extends RecoveryDevice { stripWidth = MathUtil.safeSqrt(area / ratio); stripLength = ratio * stripWidth; fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof Streamer) { + ((Streamer) listener).setAspectRatio(ratio); + } + } } @@ -88,6 +112,12 @@ public class Streamer extends RecoveryDevice { stripWidth = MathUtil.safeSqrt(area / ratio); stripLength = ratio * stripWidth; fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof Streamer) { + ((Streamer) listener).setArea(area); + } + } } diff --git a/core/src/net/sf/openrocket/rocketcomponent/StructuralComponent.java b/core/src/net/sf/openrocket/rocketcomponent/StructuralComponent.java index b7143c682..a8eae373c 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/StructuralComponent.java +++ b/core/src/net/sf/openrocket/rocketcomponent/StructuralComponent.java @@ -51,5 +51,11 @@ public abstract class StructuralComponent extends InternalComponent { this.material = mat; clearPreset(); fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof StructuralComponent) { + ((StructuralComponent) listener).setMaterial(mat); + } + } } } diff --git a/core/src/net/sf/openrocket/rocketcomponent/SymmetricComponent.java b/core/src/net/sf/openrocket/rocketcomponent/SymmetricComponent.java index aa61cd979..58d7fcd81 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/SymmetricComponent.java +++ b/core/src/net/sf/openrocket/rocketcomponent/SymmetricComponent.java @@ -118,6 +118,12 @@ public abstract class SymmetricComponent extends BodyComponent implements BoxBou filled = false; fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); clearPreset(); + + for (RocketComponent listener : configListeners) { + if (listener instanceof SymmetricComponent) { + ((SymmetricComponent) listener).setThickness(thickness); + } + } } @@ -144,6 +150,12 @@ public abstract class SymmetricComponent extends BodyComponent implements BoxBou this.filled = filled; fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); clearPreset(); + + for (RocketComponent listener : configListeners) { + if (listener instanceof SymmetricComponent) { + ((SymmetricComponent) listener).setFilled(filled); + } + } } diff --git a/core/src/net/sf/openrocket/rocketcomponent/ThicknessRingComponent.java b/core/src/net/sf/openrocket/rocketcomponent/ThicknessRingComponent.java index 84dd93767..ff6211742 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/ThicknessRingComponent.java +++ b/core/src/net/sf/openrocket/rocketcomponent/ThicknessRingComponent.java @@ -65,6 +65,12 @@ public abstract class ThicknessRingComponent extends RingComponent { clearPreset(); fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof ThicknessRingComponent) { + ((ThicknessRingComponent) listener).setOuterRadius(r); + } + } } @@ -86,6 +92,12 @@ public abstract class ThicknessRingComponent extends RingComponent { clearPreset(); fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof ThicknessRingComponent) { + ((ThicknessRingComponent) listener).setThickness(thickness); + } + } } @@ -97,6 +109,12 @@ public abstract class ThicknessRingComponent extends RingComponent { public void setInnerRadius(double r) { r = Math.max(r,0); setThickness(getOuterRadius() - r); + + for (RocketComponent listener : configListeners) { + if (listener instanceof ThicknessRingComponent) { + ((ThicknessRingComponent) listener).setInnerRadius(r); + } + } } diff --git a/core/src/net/sf/openrocket/rocketcomponent/Transition.java b/core/src/net/sf/openrocket/rocketcomponent/Transition.java index 85855c075..71cd5da4b 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/Transition.java +++ b/core/src/net/sf/openrocket/rocketcomponent/Transition.java @@ -114,6 +114,12 @@ public class Transition extends SymmetricComponent implements InsideColorCompone clearPreset(); fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof Transition) { + ((Transition) listener).setForeRadius(radius); + } + } } @Override @@ -129,6 +135,12 @@ public class Transition extends SymmetricComponent implements InsideColorCompone clearPreset(); fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof Transition) { + ((Transition) listener).setForeRadiusAutomatic(auto); + } + } } @@ -170,6 +182,12 @@ public class Transition extends SymmetricComponent implements InsideColorCompone clearPreset(); fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof Transition) { + ((Transition) listener).setAftRadius(radius); + } + } } @Override @@ -185,6 +203,12 @@ public class Transition extends SymmetricComponent implements InsideColorCompone clearPreset(); fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof Transition) { + ((Transition) listener).setAftRadiusAutomatic(auto); + } + } } @@ -233,6 +257,12 @@ public class Transition extends SymmetricComponent implements InsideColorCompone this.clipped = type.isClippable(); this.shapeParameter = type.defaultParameter(); fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof Transition) { + ((Transition) listener).setType(type); + } + } } public double getShapeParameter() { @@ -244,6 +274,12 @@ public class Transition extends SymmetricComponent implements InsideColorCompone return; this.shapeParameter = MathUtil.clamp(n, type.minParameter(), type.maxParameter()); fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof Transition) { + ((Transition) listener).setShapeParameter(n); + } + } } public boolean isClipped() { @@ -257,6 +293,12 @@ public class Transition extends SymmetricComponent implements InsideColorCompone return; clipped = c; fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof Transition) { + ((Transition) listener).setClipped(c); + } + } } public boolean isClippedEnabled() { @@ -284,6 +326,12 @@ public class Transition extends SymmetricComponent implements InsideColorCompone this.foreShoulderRadius = foreShoulderRadius; clearPreset(); fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof Transition) { + ((Transition) listener).setForeShoulderRadius(foreShoulderRadius); + } + } } public double getForeShoulderThickness() { @@ -295,6 +343,12 @@ public class Transition extends SymmetricComponent implements InsideColorCompone return; this.foreShoulderThickness = foreShoulderThickness; fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof Transition) { + ((Transition) listener).setForeShoulderThickness(foreShoulderThickness); + } + } } public double getForeShoulderLength() { @@ -306,6 +360,12 @@ public class Transition extends SymmetricComponent implements InsideColorCompone return; this.foreShoulderLength = foreShoulderLength; fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof Transition) { + ((Transition) listener).setForeShoulderLength(foreShoulderLength); + } + } } public boolean isForeShoulderCapped() { @@ -317,6 +377,12 @@ public class Transition extends SymmetricComponent implements InsideColorCompone return; this.foreShoulderCapped = capped; fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof Transition) { + ((Transition) listener).setForeShoulderCapped(capped); + } + } } @@ -332,6 +398,12 @@ public class Transition extends SymmetricComponent implements InsideColorCompone this.aftShoulderRadius = aftShoulderRadius; clearPreset(); fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof Transition) { + ((Transition) listener).setAftShoulderRadius(aftShoulderRadius); + } + } } public double getAftShoulderThickness() { @@ -343,6 +415,12 @@ public class Transition extends SymmetricComponent implements InsideColorCompone return; this.aftShoulderThickness = aftShoulderThickness; fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof Transition) { + ((Transition) listener).setAftShoulderThickness(aftShoulderThickness); + } + } } public double getAftShoulderLength() { @@ -354,6 +432,12 @@ public class Transition extends SymmetricComponent implements InsideColorCompone return; this.aftShoulderLength = aftShoulderLength; fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof Transition) { + ((Transition) listener).setAftShoulderLength(aftShoulderLength); + } + } } public boolean isAftShoulderCapped() { @@ -365,6 +449,12 @@ public class Transition extends SymmetricComponent implements InsideColorCompone return; this.aftShoulderCapped = capped; fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof Transition) { + ((Transition) listener).setAftShoulderCapped(capped); + } + } } diff --git a/core/src/net/sf/openrocket/rocketcomponent/TrapezoidFinSet.java b/core/src/net/sf/openrocket/rocketcomponent/TrapezoidFinSet.java index e03951405..7c8dd9ec3 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/TrapezoidFinSet.java +++ b/core/src/net/sf/openrocket/rocketcomponent/TrapezoidFinSet.java @@ -67,6 +67,12 @@ public class TrapezoidFinSet extends FinSet { this.thickness = thickness; fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof TrapezoidFinSet) { + ((TrapezoidFinSet) listener).setFinShape(rootChord, tipChord, sweep, height, thickness); + } + } } public double getRootChord() { @@ -80,6 +86,12 @@ public class TrapezoidFinSet extends FinSet { updateTabPosition(); fireComponentChangeEvent(ComponentChangeEvent.AEROMASS_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof TrapezoidFinSet) { + ((TrapezoidFinSet) listener).setRootChord(r); + } + } } public double getTipChord() { @@ -91,6 +103,12 @@ public class TrapezoidFinSet extends FinSet { return; tipChord = Math.max(r, 0); fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof TrapezoidFinSet) { + ((TrapezoidFinSet) listener).setTipChord(r); + } + } } /** @@ -108,6 +126,12 @@ public class TrapezoidFinSet extends FinSet { return; sweep = r; fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof TrapezoidFinSet) { + ((TrapezoidFinSet) listener).setSweep(r); + } + } } /** @@ -138,6 +162,12 @@ public class TrapezoidFinSet extends FinSet { if (Double.isNaN(mySweep) || Double.isInfinite(mySweep)) return; setSweep(mySweep); + + for (RocketComponent listener : configListeners) { + if (listener instanceof TrapezoidFinSet) { + ((TrapezoidFinSet) listener).setSweepAngle(r); + } + } } public double getHeight() { @@ -149,6 +179,12 @@ public class TrapezoidFinSet extends FinSet { return; height = Math.max(r, 0); fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof TrapezoidFinSet) { + ((TrapezoidFinSet) listener).setHeight(r); + } + } } diff --git a/core/src/net/sf/openrocket/rocketcomponent/TubeFinSet.java b/core/src/net/sf/openrocket/rocketcomponent/TubeFinSet.java index 205c48555..a414bd49a 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/TubeFinSet.java +++ b/core/src/net/sf/openrocket/rocketcomponent/TubeFinSet.java @@ -65,6 +65,12 @@ public class TubeFinSet extends ExternalComponent implements AxialPositionable, return; this.length = length; fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof TubeFinSet) { + ((TubeFinSet) listener).setLength(length); + } + } } @@ -126,6 +132,12 @@ public class TubeFinSet extends ExternalComponent implements AxialPositionable, this.thickness = this.outerRadius; fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); clearPreset(); + + for (RocketComponent listener : configListeners) { + if (listener instanceof TubeFinSet) { + ((TubeFinSet) listener).setOuterRadius(radius); + } + } } /** @@ -138,6 +150,12 @@ public class TubeFinSet extends ExternalComponent implements AxialPositionable, autoRadius = auto; fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); clearPreset(); + + for (RocketComponent listener : configListeners) { + if (listener instanceof TubeFinSet) { + ((TubeFinSet) listener).setOuterRadiusAutomatic(auto); + } + } } public double getInnerRadius() { @@ -146,6 +164,12 @@ public class TubeFinSet extends ExternalComponent implements AxialPositionable, public void setInnerRadius(double r) { setThickness(getOuterRadius() - r); + + for (RocketComponent listener : configListeners) { + if (listener instanceof TubeFinSet) { + ((TubeFinSet) listener).setInnerRadius(r); + } + } } /** @@ -166,6 +190,12 @@ public class TubeFinSet extends ExternalComponent implements AxialPositionable, this.thickness = MathUtil.clamp(thickness, 0, getOuterRadius()); fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); clearPreset(); + + for (RocketComponent listener : configListeners) { + if (listener instanceof TubeFinSet) { + ((TubeFinSet) listener).setThickness(thickness); + } + } } @@ -196,6 +226,12 @@ public class TubeFinSet extends ExternalComponent implements AxialPositionable, fins = n; finRotation = Transformation.rotate_x(2 * Math.PI / fins); fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof TubeFinSet) { + ((TubeFinSet) listener).setFinCount(n); + } + } } /** @@ -216,6 +252,12 @@ public class TubeFinSet extends ExternalComponent implements AxialPositionable, */ public void setBaseRotation(double r) { setAngleOffset(r); + + for (RocketComponent listener : configListeners) { + if (listener instanceof TubeFinSet) { + ((TubeFinSet) listener).setBaseRotation(r); + } + } } public Transformation getBaseRotationTransformation() { @@ -356,6 +398,12 @@ public class TubeFinSet extends ExternalComponent implements AxialPositionable, @Override public void setInstanceCount(int newCount) { setFinCount(newCount); + + for (RocketComponent listener : configListeners) { + if (listener instanceof TubeFinSet) { + ((TubeFinSet) listener).setInstanceCount(newCount); + } + } } @Override @@ -389,6 +437,12 @@ public class TubeFinSet extends ExternalComponent implements AxialPositionable, } fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof TubeFinSet) { + ((TubeFinSet) listener).setAngleOffset(angleRadians); + } + } } @Override @@ -406,6 +460,12 @@ public class TubeFinSet extends ExternalComponent implements AxialPositionable, mutex.verify(); this.angleMethod = newAngleMethod; fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + + for (RocketComponent listener : configListeners) { + if (listener instanceof TubeFinSet) { + ((TubeFinSet) listener).setAngleMethod(newAngleMethod); + } + } } @Override diff --git a/swing/src/net/sf/openrocket/gui/configdialog/ComponentConfigDialog.java b/swing/src/net/sf/openrocket/gui/configdialog/ComponentConfigDialog.java index 6dfae4a34..4c1a740bf 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/ComponentConfigDialog.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/ComponentConfigDialog.java @@ -213,6 +213,9 @@ public class ComponentConfigDialog extends JDialog implements ComponentChangeLis public static void hideDialog() { if (dialog != null) { dialog.setVisible(false); + if (dialog.component != null) { + dialog.component.clearConfigListeners(); + } } } diff --git a/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java index 3dc4d74bc..b753a90ba 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java @@ -6,6 +6,7 @@ import java.awt.Container; import java.awt.event.*; import java.util.ArrayList; import java.util.Iterator; +import java.util.LinkedList; import java.util.List; import java.util.Locale; diff --git a/swing/src/net/sf/openrocket/gui/main/RocketActions.java b/swing/src/net/sf/openrocket/gui/main/RocketActions.java index 7f8a6c083..228fcc112 100644 --- a/swing/src/net/sf/openrocket/gui/main/RocketActions.java +++ b/swing/src/net/sf/openrocket/gui/main/RocketActions.java @@ -786,16 +786,40 @@ public class RocketActions { @Override public void actionPerformed(ActionEvent e) { - RocketComponent c = selectionModel.getSelectedComponent(); - if (c == null) + List components = selectionModel.getSelectedComponents(); + if (!checkAllClassesEqual(components)) return; - - ComponentConfigDialog.showDialog(parentFrame, document, c); + + for (int i = 1; i < components.size(); i++) { + components.get(0).addConfigListener(components.get(i)); + } + + ComponentConfigDialog.showDialog(parentFrame, document, components.get(0)); } @Override public void clipboardChanged() { - this.setEnabled(selectionModel.getSelectedComponent() != null); + List components = selectionModel.getSelectedComponents(); + + this.setEnabled(checkAllClassesEqual(components)); + } + + /** + * Checks whether all components in the list have the same class + * @param components list to check + * @return true if all components are of the same class, false if not + */ + private boolean checkAllClassesEqual(List components) { + if (components == null || components.size() == 0) { + return false; + } + Class myClass = components.get(0).getClass(); + for (int i = 1; i < components.size(); i++) { + if (!components.get(i).getClass().equals(myClass)) { + return false; + } + } + return true; } }