[#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
|
* @return true if listener was successfully added, false if not
|
||||||
*/
|
*/
|
||||||
public boolean addConfigListener(RocketComponent component, AppearanceBuilder ab) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
configListeners.put(component, ab);
|
configListeners.put(component, ab);
|
||||||
|
@ -31,7 +31,7 @@ public class BodyTube extends SymmetricComponent implements BoxBounded, MotorMou
|
|||||||
|
|
||||||
private MotorConfigurationSet motors;
|
private MotorConfigurationSet motors;
|
||||||
|
|
||||||
private final InsideColorComponentHandler insideColorComponentHandler = new InsideColorComponentHandler(this);
|
private InsideColorComponentHandler insideColorComponentHandler = new InsideColorComponentHandler(this);
|
||||||
|
|
||||||
public BodyTube() {
|
public BodyTube() {
|
||||||
this(8 * DEFAULT_RADIUS, DEFAULT_RADIUS);
|
this(8 * DEFAULT_RADIUS, DEFAULT_RADIUS);
|
||||||
@ -521,6 +521,11 @@ public class BodyTube extends SymmetricComponent implements BoxBounded, MotorMou
|
|||||||
return this.insideColorComponentHandler;
|
return this.insideColorComponentHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setInsideColorComponentHandler(InsideColorComponentHandler handler) {
|
||||||
|
this.insideColorComponentHandler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean addConfigListener(RocketComponent listener) {
|
public boolean addConfigListener(RocketComponent listener) {
|
||||||
boolean success = super.addConfigListener(listener);
|
boolean success = super.addConfigListener(listener);
|
||||||
|
@ -123,7 +123,7 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona
|
|||||||
private double totalVolume = Double.NaN;
|
private double totalVolume = Double.NaN;
|
||||||
private Coordinate centerOfMass = Coordinate.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.
|
* 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() {
|
public InsideColorComponentHandler getInsideColorComponentHandler() {
|
||||||
return this.insideColorComponentHandler;
|
return this.insideColorComponentHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setInsideColorComponentHandler(InsideColorComponentHandler handler) {
|
||||||
|
this.insideColorComponentHandler = handler;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,4 +22,6 @@ public interface InsideColorComponent {
|
|||||||
* @return the InsideColorComponentHandler
|
* @return the InsideColorComponentHandler
|
||||||
*/
|
*/
|
||||||
InsideColorComponentHandler getInsideColorComponentHandler();
|
InsideColorComponentHandler getInsideColorComponentHandler();
|
||||||
|
|
||||||
|
void setInsideColorComponentHandler(InsideColorComponentHandler handler);
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ public class LaunchLug extends Tube implements AnglePositionable, BoxBounded, Li
|
|||||||
private int instanceCount = 1;
|
private int instanceCount = 1;
|
||||||
private double instanceSeparation = 0; // front-front along the positive rocket axis. i.e. [1,0,0];
|
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() {
|
public LaunchLug() {
|
||||||
super(AxialMethod.MIDDLE);
|
super(AxialMethod.MIDDLE);
|
||||||
@ -333,4 +333,9 @@ public class LaunchLug extends Tube implements AnglePositionable, BoxBounded, Li
|
|||||||
public InsideColorComponentHandler getInsideColorComponentHandler() {
|
public InsideColorComponentHandler getInsideColorComponentHandler() {
|
||||||
return this.insideColorComponentHandler;
|
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 {
|
public class NoseCone extends Transition implements InsideColorComponent {
|
||||||
private static final Translator trans = Application.getTranslator();
|
private static final Translator trans = Application.getTranslator();
|
||||||
|
|
||||||
private final InsideColorComponentHandler insideColorComponentHandler = new InsideColorComponentHandler(this);
|
private InsideColorComponentHandler insideColorComponentHandler = new InsideColorComponentHandler(this);
|
||||||
|
|
||||||
/********* Constructors **********/
|
/********* Constructors **********/
|
||||||
public NoseCone() {
|
public NoseCone() {
|
||||||
@ -155,4 +155,9 @@ public class NoseCone extends Transition implements InsideColorComponent {
|
|||||||
public InsideColorComponentHandler getInsideColorComponentHandler() {
|
public InsideColorComponentHandler getInsideColorComponentHandler() {
|
||||||
return this.insideColorComponentHandler;
|
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
|
* 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
|
* 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
|
* @return true if listener was successfully added, false if not
|
||||||
*/
|
*/
|
||||||
public boolean addConfigListener(RocketComponent listener) {
|
public boolean addConfigListener(RocketComponent listener) {
|
||||||
if (listener == null) {
|
if (listener == null || configListeners.contains(listener) || listener == this) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
configListeners.add(listener);
|
configListeners.add(listener);
|
||||||
@ -2247,6 +2261,12 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
|||||||
this.id = src.id;
|
this.id = src.id;
|
||||||
this.displayOrder_side = src.displayOrder_side;
|
this.displayOrder_side = src.displayOrder_side;
|
||||||
this.displayOrder_back = src.displayOrder_back;
|
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
|
// Add source components to invalidation tree
|
||||||
for (RocketComponent c : src) {
|
for (RocketComponent c : src) {
|
||||||
|
@ -44,7 +44,7 @@ public class Transition extends SymmetricComponent implements InsideColorCompone
|
|||||||
// Used to cache the clip length
|
// Used to cache the clip length
|
||||||
private double clipLength = -1;
|
private double clipLength = -1;
|
||||||
|
|
||||||
private final InsideColorComponentHandler insideColorComponentHandler = new InsideColorComponentHandler(this);
|
private InsideColorComponentHandler insideColorComponentHandler = new InsideColorComponentHandler(this);
|
||||||
|
|
||||||
public Transition() {
|
public Transition() {
|
||||||
super();
|
super();
|
||||||
@ -732,6 +732,11 @@ public class Transition extends SymmetricComponent implements InsideColorCompone
|
|||||||
return this.insideColorComponentHandler;
|
return this.insideColorComponentHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setInsideColorComponentHandler(InsideColorComponentHandler handler) {
|
||||||
|
this.insideColorComponentHandler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An enumeration listing the possible shapes of transitions.
|
* 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;
|
private AngleMethod angleMethod = AngleMethod.FIXED;
|
||||||
protected RadiusMethod radiusMethod = RadiusMethod.RELATIVE;
|
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.
|
* 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() {
|
public InsideColorComponentHandler getInsideColorComponentHandler() {
|
||||||
return this.insideColorComponentHandler;
|
return this.insideColorComponentHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setInsideColorComponentHandler(InsideColorComponentHandler handler) {
|
||||||
|
this.insideColorComponentHandler = handler;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -345,6 +345,7 @@ public class BasicFrame extends JFrame {
|
|||||||
c.clearConfigListeners();
|
c.clearConfigListeners();
|
||||||
for (int i = 1; i < paths.length; i++) {
|
for (int i = 1; i < paths.length; i++) {
|
||||||
RocketComponent listener = (RocketComponent) paths[i].getLastPathComponent();
|
RocketComponent listener = (RocketComponent) paths[i].getLastPathComponent();
|
||||||
|
listener.clearConfigListeners();
|
||||||
c.addConfigListener(listener);
|
c.addConfigListener(listener);
|
||||||
}
|
}
|
||||||
ComponentConfigDialog.showDialog(BasicFrame.this, BasicFrame.this.document, c);
|
ComponentConfigDialog.showDialog(BasicFrame.this, BasicFrame.this.document, c);
|
||||||
|
@ -791,6 +791,7 @@ public class RocketActions {
|
|||||||
Simulation[] sims = selectionModel.getSelectedSimulations();
|
Simulation[] sims = selectionModel.getSelectedSimulations();
|
||||||
|
|
||||||
if (isCopyable(components)) {
|
if (isCopyable(components)) {
|
||||||
|
if (ComponentConfigDialog.isDialogVisible())
|
||||||
ComponentConfigDialog.disposeDialog();
|
ComponentConfigDialog.disposeDialog();
|
||||||
|
|
||||||
List<RocketComponent> copiedComponents = copyComponentsMaintainParent(components);
|
List<RocketComponent> copiedComponents = copyComponentsMaintainParent(components);
|
||||||
@ -885,7 +886,9 @@ public class RocketActions {
|
|||||||
RocketComponent component = components.get(0);
|
RocketComponent component = components.get(0);
|
||||||
if (components.size() > 1) {
|
if (components.size() > 1) {
|
||||||
for (int i = 1; i < components.size(); i++) {
|
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);
|
ComponentConfigDialog.showDialog(parentFrame, document, component);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user