import javax.swing.event.ChangeListener;
+import net.sf.openrocket.util.BugException;
import net.sf.openrocket.util.ChangeSource;
import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.LineStyle;
try {
clone = (RocketComponent)this.clone();
} catch (CloneNotSupportedException e) {
- throw new RuntimeException("CloneNotSupportedException encountered, " +
+ throw new BugException("CloneNotSupportedException encountered, " +
"report a bug!",e);
}
clone.children = new ArrayList<RocketComponent>();
// Add copied children to the structure without firing events.
- for (RocketComponent c: this.children) {
- RocketComponent copy = c.copy();
- clone.children.add(copy);
- copy.parent = clone;
+ for (RocketComponent child: this.children) {
+ RocketComponent childCopy = child.copy();
+ // Don't use add method since it fires events
+ clone.children.add(childCopy);
+ childCopy.parent = clone;
}
return clone;
break;
default:
- throw new RuntimeException("Unknown relative positioning type of component"+
+ throw new BugException("Unknown relative positioning type of component"+
component+": "+component.relativePosition);
}
RocketComponent stage = this;
while (!(stage instanceof Stage)) {
stage = stage.parent;
+ if (stage == null || stage.parent == null) {
+ throw new IllegalStateException("getStageNumber() could not find parent " +
+ "stage.");
+ }
}
return stage.parent.getChildPosition(stage);
}
if (parent == null)
return null;
int pos = parent.getChildPosition(this);
+ if (pos < 0) {
+ StringBuffer sb = new StringBuffer();
+ sb.append("Inconsistent internal state: ");
+ sb.append("this=").append(this).append('[')
+ .append(System.identityHashCode(this)).append(']');
+ sb.append(" parent.children=[");
+ for (int i=0; i < parent.children.size(); i++) {
+ RocketComponent c = parent.children.get(i);
+ sb.append(c).append('[').append(System.identityHashCode(c)).append(']');
+ if (i < parent.children.size()-1)
+ sb.append(", ");
+ }
+ sb.append(']');
+ throw new IllegalStateException(sb.toString());
+ }
assert(pos >= 0);
if (pos == 0)
return parent;
/**
* Removes a ComponentChangeListener from the rocket tree. The listener is removed from
* the root component, which must be of type Rocket (which overrides this method).
+ * Does nothing if the root component is not a Rocket. (The asymmetry is so
+ * that listeners can always be removed just in case.)
*
* @param l Listener to remove
- * @throws IllegalStateException - if the root component is not a Rocket
*/
public void removeComponentChangeListener(ComponentChangeListener l) {
- getRocket().removeComponentChangeListener(l);
+ if (parent != null) {
+ getRoot().removeComponentChangeListener(l);
+ }
}
/**
* Removes a ChangeListener from the rocket tree. This is identical to
* removeComponentChangeListener() except it uses a ChangeListener.
+ * Does nothing if the root component is not a Rocket. (The asymmetry is so
+ * that listeners can always be removed just in case.)
*
* @param l Listener to remove
- * @throws IllegalStateException - if the root component is not a Rocket
*/
public void removeChangeListener(ChangeListener l) {
- getRocket().removeChangeListener(l);
+ if (this.parent != null) {
+ getRoot().removeChangeListener(l);
+ }
}
/**
* Loads the RocketComponent fields from the given component. This method is meant
- * for use with the undo/redo mechanism.
- *
+ * for in-place replacement of a component. It is used with the undo/redo
+ * mechanism and when converting a finset into a freeform fin set.
+ * This component must not have a parent, otherwise this method will fail.
+ * <p>
* The fields are copied by reference, and the supplied component must not be used
* after the call, as it is in an undefined state.
*
* TODO: MEDIUM: Make general to copy all private/protected fields...
*/
protected void copyFrom(RocketComponent src) {
+
+ if (this.parent != null) {
+ throw new UnsupportedOperationException("copyFrom called for non-root component "
+ + this);
+ }
+
// Set parents and children
- this.parent = null;
this.children = src.children;
src.children = new ArrayList<RocketComponent>();