+2010-10-09 Sampo Niskanen
+
+ * [BUG] Fixed conversion to freeform fin set
+ * Enhanced logging
+
+2010-10-08 Sampo Niskanen
+
+ * New components no longer look expandable in the component tree
+
2010-10-06 Sampo Niskanen
* Released version 1.1.3
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
+import net.sf.openrocket.logging.LogHelper;
+import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.BugException;
import net.sf.openrocket.util.ChangeSource;
import net.sf.openrocket.util.Reflection;
*/
public class BooleanModel extends AbstractAction implements ChangeListener {
-
+ private static final LogHelper log = Application.getLogger();
+
private final ChangeSource source;
private final String valueName;
private final List<Component> components = new ArrayList<Component>();
private final List<Boolean> componentEnableState = new ArrayList<Boolean>();
+ private String toString = null;
+
private int firing = 0;
private boolean oldValue;
this.source = source;
this.valueName = valueName;
- Method getter=null, setter=null;
-
+ Method getter = null, setter = null;
+
// Try get/is and set
try {
getter = source.getClass().getMethod("is" + valueName);
- } catch (NoSuchMethodException ignore) { }
+ } catch (NoSuchMethodException ignore) {
+ }
if (getter == null) {
try {
getter = source.getClass().getMethod("get" + valueName);
- } catch (NoSuchMethodException ignore) { }
+ } catch (NoSuchMethodException ignore) {
+ }
}
try {
- setter = source.getClass().getMethod("set" + valueName,boolean.class);
- } catch (NoSuchMethodException ignore) { }
+ setter = source.getClass().getMethod("set" + valueName, boolean.class);
+ } catch (NoSuchMethodException ignore) {
+ }
- if (getter==null || setter==null) {
- throw new IllegalArgumentException("get/is methods for boolean '"+valueName+
- "' not present in class "+source.getClass().getCanonicalName());
+ if (getter == null || setter == null) {
+ throw new IllegalArgumentException("get/is methods for boolean '" + valueName +
+ "' not present in class " + source.getClass().getCanonicalName());
}
-
+
getMethod = getter;
setMethod = setter;
Method e = null;
try {
e = source.getClass().getMethod("is" + valueName + "Enabled");
- } catch (NoSuchMethodException ignore) { }
+ } catch (NoSuchMethodException ignore) {
+ }
getEnabled = e;
oldValue = getValue();
public boolean getValue() {
try {
- return (Boolean)getMethod.invoke(source);
+ return (Boolean) getMethod.invoke(source);
} catch (IllegalAccessException e) {
- throw new BugException("getMethod execution error for source "+source,e);
+ throw new BugException("getMethod execution error for source " + source, e);
} catch (InvocationTargetException e) {
throw Reflection.handleWrappedException(e);
}
}
public void setValue(boolean b) {
+ log.debug("Setting value of " + this + " to " + b);
try {
- setMethod.invoke(source, new Object[] { (Boolean)b });
+ setMethod.invoke(source, new Object[] { (Boolean) b });
} catch (IllegalAccessException e) {
- throw new BugException("setMethod execution error for source "+source,e);
+ throw new BugException("setMethod execution error for source " + source, e);
} catch (InvocationTargetException e) {
throw Reflection.handleWrappedException(e);
}
private void updateEnableStatus() {
boolean state = getValue();
- for (int i=0; i < components.size(); i++) {
+ for (int i = 0; i < components.size(); i++) {
Component c = components.get(i);
boolean b = componentEnableState.get(i);
c.setEnabled(state == b);
}
-// @Override
-// public boolean isEnabled() {
-// if (getEnabled == null)
-// return true;
-// try {
-// return (Boolean)getEnabled.invoke(source);
-// } catch (IllegalAccessException e) {
-// throw new RuntimeException("getEnabled execution error for source "+source,e);
-// } catch (InvocationTargetException e) {
-// throw new RuntimeException("getEnabled execution error for source "+source,e);
-// }
-// }
-
private boolean getIsEnabled() {
if (getEnabled == null)
return true;
try {
- return (Boolean)getEnabled.invoke(source);
+ return (Boolean) getEnabled.invoke(source);
} catch (IllegalAccessException e) {
- throw new BugException("getEnabled execution error for source "+source,e);
+ throw new BugException("getEnabled execution error for source " + source, e);
} catch (InvocationTargetException e) {
throw Reflection.handleWrappedException(e);
}
}
-// @Override
-// public Object getValue(String key) {
-// if (key.equals(SELECTED_KEY)) {
-// return getValue();
-// }
-// return super.getValue(key);
-// }
-//
-// @Override
-// public void putValue(String key, Object value) {
-// if (firing > 0) // Ignore if currently firing event
-// return;
-// if (key.equals(SELECTED_KEY) && (value instanceof Boolean)) {
-// setValue((Boolean)value);
-// } else {
-// super.putValue(key, value);
-// }
-// updateEnableStatus();
-// }
-
-
@Override
public void stateChanged(ChangeEvent event) {
- if (firing > 0)
+ if (firing > 0) {
+ log.debug("Ignoring stateChanged of " + this + ", currently firing events");
return;
+ }
boolean v = getValue();
boolean e = getIsEnabled();
if (oldValue != v) {
+ log.debug("Value of " + this + " has changed to " + v + " oldValue=" + oldValue);
oldValue = v;
firing++;
this.putValue(SELECTED_KEY, getValue());
-// this.firePropertyChange(SELECTED_KEY, !v, v);
+ // this.firePropertyChange(SELECTED_KEY, !v, v);
updateEnableStatus();
firing--;
}
if (oldEnabled != e) {
+ log.debug("Enabled status of " + this + " has changed to " + e + " oldEnabled=" + oldEnabled);
oldEnabled = e;
setEnabled(e);
}
}
-
-
+
+
@Override
public void actionPerformed(ActionEvent e) {
- if (firing > 0)
+ if (firing > 0) {
+ log.debug("Ignoring actionPerformed of " + this + ", currently firing events");
return;
+ }
- boolean v = (Boolean)this.getValue(SELECTED_KEY);
+ boolean v = (Boolean) this.getValue(SELECTED_KEY);
+ log.user("Value of " + this + " changed to " + v + " oldValue=" + oldValue);
if (v != oldValue) {
firing++;
setValue(v);
@Override
public String toString() {
- return "BooleanModel["+source.getClass().getCanonicalName()+":"+valueName+"]";
+ if (toString == null) {
+ toString = "BooleanModel[" + source.getClass().getSimpleName() + ":" + valueName + "]";
+ }
+ return toString;
}
}
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
+import net.sf.openrocket.logging.LogHelper;
+import net.sf.openrocket.startup.Application;
import net.sf.openrocket.unit.Unit;
import net.sf.openrocket.unit.UnitGroup;
import net.sf.openrocket.util.BugException;
*/
public class DoubleModel implements ChangeListener, ChangeSource {
- private static final boolean DEBUG_LISTENERS = false;
+ private static final LogHelper log = Application.getLogger();
- public static final DoubleModel ZERO = new DoubleModel(0);
+ public static final DoubleModel ZERO = new DoubleModel(0);
+
//////////// JSpinner Model ////////////
/**
@Override
public Object getValue() {
return currentUnit.toUnit(DoubleModel.this.getValue());
-// return makeString(currentUnit.toUnit(DoubleModel.this.getValue()));
}
-
+
@Override
public void setValue(Object value) {
-
- System.out.println("setValue("+value+") called, valueName="+valueName+
- " firing="+firing);
-
- if (firing > 0) // Ignore, if called when model is sending events
+ if (firing > 0) {
+ // Ignore, if called when model is sending events
+ log.verbose("Ignoring call to SpinnerModel setValue for " + DoubleModel.this.toString() +
+ " value=" + value + ", currently firing events");
return;
- Number num = (Number)value;
+ }
+ Number num = (Number) value;
double newValue = num.doubleValue();
- DoubleModel.this.setValue(currentUnit.fromUnit(newValue));
+ double converted = currentUnit.fromUnit(newValue);
+ log.user("SpinnerModel setValue called for " + DoubleModel.this.toString() + " newValue=" + newValue +
+ " converted=" + converted);
+ DoubleModel.this.setValue(converted);
-// try {
-// double newValue = Double.parseDouble((String)value);
-// DoubleModel.this.setValue(currentUnit.fromUnit(newValue));
-// } catch (NumberFormatException e) {
-// DoubleModel.this.fireStateChanged();
-// };
}
@Override
public Object getNextValue() {
double d = currentUnit.toUnit(DoubleModel.this.getValue());
double max = currentUnit.toUnit(maxValue);
- if (MathUtil.equals(d,max))
+ if (MathUtil.equals(d, max))
return null;
d = currentUnit.getNextValue(d);
if (d > max)
d = max;
return d;
-// return makeString(d);
}
-
+
@Override
public Object getPreviousValue() {
double d = currentUnit.toUnit(DoubleModel.this.getValue());
double min = currentUnit.toUnit(minValue);
- if (MathUtil.equals(d,min))
+ if (MathUtil.equals(d, min))
return null;
d = currentUnit.getPreviousValue(d);
if (d < min)
d = min;
return d;
-// return makeString(d);
}
-
+
@Override
public Comparable<Double> getMinimum() {
public void addChangeListener(ChangeListener l) {
DoubleModel.this.addChangeListener(l);
}
-
+
@Override
public void removeChangeListener(ChangeListener l) {
DoubleModel.this.removeChangeListener(l);
}
-
-
-
+
+
+
//////////// JSlider model ////////////
private class ValueSliderModel implements BoundedRangeModel, ChangeListener {
* Use linear scale value = linear1 * x + linear0 when x < linearPosition
* Use quadratic scale value = quad2 * x^2 + quad1 * x + quad0 otherwise
*/
-
+
// Linear in range x <= linearPosition
private final double linearPosition;
//private final double linear0;
// Non-linear multiplier, exponent and constant
- private final double quad2,quad1,quad0;
-
+ private final double quad2, quad1, quad0;
+
public ValueSliderModel(DoubleModel min, DoubleModel max) {
linearPosition = 1.0;
-
+
this.min = min;
- this.mid = max; // Never use exponential scale
+ this.mid = max; // Never use exponential scale
this.max = max;
min.addChangeListener(this);
max.addChangeListener(this);
-
- quad2 = quad1 = quad0 = 0; // Not used
+
+ quad2 = quad1 = quad0 = 0; // Not used
}
-
+
/**
* Generate a linear model from min to max.
*/
public ValueSliderModel(double min, double max) {
linearPosition = 1.0;
-
+
this.min = new DoubleModel(min);
- this.mid = new DoubleModel(max); // Never use exponential scale
+ this.mid = new DoubleModel(max); // Never use exponential scale
this.max = new DoubleModel(max);
-
- quad2 = quad1 = quad0 = 0; // Not used
+
+ quad2 = quad1 = quad0 = 0; // Not used
}
public ValueSliderModel(double min, double mid, double max) {
- this(min,0.5,mid,max);
+ this(min, 0.5, mid, max);
}
/*
this.min = new DoubleModel(min);
this.mid = new DoubleModel(mid);
this.max = new DoubleModel(max);
-
+
linearPosition = pos;
//linear0 = min;
//linear1 = (mid-min)/pos;
if (!(min < mid && mid <= max && 0 < pos && pos < 1)) {
- throw new IllegalArgumentException("Bad arguments for ValueSliderModel "+
- "min="+min+" mid="+mid+" max="+max+" pos="+pos);
+ throw new IllegalArgumentException("Bad arguments for ValueSliderModel " +
+ "min=" + min + " mid=" + mid + " max=" + max + " pos=" + pos);
}
/*
* f(1) = max - end point
* f'(pos) = linear1 - continuity of derivative
*/
-
- double delta = (mid-min)/pos;
- quad2 = (max - mid - delta + delta*pos) / pow2(pos-1);
- quad1 = (delta + 2*(mid-max)*pos - delta*pos*pos) / pow2(pos-1);
- quad0 = (mid - (2*mid+delta)*pos + (max+delta)*pos*pos) / pow2(pos-1);
+
+ double delta = (mid - min) / pos;
+ quad2 = (max - mid - delta + delta * pos) / pow2(pos - 1);
+ quad1 = (delta + 2 * (mid - max) * pos - delta * pos * pos) / pow2(pos - 1);
+ quad0 = (mid - (2 * mid + delta) * pos + (max + delta) * pos * pos) / pow2(pos - 1);
}
private double pow2(double x) {
- return x*x;
+ return x * x;
}
public int getValue() {
//linear0 = min;
//linear1 = (mid-min)/pos;
- x = (value - min.getValue())*linearPosition/(mid.getValue()-min.getValue());
+ x = (value - min.getValue()) * linearPosition / (mid.getValue() - min.getValue());
} else {
// Use quadratic scale
// Further solution of the quadratic equation
// a*x^2 + b*x + c-value == 0
- x = (Math.sqrt(quad1*quad1 - 4*quad2*(quad0-value)) - quad1) / (2*quad2);
+ x = (Math.sqrt(quad1 * quad1 - 4 * quad2 * (quad0 - value)) - quad1) / (2 * quad2);
}
- return (int)(x*MAX);
+ return (int) (x * MAX);
}
-
-
+
+
public void setValue(int newValue) {
- if (firing > 0) // Ignore loops
+ if (firing > 0) {
+ // Ignore loops
+ log.verbose("Ignoring call to SliderModel setValue for " + DoubleModel.this.toString() +
+ " value=" + newValue + ", currently firing events");
return;
+ }
- double x = (double)newValue/MAX;
- double value;
+ double x = (double) newValue / MAX;
+ double scaledValue;
if (x <= linearPosition) {
// Use linear scale
//linear0 = min;
//linear1 = (mid-min)/pos;
-
- value = (mid.getValue()-min.getValue())/linearPosition*x + min.getValue();
+
+ scaledValue = (mid.getValue() - min.getValue()) / linearPosition * x + min.getValue();
} else {
// Use quadratic scale
- value = quad2*x*x + quad1*x + quad0;
+ scaledValue = quad2 * x * x + quad1 * x + quad0;
}
- DoubleModel.this.setValue(currentUnit.fromUnit(
- currentUnit.round(currentUnit.toUnit(value))));
+ double converted = currentUnit.fromUnit(currentUnit.round(currentUnit.toUnit(scaledValue)));
+ log.user("SliderModel setValue called for " + DoubleModel.this.toString() + " newValue=" + newValue +
+ " scaledValue=" + scaledValue + " converted=" + converted);
+ DoubleModel.this.setValue(converted);
}
-
+
// Static get-methods
private boolean isAdjusting;
- public int getExtent() { return 0; }
- public int getMaximum() { return MAX; }
- public int getMinimum() { return 0; }
- public boolean getValueIsAdjusting() { return isAdjusting; }
+
+ public int getExtent() {
+ return 0;
+ }
+
+ public int getMaximum() {
+ return MAX;
+ }
+
+ public int getMinimum() {
+ return 0;
+ }
+
+ public boolean getValueIsAdjusting() {
+ return isAdjusting;
+ }
// Ignore set-values
- public void setExtent(int newExtent) { }
- public void setMaximum(int newMaximum) { }
- public void setMinimum(int newMinimum) { }
- public void setValueIsAdjusting(boolean b) { isAdjusting = b; }
-
+ public void setExtent(int newExtent) {
+ }
+
+ public void setMaximum(int newMaximum) {
+ }
+
+ public void setMinimum(int newMinimum) {
+ }
+
+ public void setValueIsAdjusting(boolean b) {
+ isAdjusting = b;
+ }
+
public void setRangeProperties(int value, int extent, int min, int max, boolean adjusting) {
setValueIsAdjusting(adjusting);
setValue(value);
}
-
+
// Pass change listeners to the underlying model
public void addChangeListener(ChangeListener l) {
DoubleModel.this.addChangeListener(l);
}
-
+
public void removeChangeListener(ChangeListener l) {
DoubleModel.this.removeChangeListener(l);
}
-
-
+
+
public void stateChanged(ChangeEvent e) {
// Min or max range has changed.
public BoundedRangeModel getSliderModel(DoubleModel min, DoubleModel max) {
- return new ValueSliderModel(min,max);
+ return new ValueSliderModel(min, max);
}
public BoundedRangeModel getSliderModel(double min, double max) {
- return new ValueSliderModel(min,max);
+ return new ValueSliderModel(min, max);
}
public BoundedRangeModel getSliderModel(double min, double mid, double max) {
- return new ValueSliderModel(min,mid,max);
+ return new ValueSliderModel(min, mid, max);
}
public BoundedRangeModel getSliderModel(double min, double pos, double mid, double max) {
- return new ValueSliderModel(min,pos,mid,max);
+ return new ValueSliderModel(min, pos, mid, max);
}
-
-
+
+
//////////// Action model ////////////
addChangeListener(this);
}
-
+
@Override
public boolean isEnabled() {
- // TODO: LOW: does not reflect if component is currently able to support automatic setting
return isAutomaticAvailable();
}
}
return super.getValue(key);
}
-
+
@Override
public void putValue(String key, Object value) {
- if (firing > 0)
+ if (firing > 0) {
+ log.verbose("Ignoring call to ActionModel putValue for " + DoubleModel.this.toString() +
+ " key=" + key + " value=" + value + ", currently firing events");
return;
+ }
if (key.equals(Action.SELECTED_KEY) && (value instanceof Boolean)) {
- oldValue = (Boolean)value;
- setAutomatic((Boolean)value);
+ log.user("ActionModel putValue called for " + DoubleModel.this.toString() +
+ " key=" + key + " value=" + value);
+ oldValue = (Boolean) value;
+ setAutomatic((Boolean) value);
} else {
+ log.debug("Passing ActionModel putValue call to supermethod for " + DoubleModel.this.toString() +
+ " key=" + key + " value=" + value);
super.putValue(key, value);
}
}
-
+
// Implement a wrapper to the ChangeListeners
- ArrayList<PropertyChangeListener> propertyChangeListeners =
- new ArrayList<PropertyChangeListener>();
+ ArrayList<PropertyChangeListener> propertyChangeListeners =
+ new ArrayList<PropertyChangeListener>();
+
@Override
public void addPropertyChangeListener(PropertyChangeListener listener) {
propertyChangeListeners.add(listener);
DoubleModel.this.addChangeListener(this);
}
+
@Override
public void removePropertyChangeListener(PropertyChangeListener listener) {
propertyChangeListeners.remove(listener);
if (propertyChangeListeners.isEmpty())
DoubleModel.this.removeChangeListener(this);
}
+
// If the value has changed, generate an event to the listeners
public void stateChanged(ChangeEvent e) {
boolean newValue = isAutomatic();
if (oldValue == newValue)
return;
- PropertyChangeEvent event = new PropertyChangeEvent(this,Action.SELECTED_KEY,
- oldValue,newValue);
+ PropertyChangeEvent event = new PropertyChangeEvent(this, Action.SELECTED_KEY,
+ oldValue, newValue);
oldValue = newValue;
Object[] l = propertyChangeListeners.toArray();
- for (int i=0; i<l.length; i++) {
- ((PropertyChangeListener)l[i]).propertyChange(event);
+ for (int i = 0; i < l.length; i++) {
+ ((PropertyChangeListener) l[i]).propertyChange(event);
}
}
-
+
public void actionPerformed(ActionEvent e) {
// Setting performed in putValue
}
-
+
}
/**
}
-
-
- //////////// Main model /////////////
+ //////////// Main model /////////////
+
/*
* The main model handles all values in SI units, i.e. no conversion is made within the model.
*/
-
+
private final ChangeSource source;
private final String valueName;
private final double multiplier;
private final UnitGroup units;
private Unit currentUnit;
-
+
private final double minValue;
private final double maxValue;
-
- private int firing = 0; // >0 when model itself is sending events
+ private String toString = null;
+
+ private int firing = 0; // >0 when model itself is sending events
+
// Used to differentiate changes in valueName and other changes in the component:
private double lastValue = 0;
private boolean lastAutomatic = false;
-
+
public DoubleModel(double value) {
- this(value, UnitGroup.UNITS_NONE,Double.NEGATIVE_INFINITY,Double.POSITIVE_INFINITY);
+ this(value, UnitGroup.UNITS_NONE, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);
}
public DoubleModel(double value, UnitGroup unit) {
- this(value,unit,Double.NEGATIVE_INFINITY,Double.POSITIVE_INFINITY);
+ this(value, unit, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);
}
public DoubleModel(double value, UnitGroup unit, double min) {
- this(value,unit,min,Double.POSITIVE_INFINITY);
+ this(value, unit, min, Double.POSITIVE_INFINITY);
}
public DoubleModel(double value, UnitGroup unit, double min, double max) {
this.lastValue = value;
this.minValue = min;
this.maxValue = max;
-
+
source = null;
valueName = "Constant value";
multiplier = 1;
units = unit;
currentUnit = units.getDefaultUnit();
}
-
+
/**
* Generates a new DoubleModel that changes the values of the specified component.
this.source = source;
this.valueName = valueName;
this.multiplier = multiplier;
-
+
this.units = unit;
currentUnit = units.getDefaultUnit();
try {
getMethod = source.getClass().getMethod("get" + valueName);
} catch (NoSuchMethodException e) {
- throw new IllegalArgumentException("get method for value '"+valueName+
- "' not present in class "+source.getClass().getCanonicalName());
+ throw new IllegalArgumentException("get method for value '" + valueName +
+ "' not present in class " + source.getClass().getCanonicalName());
}
-
- Method s=null;
+
+ Method s = null;
try {
- s = source.getClass().getMethod("set" + valueName,double.class);
- } catch (NoSuchMethodException e1) { } // Ignore
+ s = source.getClass().getMethod("set" + valueName, double.class);
+ } catch (NoSuchMethodException e1) {
+ } // Ignore
setMethod = s;
// Automatic selection methods
- Method set=null,get=null;
+ Method set = null, get = null;
try {
get = source.getClass().getMethod("is" + valueName + "Automatic");
- set = source.getClass().getMethod("set" + valueName + "Automatic",boolean.class);
- } catch (NoSuchMethodException e) { } // ignore
+ set = source.getClass().getMethod("set" + valueName + "Automatic", boolean.class);
+ } catch (NoSuchMethodException e) {
+ } // ignore
- if (set!=null && get!=null) {
+ if (set != null && get != null) {
getAutoMethod = get;
setAutoMethod = set;
} else {
}
}
-
+
public DoubleModel(ChangeSource source, String valueName, double multiplier, UnitGroup unit,
double min) {
- this(source,valueName,multiplier,unit,min,Double.POSITIVE_INFINITY);
+ this(source, valueName, multiplier, unit, min, Double.POSITIVE_INFINITY);
}
public DoubleModel(ChangeSource source, String valueName, double multiplier, UnitGroup unit) {
- this(source,valueName,multiplier,unit,Double.NEGATIVE_INFINITY,Double.POSITIVE_INFINITY);
+ this(source, valueName, multiplier, unit, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);
}
- public DoubleModel(ChangeSource source, String valueName, UnitGroup unit,
+ public DoubleModel(ChangeSource source, String valueName, UnitGroup unit,
double min, double max) {
- this(source,valueName,1.0,unit,min,max);
+ this(source, valueName, 1.0, unit, min, max);
}
public DoubleModel(ChangeSource source, String valueName, UnitGroup unit, double min) {
- this(source,valueName,1.0,unit,min,Double.POSITIVE_INFINITY);
+ this(source, valueName, 1.0, unit, min, Double.POSITIVE_INFINITY);
}
public DoubleModel(ChangeSource source, String valueName, UnitGroup unit) {
- this(source,valueName,1.0,unit,Double.NEGATIVE_INFINITY,Double.POSITIVE_INFINITY);
+ this(source, valueName, 1.0, unit, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);
}
-
+
public DoubleModel(ChangeSource source, String valueName) {
- this(source,valueName,1.0,UnitGroup.UNITS_NONE,
- Double.NEGATIVE_INFINITY,Double.POSITIVE_INFINITY);
+ this(source, valueName, 1.0, UnitGroup.UNITS_NONE,
+ Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);
}
-
+
public DoubleModel(ChangeSource source, String valueName, double min) {
- this(source,valueName,1.0,UnitGroup.UNITS_NONE,min,Double.POSITIVE_INFINITY);
+ this(source, valueName, 1.0, UnitGroup.UNITS_NONE, min, Double.POSITIVE_INFINITY);
}
public DoubleModel(ChangeSource source, String valueName, double min, double max) {
- this(source,valueName,1.0,UnitGroup.UNITS_NONE,min,max);
+ this(source, valueName, 1.0, UnitGroup.UNITS_NONE, min, max);
}
-
+
/**
* Returns the value of the variable (in SI units).
*/
public double getValue() {
- if (getMethod==null) // Constant value
+ if (getMethod == null) // Constant value
return lastValue;
-
+
try {
- return (Double)getMethod.invoke(source)*multiplier;
+ return (Double) getMethod.invoke(source) * multiplier;
} catch (IllegalArgumentException e) {
- throw new BugException("Unable to invoke getMethod of "+this, e);
+ throw new BugException("Unable to invoke getMethod of " + this, e);
} catch (IllegalAccessException e) {
- throw new BugException("Unable to invoke getMethod of "+this, e);
+ throw new BugException("Unable to invoke getMethod of " + this, e);
} catch (InvocationTargetException e) {
throw Reflection.handleWrappedException(e);
}
* @param v New value for parameter in SI units.
*/
public void setValue(double v) {
- if (setMethod==null) {
+ log.debug("Setting value " + v + " for " + this);
+ if (setMethod == null) {
if (getMethod != null) {
- throw new RuntimeException("setMethod not available for variable '"+valueName+
- "' in class "+source.getClass().getCanonicalName());
+ throw new BugException("setMethod not available for variable '" + valueName +
+ "' in class " + source.getClass().getCanonicalName());
}
lastValue = v;
fireStateChanged();
return;
}
-
+
try {
- setMethod.invoke(source, v/multiplier);
+ setMethod.invoke(source, v / multiplier);
} catch (IllegalArgumentException e) {
- throw new BugException("Unable to invoke setMethod of "+this, e);
+ throw new BugException("Unable to invoke setMethod of " + this, e);
} catch (IllegalAccessException e) {
- throw new BugException("Unable to invoke setMethod of "+this, e);
+ throw new BugException("Unable to invoke setMethod of " + this, e);
} catch (InvocationTargetException e) {
throw Reflection.handleWrappedException(e);
}
}
-
+
/**
* Returns whether setting the value automatically is available.
public boolean isAutomaticAvailable() {
return (getAutoMethod != null) && (setAutoMethod != null);
}
-
+
/**
* Returns whether the value is currently being set automatically.
* Returns false if automatic setting is not available at all.
return false;
try {
- return (Boolean)getAutoMethod.invoke(source);
+ return (Boolean) getAutoMethod.invoke(source);
} catch (IllegalArgumentException e) {
throw new BugException("Method call failed", e);
} catch (IllegalAccessException e) {
*/
public void setAutomatic(boolean auto) {
if (setAutoMethod == null) {
- fireStateChanged(); // in case something is out-of-sync
+ log.debug("Setting automatic to " + auto + " for " + this + ", automatic not available");
+ fireStateChanged(); // in case something is out-of-sync
return;
}
+ log.debug("Setting automatic to " + auto + " for " + this);
lastAutomatic = auto;
try {
setAutoMethod.invoke(source, auto);
}
}
-
+
/**
* Returns the current Unit. At the beginning it is the default unit of the UnitGroup.
* @return The most recently set unit.
public void setCurrentUnit(Unit u) {
if (currentUnit == u)
return;
+ log.debug("Setting unit for " + this + " to '" + u + "'");
currentUnit = u;
fireStateChanged();
}
}
-
+
/**
* Add a listener to the model. Adds the model as a listener to the value source if this
* is the first listener.
lastAutomatic = isAutomatic();
}
}
-
+
listeners.add(l);
- if (DEBUG_LISTENERS)
- System.out.println(this+" adding listener (total "+listeners.size()+"): "+l);
+ log.verbose(this + " adding listener (total " + listeners.size() + "): " + l);
}
-
+
/**
* Remove a listener from the model. Removes the model from being a listener to the Component
* if this was the last listener of the model.
if (listeners.isEmpty() && source != null) {
source.removeChangeListener(this);
}
- if (DEBUG_LISTENERS)
- System.out.println(this+" removing listener (total "+listeners.size()+"): "+l);
+ log.verbose(this + " removing listener (total " + listeners.size() + "): " + l);
}
+
+ @Override
+ protected void finalize() throws Throwable {
+ super.finalize();
+ if (!listeners.isEmpty()) {
+ log.warn(this + " being garbage-collected while having listeners " + listeners);
+ }
+ };
+
+
/**
* Fire a ChangeEvent to all listeners.
*/
Object[] l = listeners.toArray();
ChangeEvent event = new ChangeEvent(this);
firing++;
- for (int i=0; i<l.length; i++)
- ((ChangeListener)l[i]).stateChanged(event);
+ for (int i = 0; i < l.length; i++)
+ ((ChangeListener) l[i]).stateChanged(event);
firing--;
}
-
+
/**
* Called when the component changes. Checks whether the modeled value has changed, and if
* it has, updates lastValue and generates ChangeEvents for all listeners of the model.
lastAutomatic = b;
fireStateChanged();
}
-
+
+
/**
* Explain the DoubleModel as a String.
*/
@Override
public String toString() {
- if (source == null)
- return "DoubleModel[constant="+lastValue+"]";
- return "DoubleModel["+source.getClass().getCanonicalName()+":"+valueName+"]";
+ if (toString == null) {
+ if (source == null) {
+ toString = "DoubleModel[constant=" + lastValue + "]";
+ } else {
+ toString = "DoubleModel[" + source.getClass().getSimpleName() + ":" + valueName + "]";
+ }
+ }
+ return toString;
}
}
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
+import net.sf.openrocket.logging.LogHelper;
+import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.BugException;
import net.sf.openrocket.util.ChangeSource;
import net.sf.openrocket.util.Reflection;
public class IntegerModel implements ChangeListener {
-
-
+ private static final LogHelper log = Application.getLogger();
+
+
//////////// JSpinner Model ////////////
private class IntegerSpinnerModel extends SpinnerNumberModel {
public Object getValue() {
return IntegerModel.this.getValue();
}
-
+
@Override
public void setValue(Object value) {
- if (firing > 0) // Ignore, if called when model is sending events
+ if (firing > 0) {
+ // Ignore, if called when model is sending events
+ log.verbose("Ignoring call to SpinnerModel setValue for " + IntegerModel.this.toString() +
+ " value=" + value + ", currently firing events");
return;
- Number num = (Number)value;
+
+ }
+ Number num = (Number) value;
int newValue = num.intValue();
+ log.user("SpinnerModel setValue called for " + IntegerModel.this.toString() + " newValue=" + newValue);
IntegerModel.this.setValue(newValue);
-
-// try {
-// int newValue = Integer.parseInt((String)value);
-// IntegerModel.this.setValue(newValue);
-// } catch (NumberFormatException e) {
-// IntegerModel.this.fireStateChanged();
-// };
}
-
+
@Override
public Object getNextValue() {
int d = IntegerModel.this.getValue();
if (d >= maxValue)
return null;
- return (d+1);
+ return (d + 1);
}
-
+
@Override
public Object getPreviousValue() {
int d = IntegerModel.this.getValue();
if (d <= minValue)
return null;
- return (d-1);
+ return (d - 1);
}
@Override
public void addChangeListener(ChangeListener l) {
IntegerModel.this.addChangeListener(l);
}
-
+
@Override
public void removeChangeListener(ChangeListener l) {
IntegerModel.this.removeChangeListener(l);
//////////// Main model /////////////
-
+
/*
* The main model handles all values in SI units, i.e. no conversion is made within the model.
*/
-
+
private final ChangeSource source;
private final String valueName;
private final Method setMethod;
private final ArrayList<ChangeListener> listeners = new ArrayList<ChangeListener>();
-
+
private final int minValue;
private final int maxValue;
-
- private int firing = 0; // >0 when model itself is sending events
+ private String toString = null;
+
+ private int firing = 0; // >0 when model itself is sending events
+
// Used to differentiate changes in valueName and other changes in the source:
private int lastValue = 0;
-
-
+
+
/**
* Generates a new DoubleModel that changes the values of the specified source.
* The double value is read and written using the methods "get"/"set" + valueName.
*
* @param source Component whose parameter to use.
- * @param valueName Name of metods used to get/set the parameter.
- * @param multiplier Value shown by the model is the value from source.getXXX * multiplier
+ * @param valueName Name of methods used to get/set the parameter.
* @param min Minimum value allowed (in SI units)
* @param max Maximum value allowed (in SI units)
*/
try {
getMethod = source.getClass().getMethod("get" + valueName);
- setMethod = source.getClass().getMethod("set" + valueName,int.class);
+ setMethod = source.getClass().getMethod("set" + valueName, int.class);
} catch (NoSuchMethodException e) {
- throw new IllegalArgumentException("get/set methods for value '"+valueName+
- "' not present in class "+source.getClass().getCanonicalName());
+ throw new IllegalArgumentException("get/set methods for value '" + valueName +
+ "' not present in class " + source.getClass().getCanonicalName());
}
}
-
+
public IntegerModel(ChangeSource source, String valueName, int min) {
- this(source,valueName,min,Integer.MAX_VALUE);
+ this(source, valueName, min, Integer.MAX_VALUE);
}
public IntegerModel(ChangeSource source, String valueName) {
- this(source,valueName,Integer.MIN_VALUE,Integer.MAX_VALUE);
+ this(source, valueName, Integer.MIN_VALUE, Integer.MAX_VALUE);
}
-
-
+
+
/**
* Returns the value of the variable.
*/
public int getValue() {
try {
- return (Integer)getMethod.invoke(source);
+ return (Integer) getMethod.invoke(source);
} catch (IllegalArgumentException e) {
throw new BugException(e);
} catch (IllegalAccessException e) {
* Sets the value of the variable.
*/
public void setValue(int v) {
+ log.debug("Setting value " + v + " for " + this);
try {
setMethod.invoke(source, v);
} catch (IllegalArgumentException e) {
throw Reflection.handleWrappedException(e);
}
}
-
+
/**
* Add a listener to the model. Adds the model as a listener to the Component if this
source.addChangeListener(this);
lastValue = getValue();
}
-
+
listeners.add(l);
+ log.verbose(this + " adding listener (total " + listeners.size() + "): " + l);
}
-
+
/**
* Remove a listener from the model. Removes the model from being a listener to the Component
* if this was the last listener of the model.
if (listeners.isEmpty()) {
source.removeChangeListener(this);
}
+ log.verbose(this + " removing listener (total " + listeners.size() + "): " + l);
}
+
+ @Override
+ protected void finalize() throws Throwable {
+ super.finalize();
+ if (!listeners.isEmpty()) {
+ log.warn(this + " being garbage-collected while having listeners " + listeners);
+ }
+ };
+
+
public void fireStateChanged() {
Object[] l = listeners.toArray();
ChangeEvent event = new ChangeEvent(this);
firing++;
- for (int i=0; i<l.length; i++)
- ((ChangeListener)l[i]).stateChanged(event);
+ for (int i = 0; i < l.length; i++)
+ ((ChangeListener) l[i]).stateChanged(event);
firing--;
}
-
+
/**
* Called when the source changes. Checks whether the modeled value has changed, and if
* it has, updates lastValue and generates ChangeEvents for all listeners of the model.
lastValue = v;
fireStateChanged();
}
-
+
/**
* Explain the DoubleModel as a String.
*/
@Override
public String toString() {
- return "IntegerModel["+source.getClass().getCanonicalName()+":"+valueName+"]";
+ if (toString == null) {
+ toString = "IntegerModel[" + source.getClass().getSimpleName() + ":" + valueName + "]";
+ }
+ return toString;
}
}
import net.sf.openrocket.gui.components.StyledLabel;
import net.sf.openrocket.gui.components.UnitSelector;
import net.sf.openrocket.gui.components.StyledLabel.Style;
+import net.sf.openrocket.logging.LogHelper;
import net.sf.openrocket.rocketcomponent.FinSet;
import net.sf.openrocket.rocketcomponent.FreeformFinSet;
import net.sf.openrocket.rocketcomponent.RocketComponent;
+import net.sf.openrocket.startup.Application;
import net.sf.openrocket.unit.UnitGroup;
public abstract class FinSetConfig extends RocketComponentConfig {
-
+ private static final LogHelper log = Application.getLogger();
+
private JButton split = null;
public FinSetConfig(RocketComponent component) {
tabbedPane.insertTab("Fin tabs", null, finTabPanel(), "Through-the-wall fin tabs", 0);
}
-
+
protected void addFinSetButtons() {
- JButton convert=null;
+ JButton convert = null;
//// Convert buttons
if (!(component instanceof FreeformFinSet)) {
convert.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
+ log.user("Converting " + component.getComponentName() + " into freeform fin set");
+
// Do change in future for overall safety
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
ComponentConfigDialog.addUndoPosition("Convert fin set");
- RocketComponent freeform =
- FreeformFinSet.convertFinSet((FinSet)component);
+ RocketComponent freeform =
+ FreeformFinSet.convertFinSet((FinSet) component);
ComponentConfigDialog.showDialog(freeform);
}
});
-
+
ComponentConfigDialog.hideDialog();
}
});
}
-
+
split = new JButton("Split fins");
split.setToolTipText("Split the fin set into separate fins");
split.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
+ log.user("Splitting " + component.getComponentName() + " into separate fins, fin count=" +
+ ((FinSet) component).getFinCount());
+
// Do change in future for overall safety
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
RocketComponent parent = component.getParent();
int index = parent.getChildPosition(component);
- int count = ((FinSet)component).getFinCount();
- double base = ((FinSet)component).getBaseRotation();
+ int count = ((FinSet) component).getFinCount();
+ double base = ((FinSet) component).getBaseRotation();
if (count <= 1)
return;
ComponentConfigDialog.addUndoPosition("Split fin set");
parent.removeChild(index);
- for (int i=0; i<count; i++) {
- FinSet copy = (FinSet)component.copy();
+ for (int i = 0; i < count; i++) {
+ FinSet copy = (FinSet) component.copy();
copy.setFinCount(1);
- copy.setBaseRotation(base + i*2*Math.PI/count);
- copy.setName(copy.getName() + " #" + (i+1));
- parent.addChild(copy, index+i);
+ copy.setBaseRotation(base + i * 2 * Math.PI / count);
+ copy.setName(copy.getName() + " #" + (i + 1));
+ parent.addChild(copy, index + i);
}
}
});
-
+
ComponentConfigDialog.hideDialog();
}
});
- split.setEnabled(((FinSet)component).getFinCount() > 1);
+ split.setEnabled(((FinSet) component).getFinCount() > 1);
- if (convert==null)
+ if (convert == null)
addButtons(split);
else
- addButtons(split,convert);
-
+ addButtons(split, convert);
+
}
-
+
public JPanel finTabPanel() {
JPanel panel = new JPanel(
new MigLayout("align 50% 20%, fillx, gap rel unrel, ins 20lp 10% 20lp 10%",
- "[150lp::][65lp::][30lp::][200lp::]",""));
-// JPanel panel = new JPanel(new MigLayout("fillx, align 20% 20%, gap rel unrel",
-// "[40lp][80lp::][30lp::][100lp::]",""));
-
- panel.add(new StyledLabel("Through-the-wall fin tabs:", Style.BOLD),
+ "[150lp::][65lp::][30lp::][200lp::]", ""));
+ // JPanel panel = new JPanel(new MigLayout("fillx, align 20% 20%, gap rel unrel",
+ // "[40lp][80lp::][30lp::][100lp::]",""));
+
+ panel.add(new StyledLabel("Through-the-wall fin tabs:", Style.BOLD),
"spanx, wrap 30lp");
JLabel label;
DoubleModel length2;
DoubleModel length_2;
JSpinner spin;
-
+
length = new DoubleModel(component, "Length", UnitGroup.UNITS_LENGTH, 0);
length2 = new DoubleModel(component, "Length", 0.5, UnitGroup.UNITS_LENGTH, 0);
length_2 = new DoubleModel(component, "Length", -0.5, UnitGroup.UNITS_LENGTH, 0);
spin = new JSpinner(m.getSpinnerModel());
spin.setEditor(new SpinnerEditor(spin));
- panel.add(spin,"growx 1");
+ panel.add(spin, "growx 1");
- panel.add(new UnitSelector(m),"growx 1");
+ panel.add(new UnitSelector(m), "growx 1");
panel.add(new BasicSlider(m.getSliderModel(DoubleModel.ZERO, length)),
"w 100lp, growx 5, wrap");
-
+
//// Tab length
label = new JLabel("Tab height:");
label.setToolTipText("The spanwise height of the fin tab.");
spin = new JSpinner(m.getSpinnerModel());
spin.setEditor(new SpinnerEditor(spin));
- panel.add(spin,"growx");
+ panel.add(spin, "growx");
- panel.add(new UnitSelector(m),"growx");
+ panel.add(new UnitSelector(m), "growx");
panel.add(new BasicSlider(m.getSliderModel(DoubleModel.ZERO, length2)),
"w 100lp, growx 5, wrap para");
-
+
//// Tab position
label = new JLabel("Tab position:");
label.setToolTipText("The position of the fin tab.");
spin = new JSpinner(m.getSpinnerModel());
spin.setEditor(new SpinnerEditor(spin));
- panel.add(spin,"growx");
-
- panel.add(new UnitSelector(m),"growx");
- panel.add(new BasicSlider(m.getSliderModel(length_2, length2)),"w 100lp, growx 5, wrap");
-
+ panel.add(spin, "growx");
+ panel.add(new UnitSelector(m), "growx");
+ panel.add(new BasicSlider(m.getSliderModel(length_2, length2)), "w 100lp, growx 5, wrap");
+
+
label = new JLabel("relative to");
panel.add(label, "right, gapright unrel");
- EnumModel<FinSet.TabRelativePosition> em =
- new EnumModel<FinSet.TabRelativePosition>(component, "TabRelativePosition");
+ EnumModel<FinSet.TabRelativePosition> em =
+ new EnumModel<FinSet.TabRelativePosition>(component, "TabRelativePosition");
panel.add(new JComboBox(em), "spanx 3, growx");
return panel;
}
-
+
@Override
public void updateFields() {
super.updateFields();
if (split != null)
- split.setEnabled(((FinSet)component).getFinCount() > 1);
+ split.setEnabled(((FinSet) component).getFinCount() > 1);
}
}
import net.sf.openrocket.gui.components.StyledLabel;
import net.sf.openrocket.gui.configdialog.ComponentConfigDialog;
import net.sf.openrocket.gui.main.componenttree.ComponentTreeModel;
+import net.sf.openrocket.logging.LogHelper;
import net.sf.openrocket.rocketcomponent.BodyComponent;
import net.sf.openrocket.rocketcomponent.BodyTube;
import net.sf.openrocket.rocketcomponent.Bulkhead;
import net.sf.openrocket.rocketcomponent.Transition;
import net.sf.openrocket.rocketcomponent.TrapezoidFinSet;
import net.sf.openrocket.rocketcomponent.TubeCoupler;
+import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.BugException;
import net.sf.openrocket.util.Pair;
import net.sf.openrocket.util.Prefs;
*/
public class ComponentAddButtons extends JPanel implements Scrollable {
+ private static final LogHelper log = Application.getLogger();
private static final int ROWS = 3;
private static final int MAXCOLS = 6;
@Override
protected void fireActionPerformed(ActionEvent event) {
super.fireActionPerformed(event);
+ log.user("Adding component of type " + componentClass.getSimpleName());
RocketComponent c = null;
Integer position = null;
Pair<RocketComponent, Integer> pos = getAdditionPosition(c);
if (pos == null) {
// Cancel addition
+ log.info("No position to add component");
return;
}
c = pos.getU();
try {
component = (RocketComponent) constructor.newInstance();
} catch (InstantiationException e) {
- throw new BugException("Could not construct new instance of class " +
- constructor, e);
+ throw new BugException("Could not construct new instance of class " + constructor, e);
} catch (IllegalAccessException e) {
- throw new BugException("Could not construct new instance of class " +
- constructor, e);
+ throw new BugException("Could not construct new instance of class " + constructor, e);
} catch (InvocationTargetException e) {
throw Reflection.handleWrappedException(e);
}
// Next undo position is set by opening the configuration dialog
document.addUndoPosition("Add " + component.getComponentName());
-
+ log.info("Adding component " + component.getComponentName() + " to component " + c.getComponentName() +
+ " position=" + position);
+
if (position == null)
c.addChild(component);
else
import javax.swing.Icon;
import javax.swing.JTree;
import javax.swing.ToolTipManager;
+import javax.swing.tree.TreeModel;
+import javax.swing.tree.TreePath;
import net.sf.openrocket.document.OpenRocketDocument;
public class ComponentTree extends JTree {
- private static final long serialVersionUID = 1L;
public ComponentTree(OpenRocketDocument document) {
super();
this.setModel(new ComponentTreeModel(document.getRocket(), this));
this.setToggleClickCount(0);
- javax.swing.plaf.basic.BasicTreeUI ui = new javax.swing.plaf.basic.BasicTreeUI();
- this.setUI(ui);
-
- ui.setExpandedIcon(TreeIcon.MINUS);
- ui.setCollapsedIcon(TreeIcon.PLUS);
-
- ui.setLeftChildIndent(15);
+ javax.swing.plaf.basic.BasicTreeUI plainUI = new javax.swing.plaf.basic.BasicTreeUI();
+ this.setUI(plainUI);
+ plainUI.setExpandedIcon(TreeIcon.MINUS);
+ plainUI.setCollapsedIcon(TreeIcon.PLUS);
+ plainUI.setLeftChildIndent(15);
- setBackground(Color.WHITE);
- setShowsRootHandles(false);
+ this.setBackground(Color.WHITE);
+ this.setShowsRootHandles(false);
- setCellRenderer(new ComponentTreeRenderer());
+ this.setCellRenderer(new ComponentTreeRenderer());
this.setDragEnabled(true);
this.setDropMode(DropMode.INSERT);
public void expandTree() {
for (int i = 0; i < getRowCount(); i++)
expandRow(i);
-
}
+ @Override
+ public void treeDidChange() {
+ super.treeDidChange();
+ expandChildlessNodes();
+ }
+
+ /**
+ * Expand all nodes in the tree that are visible and have no children. This can be used
+ * to avoid the situation where a non-leaf node is marked as being expandable, but when
+ * expanding it it has no children.
+ */
+ private void expandChildlessNodes() {
+ TreeModel model = this.getModel();
+ if (model == null) {
+ return;
+ }
+ Object root = model.getRoot();
+ expandChildlessNodes(model, new TreePath(root));
+ }
+
+ private void expandChildlessNodes(TreeModel model, TreePath path) {
+ Object object = path.getLastPathComponent();
+ if (this.isVisible(path)) {
+ int count = model.getChildCount(object);
+ if (count == 0) {
+ this.expandPath(path);
+ }
+ for (int i = 0; i < count; i++) {
+ expandChildlessNodes(model, path.pathByAddingChild(model.getChild(object, i)));
+ }
+ }
+ }
+
+
+
private static class TreeIcon implements Icon {
public static final Icon PLUS = new TreeIcon(true);
public static final Icon MINUS = new TreeIcon(false);
import java.util.ArrayList;
import java.util.Arrays;
+import net.sf.openrocket.logging.LogHelper;
+import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.BugException;
import net.sf.openrocket.util.Coordinate;
public class FreeformFinSet extends FinSet {
+ private static final LogHelper log = Application.getLogger();
private ArrayList<Coordinate> points = new ArrayList<Coordinate>();
* @return the new freeform fin set.
*/
public static FreeformFinSet convertFinSet(FinSet finset) {
+ log.info("Converting " + finset.getComponentName() + " into freeform fin set");
final RocketComponent root = finset.getRoot();
FreeformFinSet freeform;
* @see #isCompatible(Class)
*/
public final boolean isCompatible(RocketComponent c) {
- checkState();
return isCompatible(c.getClass());
}
* to use the default color.
*/
public final Color getColor() {
- checkState();
return color;
}
* Set the color of the object to use in 2D figures.
*/
public final void setColor(Color c) {
- checkState();
if ((color == null && c == null) ||
(color != null && color.equals(c)))
return;
+ checkState();
this.color = c;
fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE);
}
public final LineStyle getLineStyle() {
- checkState();
return lineStyle;
}
public final void setLineStyle(LineStyle style) {
- checkState();
if (this.lineStyle == style)
return;
+ checkState();
this.lineStyle = style;
fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE);
}
* @return the override mass
*/
public final double getOverrideMass() {
- checkState();
return overrideMass;
}
* @param m the override mass
*/
public final void setOverrideMass(double m) {
+ if (MathUtil.equals(m, overrideMass))
+ return;
checkState();
overrideMass = Math.max(m, 0);
if (massOverriden)
* @return whether the mass is overridden
*/
public final boolean isMassOverridden() {
- checkState();
return massOverriden;
}
* @param o whether the mass is overridden
*/
public final void setMassOverridden(boolean o) {
- checkState();
- if (massOverriden != o) {
- massOverriden = o;
- fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
+ if (massOverriden == o) {
+ return;
}
+ checkState();
+ massOverriden = o;
+ fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
}
* @return the override CG
*/
public final Coordinate getOverrideCG() {
- checkState();
return getComponentCG().setX(overrideCGX);
}
* @return the x-coordinate of the override CG.
*/
public final double getOverrideCGX() {
- checkState();
return overrideCGX;
}
* @param x the x-coordinate of the override CG to set.
*/
public final void setOverrideCGX(double x) {
- checkState();
if (MathUtil.equals(overrideCGX, x))
return;
+ checkState();
this.overrideCGX = x;
if (isCGOverridden())
fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
* @return whether the CG is overridden
*/
public final boolean isCGOverridden() {
- checkState();
return cgOverriden;
}
* @param o whether the CG is overridden
*/
public final void setCGOverridden(boolean o) {
- checkState();
- if (cgOverriden != o) {
- cgOverriden = o;
- fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
+ if (cgOverriden == o) {
+ return;
}
+ checkState();
+ cgOverriden = o;
+ fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
}
* @return whether the current mass and/or CG override overrides subcomponents as well.
*/
public boolean getOverrideSubcomponents() {
- checkState();
return overrideSubcomponents;
}
* @param override whether the mass and/or CG override overrides all subcomponent.
*/
public void setOverrideSubcomponents(boolean override) {
- checkState();
- if (overrideSubcomponents != override) {
- overrideSubcomponents = override;
- fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
+ if (overrideSubcomponents == override) {
+ return;
}
+ checkState();
+ overrideSubcomponents = override;
+ fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
}
/**
* @return whether the option to override subcomponents is currently enabled.
*/
public boolean isOverrideSubcomponentsEnabled() {
- checkState();
return isCGOverridden() || isMassOverridden();
}
* the default name, currently the component name.
*/
public final void setName(String name) {
+ if (this.name.equals(name)) {
+ return;
+ }
checkState();
if (name == null || name.matches("^\\s*$"))
this.name = getComponentName();
* @return the comment of the component.
*/
public final String getComment() {
- checkState();
return comment;
}
* @param comment the comment of the component.
*/
public final void setComment(String comment) {
- checkState();
if (this.comment.equals(comment))
return;
+ checkState();
if (comment == null)
this.comment = "";
else
* itself.
*/
public final double getLength() {
- checkState();
return length;
}
* but can be provided by a subclass.
*/
public final Position getRelativePosition() {
- checkState();
return relativePosition;
}
* @param position the relative positioning.
*/
protected void setRelativePosition(RocketComponent.Position position) {
- checkState();
if (this.relativePosition == position)
return;
+ checkState();
// Update position so as not to move the component
if (this.parent != null) {
* @return the positional value.
*/
public final double getPositionValue() {
- checkState();
return position;
}
* @param value the position value of the component.
*/
public void setPositionValue(double value) {
- checkState();
if (MathUtil.equals(this.position, value))
return;
+ checkState();
this.position = value;
}
* @return The mass of the component or the given override mass.
*/
public final double getMass() {
- checkState();
if (massOverriden)
return overrideMass;
return getComponentMass();
/**
* Checks whether this component has been invalidated and should no longer be used.
* This is a safety check that in-place replaced components are no longer used.
- * All non-trivial methods should call this method as the first thing, unless the
- * method may be used in debugging cases.
+ * All non-trivial methods (with the exception of methods simply getting a property)
+ * should call this method before changing or computing anything.
*
* @throws BugException if this component has been invalidated by {@link #copyFrom(RocketComponent)}.
*/
// Check cg+cp + altitude
checkCgCp(0.221, 0.0797, 0.320, 12.0);
checkAlt(32.7);
+
+
}
private String massComponentID = null;