diff --git a/core/src/net/sf/openrocket/document/OpenRocketDocument.java b/core/src/net/sf/openrocket/document/OpenRocketDocument.java index 339e502ee..8729c39d0 100644 --- a/core/src/net/sf/openrocket/document/OpenRocketDocument.java +++ b/core/src/net/sf/openrocket/document/OpenRocketDocument.java @@ -62,7 +62,6 @@ public class OpenRocketDocument implements ComponentChangeListener { private static boolean undoErrorReported = false; private final Rocket rocket; - private final FlightConfiguration configuration; private final ArrayList simulations = new ArrayList(); private ArrayList customExpressions = new ArrayList(); @@ -104,7 +103,6 @@ public class OpenRocketDocument implements ComponentChangeListener { private final List listeners = new ArrayList(); OpenRocketDocument(Rocket rocket) { - this.configuration = rocket.getDefaultConfiguration(); this.rocket = rocket; init(); } @@ -166,7 +164,7 @@ public class OpenRocketDocument implements ComponentChangeListener { public FlightConfiguration getDefaultConfiguration() { - return configuration; + return rocket.getDefaultConfiguration(); } public File getFile() { diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/MotorConfigurationHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/MotorConfigurationHandler.java index d8415cdf3..11c7bd675 100644 --- a/core/src/net/sf/openrocket/file/openrocket/importt/MotorConfigurationHandler.java +++ b/core/src/net/sf/openrocket/file/openrocket/importt/MotorConfigurationHandler.java @@ -12,7 +12,7 @@ import net.sf.openrocket.file.simplesax.ElementHandler; import net.sf.openrocket.file.simplesax.PlainTextHandler; import net.sf.openrocket.rocketcomponent.FlightConfiguration; import net.sf.openrocket.rocketcomponent.FlightConfigurationID; -import net.sf.openrocket.rocketcomponent.FlightConfigurationSet; +import net.sf.openrocket.rocketcomponent.ParameterSet; import net.sf.openrocket.rocketcomponent.Rocket; class MotorConfigurationHandler extends AbstractElementHandler { @@ -64,7 +64,7 @@ class MotorConfigurationHandler extends AbstractElementHandler { if ("true".equals(attributes.remove("default"))) { // associate this configuration with both this FCID and the default. - FlightConfigurationSet fcs = rocket.getConfigurationSet(); + ParameterSet fcs = rocket.getConfigurationSet(); FlightConfiguration fc = fcs.get(fcid); fcs.setDefault(fc); } diff --git a/core/src/net/sf/openrocket/file/openrocket/savers/RecoveryDeviceSaver.java b/core/src/net/sf/openrocket/file/openrocket/savers/RecoveryDeviceSaver.java index fb865164d..ed37a1101 100644 --- a/core/src/net/sf/openrocket/file/openrocket/savers/RecoveryDeviceSaver.java +++ b/core/src/net/sf/openrocket/file/openrocket/savers/RecoveryDeviceSaver.java @@ -7,7 +7,7 @@ import java.util.Locale; import net.sf.openrocket.rocketcomponent.DeploymentConfiguration; import net.sf.openrocket.rocketcomponent.FlightConfiguration; import net.sf.openrocket.rocketcomponent.FlightConfigurationID; -import net.sf.openrocket.rocketcomponent.FlightConfigurationSet; +import net.sf.openrocket.rocketcomponent.ParameterSet; import net.sf.openrocket.rocketcomponent.RecoveryDevice; import net.sf.openrocket.rocketcomponent.Rocket; @@ -37,7 +37,7 @@ public class RecoveryDeviceSaver extends MassObjectSaver { //dev.getDeploymentConfigurations().printDebug(); // DEBUG - FlightConfigurationSet configList = rocket.getConfigurationSet(); + ParameterSet configList = rocket.getConfigurationSet(); for (FlightConfigurationID fcid : configList.getSortedConfigurationIDs()) { //System.err.println("checking FlightConfiguration:"+fcid.getShortKey()+ " save?"); diff --git a/core/src/net/sf/openrocket/file/openrocket/savers/RocketComponentSaver.java b/core/src/net/sf/openrocket/file/openrocket/savers/RocketComponentSaver.java index f75eccaab..3a005311f 100644 --- a/core/src/net/sf/openrocket/file/openrocket/savers/RocketComponentSaver.java +++ b/core/src/net/sf/openrocket/file/openrocket/savers/RocketComponentSaver.java @@ -17,7 +17,7 @@ import net.sf.openrocket.preset.ComponentPreset; import net.sf.openrocket.rocketcomponent.ComponentAssembly; import net.sf.openrocket.rocketcomponent.FlightConfiguration; import net.sf.openrocket.rocketcomponent.FlightConfigurationID; -import net.sf.openrocket.rocketcomponent.FlightConfigurationSet; +import net.sf.openrocket.rocketcomponent.ParameterSet; import net.sf.openrocket.rocketcomponent.MotorMount; import net.sf.openrocket.rocketcomponent.Rocket; import net.sf.openrocket.rocketcomponent.RocketComponent; @@ -148,7 +148,7 @@ public class RocketComponentSaver { return Collections.emptyList(); //FlightConfigurationID[] motorConfigIDs = ((RocketComponent) mount).getRocket().getFlightConfigurationIDs(); - FlightConfigurationSet configs = ((RocketComponent) mount).getRocket().getConfigurationSet(); + ParameterSet configs = ((RocketComponent) mount).getRocket().getConfigurationSet(); List elements = new ArrayList(); MotorInstance defaultInstance = mount.getDefaultMotorInstance(); diff --git a/core/src/net/sf/openrocket/file/openrocket/savers/RocketSaver.java b/core/src/net/sf/openrocket/file/openrocket/savers/RocketSaver.java index de98b07a1..28ff77620 100644 --- a/core/src/net/sf/openrocket/file/openrocket/savers/RocketSaver.java +++ b/core/src/net/sf/openrocket/file/openrocket/savers/RocketSaver.java @@ -6,7 +6,7 @@ import java.util.Locale; import net.sf.openrocket.rocketcomponent.FlightConfiguration; import net.sf.openrocket.rocketcomponent.FlightConfigurationID; -import net.sf.openrocket.rocketcomponent.FlightConfigurationSet; +import net.sf.openrocket.rocketcomponent.ParameterSet; import net.sf.openrocket.rocketcomponent.ReferenceType; import net.sf.openrocket.rocketcomponent.Rocket; @@ -43,7 +43,7 @@ public class RocketSaver extends RocketComponentSaver { // Motor configurations - FlightConfigurationSet allConfigs = rocket.getConfigurationSet(); + ParameterSet allConfigs = rocket.getConfigurationSet(); for (FlightConfigurationID fcid : allConfigs.getSortedConfigurationIDs()) { FlightConfiguration flightConfig = allConfigs.get(fcid); if (fcid == null) diff --git a/core/src/net/sf/openrocket/rocketcomponent/AxialStage.java b/core/src/net/sf/openrocket/rocketcomponent/AxialStage.java index 5590c3b64..918fb196f 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/AxialStage.java +++ b/core/src/net/sf/openrocket/rocketcomponent/AxialStage.java @@ -12,12 +12,12 @@ public class AxialStage extends ComponentAssembly implements FlightConfigurableC private static final Translator trans = Application.getTranslator(); //private static final Logger log = LoggerFactory.getLogger(AxialStage.class); - protected FlightConfigurationSet separationConfigurations; + protected ParameterSet separationConfigurations; protected int stageNumber; public AxialStage(){ - this.separationConfigurations = new FlightConfigurationSet( + this.separationConfigurations = new ParameterSet( this, ComponentChangeEvent.EVENT_CHANGE, new StageSeparationConfiguration()); this.relativePosition = Position.AFTER; this.stageNumber = 0; @@ -34,7 +34,7 @@ public class AxialStage extends ComponentAssembly implements FlightConfigurableC return trans.get("Stage.Stage"); } - public FlightConfigurationSet getSeparationConfigurations() { + public ParameterSet getSeparationConfigurations() { return separationConfigurations; } @@ -80,7 +80,7 @@ public class AxialStage extends ComponentAssembly implements FlightConfigurableC @Override protected RocketComponent copyWithOriginalID() { AxialStage copy = (AxialStage) super.copyWithOriginalID(); - copy.separationConfigurations = new FlightConfigurationSet(separationConfigurations, + copy.separationConfigurations = new ParameterSet(separationConfigurations, copy, ComponentChangeEvent.EVENT_CHANGE); return copy; } diff --git a/core/src/net/sf/openrocket/rocketcomponent/BodyTube.java b/core/src/net/sf/openrocket/rocketcomponent/BodyTube.java index 03214a1b8..0c58d0254 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/BodyTube.java +++ b/core/src/net/sf/openrocket/rocketcomponent/BodyTube.java @@ -462,8 +462,8 @@ public class BodyTube extends SymmetricComponent implements MotorMount, Coaxial return new Coordinate(this.getLength() - motor.getLength() + this.getMotorOverhang()); } - public void printMotorDebug(){ - this.motors.printDebug(); + public String toMotorDebug(){ + return this.motors.toDebug(); } @Override diff --git a/core/src/net/sf/openrocket/rocketcomponent/BoosterSet.java b/core/src/net/sf/openrocket/rocketcomponent/BoosterSet.java index b46c0dc67..6ccbd6dad 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/BoosterSet.java +++ b/core/src/net/sf/openrocket/rocketcomponent/BoosterSet.java @@ -114,7 +114,7 @@ public class BoosterSet extends AxialStage implements FlightConfigurableComponen // there must be at least one instance.... return; } - System.err.println("?! Setting BoosterSet instance count to: "+newCount ); + this.count = newCount; this.angularSeparation = Math.PI * 2 / this.count; fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); diff --git a/core/src/net/sf/openrocket/rocketcomponent/FlightConfiguration.java b/core/src/net/sf/openrocket/rocketcomponent/FlightConfiguration.java index ab9e1e798..a0ce1f05d 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/FlightConfiguration.java +++ b/core/src/net/sf/openrocket/rocketcomponent/FlightConfiguration.java @@ -184,14 +184,10 @@ public class FlightConfiguration implements FlightConfigurableParameter getActiveMotors() { ArrayList toReturn = new ArrayList(); for ( RocketComponent comp : this.getActiveComponents() ){ - // DEVEL - if (!this.isComponentActive(comp)){ - log.error( "Detected inactive component in list returned from .getActiveComponents()"); - } - // DEVEL // see planning notes... if ( comp instanceof MotorMount ){ @@ -223,7 +219,8 @@ public class FlightConfiguration implements FlightConfigurableParameter the parameter type */ -public class FlightConfigurationSet> implements FlightConfigurable { - - private static final Logger log = LoggerFactory.getLogger(FlightConfigurationSet.class); - protected final HashMap map = new HashMap(); - - protected E defaultValue; - protected final RocketComponent component; - protected final int eventType; - - private final Listener listener = new Listener(); - +public class FlightConfigurationSet extends ParameterSet { /** * Construct a FlightConfiguration that has no overrides. @@ -37,212 +14,19 @@ public class FlightConfigurationSet> im * @param component the rocket component on which events are fired when the parameter values are changed * @param eventType the event type that will be fired on changes */ - public FlightConfigurationSet(RocketComponent component, int eventType, E _defaultValue) { - this.component = component; - this.eventType = eventType; - - this.defaultValue= _defaultValue; - - addListener(_defaultValue); + public FlightConfigurationSet( RocketComponent component, int eventType, FlightConfiguration _defaultValue) { + super( component, eventType, _defaultValue); } /** - * Construct a copy of an existing FlightConfigurationImpl. + * Construct a copy of an existing FlightConfigurationSet * * @param component the rocket component on which events are fired when the parameter values are changed * @param eventType the event type that will be fired on changes */ - public FlightConfigurationSet(FlightConfigurationSet flightConfiguration, RocketComponent component, int eventType) { - this.component = component; - this.eventType = eventType; - - this.defaultValue= flightConfiguration.getDefault().clone(); - for (FlightConfigurationID key : flightConfiguration.map.keySet()) { - this.map.put(key, flightConfiguration.map.get(key).clone()); - } + public FlightConfigurationSet(FlightConfigurationSet configSet, RocketComponent component, int eventType) { + super( configSet, component, eventType ); } - - public boolean containsKey( final FlightConfigurationID fcid ){ - return this.map.containsKey(fcid); - } - - @Override - public E getDefault(){ - return this.defaultValue; - } - - @Override - public void setDefault(E nextDefaultValue) { - if (nextDefaultValue == null) { - throw new NullPointerException("new Default Value is null"); - } - if( this.isDefault(nextDefaultValue)){ - return; - } - this.defaultValue = nextDefaultValue; - } - - @Override - public Iterator iterator() { - return map.values().iterator(); - } - - - @Override - public int size() { - return map.size(); - } - - @Override - public FlightConfigurationID get(E testValue) { - if( null == testValue ){ - return null; - } - for( Entry curEntry : this.map.entrySet()){ - FlightConfigurationID curKey = curEntry.getKey(); - E curValue = curEntry.getValue(); - if( testValue.equals(curValue)){ - return curKey; - } - } - - return null; - } - - @Override - public E get(FlightConfigurationID id) { - E toReturn; - if (map.containsKey(id)) { - toReturn = map.get(id); - } else { - toReturn = this.getDefault(); - } - return toReturn; - } - - @Override - public List getSortedConfigurationIDs(){ - Vector toReturn = new Vector(); - - toReturn.addAll( this.map.keySet() ); - toReturn.sort( null ); - - return toReturn; - } - - public List getIDs(){ - return this.getSortedConfigurationIDs(); - } - - @Override - public void set(FlightConfigurationID fcid, E nextValue) { - if (null == fcid) { - throw new NullPointerException("id is null"); - }else if( !fcid.isValid()){ - throw new IllegalStateException(" Attempt to reset the default value on with an invalid key: "+fcid.toString()); - } - if ( nextValue == null) { - // null value means to delete this fcid - E previousValue = map.remove(fcid); - removeListener(previousValue); - }else{ - E previousValue = map.put(fcid, nextValue); - removeListener(previousValue); - addListener(nextValue); - } - - fireEvent(); - } - - public boolean isDefault(E testVal) { - return (Utils.equals( this.getDefault(), testVal)); - } - - @Override - public boolean isDefault( FlightConfigurationID fcid) { - return ( this.getDefault() == this.map.get(fcid)); - } - - @Override - public void reset( FlightConfigurationID fcid) { - // enforce at least one value in the set - if( 1 < this.map.size() ){ - set( fcid, null); - }else{ - log.warn(" attempted to remove last element from the FlightConfigurationSet<"+this.getDefault().getClass().getSimpleName()+"> attached to: "+component.getName()+". Ignoring. "); - return; - } - } - - private void fireEvent() { - component.fireComponentChangeEvent(eventType); - } - - - @Override - public void cloneFlightConfiguration(FlightConfigurationID oldConfigId, FlightConfigurationID newConfigId) { - // clones the ENTRIES for the given fcid's. - E oldValue = this.get(oldConfigId); - this.set(newConfigId, oldValue.clone()); - fireEvent(); - } - - private void addListener(E value) { - if (value != null) { - value.addChangeListener(listener); - } - } - - private void removeListener(E value) { - if (value != null) { - value.removeChangeListener(listener); - } - } - - - private class Listener implements StateChangeListener { - @Override - public void stateChanged(EventObject e) { - fireEvent(); - } - } - - public void printDebug(){ - System.err.println("====== Dumping ConfigurationSet for comp: '"+this.component.getName()+"' of type: "+this.component.getClass().getSimpleName()+" ======"); - System.err.println(" >> FlightConfigurationSet ("+this.size()+ " configurations)"); - - if( 0 == this.size() ){ - String designation = ""; - E inst = this.getDefault(); - - if( inst instanceof FlightConfiguration){ - designation = ((FlightConfiguration) inst).getFlightConfigurationID().getShortKey(); - }else{ - designation = inst.toString(); - } - - System.err.println(" ( DEFAULT_VALUE = "+designation + ")"); - } - - for( FlightConfigurationID loopFCID : this.getSortedConfigurationIDs()){ - String shortKey = loopFCID.getShortKey(); - String designation = ""; - - E inst = this.map.get(loopFCID); - if( inst instanceof FlightConfiguration){ - FlightConfiguration fc = (FlightConfiguration) inst; - designation = ( fc.isNameOverridden() ? "" : fc.getName()); - }else{ - designation = inst.toString(); - } - if( this.isDefault(inst)){ - shortKey = "*"+shortKey+"*"; - } - System.err.println(" >> ["+shortKey+"]= "+designation); - } - - } - } diff --git a/core/src/net/sf/openrocket/rocketcomponent/InnerTube.java b/core/src/net/sf/openrocket/rocketcomponent/InnerTube.java index e66dcfae1..f52cb9ce7 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/InnerTube.java +++ b/core/src/net/sf/openrocket/rocketcomponent/InnerTube.java @@ -383,7 +383,7 @@ public class InnerTube extends ThicknessRingComponent implements Clusterable, Ra } public void printMotorDebug( FlightConfigurationID fcid ){ - this.motors.printDebug(); + System.err.println(this.motors.toDebug()); } @Override @@ -393,26 +393,29 @@ public class InnerTube extends ThicknessRingComponent implements Clusterable, Ra Coordinate[] relCoords = this.shiftCoordinates(new Coordinate[] { Coordinate.ZERO }); Coordinate[] absCoords = this.getLocations(); + FlightConfigurationID curId = this.getRocket().getDefaultConfiguration().getFlightConfigurationID(); int count = this.getInstanceCount(); - for (int instanceNumber = 0; instanceNumber < count; instanceNumber++) { - Coordinate instanceRelativePosition = relCoords[instanceNumber]; - Coordinate instanceAbsolutePosition = absCoords[instanceNumber]; - buffer.append(String.format("%s [instance %2d / %2d] %28s %28s\n", prefix, instanceNumber, count, - instanceRelativePosition, instanceAbsolutePosition)); - } - - if( this.hasMotor()){ - MotorInstance curInstance = this.getMotorInstance(null); - Motor curMotor = curInstance.getMotor(); - buffer.append(String.format("%s %-24s (cluster: %s)", prefix, curMotor.getDesignation(), this.getPatternName())); + MotorInstance curInstance = this.motors.get(curId); + if( curInstance.isEmpty() ){ + // print just the tube locations + buffer.append(prefix+" [X] This Instance doesn't have any motors... showing mount tubes only\n"); for (int instanceNumber = 0; instanceNumber < count; instanceNumber++) { Coordinate instanceRelativePosition = relCoords[instanceNumber]; Coordinate instanceAbsolutePosition = absCoords[instanceNumber]; - buffer.append(String.format("%s [MotorInstance %2d / %2d] %28s %28s\n", prefix, instanceNumber, count, + buffer.append(String.format("%s [%2d / %2d] %28s %28s\n", prefix, instanceNumber, count, instanceRelativePosition, instanceAbsolutePosition)); } }else{ - buffer.append(prefix+" [X] This Instance doesn't have any motors.\n"); + // curInstance has a motor ... + Motor curMotor = curInstance.getMotor(); + buffer.append(String.format("%s %-24s (in cluster: %s)\n", prefix, curMotor.getDesignation(), this.getPatternName())); + for (int instanceNumber = 0; instanceNumber < count; instanceNumber++) { + Coordinate instanceRelativePosition = relCoords[instanceNumber]; + Coordinate instanceAbsolutePosition = absCoords[instanceNumber]; + buffer.append(String.format("%s [%2d / %2d] %28s %28s\n", prefix, instanceNumber, count, + instanceRelativePosition, instanceAbsolutePosition)); + } + } } diff --git a/core/src/net/sf/openrocket/rocketcomponent/MotorConfigurationSet.java b/core/src/net/sf/openrocket/rocketcomponent/MotorConfigurationSet.java index 56fc0acb9..db678110d 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/MotorConfigurationSet.java +++ b/core/src/net/sf/openrocket/rocketcomponent/MotorConfigurationSet.java @@ -6,7 +6,7 @@ import net.sf.openrocket.motor.MotorInstance; * FlightConfigurationSet for motors. * This is used for motors, where the default value is always no motor. */ -public class MotorConfigurationSet extends FlightConfigurationSet { +public class MotorConfigurationSet extends ParameterSet { public static final int DEFAULT_EVENT_TYPE = ComponentChangeEvent.MOTOR_CHANGE | ComponentChangeEvent.EVENT_CHANGE; @@ -21,7 +21,7 @@ public class MotorConfigurationSet extends FlightConfigurationSet * @param component the rocket component on which events are fired when the parameter values are changed * @param eventType the event type that will be fired on changes */ - public MotorConfigurationSet(FlightConfigurationSet flightConfiguration, RocketComponent component, int eventType) { + public MotorConfigurationSet(ParameterSet flightConfiguration, RocketComponent component, int eventType) { super(flightConfiguration, component, eventType); } @@ -32,9 +32,10 @@ public class MotorConfigurationSet extends FlightConfigurationSet } @Override - public void printDebug(){ - System.err.println("====== Dumping MotorConfigurationSet for mount '"+this.component.getName()+"' of type: "+this.component.getClass().getSimpleName()+" ======"); - System.err.println(" >> motorSet ("+this.size()+ " motors)"); + public String toDebug(){ + StringBuilder buffer = new StringBuilder(); + buffer.append("====== Dumping MotorConfigurationSet for mount '"+this.component.getName()+"' of type: "+this.component.getClass().getSimpleName()+" ======"); + buffer.append(" >> motorSet ("+this.size()+ " motors)"); for( FlightConfigurationID loopFCID : this.map.keySet()){ String shortKey = loopFCID.getShortKey(); @@ -46,9 +47,9 @@ public class MotorConfigurationSet extends FlightConfigurationSet }else{ designation = curInstance.getMotor().getDesignation(curInstance.getEjectionDelay()); } - System.err.println(" >> ["+shortKey+"]= "+designation); - + buffer.append(" >> ["+shortKey+"]= "+designation); } + return buffer.toString(); } // public void printDebug(FlightConfigurationID curFCID){ diff --git a/core/src/net/sf/openrocket/rocketcomponent/ParameterSet.java b/core/src/net/sf/openrocket/rocketcomponent/ParameterSet.java new file mode 100644 index 000000000..01e04b488 --- /dev/null +++ b/core/src/net/sf/openrocket/rocketcomponent/ParameterSet.java @@ -0,0 +1,233 @@ +package net.sf.openrocket.rocketcomponent; + +import java.util.EventObject; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map.Entry; +import java.util.Vector; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import net.sf.openrocket.util.StateChangeListener; +import net.sf.openrocket.util.Utils; + +/** + * An implementation of FlightConfiguration that fires off events + * to the rocket components when the parameter value is changed. + * + * @param the parameter type + */ +public class ParameterSet> implements FlightConfigurable { + + private static final Logger log = LoggerFactory.getLogger(ParameterSet.class); + protected final HashMap map = new HashMap(); + + protected E defaultValue; + protected final RocketComponent component; + protected final int eventType; + + private final Listener listener = new Listener(); + + + /** + * Construct a FlightConfiguration that has no overrides. + * + * @param component the rocket component on which events are fired when the parameter values are changed + * @param eventType the event type that will be fired on changes + */ + public ParameterSet(RocketComponent component, int eventType, E _defaultValue) { + this.component = component; + this.eventType = eventType; + + this.defaultValue= _defaultValue; + + addListener(_defaultValue); + } + + + /** + * Construct a copy of an existing FlightConfigurationImpl. + * + * @param component the rocket component on which events are fired when the parameter values are changed + * @param eventType the event type that will be fired on changes + */ + public ParameterSet(ParameterSet flightConfiguration, RocketComponent component, int eventType) { + this.component = component; + this.eventType = eventType; + + this.defaultValue= flightConfiguration.getDefault().clone(); + for (FlightConfigurationID key : flightConfiguration.map.keySet()) { + this.map.put(key, flightConfiguration.map.get(key).clone()); + } + } + + public boolean containsKey( final FlightConfigurationID fcid ){ + return this.map.containsKey(fcid); + } + + @Override + public E getDefault(){ + return this.defaultValue; + } + + @Override + public void setDefault(E nextDefaultValue) { + if (nextDefaultValue == null) { + throw new NullPointerException("new Default Value is null"); + } + if( this.isDefault(nextDefaultValue)){ + return; + } + this.defaultValue = nextDefaultValue; + } + + @Override + public Iterator iterator() { + return map.values().iterator(); + } + + + @Override + public int size() { + return map.size(); + } + + @Override + public FlightConfigurationID get(E testValue) { + if( null == testValue ){ + return null; + } + for( Entry curEntry : this.map.entrySet()){ + FlightConfigurationID curKey = curEntry.getKey(); + E curValue = curEntry.getValue(); + + if( testValue.equals(curValue)){ + return curKey; + } + } + + return null; + } + + @Override + public E get(FlightConfigurationID id) { + E toReturn; + if (map.containsKey(id)) { + toReturn = map.get(id); + } else { + toReturn = this.getDefault(); + } + return toReturn; + } + + @Override + public List getSortedConfigurationIDs(){ + Vector toReturn = new Vector(); + + toReturn.addAll( this.map.keySet() ); + toReturn.sort( null ); + + return toReturn; + } + + public List getIDs(){ + return this.getSortedConfigurationIDs(); + } + + @Override + public void set(FlightConfigurationID fcid, E nextValue) { + if (null == fcid) { + throw new NullPointerException("id is null"); + }else if( !fcid.isValid()){ + throw new IllegalStateException(" Attempt to reset the default value on with an invalid key: "+fcid.toString()); + } + if ( nextValue == null) { + // null value means to delete this fcid + E previousValue = map.remove(fcid); + removeListener(previousValue); + }else{ + E previousValue = map.put(fcid, nextValue); + removeListener(previousValue); + addListener(nextValue); + } + + fireEvent(); + } + + public boolean isDefault(E testVal) { + return (Utils.equals( this.getDefault(), testVal)); + } + + @Override + public boolean isDefault( FlightConfigurationID fcid) { + return ( this.getDefault() == this.map.get(fcid)); + } + + @Override + public void reset( FlightConfigurationID fcid) { + // enforce at least one value in the set + if( 1 < this.map.size() ){ + set( fcid, null); + }else{ + log.warn(" attempted to remove last element from the FlightConfigurationSet<"+this.getDefault().getClass().getSimpleName()+"> attached to: "+component.getName()+". Ignoring. "); + return; + } + } + + private void fireEvent() { + component.fireComponentChangeEvent(eventType); + } + + + @Override + public void cloneFlightConfiguration(FlightConfigurationID oldConfigId, FlightConfigurationID newConfigId) { + // clones the ENTRIES for the given fcid's. + E oldValue = this.get(oldConfigId); + this.set(newConfigId, oldValue.clone()); + fireEvent(); + } + + private void addListener(E value) { + if (value != null) { + value.addChangeListener(listener); + } + } + + private void removeListener(E value) { + if (value != null) { + value.removeChangeListener(listener); + } + } + + + private class Listener implements StateChangeListener { + @Override + public void stateChanged(EventObject e) { + fireEvent(); + } + } + + public String toDebug(){ + StringBuilder buf = new StringBuilder(); + buf.append(String.format("====== Dumping ConfigurationSet for: '%s' of type: %s ======\n", this.component.getName(), this.component.getClass().getSimpleName() )); + buf.append(String.format(" >> FlightConfigurationSet (%d configurations)\n", this.size() )); + + if( 0 == this.map.size() ){ + buf.append(String.format(" >> [%s]= %s\n", "*DEFAULT*", this.getDefault().toString() )); + }else{ + for( FlightConfigurationID loopFCID : this.getSortedConfigurationIDs()){ + String shortKey = loopFCID.getShortKey(); + + E inst = this.map.get(loopFCID); + if( this.isDefault(inst)){ + shortKey = "*"+shortKey+"*"; + } + buf.append(String.format(" >> [%s]= %s\n", shortKey, inst.toString() )); + } + } + return buf.toString(); + } + +} diff --git a/core/src/net/sf/openrocket/rocketcomponent/RecoveryDevice.java b/core/src/net/sf/openrocket/rocketcomponent/RecoveryDevice.java index 4f252d52c..441e27a4f 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/RecoveryDevice.java +++ b/core/src/net/sf/openrocket/rocketcomponent/RecoveryDevice.java @@ -25,10 +25,10 @@ public abstract class RecoveryDevice extends MassObject implements FlightConfigu private Material.Surface material; - private FlightConfigurationSet deploymentConfigurations; + private ParameterSet deploymentConfigurations; public RecoveryDevice() { - this.deploymentConfigurations = new FlightConfigurationSet(this, ComponentChangeEvent.EVENT_CHANGE, new DeploymentConfiguration()); + this.deploymentConfigurations = new ParameterSet(this, ComponentChangeEvent.EVENT_CHANGE, new DeploymentConfiguration()); setMaterial(Application.getPreferences().getDefaultComponentMaterial(RecoveryDevice.class, Material.Type.SURFACE)); } @@ -85,7 +85,7 @@ public abstract class RecoveryDevice extends MassObject implements FlightConfigu fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); } - public FlightConfigurationSet getDeploymentConfigurations() { + public ParameterSet getDeploymentConfigurations() { return deploymentConfigurations; } @@ -113,7 +113,7 @@ public abstract class RecoveryDevice extends MassObject implements FlightConfigu @Override protected RocketComponent copyWithOriginalID() { RecoveryDevice copy = (RecoveryDevice) super.copyWithOriginalID(); - copy.deploymentConfigurations = new FlightConfigurationSet(deploymentConfigurations, + copy.deploymentConfigurations = new ParameterSet(deploymentConfigurations, copy, ComponentChangeEvent.EVENT_CHANGE); return copy; } diff --git a/core/src/net/sf/openrocket/rocketcomponent/Rocket.java b/core/src/net/sf/openrocket/rocketcomponent/Rocket.java index 3f7fc7d2a..9115f5834 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/Rocket.java +++ b/core/src/net/sf/openrocket/rocketcomponent/Rocket.java @@ -66,7 +66,7 @@ public class Rocket extends RocketComponent { // Flight configuration list - private FlightConfigurationSet configurations; + private FlightConfigurationSet configSet; // Does the rocket have a perfect finish (a notable amount of laminar flow) private boolean perfectFinish = false; @@ -84,7 +84,7 @@ public class Rocket extends RocketComponent { functionalModID = modID; FlightConfiguration defaultConfiguration = new FlightConfiguration( null, this); - this.configurations = new FlightConfigurationSet(this, ComponentChangeEvent.ALL_CHANGE, defaultConfiguration); + this.configSet = new FlightConfigurationSet(this, ComponentChangeEvent.ALL_CHANGE, defaultConfiguration); } public String getDesigner() { @@ -281,8 +281,8 @@ public class Rocket extends RocketComponent { @Override public Rocket copyWithOriginalID() { Rocket copy = (Rocket) super.copyWithOriginalID(); - copy.configurations = new FlightConfigurationSet( - this.configurations, copy, ComponentChangeEvent.ALL_CHANGE); + copy.configSet = new FlightConfigurationSet( + this.configSet, copy, ComponentChangeEvent.ALL_CHANGE); copy.resetListeners(); return copy; @@ -319,8 +319,8 @@ public class Rocket extends RocketComponent { this.refType = r.refType; this.customReferenceLength = r.customReferenceLength; - this.configurations = new FlightConfigurationSet( - r.configurations, this, ComponentChangeEvent.ALL_CHANGE); + this.configSet = new FlightConfigurationSet( + r.configSet, this, ComponentChangeEvent.ALL_CHANGE); this.perfectFinish = r.perfectFinish; this.checkComponentStructure(); @@ -499,17 +499,17 @@ public class Rocket extends RocketComponent { */ public FlightConfiguration getDefaultConfiguration() { checkState(); - return this.configurations.getDefault(); + return this.configSet.getDefault(); } public FlightConfiguration createFlightConfiguration( final FlightConfigurationID fcid) { checkState(); FlightConfiguration nextConfig = null; - if( configurations.containsKey(fcid)){ - nextConfig = this.configurations.get(fcid); + if( configSet.containsKey(fcid)){ + nextConfig = this.configSet.get(fcid); }else{ nextConfig = new FlightConfiguration(fcid, this); - this.configurations.set(fcid, nextConfig); + this.configSet.set(fcid, nextConfig); } this.setFlightConfiguration( fcid, nextConfig ); @@ -518,16 +518,16 @@ public class Rocket extends RocketComponent { } public int getConfigurationCount(){ - return this.configurations.size(); + return this.configSet.size(); } - public FlightConfigurationSet getConfigurationSet(){ + public ParameterSet getConfigurationSet(){ checkState(); - return this.configurations; + return this.configSet; } public List getSortedConfigurationIDs(){ - return configurations.getSortedConfigurationIDs(); + return configSet.getSortedConfigurationIDs(); } @@ -543,7 +543,7 @@ public class Rocket extends RocketComponent { return; // Get current configuration: - this.configurations.set(fcid, null); + this.configSet.set(fcid, null); fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); } @@ -556,7 +556,7 @@ public class Rocket extends RocketComponent { */ public boolean containsFlightConfigurationID(FlightConfigurationID id) { checkState(); - FlightConfiguration config = configurations.get( id); + FlightConfiguration config = configSet.get( id); return (null != config); } @@ -597,7 +597,7 @@ public class Rocket extends RocketComponent { */ public FlightConfiguration getFlightConfiguration(final FlightConfigurationID id) { checkState(); - return this.configurations.get(id); + return this.configSet.get(id); } @@ -614,7 +614,7 @@ public class Rocket extends RocketComponent { // silently ignore return; }else{ - configurations.set(fcid, newConfig); + configSet.set(fcid, newConfig); } fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE); } diff --git a/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java b/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java index 7a3530cb2..fb69179fe 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java +++ b/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java @@ -1358,25 +1358,15 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab /** * Removes a child from the rocket component tree. + * (redirect to the removed-by-component * * @param n remove the n'th child. * @throws IndexOutOfBoundsException if n is out of bounds */ public final void removeChild(int n) { checkState(); - RocketComponent component = children.remove(n); - component.parent = null; - - if (component instanceof AxialStage) { - AxialStage nStage = (AxialStage) component; - this.getRocket().forgetStage(nStage); - } - - this.checkComponentStructure(); - component.checkComponentStructure(); - - updateBounds(); - fireAddRemoveEvent(component); + RocketComponent component = this.getChild(n); + this.removeChild(component); } /** @@ -1391,9 +1381,15 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab component.checkComponentStructure(); + if (children.remove(component)) { component.parent = null; + if (component instanceof AxialStage) { + AxialStage stage = (AxialStage) component; + this.getRocket().forgetStage(stage); + } + this.checkComponentStructure(); component.checkComponentStructure(); diff --git a/core/test/net/sf/openrocket/rocketcomponent/ConfigurationTest.java b/core/test/net/sf/openrocket/rocketcomponent/ConfigurationTest.java index 5dfca93da..2286ed633 100644 --- a/core/test/net/sf/openrocket/rocketcomponent/ConfigurationTest.java +++ b/core/test/net/sf/openrocket/rocketcomponent/ConfigurationTest.java @@ -191,7 +191,7 @@ public class ConfigurationTest extends BaseTestCase { // test explicitly setting all stages up to second stage active config.setOnlyStage(1); - assertThat(config.toDebugDetail() + "Setting single stage active: ", config.isStageActive(1), equalTo(true)); + assertThat(config.toStageListDetail() + "Setting single stage active: ", config.isStageActive(1), equalTo(true)); config.clearOnlyStage(0); assertThat(" deactivate stage #0: ", config.isStageActive(0), equalTo(false)); diff --git a/swing/src/net/sf/openrocket/gui/adaptors/EnumModel.java b/swing/src/net/sf/openrocket/gui/adaptors/EnumModel.java index 4a7b49f98..0dee97fef 100644 --- a/swing/src/net/sf/openrocket/gui/adaptors/EnumModel.java +++ b/swing/src/net/sf/openrocket/gui/adaptors/EnumModel.java @@ -7,8 +7,6 @@ import javax.swing.AbstractListModel; import javax.swing.ComboBoxModel; import javax.swing.MutableComboBoxModel; -import org.jfree.util.Log; - import net.sf.openrocket.util.ChangeSource; import net.sf.openrocket.util.Reflection; import net.sf.openrocket.util.StateChangeListener; @@ -131,8 +129,6 @@ public class EnumModel> extends AbstractListModel this.fireContentsChanged(this, 0, values.length); } } - - @Override public String toString() { diff --git a/swing/src/net/sf/openrocket/gui/adaptors/FlightConfigurationModel.java b/swing/src/net/sf/openrocket/gui/adaptors/ParameterSetModel.java similarity index 73% rename from swing/src/net/sf/openrocket/gui/adaptors/FlightConfigurationModel.java rename to swing/src/net/sf/openrocket/gui/adaptors/ParameterSetModel.java index 90b13b30f..e3c1a3dcd 100644 --- a/swing/src/net/sf/openrocket/gui/adaptors/FlightConfigurationModel.java +++ b/swing/src/net/sf/openrocket/gui/adaptors/ParameterSetModel.java @@ -11,55 +11,54 @@ import javax.swing.event.ListDataEvent; import javax.swing.event.ListDataListener; import net.sf.openrocket.rocketcomponent.ComponentChangeEvent; -import net.sf.openrocket.rocketcomponent.FlightConfiguration; +import net.sf.openrocket.rocketcomponent.FlightConfigurableParameter; import net.sf.openrocket.rocketcomponent.FlightConfigurationID; -import net.sf.openrocket.rocketcomponent.FlightConfigurationSet; -import net.sf.openrocket.rocketcomponent.Rocket; +import net.sf.openrocket.rocketcomponent.ParameterSet; import net.sf.openrocket.util.StateChangeListener; /** * A ComboBoxModel that contains a list of flight configurations. The list can * optionally contain a last element that opens up the configuration edit dialog. */ -public class FlightConfigurationModel implements ComboBoxModel, StateChangeListener { +public class ParameterSetModel> implements ComboBoxModel, StateChangeListener { //private static final Translator trans = Application.getTranslator(); //private RocketDescriptor descriptor = Application.getInjector().getInstance(RocketDescriptor.class); private EventListenerList listenerList = new EventListenerList(); - private FlightConfiguration config; - private final Rocket rocket; - List ids= new Vector(); - - public FlightConfigurationModel(FlightConfiguration config) { - this.config = config; - this.rocket = config.getRocket(); - config.addChangeListener(this); - } + private T selected; + private final ParameterSet sourceSet; + List idList= new Vector(); + public ParameterSetModel(ParameterSet set ) { + this.sourceSet = set; + this.selected = this.sourceSet.getDefault(); + } @Override public FlightConfigurationID getElementAt(int index) { - this.ids = rocket.getSortedConfigurationIDs(); + this.idList = this.sourceSet.getSortedConfigurationIDs(); + if (index < 0){ return FlightConfigurationID.ERROR_CONFIGURATION_FCID; - }else if ( index >= this.ids.size()){ + }else if ( index >= this.idList.size()){ return FlightConfigurationID.ERROR_CONFIGURATION_FCID; } - return this.ids.get(index); + return this.idList.get(index); } @Override public int getSize() { - return this.ids.size(); + this.idList = this.sourceSet.getSortedConfigurationIDs(); + return this.idList.size(); } @Override public Object getSelectedItem() { - return config.getFlightConfigurationID(); + return selected; } @Override @@ -68,14 +67,13 @@ public class FlightConfigurationModel implements ComboBoxModel psm = new ParameterSetModel( configuration.getRocket().getConfigurationSet()); + JComboBox combo = new JComboBox(psm); + panel.add(combo, "wrap"); // Tabbed pane diff --git a/swing/src/net/sf/openrocket/gui/dialogs/flightconfiguration/RenameConfigDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/flightconfiguration/RenameConfigDialog.java index f6d9102d5..a9422e5dd 100644 --- a/swing/src/net/sf/openrocket/gui/dialogs/flightconfiguration/RenameConfigDialog.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/flightconfiguration/RenameConfigDialog.java @@ -40,7 +40,7 @@ public class RenameConfigDialog extends JDialog { public void actionPerformed(ActionEvent e) { String newName = textbox.getText(); rocket.getFlightConfiguration(fcid).setName( newName); - rocket.getConfigurationSet().printDebug(); + System.err.println(rocket.getConfigurationSet().toDebug()); RenameConfigDialog.this.setVisible(false); } }); diff --git a/swing/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java b/swing/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java index ce48cbbaf..c00320064 100644 --- a/swing/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java +++ b/swing/src/net/sf/openrocket/gui/scalefigure/RocketFigure.java @@ -345,33 +345,21 @@ public class RocketFigure extends AbstractScaleFigure { Motor motor = curInstance.getMotor(); double motorLength = motor.getLength(); double motorRadius = motor.getDiameter() / 2; - - // Steps for instancing: - // 1) mountComponent has an instanced ancestor: - // 2) which may be an arbitrary number of levels up, so calling mount.parent.getInstances is not enough. - // 3) therefore .getLocation() will return all the instances of this owning component - // 4) Then, for each instance of the component, draw each cluster. RocketComponent mountComponent = ((RocketComponent) mount); + + // .getLocation() will return all the parent instances of this owning component, AND all of it's own instances as well. + // so, just draw a motor once for each Coordinate returned... Coordinate[] mountLocations = mountComponent.getLocations(); double mountLength = mountComponent.getLength(); - for ( Coordinate curInstanceLocation : mountLocations ){ - Coordinate[] motorPositions; - Coordinate[] clusterCenterTop = new Coordinate[]{ curInstanceLocation.add( mountLength - motorLength + mount.getMotorOverhang(), 0, 0)}; - - // old code... - // motorPositions = mountComponent.shiftCoordinates(clusterCenterTop); - - // new code - motorPositions = mountComponent.getLocations(); - System.err.println("the motors are probably being drawn wrong, and its probably from here.... "); - - for (int i = 0; i < motorPositions.length; i++) { - motorPositions[i] = transformation.transform(motorPositions[i]); - } + System.err.println("motors are drawing wrong... from here?"); + for ( Coordinate curMountLocation : mountLocations ){ + Coordinate curMotorLocation = curMountLocation.add( mountLength - motorLength + mount.getMotorOverhang(), 0, 0); + System.err.println("Translating from mount at "+curMountLocation+" to motor at "+curMotorLocation); - for (Coordinate coord : motorPositions) { + Coordinate coord = curMotorLocation; + { Shape s; if (currentViewType == RocketPanel.VIEW_TYPE.SideView) { s = new Rectangle2D.Double(EXTRA_SCALE * coord.x, diff --git a/swing/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java b/swing/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java index 8fbf7f9c4..4be799148 100644 --- a/swing/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java +++ b/swing/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java @@ -37,7 +37,7 @@ import net.sf.openrocket.aerodynamics.WarningSet; import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.document.Simulation; import net.sf.openrocket.gui.adaptors.DoubleModel; -import net.sf.openrocket.gui.adaptors.FlightConfigurationModel; +import net.sf.openrocket.gui.adaptors.ParameterSetModel; import net.sf.openrocket.gui.components.BasicSlider; import net.sf.openrocket.gui.components.StageSelector; import net.sf.openrocket.gui.components.UnitSelector; @@ -304,7 +304,12 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change JLabel label = new JLabel(trans.get("RocketPanel.lbl.Flightcfg")); label.setHorizontalAlignment(JLabel.RIGHT); add(label, "growx, right"); - add(new JComboBox(new FlightConfigurationModel(configuration)), "wrap"); + + // ?? this model should operate off of either: the rocket (or the FlightConfigurationSet contained in the rocket... ) + + ParameterSetModel psm = new ParameterSetModel( configuration.getRocket().getConfigurationSet()); + JComboBox flightConfigurationcomboBox = new JComboBox(psm); + add(flightConfigurationcomboBox, "wrap"); // Create slider and scroll pane diff --git a/swing/src/net/sf/openrocket/gui/simulation/SimulationEditDialog.java b/swing/src/net/sf/openrocket/gui/simulation/SimulationEditDialog.java index 8351667d5..b24545c86 100644 --- a/swing/src/net/sf/openrocket/gui/simulation/SimulationEditDialog.java +++ b/swing/src/net/sf/openrocket/gui/simulation/SimulationEditDialog.java @@ -21,10 +21,11 @@ import javax.swing.event.DocumentListener; import net.miginfocom.swing.MigLayout; import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.document.Simulation; -import net.sf.openrocket.gui.adaptors.FlightConfigurationModel; +import net.sf.openrocket.gui.adaptors.ParameterSetModel; import net.sf.openrocket.gui.util.GUIUtil; import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.rocketcomponent.FlightConfiguration; +import net.sf.openrocket.rocketcomponent.FlightConfigurationID; import net.sf.openrocket.simulation.SimulationOptions; import net.sf.openrocket.simulation.extension.SimulationExtension; import net.sf.openrocket.startup.Application; @@ -150,7 +151,9 @@ public class SimulationEditDialog extends JDialog { label.setToolTipText(trans.get("simedtdlg.lbl.ttip.Flightcfg")); panel.add(label, "growx 0, gapright para"); - JComboBox combo = new JComboBox(new FlightConfigurationModel(configuration)); + ParameterSetModel psm = new ParameterSetModel( configuration.getRocket().getConfigurationSet()); + JComboBox combo = new JComboBox(psm); + //// Select the motor configuration to use. combo.setToolTipText(trans.get("simedtdlg.combo.ttip.Flightcfg")); combo.addActionListener(new ActionListener() {