[#1454] Fix stackoverflow error
Make sure the InsideColorComponentHandler is cloned when a RocketComponent is cloned + don't clone the configListeners
This commit is contained in:
parent
f1a203ea6c
commit
00fcc34509
@ -555,7 +555,7 @@ public class AppearanceBuilder extends AbstractChangeSource {
|
||||
* @return true if listener was successfully added, false if not
|
||||
*/
|
||||
public boolean addConfigListener(RocketComponent component, AppearanceBuilder ab) {
|
||||
if (component == null || ab == null) {
|
||||
if (component == null || ab == null || configListeners.values().contains(ab) || ab == this) {
|
||||
return false;
|
||||
}
|
||||
configListeners.put(component, ab);
|
||||
|
@ -31,7 +31,7 @@ public class BodyTube extends SymmetricComponent implements BoxBounded, MotorMou
|
||||
|
||||
private MotorConfigurationSet motors;
|
||||
|
||||
private final InsideColorComponentHandler insideColorComponentHandler = new InsideColorComponentHandler(this);
|
||||
private InsideColorComponentHandler insideColorComponentHandler = new InsideColorComponentHandler(this);
|
||||
|
||||
public BodyTube() {
|
||||
this(8 * DEFAULT_RADIUS, DEFAULT_RADIUS);
|
||||
@ -521,6 +521,11 @@ public class BodyTube extends SymmetricComponent implements BoxBounded, MotorMou
|
||||
return this.insideColorComponentHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInsideColorComponentHandler(InsideColorComponentHandler handler) {
|
||||
this.insideColorComponentHandler = handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addConfigListener(RocketComponent listener) {
|
||||
boolean success = super.addConfigListener(listener);
|
||||
|
@ -123,7 +123,7 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona
|
||||
private double totalVolume = Double.NaN;
|
||||
private Coordinate centerOfMass = Coordinate.NaN;
|
||||
|
||||
private final InsideColorComponentHandler insideColorComponentHandler = new InsideColorComponentHandler(this);
|
||||
private InsideColorComponentHandler insideColorComponentHandler = new InsideColorComponentHandler(this);
|
||||
|
||||
/**
|
||||
* New FinSet with given number of fins and given base rotation angle.
|
||||
@ -1369,4 +1369,9 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona
|
||||
public InsideColorComponentHandler getInsideColorComponentHandler() {
|
||||
return this.insideColorComponentHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInsideColorComponentHandler(InsideColorComponentHandler handler) {
|
||||
this.insideColorComponentHandler = handler;
|
||||
}
|
||||
}
|
||||
|
@ -22,4 +22,6 @@ public interface InsideColorComponent {
|
||||
* @return the InsideColorComponentHandler
|
||||
*/
|
||||
InsideColorComponentHandler getInsideColorComponentHandler();
|
||||
|
||||
void setInsideColorComponentHandler(InsideColorComponentHandler handler);
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ public class LaunchLug extends Tube implements AnglePositionable, BoxBounded, Li
|
||||
private int instanceCount = 1;
|
||||
private double instanceSeparation = 0; // front-front along the positive rocket axis. i.e. [1,0,0];
|
||||
|
||||
private final InsideColorComponentHandler insideColorComponentHandler = new InsideColorComponentHandler(this);
|
||||
private InsideColorComponentHandler insideColorComponentHandler = new InsideColorComponentHandler(this);
|
||||
|
||||
public LaunchLug() {
|
||||
super(AxialMethod.MIDDLE);
|
||||
@ -333,4 +333,9 @@ public class LaunchLug extends Tube implements AnglePositionable, BoxBounded, Li
|
||||
public InsideColorComponentHandler getInsideColorComponentHandler() {
|
||||
return this.insideColorComponentHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInsideColorComponentHandler(InsideColorComponentHandler handler) {
|
||||
this.insideColorComponentHandler = handler;
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ import java.util.EventObject;
|
||||
public class NoseCone extends Transition implements InsideColorComponent {
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
|
||||
private final InsideColorComponentHandler insideColorComponentHandler = new InsideColorComponentHandler(this);
|
||||
private InsideColorComponentHandler insideColorComponentHandler = new InsideColorComponentHandler(this);
|
||||
|
||||
/********* Constructors **********/
|
||||
public NoseCone() {
|
||||
@ -155,4 +155,9 @@ public class NoseCone extends Transition implements InsideColorComponent {
|
||||
public InsideColorComponentHandler getInsideColorComponentHandler() {
|
||||
return this.insideColorComponentHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInsideColorComponentHandler(InsideColorComponentHandler handler) {
|
||||
this.insideColorComponentHandler = handler;
|
||||
}
|
||||
}
|
||||
|
@ -134,7 +134,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
||||
/**
|
||||
* List of components that will set their properties to the same as the current component
|
||||
*/
|
||||
protected final List<RocketComponent> configListeners = new LinkedList<>();
|
||||
protected List<RocketComponent> configListeners = new LinkedList<>();
|
||||
|
||||
|
||||
/**
|
||||
@ -427,6 +427,20 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public RocketComponent clone() throws CloneNotSupportedException {
|
||||
RocketComponent clone = (RocketComponent) super.clone();
|
||||
// Make sure the InsideColorComponentHandler is cloned
|
||||
if (clone instanceof InsideColorComponent && this instanceof InsideColorComponent) {
|
||||
InsideColorComponentHandler icch = new InsideColorComponentHandler(clone);
|
||||
icch.copyFrom(((InsideColorComponent) this).getInsideColorComponentHandler());
|
||||
((InsideColorComponent) clone).setInsideColorComponentHandler(icch);
|
||||
}
|
||||
// Make sure the config listeners aren't cloned
|
||||
clone.configListeners = new LinkedList<>();
|
||||
return clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if any of this component's children are a RecoveryDevice
|
||||
*/
|
||||
@ -1983,7 +1997,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
||||
* @return true if listener was successfully added, false if not
|
||||
*/
|
||||
public boolean addConfigListener(RocketComponent listener) {
|
||||
if (listener == null) {
|
||||
if (listener == null || configListeners.contains(listener) || listener == this) {
|
||||
return false;
|
||||
}
|
||||
configListeners.add(listener);
|
||||
@ -2247,6 +2261,12 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
||||
this.id = src.id;
|
||||
this.displayOrder_side = src.displayOrder_side;
|
||||
this.displayOrder_back = src.displayOrder_back;
|
||||
this.configListeners = new LinkedList<>();
|
||||
if (this instanceof InsideColorComponent && src instanceof InsideColorComponent) {
|
||||
InsideColorComponentHandler icch = new InsideColorComponentHandler(this);
|
||||
icch.copyFrom(((InsideColorComponent) src).getInsideColorComponentHandler());
|
||||
((InsideColorComponent) this).setInsideColorComponentHandler(icch);
|
||||
}
|
||||
|
||||
// Add source components to invalidation tree
|
||||
for (RocketComponent c : src) {
|
||||
|
@ -44,7 +44,7 @@ public class Transition extends SymmetricComponent implements InsideColorCompone
|
||||
// Used to cache the clip length
|
||||
private double clipLength = -1;
|
||||
|
||||
private final InsideColorComponentHandler insideColorComponentHandler = new InsideColorComponentHandler(this);
|
||||
private InsideColorComponentHandler insideColorComponentHandler = new InsideColorComponentHandler(this);
|
||||
|
||||
public Transition() {
|
||||
super();
|
||||
@ -732,6 +732,11 @@ public class Transition extends SymmetricComponent implements InsideColorCompone
|
||||
return this.insideColorComponentHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInsideColorComponentHandler(InsideColorComponentHandler handler) {
|
||||
this.insideColorComponentHandler = handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* An enumeration listing the possible shapes of transitions.
|
||||
*
|
||||
|
@ -28,7 +28,7 @@ public class TubeFinSet extends Tube implements AxialPositionable, BoxBounded, R
|
||||
private AngleMethod angleMethod = AngleMethod.FIXED;
|
||||
protected RadiusMethod radiusMethod = RadiusMethod.RELATIVE;
|
||||
|
||||
private final InsideColorComponentHandler insideColorComponentHandler = new InsideColorComponentHandler(this);
|
||||
private InsideColorComponentHandler insideColorComponentHandler = new InsideColorComponentHandler(this);
|
||||
|
||||
/**
|
||||
* Rotation angle of the first fin. Zero corresponds to the positive y-axis.
|
||||
@ -523,4 +523,9 @@ public class TubeFinSet extends Tube implements AxialPositionable, BoxBounded, R
|
||||
public InsideColorComponentHandler getInsideColorComponentHandler() {
|
||||
return this.insideColorComponentHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInsideColorComponentHandler(InsideColorComponentHandler handler) {
|
||||
this.insideColorComponentHandler = handler;
|
||||
}
|
||||
}
|
||||
|
@ -345,6 +345,7 @@ public class BasicFrame extends JFrame {
|
||||
c.clearConfigListeners();
|
||||
for (int i = 1; i < paths.length; i++) {
|
||||
RocketComponent listener = (RocketComponent) paths[i].getLastPathComponent();
|
||||
listener.clearConfigListeners();
|
||||
c.addConfigListener(listener);
|
||||
}
|
||||
ComponentConfigDialog.showDialog(BasicFrame.this, BasicFrame.this.document, c);
|
||||
|
@ -791,7 +791,8 @@ public class RocketActions {
|
||||
Simulation[] sims = selectionModel.getSelectedSimulations();
|
||||
|
||||
if (isCopyable(components)) {
|
||||
ComponentConfigDialog.disposeDialog();
|
||||
if (ComponentConfigDialog.isDialogVisible())
|
||||
ComponentConfigDialog.disposeDialog();
|
||||
|
||||
List<RocketComponent> copiedComponents = copyComponentsMaintainParent(components);
|
||||
OpenRocketClipboard.setClipboard(copiedComponents);
|
||||
@ -885,7 +886,9 @@ public class RocketActions {
|
||||
RocketComponent component = components.get(0);
|
||||
if (components.size() > 1) {
|
||||
for (int i = 1; i < components.size(); i++) {
|
||||
component.addConfigListener(components.get(i));
|
||||
RocketComponent listener = components.get(i);
|
||||
listener.clearConfigListeners(); // Make sure all the listeners are cleared (should not be possible, but just in case)
|
||||
component.addConfigListener(listener);
|
||||
}
|
||||
}
|
||||
ComponentConfigDialog.showDialog(parentFrame, document, component);
|
||||
|
Loading…
x
Reference in New Issue
Block a user