[Bugfix] Fixing Configuration Editing UI

- Default Parameter in FlightConfigurationSet<T> is now totally separate from those listed in the map.
    - note: the default option =/= the option for the default FlightConfiguration ...
    - defaultValue is now included in the map, with a dedicated static final key.
    - defaultValue may only be replaced, not removed.
- "Select Ignition" button now functions correctly
- "Reset Ignition" button functions correctly
This commit is contained in:
Daniel_M_Williams 2015-10-15 11:33:33 -04:00
parent b3c1c5fac1
commit 55acf6cebf
23 changed files with 320 additions and 212 deletions

View File

@ -51,7 +51,7 @@ class IgnitionConfigurationHandler extends AbstractElementHandler {
if (element.equals("ignitionevent")) {
for (IgnitionEvent ie : IgnitionEvent.events) {
for (IgnitionEvent ie : IgnitionEvent.values()) {
if (ie.equals(content)) {
ignitionEvent = ie;
break;

View File

@ -61,7 +61,7 @@ class MotorConfigurationHandler extends AbstractElementHandler {
}
if ("true".equals(attributes.remove("default"))) {
rocket.getConfigurationSet().resetDefault(fcid);
rocket.getConfigurationSet().reset(fcid);
}
super.closeElement(element, attributes, content, warnings);

View File

@ -15,6 +15,8 @@ import net.sf.openrocket.motor.MotorInstance;
import net.sf.openrocket.rocketcomponent.FlightConfigurationID;
import net.sf.openrocket.rocketcomponent.IgnitionEvent;
import net.sf.openrocket.rocketcomponent.MotorMount;
import net.sf.openrocket.rocketcomponent.Rocket;
import net.sf.openrocket.rocketcomponent.RocketComponent;
class MotorMountHandler extends AbstractElementHandler {
private final DocumentLoadingContext context;
@ -57,6 +59,7 @@ class MotorMountHandler extends AbstractElementHandler {
@Override
public void closeElement(String element, HashMap<String, String> attributes,
String content, WarningSet warnings) throws SAXException {
// DEBUG ONLY
// System.err.println("closing MotorMount element: "+ element);
@ -72,20 +75,32 @@ class MotorMountHandler extends AbstractElementHandler {
MotorInstance motorInstance = motor.getNewInstance();
motorInstance.setEjectionDelay(motorHandler.getDelay(warnings));
mount.setMotorInstance(fcid, motorInstance);
Rocket rkt = ((RocketComponent)mount).getRocket();
rkt.createFlightConfiguration(fcid);
// // vvvvvvv DEBUG vvvvvvv
// System.err.println(" processing <motor> element:"+fcid.key);
// MotorInstance justSet = mount.getMotorInstance(fcid);
// System.err.println(" just set Motor: "+motor.getDesignation()+" to Mount: "+((RocketComponent)mount).getName()+".");
// String contains;
// if( justSet.isEmpty()){
// contains = "empty";
// }else{
// contains = justSet.getMotor().getDesignation();
// if( mount instanceof BodyTube ){
// System.err.println(" processing <"+element+"> element with mount: "+((RocketComponent)mount).getName()+" with content: "+content);
// MotorInstance justSet = mount.getMotorInstance(fcid);
// String shortKey = fcid.key.substring(0,8);
// String motorKey = justSet.getMotorID().toString().substring(0,8);
// String contains;
// if( justSet.isEmpty()){
// contains = "empty";
// }else{
// contains = justSet.getMotor().getDesignation();
// }
// System.err.println(" set( key:"+ shortKey + " to Motor: "+motorKey+ " containing: "+contains);
//
// // exhaustive part...
//
// ((BodyTube)mount).printMotorDebug( fcid );
//
// rkt.getConfigurationSet().printDebug();
// }
// System.err.println(" to Motor: "+justSet.getMotorID()+ " containing: "+contains);
// System.err.println(" mount now contains "+mount.getMotorCount()+" motors.");
// // ... well, we know it's at least 2 configurations now....
// // ^^^^^^^ DEBUG ^^^^^^^^
return;
}
@ -106,7 +121,7 @@ class MotorMountHandler extends AbstractElementHandler {
if (element.equals("ignitionevent")) {
IgnitionEvent event = null;
for (IgnitionEvent ie : IgnitionEvent.events) {
for (IgnitionEvent ie : IgnitionEvent.values()) {
if (ie.equals(content)) {
event = ie;
break;

View File

@ -38,6 +38,9 @@ public class MotorInstance implements FlightConfigurableParameter<MotorInstance>
protected MotorInstance() {
this.id = MotorInstanceId.EMPTY_ID;
ejectionDelay = 0.0;
ignitionEvent = IgnitionEvent.NEVER;
ignitionDelay = 0.0;
modID++;
}

View File

@ -12,10 +12,10 @@ public final class MotorInstanceId {
private final String componentId;
private final int number;
private final static String COMPONENT_ERROR_TEXT = "Error Motor Instance";
private final static String COMPONENT_ERROR_TEXT = "Error Motor Id";
private final static int ERROR_NUMBER = -1;
public final static MotorInstanceId ERROR_ID = new MotorInstanceId();
private final static String EMPTY_COMPONENT_TEXT = "Empty Motor Instance";
private final static String EMPTY_COMPONENT_TEXT = "Empty Motor Id";
private final static int EMPTY_NUMBER = 1;
public final static MotorInstanceId EMPTY_ID = new MotorInstanceId(EMPTY_COMPONENT_TEXT, EMPTY_NUMBER);
@ -71,6 +71,12 @@ public final class MotorInstanceId {
@Override
public String toString(){
return Integer.toString( this.hashCode());
if( this == ERROR_ID){
return "ERROR_ID";
}else if( this == EMPTY_ID){
return "EMPTY_ID";
}else{
return Integer.toString( this.hashCode());
}
}
}

View File

@ -461,8 +461,10 @@ public class BodyTube extends SymmetricComponent implements MotorMount, Coaxial
return new Coordinate(this.getLength() - motor.getLength() + this.getMotorOverhang());
}
public void printMotorDebug(){
this.motors.printDebug();
}
@Override
protected RocketComponent copyWithOriginalID() {

View File

@ -1,5 +1,7 @@
package net.sf.openrocket.rocketcomponent;
import java.util.List;
import net.sf.openrocket.util.ChangeSource;
/**
@ -60,6 +62,11 @@ public interface FlightConfigurable<E extends ChangeSource> extends FlightConfig
*/
public void set(FlightConfigurationID id, E value);
/**
*
* @return a sorted list of all the contained FlightConfigurationIDs
*/
public List<FlightConfigurationID> getSortedConfigurationIDs();
/**
* Return whether a specific flight configuration ID is using the
@ -75,7 +82,7 @@ public interface FlightConfigurable<E extends ChangeSource> extends FlightConfig
*
* @param id the flight configuration ID
*/
public void resetDefault(FlightConfigurationID id);
public void reset(FlightConfigurationID id);
/**
* Return the number of specific flight configurations other than the default.

View File

@ -63,7 +63,7 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
private int modID = 0;
public FlightConfiguration( ){
this.fcid = FlightConfigurationID.ERROR_CONFIGURATION_ID;
this.fcid = FlightConfigurationID.ERROR_CONFIGURATION_FCID;
this.rocket = new Rocket();
this.configurationName = "<ERROR: FlightConfiguration created without an id or rocket instance. ERROR!> ";
}
@ -194,22 +194,29 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
log.error( "Detected inactive component in list returned from <config>.getActiveComponents()");
}
// DEVEL
// see planning notes...
if ( comp instanceof MotorMount ){
MotorMount mount = (MotorMount)comp;
//if( mount.isActive() ){
MotorInstance inst = mount.getMotorInstance(this.fcid);
// if( mount instanceof Clusterable ){
// if( 1 < comp.getInstanceCount() ){
// if comp is clustered, it will be clustered from the innerTube, no?
//List<MotorInstance> instanceList = mount.getMotorInstance(this.fcid);
MotorInstance inst = mount.getMotorInstance(this.fcid);
if(( mount.isMotorMount()) && ( MotorInstance.EMPTY_INSTANCE == inst)){
// DEVEL
log.error("Detected 'Empty' Motor Instance on Activated MotorMount: "+this.getName()+" / "+comp.getName()+" / (#)");
continue;
}
// // vvvv DEVEL vvvv
//
// if(( mount.isMotorMount()) && ( MotorInstance.EMPTY_INSTANCE == inst)){
// if( mount instanceof BodyTube){
// MotorInstance bt_inst = ((BodyTube)mount).getMotorInstance(this.fcid);
// log.error("Detected EMPTY_INSTANCE in config: "+this.fcid.key.substring(0,8)+", mount: \""+comp.getName()+"\"");
// ((BodyTube)mount).printMotorDebug();
// }
// continue;
// }
// // ^^^^ DEVEL ^^^^
// motors go inactive after burnout, so we
if (inst.isActive()){
@ -457,7 +464,7 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
return;
}else if( "".equals(newName)){
return;
}else if( this.getFlightConfigurationID().equals( FlightConfigurationID.DEFAULT_CONFIGURATION_ID)){
}else if( this.getFlightConfigurationID().equals( FlightConfigurationID.DEFAULT_CONFIGURATION_FCID)){
this.configurationName = FlightConfiguration.DEFAULT_CONFIGURATION_NAME;
return;
}else if( ! this.getFlightConfigurationID().isValid()){

View File

@ -10,11 +10,13 @@ import java.util.UUID;
public final class FlightConfigurationID implements Comparable<FlightConfigurationID> {
final public String key;
private final static String ERROR_CONFIGURATION_KEY = "j567uryk2489yfjbr8i1fi";
private final static String DEFAULT_CONFIGURATION_KEY = "default_configuration_662002";
private final static String ERROR_CONFIGURATION_KEYTEXT = "j567uryk2489yfjbr8i1fi";
private final static String DEFAULT_CONFIGURATION_KEYTEXT = "default_configuration_662002";
private final static String DEFAULT_VALUE_KEYTEXT = "default_value_567866";
public final static FlightConfigurationID ERROR_CONFIGURATION_ID = new FlightConfigurationID( FlightConfigurationID.ERROR_CONFIGURATION_KEY);
public final static FlightConfigurationID DEFAULT_CONFIGURATION_ID = new FlightConfigurationID( FlightConfigurationID.DEFAULT_CONFIGURATION_KEY );
public final static FlightConfigurationID ERROR_CONFIGURATION_FCID = new FlightConfigurationID( FlightConfigurationID.ERROR_CONFIGURATION_KEYTEXT);
public final static FlightConfigurationID DEFAULT_CONFIGURATION_FCID = new FlightConfigurationID( FlightConfigurationID.DEFAULT_CONFIGURATION_KEYTEXT );
public final static FlightConfigurationID DEFAULT_VALUE_FCID = new FlightConfigurationID( FlightConfigurationID.DEFAULT_VALUE_KEYTEXT );
public FlightConfigurationID() {
this(UUID.randomUUID().toString());
@ -22,9 +24,9 @@ public final class FlightConfigurationID implements Comparable<FlightConfigurati
public FlightConfigurationID(final String _val) {
if (null == _val){
this.key = FlightConfigurationID.ERROR_CONFIGURATION_KEY;
this.key = FlightConfigurationID.ERROR_CONFIGURATION_KEYTEXT;
}else if (5 >_val.length()){
this.key = FlightConfigurationID.ERROR_CONFIGURATION_KEY;
this.key = FlightConfigurationID.ERROR_CONFIGURATION_KEYTEXT;
} else {
// vv temp vv
String temp_val = _val;
@ -60,7 +62,7 @@ public final class FlightConfigurationID implements Comparable<FlightConfigurati
}
public boolean isValid() {
if (this.key.intern() == FlightConfigurationID.ERROR_CONFIGURATION_KEY) {
if (this.key.intern() == FlightConfigurationID.ERROR_CONFIGURATION_KEYTEXT) {
return false;
}
@ -70,6 +72,15 @@ public final class FlightConfigurationID implements Comparable<FlightConfigurati
public int length() {
return this.key.length();
}
public String toShortKey(){
if( this == DEFAULT_VALUE_FCID ){
return "DEFVAL";
}else if( this == FlightConfigurationID.DEFAULT_CONFIGURATION_FCID){
return "DEFCONFIG";
}
return this.key.substring(0,8);
}
@Override
public String toString() {

View File

@ -3,8 +3,10 @@ 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.Set;
import java.util.Vector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -21,11 +23,11 @@ import net.sf.openrocket.util.Utils;
public class FlightConfigurationSet<E extends FlightConfigurableParameter<E>> implements FlightConfigurable<E> {
private static final Logger log = LoggerFactory.getLogger(FlightConfigurationSet.class);
private final HashMap<FlightConfigurationID, E> map = new HashMap<FlightConfigurationID, E>();
private E defaultValue = null;
protected final HashMap<FlightConfigurationID, E> map = new HashMap<FlightConfigurationID, E>();
protected final static FlightConfigurationID DEFAULT_VALUE_FCID = FlightConfigurationID.DEFAULT_VALUE_FCID;
private final RocketComponent component;
private final int eventType;
protected final RocketComponent component;
protected final int eventType;
private final Listener listener = new Listener();
@ -40,13 +42,9 @@ public class FlightConfigurationSet<E extends FlightConfigurableParameter<E>> im
this.component = component;
this.eventType = eventType;
this.defaultValue = _defaultValue;
if ( null == defaultValue ) {
throw new NullPointerException("defaultValue is null");
}
this.map.put( FlightConfigurationID.DEFAULT_CONFIGURATION_ID, defaultValue );
this.map.put( DEFAULT_VALUE_FCID, _defaultValue );
add(defaultValue);
addListener(_defaultValue);
}
@ -60,7 +58,7 @@ public class FlightConfigurationSet<E extends FlightConfigurableParameter<E>> im
this.component = component;
this.eventType = eventType;
this.defaultValue = flightConfiguration.defaultValue.clone();
this.map.put( DEFAULT_VALUE_FCID, flightConfiguration.getDefault().clone());
for (FlightConfigurationID key : flightConfiguration.map.keySet()) {
this.map.put(key, flightConfiguration.map.get(key).clone());
}
@ -72,21 +70,18 @@ public class FlightConfigurationSet<E extends FlightConfigurableParameter<E>> im
@Override
public E getDefault(){
return defaultValue;
return this.map.get(DEFAULT_VALUE_FCID);
}
@Override
public void setDefault(E value) {
if (value == null) {
throw new NullPointerException("value is null");
public void setDefault(E nextDefaultValue) {
if (nextDefaultValue == null) {
throw new NullPointerException("new Default Value is null");
}
if( this.isDefault(value)){
if( this.isDefault(nextDefaultValue)){
return;
}
remove(this.defaultValue);
this.defaultValue = value;
add(value);
fireEvent();
this.set( DEFAULT_VALUE_FCID, nextDefaultValue);
}
@Override
@ -123,11 +118,21 @@ public class FlightConfigurationSet<E extends FlightConfigurableParameter<E>> im
if (map.containsKey(id)) {
toReturn = map.get(id);
} else {
toReturn = defaultValue;
toReturn = this.getDefault();
}
return toReturn;
}
@Override
public List<FlightConfigurationID> getSortedConfigurationIDs(){
Vector<FlightConfigurationID> toReturn = new Vector<FlightConfigurationID>();
toReturn.addAll( this.getIDs() );
toReturn.sort( null );
return toReturn;
}
public Set<FlightConfigurationID> getIDs(){
return this.map.keySet();
}
@ -136,93 +141,67 @@ public class FlightConfigurationSet<E extends FlightConfigurableParameter<E>> im
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) {
if ( nextValue == null) {
// null value means to delete this fcid
this.remove(fcid);
if ( DEFAULT_VALUE_FCID == fcid ) {
// NEVER delete the default value....
return;
}
E previousValue = map.remove(fcid);
removeListener(previousValue);
}else{
E previousValue = map.put(fcid, nextValue);
remove(previousValue);
if (previousValue == this.defaultValue) {
this.defaultValue = nextValue;
}
add(nextValue);
removeListener(previousValue);
addListener(nextValue);
}
fireEvent();
}
public boolean isDefault(E _value) {
return (Utils.equals(this.defaultValue, _value));
public boolean isDefault(E testVal) {
return (Utils.equals( this.getDefault(), testVal));
}
@Override
public boolean isDefault(FlightConfigurationID id) {
return (this.defaultValue == map.get(id));
public boolean isDefault( FlightConfigurationID fcid) {
return (getDefault() == map.get(fcid));
}
@Override
public void resetDefault(FlightConfigurationID id) {
if( null == id){
this.resetDefault();
}else if( !id.isValid()){
throw new IllegalStateException(" Attempt to reset the default value on with an invalid key: "+id.toString());
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;
}
E previous = map.get(id);
remove(previous);
if ( previous == this.defaultValue ) {
this.defaultValue = null;
resetDefault();
}
fireEvent();
}
private void resetDefault(){
if( 0 == this.map.keySet().size()){
throw new IllegalStateException(" Attempt to reset the default value on an empty configurationSet.");
}
FlightConfigurationID firstFCID = map.keySet().iterator().next();
this.defaultValue = map.get( firstFCID);
}
private void fireEvent() {
component.fireComponentChangeEvent(eventType);
}
@Override
public void cloneFlightConfiguration(FlightConfigurationID oldConfigId, FlightConfigurationID newConfigId) {
if (isDefault(oldConfigId)) {
this.resetDefault(newConfigId);
} else {
E original = this.get(oldConfigId);
this.set(newConfigId, original.clone());
}
// clones the ENTRIES for the given fcid's.
E oldValue = this.get(oldConfigId);
this.set(newConfigId, oldValue.clone());
fireEvent();
}
private void add(E value) {
private void addListener(E value) {
if (value != null) {
value.addChangeListener(listener);
}
}
public void remove(FlightConfigurationID fcid) {
// enforce at least one value in the set
if( 1 < this.map.size() ){
this.map.remove(fcid);
if( this.isDefault(fcid)){
this.defaultValue = map.values().iterator().next();
}
}else{
log.warn(" attempted to remove last element from the FlightConfigurationSet<"+this.defaultValue.getClass().getSimpleName()+">. Action not allowed. ");
return;
}
}
private void remove(E value) {
private void removeListener(E value) {
if (value != null) {
value.removeChangeListener(listener);
}
@ -236,4 +215,28 @@ public class FlightConfigurationSet<E extends FlightConfigurableParameter<E>> im
}
}
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)");
for( FlightConfigurationID loopFCID : this.map.keySet()){
String shortKey = loopFCID.toShortKey();
E inst = this.map.get(loopFCID);
if( this.isDefault(inst)){
shortKey = "*"+shortKey+"*";
}
String designation;
if( inst instanceof FlightConfiguration){
FlightConfiguration fc = (FlightConfiguration) inst;
designation = fc.getName();
}else{
designation = inst.toString();
}
System.err.println(" >> ["+shortKey+"]= "+designation);
}
}
}

View File

@ -6,35 +6,29 @@ import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.simulation.FlightEvent;
import net.sf.openrocket.startup.Application;
public class IgnitionEvent {
public enum IgnitionEvent {
private static final Translator trans = Application.getTranslator();
public final String name;
private final String key;
protected String description=null;
public static final IgnitionEvent AUTOMATIC = new IgnitionEvent( "AUTOMATIC", "MotorMount.IgnitionEvent.AUTOMATIC"){
//// Automatic (launch or ejection charge)
AUTOMATIC( "AUTOMATIC", "MotorMount.IgnitionEvent.AUTOMATIC"){
@Override
public boolean isActivationEvent( FlightEvent fe, RocketComponent source){
public boolean isActivationEvent(FlightEvent e, RocketComponent source) {
int count = source.getRocket().getStageCount();
int stage = source.getStageNumber();
if (stage == count - 1) {
return LAUNCH.isActivationEvent( fe, source);
} else {
return EJECTION_CHARGE.isActivationEvent( fe, source);
}
}
};
public static final IgnitionEvent LAUNCH = new IgnitionEvent( "LAUNCH", "MotorMount.IgnitionEvent.LAUNCH"){
return LAUNCH.isActivationEvent(e, source);
} else {
return EJECTION_CHARGE.isActivationEvent(e, source);
}
}
},
LAUNCH ( "LAUNCH", "MotorMount.IgnitionEvent.LAUNCH"){
@Override
public boolean isActivationEvent( FlightEvent fe, RocketComponent source){
return (fe.getType() == FlightEvent.Type.LAUNCH);
}
};
public static final IgnitionEvent EJECTION_CHARGE= new IgnitionEvent("EJECTION_CHARGE", "MotorMount.IgnitionEvent.EJECTION_CHARGE"){
},
EJECTION_CHARGE ("EJECTION_CHARGE", "MotorMount.IgnitionEvent.EJECTION_CHARGE"){
@Override
public boolean isActivationEvent( FlightEvent fe, RocketComponent source){
if (fe.getType() != FlightEvent.Type.EJECTION_CHARGE){
@ -44,9 +38,8 @@ public class IgnitionEvent {
int mount = source.getStageNumber();
return (mount + 1 == charge);
}
};
public static final IgnitionEvent BURNOUT = new IgnitionEvent("BURNOUT", "MotorMount.IgnitionEvent.BURNOUT"){
},
BURNOUT ("BURNOUT", "MotorMount.IgnitionEvent.BURNOUT"){
@Override
public boolean isActivationEvent( FlightEvent fe, RocketComponent source){
if (fe.getType() != FlightEvent.Type.BURNOUT)
@ -56,30 +49,33 @@ public class IgnitionEvent {
int mount = source.getStageNumber();
return (mount + 1 == charge);
}
};
public static final IgnitionEvent NEVER= new IgnitionEvent("NEVER", "MotorMount.IgnitionEvent.NEVER");
},
NEVER("NEVER", "MotorMount.IgnitionEvent.NEVER")
;
public static final IgnitionEvent[] events = {AUTOMATIC, LAUNCH, EJECTION_CHARGE, BURNOUT, NEVER};
private static final Translator trans = Application.getTranslator();
public final String name;
private final String key;
protected String description=null;
//public static final IgnitionEvent[] events = {AUTOMATIC, LAUNCH, EJECTION_CHARGE, BURNOUT, NEVER};
public boolean isActivationEvent( FlightEvent fe, RocketComponent source){
// default behavior. Also for the NEVER case.
return false;
}
public IgnitionEvent(final String _name, final String _key) {
private IgnitionEvent(final String _name, final String _key) {
this.name = _name;
this.key = _key;
this.description = trans.get(this.key);
}
public boolean equals( final String content){
String comparator = this.name.toLowerCase(Locale.ENGLISH).replaceAll("_", "");
return comparator.equals(content);
}
public String name(){
public String getName(){
return this.name;
}

View File

@ -33,7 +33,7 @@ public class InnerTube extends ThicknessRingComponent implements Clusterable, Ra
private double overhang = 0;
private boolean isActing;
private FlightConfigurationSet<MotorInstance> motors;
private MotorConfigurationSet motors;
/**
* Main constructor.
@ -248,7 +248,7 @@ public class InnerTube extends ThicknessRingComponent implements Clusterable, Ra
@Override
public boolean isDefaultMotorInstance( final MotorInstance testInstance){
return this.motors.getDefault() == testInstance;
return this.motors.isDefault( testInstance);
}
@Override
@ -343,7 +343,7 @@ public class InnerTube extends ThicknessRingComponent implements Clusterable, Ra
@Override
protected RocketComponent copyWithOriginalID() {
InnerTube copy = (InnerTube) super.copyWithOriginalID();
copy.motors = new FlightConfigurationSet<MotorInstance>(motors, copy, ComponentChangeEvent.MOTOR_CHANGE);
copy.motors = new MotorConfigurationSet(motors, copy, ComponentChangeEvent.MOTOR_CHANGE);
return copy;
}
@ -368,6 +368,9 @@ public class InnerTube extends ThicknessRingComponent implements Clusterable, Ra
return copy;
}
public void printMotorDebug( FlightConfigurationID fcid ){
this.motors.printDebug();
}
}

View File

@ -27,8 +27,46 @@ public class MotorConfigurationSet extends FlightConfigurationSet<MotorInstance>
@Override
public void setDefault(MotorInstance value) {
public void setDefault( MotorInstance value) {
throw new UnsupportedOperationException("Cannot change default value of motor configuration");
}
@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)");
for( FlightConfigurationID loopFCID : this.map.keySet()){
String shortKey = loopFCID.toShortKey();
MotorInstance curInstance = this.map.get(loopFCID);
String designation;
if( MotorInstance.EMPTY_INSTANCE == curInstance){
designation = "EMPTY_INSTANCE";
}else{
designation = curInstance.getMotor().getDesignation(curInstance.getEjectionDelay());
}
System.err.println(" >> ["+shortKey+"]= "+designation);
}
}
// public void printDebug(FlightConfigurationID curFCID){
// if( this.map.containsKey(curFCID)){
// // no-op
// }else{
// String shortKey = curFCID.toShortKey();
// MotorInstance curInstance= this.get(curFCID);
//
// String designation;
// if( MotorInstance.EMPTY_INSTANCE == curInstance){
// designation = "EMPTY_INSTANCE";
// }else{
// designation = curInstance.getMotor().getDesignation(curInstance.getEjectionDelay());
// }
// System.err.println(" Queried FCID:");
// System.err.println(" >> ["+shortKey+"]= "+designation);
// }
// }
}

View File

@ -7,7 +7,6 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Vector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -68,7 +67,6 @@ public class Rocket extends RocketComponent {
// Flight configuration list
private FlightConfigurationSet<FlightConfiguration> configurations;
private final Vector<FlightConfigurationID> ids = new Vector<FlightConfigurationID>();
// Does the rocket have a perfect finish (a notable amount of laminar flow)
private boolean perfectFinish = false;
@ -85,7 +83,7 @@ public class Rocket extends RocketComponent {
treeModID = modID;
functionalModID = modID;
FlightConfigurationID defaultFCID = FlightConfigurationID.DEFAULT_CONFIGURATION_ID;
FlightConfigurationID defaultFCID = FlightConfigurationID.DEFAULT_CONFIGURATION_FCID;
FlightConfiguration defaultConfiguration = new FlightConfiguration( defaultFCID, this);
this.configurations = new FlightConfigurationSet<FlightConfiguration>(this, ComponentChangeEvent.ALL_CHANGE, defaultConfiguration);
}
@ -528,22 +526,9 @@ public class Rocket extends RocketComponent {
checkState();
return this.configurations;
}
public FlightConfiguration getFlightConfig( final FlightConfigurationID fcid ){
checkState();
return this.configurations.get(fcid);
}
public Vector<FlightConfigurationID> getSortedConfigurationIDs(){
// if the configuration list has changed, refresh it.
if( configurations.size() != ids.size()){
this.ids.clear();
//this.ids = new Vector<FlightConfigurationID>( idSet );
this.ids.addAll( this.configurations.getIDs() );
this.ids .sort( null );
}
return this.ids;
public List<FlightConfigurationID> getSortedConfigurationIDs(){
return configurations.getSortedConfigurationIDs();
}
@ -613,7 +598,7 @@ public class Rocket extends RocketComponent {
*/
public FlightConfiguration getFlightConfiguration(final FlightConfigurationID id) {
checkState();
return configurations.get(id);
return this.configurations.get(id);
}

View File

@ -2,6 +2,7 @@ package net.sf.openrocket.gui.adaptors;
import java.util.EventObject;
import java.util.List;
import java.util.Vector;
import javax.swing.ComboBoxModel;
@ -29,7 +30,7 @@ public class FlightConfigurationModel implements ComboBoxModel<FlightConfigurati
private FlightConfiguration config;
private final Rocket rocket;
Vector<FlightConfigurationID> ids= new Vector<FlightConfigurationID>();
List<FlightConfigurationID> ids= new Vector<FlightConfigurationID>();
public FlightConfigurationModel(FlightConfiguration config) {
this.config = config;
@ -43,9 +44,9 @@ public class FlightConfigurationModel implements ComboBoxModel<FlightConfigurati
this.ids = rocket.getSortedConfigurationIDs();
if (index < 0){
return FlightConfigurationID.ERROR_CONFIGURATION_ID;
return FlightConfigurationID.ERROR_CONFIGURATION_FCID;
}else if ( index >= this.ids.size()){
return FlightConfigurationID.ERROR_CONFIGURATION_ID;
return FlightConfigurationID.ERROR_CONFIGURATION_FCID;
}
return this.ids.get(index);

View File

@ -16,6 +16,7 @@ import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.gui.SpinnerEditor;
import net.sf.openrocket.gui.adaptors.BooleanModel;
import net.sf.openrocket.gui.adaptors.DoubleModel;
import net.sf.openrocket.gui.adaptors.EnumModel;
import net.sf.openrocket.gui.components.BasicSlider;
import net.sf.openrocket.gui.components.StyledLabel;
import net.sf.openrocket.gui.components.UnitSelector;
@ -70,9 +71,9 @@ public class MotorConfig extends JPanel {
MotorInstance motorInstance = mount.getDefaultMotorInstance();
JComboBox<IgnitionEvent> combo = new JComboBox<IgnitionEvent>( IgnitionEvent.events );
panel.add(combo, "growx, wrap");
final EnumModel<IgnitionEvent> igEvModel = new EnumModel<IgnitionEvent>(motorMount, "IgnitionEvent", IgnitionEvent.values());
final JComboBox<IgnitionEvent> eventBox = new JComboBox<IgnitionEvent>( igEvModel);
panel.add(eventBox , "growx, wrap");
// ... and delay
//// plus

View File

@ -4,6 +4,7 @@ import java.awt.Dialog;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Iterator;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
@ -15,14 +16,18 @@ import javax.swing.JRadioButton;
import javax.swing.JSpinner;
import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.formatting.RocketDescriptor;
import net.sf.openrocket.gui.SpinnerEditor;
import net.sf.openrocket.gui.adaptors.DoubleModel;
import net.sf.openrocket.gui.adaptors.EnumModel;
import net.sf.openrocket.gui.util.GUIUtil;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.motor.MotorInstance;
import net.sf.openrocket.rocketcomponent.FlightConfigurationID;
import net.sf.openrocket.rocketcomponent.IgnitionEvent;
import net.sf.openrocket.rocketcomponent.MotorMount;
import net.sf.openrocket.rocketcomponent.Rocket;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.unit.UnitGroup;
@ -31,31 +36,31 @@ public class IgnitionSelectionDialog extends JDialog {
private static final Translator trans = Application.getTranslator();
//private RocketDescriptor descriptor = Application.getInjector().getInstance(RocketDescriptor.class);
private RocketDescriptor descriptor = Application.getInjector().getInstance(RocketDescriptor.class);
private MotorMount curMount;
private MotorInstance destMotorInstance;
private MotorInstance curMotorInstance;
private IgnitionEvent startIgnEvent;
private double ignitionDelay;
private IgnitionEvent startIgnitionEvent;
private double startIgnitionDelay;
public IgnitionSelectionDialog(Window parent, final FlightConfigurationID curFCID, MotorMount _mount) {
super(parent, trans.get("edtmotorconfdlg.title.Selectignitionconf"), Dialog.ModalityType.APPLICATION_MODAL);
curMount = _mount;
destMotorInstance = curMount.getMotorInstance(curFCID);
startIgnEvent = destMotorInstance.getIgnitionEvent();
ignitionDelay = destMotorInstance.getIgnitionDelay();
final MotorInstance defaultMotorInstance = curMount.getDefaultMotorInstance();
curMotorInstance = curMount.getMotorInstance(curFCID);
startIgnitionEvent = curMotorInstance.getIgnitionEvent();
startIgnitionDelay = curMotorInstance.getIgnitionDelay();
JPanel panel = new JPanel(new MigLayout("fill"));
// Edit default or override option
boolean isDefault = curMount.isDefaultMotorInstance( destMotorInstance );
boolean isDefault = curMount.isDefaultMotorInstance( curMotorInstance );
panel.add(new JLabel(trans.get("IgnitionSelectionDialog.opt.title")), "span, wrap rel");
final JRadioButton defaultButton = new JRadioButton(trans.get("IgnitionSelectionDialog.opt.default"), isDefault);
panel.add(defaultButton, "span, gapleft para, wrap rel");
String str = trans.get("IgnitionSelectionDialog.opt.override");
//str = str.replace("{0}", descriptor.format(rocket, id));
Rocket rkt = ((RocketComponent)_mount).getRocket();
str = str.replace("{0}", descriptor.format(rkt, curFCID));
final JRadioButton overrideButton = new JRadioButton(str, !isDefault);
panel.add(overrideButton, "span, gapleft para, wrap para");
@ -71,18 +76,16 @@ public class IgnitionSelectionDialog extends JDialog {
}
// Select ignition event
//// Ignition at:
panel.add(new JLabel(trans.get("MotorCfg.lbl.Ignitionat")), "");
final JComboBox<IgnitionEvent> eventBox = new JComboBox<IgnitionEvent>(IgnitionEvent.events);
//eventBox.setTit
final EnumModel<IgnitionEvent> igEvModel = new EnumModel<IgnitionEvent>(curMotorInstance, "IgnitionEvent", IgnitionEvent.values());
final JComboBox<IgnitionEvent> eventBox = new JComboBox<IgnitionEvent>( igEvModel);
panel.add(eventBox, "growx, wrap");
// ... and delay
// ... and delay
//// plus
panel.add(new JLabel(trans.get("MotorCfg.lbl.plus")), "gap indent, skip 1, span, split");
DoubleModel delay = new DoubleModel(destMotorInstance, "IgnitionDelay", UnitGroup.UNITS_SHORT_TIME, 0);
DoubleModel delay = new DoubleModel(curMotorInstance, "IgnitionDelay", UnitGroup.UNITS_SHORT_TIME, 0);
JSpinner spin = new JSpinner(delay.getSpinnerModel());
spin.setEditor(new SpinnerEditor(spin, 3));
panel.add(spin, "gap rel rel");
@ -98,14 +101,29 @@ public class IgnitionSelectionDialog extends JDialog {
public void actionPerformed(ActionEvent e) {
if (defaultButton.isSelected()) {
System.err.println("setting motor ignition to.... default values");
// change the default...
IgnitionEvent cie = curMotorInstance.getIgnitionEvent();
double cid = curMotorInstance.getIgnitionDelay();
// and change all remaining configs?
// this seems like odd behavior to me, but it matches the text on the UI dialog popup. -teyrana (equipoise@gmail.com)
Iterator<MotorInstance> iter = curMount.getMotorIterator();
while( iter.hasNext() ){
MotorInstance next = iter.next();
next.setIgnitionDelay( cid);
next.setIgnitionEvent( cie);
}
final MotorInstance defaultMotorInstance = curMount.getDefaultMotorInstance();
System.err.println("setting default motor ignition ("+defaultMotorInstance.getMotorID().toString()+") to: ");
System.err.println(" event: "+defaultMotorInstance.getIgnitionEvent()+" w/delay: "+defaultMotorInstance.getIgnitionDelay());
destMotorInstance.setIgnitionDelay( defaultMotorInstance.getIgnitionDelay());
destMotorInstance.setIgnitionEvent( defaultMotorInstance.getIgnitionEvent());
} else {
System.err.println("setting motor ignition to.... new values: ");
System.err.println(" "+destMotorInstance.getIgnitionEvent()+" w/ "+destMotorInstance.getIgnitionDelay());
}
// else {
// System.err.println("setting motor ignition to.... new values: ");
// //destMotorInstance.setIgnitionEvent((IgnitionEvent)eventBox.getSelectedItem());
// System.err.println(" "+curMotorInstance.getIgnitionEvent()+" w/ "+curMotorInstance.getIgnitionDelay());
// }
IgnitionSelectionDialog.this.setVisible(false);
}
});
@ -119,8 +137,8 @@ public class IgnitionSelectionDialog extends JDialog {
public void actionPerformed(ActionEvent e) {
IgnitionSelectionDialog.this.setVisible(false);
// if cancelled, reset to starting values
destMotorInstance.setIgnitionEvent( startIgnEvent );
destMotorInstance.setIgnitionDelay( ignitionDelay );
curMotorInstance.setIgnitionEvent( startIgnitionEvent );
curMotorInstance.setIgnitionDelay( startIgnitionDelay );
}
});

View File

@ -4,7 +4,6 @@ import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.util.EventObject;
import java.util.Vector;
import javax.swing.JComponent;
import javax.swing.JLabel;
@ -78,7 +77,8 @@ public abstract class FlightConfigurablePanel<T extends FlightConfigurableCompon
if ( col < 0 ) {
col = (table.getColumnCount() > 1) ? 1 : 0;
}
Vector<FlightConfigurationID> ids = rocket.getSortedConfigurationIDs();
java.util.List<FlightConfigurationID> ids = rocket.getSortedConfigurationIDs();
for( int rowNum = 0; rowNum < table.getRowCount(); rowNum++ ) {
FlightConfigurationID rowFCID = ids.get(rowNum );
if ( rowFCID.equals(selectedFCID) ) {
@ -163,7 +163,7 @@ public abstract class FlightConfigurablePanel<T extends FlightConfigurableCompon
// this really should be un-implemented.
//return new FlightConfigurationID((String) tableValue);
}
return FlightConfigurationID.ERROR_CONFIGURATION_ID;
return FlightConfigurationID.ERROR_CONFIGURATION_FCID;
}
protected abstract class FlightConfigurableCellRenderer extends DefaultTableCellRenderer {

View File

@ -26,7 +26,7 @@ public class FlightConfigurableTableModel<T extends FlightConfigurableComponent>
protected final Rocket rocket;
protected final Class<T> clazz;
private final List<T> components = new ArrayList<T>();
private Vector<FlightConfigurationID> ids = new Vector<FlightConfigurationID>();
private List<FlightConfigurationID> ids = new Vector<FlightConfigurationID>();
public FlightConfigurableTableModel(Class<T> clazz, Rocket rocket) {
super();
@ -66,7 +66,8 @@ public class FlightConfigurableTableModel<T extends FlightConfigurableComponent>
@Override
public int getRowCount() {
return rocket.getConfigurationSet().size();
// the -1 removes the DEFAULT_VALUE row, which is hidden.
return (rocket.getConfigurationCount()-1);
}
@Override
@ -106,8 +107,9 @@ public class FlightConfigurableTableModel<T extends FlightConfigurableComponent>
}
private FlightConfigurationID getConfigurationID(int rowNum) {
if( rocket.getConfigurationCount() != ids.size()){
if( rocket.getConfigurationCount() != (1+ ids.size() ) ){
this.ids = rocket.getSortedConfigurationIDs();
this.ids.remove(FlightConfigurationID.DEFAULT_VALUE_FCID);
}
return this.ids.get(rowNum);

View File

@ -127,6 +127,7 @@ public class FlightConfigurationPanel extends JPanel implements StateChangeListe
FlightConfiguration newConfig = new FlightConfiguration( newFCID, rocket );
rocket.setFlightConfiguration(newFCID, newConfig);
//System.err.println("Adding new config: "+newFCID.key+" called: "+newConfig.getName()+" (sz: "+newConfig?+")");
// Create a new simulation for this configuration.
createSimulationForNewConfiguration();
@ -139,15 +140,15 @@ public class FlightConfigurationPanel extends JPanel implements StateChangeListe
FlightConfiguration newConfig = oldConfig.clone();
FlightConfigurationID oldId = oldConfig.getFlightConfigurationID();
FlightConfigurationID newId = newConfig.getFlightConfigurationID();
String oldName = oldConfig.getName();
for (RocketComponent c : rocket) {
if (c instanceof FlightConfigurableComponent) {
((FlightConfigurableComponent) c).cloneFlightConfiguration(oldId, newId);
}
}
newConfig.setName( oldName+"2");
newConfig.setName( newId.key );
rocket.setFlightConfiguration(newId, newConfig);
// Create a new simulation for this configuration.
createSimulationForNewConfiguration();

View File

@ -280,8 +280,14 @@ public class MotorConfigurationPanel extends FlightConfigurablePanel<MotorMount>
protected JLabel format( MotorMount mount, FlightConfigurationID configId, JLabel l ) {
JLabel label = new JLabel();
label.setLayout(new BoxLayout(label, BoxLayout.X_AXIS));
MotorInstance curMotor = mount.getMotorInstance( configId);
String motorString = getMotorSpecification( curMotor );
// if( mount instanceof BodyTube ){
// System.err.println("Formatting Cell: fcid="+configId.key.substring(0, 8));
// ((BodyTube) mount).printMotorDebug();
// }
JLabel motorDescriptionLabel = new JLabel(motorString);
label.add(motorDescriptionLabel);
label.add( Box.createRigidArea(new Dimension(10,0)));

View File

@ -103,7 +103,7 @@ public class RecoveryConfigurationPanel extends FlightConfigurablePanel<Recovery
return;
}
FlightConfigurationID id = rocket.getDefaultConfiguration().getFlightConfigurationID();
c.getDeploymentConfigurations().resetDefault(id);
c.getDeploymentConfigurations().reset(id);
fireTableDataChanged();
}

View File

@ -107,8 +107,11 @@ public class SeparationConfigurationPanel extends FlightConfigurablePanel<AxialS
if (stage == null) {
return;
}
FlightConfigurationID id = rocket.getDefaultConfiguration().getFlightConfigurationID();
stage.getSeparationConfigurations().resetDefault(id);
// why?
FlightConfigurationID id = rocket.getDefaultConfiguration().getFlightConfigurationID();
stage.getSeparationConfigurations().reset(id);
fireTableDataChanged();
}
public void updateButtonState() {