From d30083c05bf77a7c480a0615855bdb96a458e71e Mon Sep 17 00:00:00 2001 From: Kevin Ruland Date: Mon, 5 Dec 2011 18:49:49 +0000 Subject: [PATCH] Reduce dependency on swing ChangeListener and ChangeEvent classes. Changed the interface ChangeSource from using ChangeListener to using java.util.EventListener. Changed from using ChangeEvent object instances to using EventObject. Added marker interface StateChangeListener to declare a stateChanged method. --- .../aerodynamics/FlightConditions.java | 27 +++++----- .../sf/openrocket/document/Simulation.java | 29 ++++++----- .../openrocket/gui/adaptors/DoubleModel.java | 34 +++++++------ .../gui/adaptors/MotorConfigurationModel.java | 8 +-- .../gui/scalefigure/AbstractScaleFigure.java | 26 ++++++---- .../gui/scalefigure/RocketPanel.java | 28 ++++++----- .../modifiers/AbstractSimulationModifier.java | 23 +++++---- .../rocketcomponent/ComponentChangeEvent.java | 4 +- .../rocketcomponent/Configuration.java | 32 ++++++------ .../sf/openrocket/rocketcomponent/Rocket.java | 50 +++++++++---------- .../rocketcomponent/RocketComponent.java | 22 ++++---- .../simulation/SimulationOptions.java | 25 ++++++---- .../openrocket/util/AbstractChangeSource.java | 23 +++++---- src/net/sf/openrocket/util/ChangeSource.java | 6 +-- .../openrocket/util/StateChangeListener.java | 10 ++++ 15 files changed, 191 insertions(+), 156 deletions(-) create mode 100644 src/net/sf/openrocket/util/StateChangeListener.java diff --git a/src/net/sf/openrocket/aerodynamics/FlightConditions.java b/src/net/sf/openrocket/aerodynamics/FlightConditions.java index 45b9d20f4..0b079e682 100644 --- a/src/net/sf/openrocket/aerodynamics/FlightConditions.java +++ b/src/net/sf/openrocket/aerodynamics/FlightConditions.java @@ -1,11 +1,10 @@ package net.sf.openrocket.aerodynamics; import java.util.ArrayList; +import java.util.EventListener; +import java.util.EventObject; import java.util.List; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; - import net.sf.openrocket.models.atmosphere.AtmosphericConditions; import net.sf.openrocket.rocketcomponent.Configuration; import net.sf.openrocket.util.BugException; @@ -13,6 +12,7 @@ import net.sf.openrocket.util.ChangeSource; import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.MathUtil; import net.sf.openrocket.util.Monitorable; +import net.sf.openrocket.util.StateChangeListener; import net.sf.openrocket.util.UniqueID; /** @@ -23,8 +23,8 @@ import net.sf.openrocket.util.UniqueID; */ public class FlightConditions implements Cloneable, ChangeSource, Monitorable { - private List listenerList = new ArrayList(); - private ChangeEvent event = new ChangeEvent(this); + private List listenerList = new ArrayList(); + private EventObject event = new EventObject(this); /** Reference length used in calculations. */ @@ -409,8 +409,8 @@ public class FlightConditions implements Cloneable, ChangeSource, Monitorable { public FlightConditions clone() { try { FlightConditions cond = (FlightConditions) super.clone(); - cond.listenerList = new ArrayList(); - cond.event = new ChangeEvent(cond); + cond.listenerList = new ArrayList(); + cond.event = new EventObject(cond); cond.atmosphericConditions = atmosphericConditions.clone(); return cond; } catch (CloneNotSupportedException e) { @@ -445,20 +445,23 @@ public class FlightConditions implements Cloneable, ChangeSource, Monitorable { @Override - public void addChangeListener(ChangeListener listener) { + public void addChangeListener(EventListener listener) { listenerList.add(0, listener); } @Override - public void removeChangeListener(ChangeListener listener) { + public void removeChangeListener(EventListener listener) { listenerList.remove(listener); } protected void fireChangeEvent() { modID = UniqueID.next(); - ChangeListener[] listeners = listenerList.toArray(new ChangeListener[0]); - for (ChangeListener l : listeners) { - l.stateChanged(event); + // Copy the list before iterating to prevent concurrent modification exceptions. + EventListener[] listeners = listenerList.toArray(new EventListener[0]); + for (EventListener l : listeners) { + if ( l instanceof StateChangeListener ) { + ((StateChangeListener)l).stateChanged(event); + } } } } diff --git a/src/net/sf/openrocket/document/Simulation.java b/src/net/sf/openrocket/document/Simulation.java index 3c1e2c01a..74d3ab28e 100644 --- a/src/net/sf/openrocket/document/Simulation.java +++ b/src/net/sf/openrocket/document/Simulation.java @@ -1,10 +1,9 @@ package net.sf.openrocket.document; +import java.util.EventListener; +import java.util.EventObject; import java.util.List; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; - import net.sf.openrocket.aerodynamics.AerodynamicCalculator; import net.sf.openrocket.aerodynamics.BarrowmanCalculator; import net.sf.openrocket.aerodynamics.WarningSet; @@ -28,6 +27,7 @@ import net.sf.openrocket.util.ArrayList; import net.sf.openrocket.util.BugException; import net.sf.openrocket.util.ChangeSource; import net.sf.openrocket.util.SafetyMutex; +import net.sf.openrocket.util.StateChangeListener; /** * A class defining a simulation, its conditions and simulated data. @@ -79,7 +79,7 @@ public class Simulation implements ChangeSource, Cloneable { /** Listeners for this object */ - private List listeners = new ArrayList(); + private List listeners = new ArrayList(); /** The conditions actually used in the previous simulation, or null */ @@ -386,7 +386,7 @@ public class Simulation implements ChangeSource, Cloneable { copy.status = Status.NOT_SIMULATED; copy.options = this.options.clone(); copy.simulationListeners = this.simulationListeners.clone(); - copy.listeners = new ArrayList(); + copy.listeners = new ArrayList(); copy.simulatedConditions = null; copy.simulatedMotors = null; copy.simulatedData = null; @@ -429,34 +429,37 @@ public class Simulation implements ChangeSource, Cloneable { @Override - public void addChangeListener(ChangeListener listener) { + public void addChangeListener(EventListener listener) { mutex.verify(); listeners.add(listener); } @Override - public void removeChangeListener(ChangeListener listener) { + public void removeChangeListener(EventListener listener) { mutex.verify(); listeners.remove(listener); } protected void fireChangeEvent() { - ChangeListener[] ls = listeners.toArray(new ChangeListener[0]); - ChangeEvent e = new ChangeEvent(this); - for (ChangeListener l : ls) { - l.stateChanged(e); + EventObject e = new EventObject(this); + // Copy the list before iterating to prevent concurrent modification exceptions. + EventListener[] ls = listeners.toArray(new EventListener[0]); + for (EventListener l : ls) { + if ( l instanceof StateChangeListener ) { + ((StateChangeListener)l).stateChanged(e); + } } } - private class ConditionListener implements ChangeListener { + private class ConditionListener implements StateChangeListener { private Status oldStatus = null; @Override - public void stateChanged(ChangeEvent e) { + public void stateChanged(EventObject e) { if (getStatus() != oldStatus) { oldStatus = getStatus(); fireChangeEvent(); diff --git a/src/net/sf/openrocket/gui/adaptors/DoubleModel.java b/src/net/sf/openrocket/gui/adaptors/DoubleModel.java index 3b4e0dae2..3b5174593 100644 --- a/src/net/sf/openrocket/gui/adaptors/DoubleModel.java +++ b/src/net/sf/openrocket/gui/adaptors/DoubleModel.java @@ -6,13 +6,14 @@ import java.beans.PropertyChangeListener; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; +import java.util.EventListener; +import java.util.EventObject; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.BoundedRangeModel; import javax.swing.SpinnerModel; import javax.swing.SpinnerNumberModel; -import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import net.sf.openrocket.logging.LogHelper; @@ -26,6 +27,7 @@ import net.sf.openrocket.util.Invalidator; import net.sf.openrocket.util.MathUtil; import net.sf.openrocket.util.MemoryManagement; import net.sf.openrocket.util.Reflection; +import net.sf.openrocket.util.StateChangeListener; /** @@ -42,7 +44,7 @@ import net.sf.openrocket.util.Reflection; * @author Sampo Niskanen */ -public class DoubleModel implements ChangeListener, ChangeSource, Invalidatable { +public class DoubleModel implements StateChangeListener, ChangeSource, Invalidatable { private static final LogHelper log = Application.getLogger(); @@ -147,7 +149,7 @@ public class DoubleModel implements ChangeListener, ChangeSource, Invalidatable //////////// JSlider model //////////// - private class ValueSliderModel implements BoundedRangeModel, ChangeListener, Invalidatable { + private class ValueSliderModel implements BoundedRangeModel, StateChangeListener, Invalidatable { private static final int MAX = 1000; /* @@ -361,7 +363,7 @@ public class DoubleModel implements ChangeListener, ChangeSource, Invalidatable } @Override - public void stateChanged(ChangeEvent e) { + public void stateChanged(EventObject e) { // Min or max range has changed. // Fire if not already firing if (firing == 0) @@ -392,7 +394,7 @@ public class DoubleModel implements ChangeListener, ChangeSource, Invalidatable //////////// Action model //////////// - private class AutomaticActionModel extends AbstractAction implements ChangeListener, Invalidatable { + private class AutomaticActionModel extends AbstractAction implements StateChangeListener, Invalidatable { private boolean oldValue = false; public AutomaticActionModel() { @@ -453,7 +455,7 @@ public class DoubleModel implements ChangeListener, ChangeSource, Invalidatable // If the value has changed, generate an event to the listeners @Override - public void stateChanged(ChangeEvent e) { + public void stateChanged(EventObject e) { boolean newValue = isAutomatic(); if (oldValue == newValue) return; @@ -507,7 +509,7 @@ public class DoubleModel implements ChangeListener, ChangeSource, Invalidatable private final Method getAutoMethod; private final Method setAutoMethod; - private final ArrayList listeners = new ArrayList(); + private final ArrayList listeners = new ArrayList(); private final UnitGroup units; private Unit currentUnit; @@ -815,7 +817,7 @@ public class DoubleModel implements ChangeListener, ChangeSource, Invalidatable * @param l Listener to add. */ @Override - public void addChangeListener(ChangeListener l) { + public void addChangeListener(EventListener l) { checkState(true); if (listeners.isEmpty()) { @@ -836,7 +838,7 @@ public class DoubleModel implements ChangeListener, ChangeSource, Invalidatable * @param l Listener to remove. */ @Override - public void removeChangeListener(ChangeListener l) { + public void removeChangeListener(EventListener l) { checkState(false); listeners.remove(l); @@ -888,11 +890,15 @@ public class DoubleModel implements ChangeListener, ChangeSource, Invalidatable protected void fireStateChanged() { checkState(true); - Object[] l = listeners.toArray(); - ChangeEvent event = new ChangeEvent(this); + EventObject event = new EventObject(this); firing++; - for (int i = 0; i < l.length; i++) - ((ChangeListener) l[i]).stateChanged(event); + // Copy the list before iterating to prevent concurrent modification exceptions. + EventListener[] ls = listeners.toArray(new EventListener[0]); + for (EventListener l : ls) { + if ( l instanceof StateChangeListener ) { + ((StateChangeListener)l).stateChanged(event); + } + } firing--; } @@ -901,7 +907,7 @@ public class DoubleModel implements ChangeListener, ChangeSource, Invalidatable * it has, updates lastValue and generates ChangeEvents for all listeners of the model. */ @Override - public void stateChanged(ChangeEvent e) { + public void stateChanged(EventObject e) { checkState(true); double v = getValue(); diff --git a/src/net/sf/openrocket/gui/adaptors/MotorConfigurationModel.java b/src/net/sf/openrocket/gui/adaptors/MotorConfigurationModel.java index d2b2a9fcd..57852699e 100644 --- a/src/net/sf/openrocket/gui/adaptors/MotorConfigurationModel.java +++ b/src/net/sf/openrocket/gui/adaptors/MotorConfigurationModel.java @@ -1,13 +1,12 @@ package net.sf.openrocket.gui.adaptors; +import java.util.EventObject; import java.util.HashMap; import java.util.Map; import javax.swing.ComboBoxModel; import javax.swing.SwingUtilities; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; import javax.swing.event.EventListenerList; import javax.swing.event.ListDataEvent; import javax.swing.event.ListDataListener; @@ -19,8 +18,9 @@ import net.sf.openrocket.rocketcomponent.ComponentChangeEvent; import net.sf.openrocket.rocketcomponent.Configuration; import net.sf.openrocket.rocketcomponent.Rocket; import net.sf.openrocket.startup.Application; +import net.sf.openrocket.util.StateChangeListener; -public class MotorConfigurationModel implements ComboBoxModel, ChangeListener { +public class MotorConfigurationModel implements ComboBoxModel, StateChangeListener { private static final Translator trans = Application.getTranslator(); private static final String EDIT = trans.get("MotorCfgModel.Editcfg"); @@ -121,7 +121,7 @@ public class MotorConfigurationModel implements ComboBoxModel, ChangeListener { @Override - public void stateChanged(ChangeEvent e) { + public void stateChanged(EventObject e) { if (e instanceof ComponentChangeEvent) { // Ignore unnecessary changes if (!((ComponentChangeEvent)e).isMotorChange()) diff --git a/src/net/sf/openrocket/gui/scalefigure/AbstractScaleFigure.java b/src/net/sf/openrocket/gui/scalefigure/AbstractScaleFigure.java index 63d2f4698..02fbac586 100644 --- a/src/net/sf/openrocket/gui/scalefigure/AbstractScaleFigure.java +++ b/src/net/sf/openrocket/gui/scalefigure/AbstractScaleFigure.java @@ -2,14 +2,15 @@ package net.sf.openrocket.gui.scalefigure; import java.awt.Color; import java.awt.Dimension; +import java.util.EventListener; +import java.util.EventObject; import java.util.LinkedList; import java.util.List; import javax.swing.JPanel; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; import net.sf.openrocket.util.Prefs; +import net.sf.openrocket.util.StateChangeListener; public abstract class AbstractScaleFigure extends JPanel implements ScaleFigure { @@ -27,7 +28,7 @@ public abstract class AbstractScaleFigure extends JPanel implements ScaleFigure protected int borderPixelsWidth = DEFAULT_BORDER_PIXELS_WIDTH; protected int borderPixelsHeight = DEFAULT_BORDER_PIXELS_HEIGHT; - protected final List listeners = new LinkedList(); + protected final List listeners = new LinkedList(); public AbstractScaleFigure() { @@ -106,23 +107,26 @@ public abstract class AbstractScaleFigure extends JPanel implements ScaleFigure @Override - public void addChangeListener(ChangeListener listener) { + public void addChangeListener(EventListener listener) { listeners.add(0, listener); } @Override - public void removeChangeListener(ChangeListener listener) { + public void removeChangeListener(EventListener listener) { listeners.remove(listener); } - private ChangeEvent changeEvent = null; + private EventObject changeEvent = null; protected void fireChangeEvent() { - ChangeListener[] list = listeners.toArray(new ChangeListener[0]); - for (ChangeListener l : list) { - if (changeEvent == null) - changeEvent = new ChangeEvent(this); - l.stateChanged(changeEvent); + if (changeEvent == null) + changeEvent = new EventObject(this); + // Copy the list before iterating to prevent concurrent modification exceptions. + EventListener[] list = listeners.toArray(new EventListener[0]); + for (EventListener l : list) { + if ( l instanceof StateChangeListener ) { + ((StateChangeListener)l).stateChanged(changeEvent); + } } } diff --git a/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java b/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java index 8381313c4..f9e2efd6b 100644 --- a/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java +++ b/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java @@ -9,6 +9,8 @@ import java.awt.event.InputEvent; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.Collection; +import java.util.EventListener; +import java.util.EventObject; import java.util.List; import java.util.concurrent.Executor; import java.util.concurrent.Executors; @@ -23,8 +25,6 @@ import javax.swing.JSlider; import javax.swing.JToggleButton; import javax.swing.JViewport; import javax.swing.SwingUtilities; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.TreePath; @@ -68,6 +68,7 @@ import net.sf.openrocket.util.Chars; import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.MathUtil; import net.sf.openrocket.util.Prefs; +import net.sf.openrocket.util.StateChangeListener; /** * A JPanel that contains a RocketFigure and buttons to manipulate the figure. @@ -110,7 +111,7 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change private SimulationWorker backgroundSimulationWorker = null; - private List listeners = new ArrayList(); + private List listeners = new ArrayList(); /** @@ -158,9 +159,9 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change createPanel(); - configuration.addChangeListener(new ChangeListener() { + configuration.addChangeListener(new StateChangeListener() { @Override - public void stateChanged(ChangeEvent e) { + public void stateChanged(EventObject e) { System.out.println("Configuration changed, calling updateFigure"); updateExtras(); figure.updateFigure(); @@ -374,20 +375,21 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change @Override - public void addChangeListener(ChangeListener listener) { + public void addChangeListener(EventListener listener) { listeners.add(0, listener); } @Override - public void removeChangeListener(ChangeListener listener) { + public void removeChangeListener(EventListener listener) { listeners.remove(listener); } protected void fireChangeEvent() { - ChangeEvent e = new ChangeEvent(this); - ChangeListener[] list = listeners.toArray(new ChangeListener[0]); - for (ChangeListener l : list) { - l.stateChanged(e); + EventObject e = new EventObject(this); + for (EventListener l : listeners) { + if ( l instanceof StateChangeListener ) { + ((StateChangeListener)l).stateChanged(e); + } } } @@ -711,7 +713,7 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change * * @author Sampo Niskanen */ - private class FigureTypeAction extends AbstractAction implements ChangeListener { + private class FigureTypeAction extends AbstractAction implements StateChangeListener { private final int type; public FigureTypeAction(int type) { @@ -732,7 +734,7 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change } @Override - public void stateChanged(ChangeEvent e) { + public void stateChanged(EventObject e) { putValue(Action.SELECTED_KEY, figure.getType() == type); } } diff --git a/src/net/sf/openrocket/optimization/rocketoptimization/modifiers/AbstractSimulationModifier.java b/src/net/sf/openrocket/optimization/rocketoptimization/modifiers/AbstractSimulationModifier.java index 46c167d48..1d8c0fd18 100644 --- a/src/net/sf/openrocket/optimization/rocketoptimization/modifiers/AbstractSimulationModifier.java +++ b/src/net/sf/openrocket/optimization/rocketoptimization/modifiers/AbstractSimulationModifier.java @@ -1,16 +1,16 @@ package net.sf.openrocket.optimization.rocketoptimization.modifiers; import java.util.ArrayList; +import java.util.EventListener; +import java.util.EventObject; import java.util.List; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; - import net.sf.openrocket.document.Simulation; import net.sf.openrocket.optimization.general.OptimizationException; import net.sf.openrocket.optimization.rocketoptimization.SimulationModifier; import net.sf.openrocket.unit.UnitGroup; import net.sf.openrocket.util.MathUtil; +import net.sf.openrocket.util.StateChangeListener; /** * An abstract implementation of the SimulationModifier interface. An implementation @@ -29,7 +29,7 @@ public abstract class AbstractSimulationModifier implements SimulationModifier { private double minValue = 0.0; private double maxValue = 1.0; - private final List listeners = new ArrayList(); + private final List listeners = new ArrayList(); /** @@ -148,12 +148,12 @@ public abstract class AbstractSimulationModifier implements SimulationModifier { @Override - public void addChangeListener(ChangeListener listener) { + public void addChangeListener(EventListener listener) { listeners.add(listener); } @Override - public void removeChangeListener(ChangeListener listener) { + public void removeChangeListener(EventListener listener) { listeners.remove(listener); } @@ -162,10 +162,13 @@ public abstract class AbstractSimulationModifier implements SimulationModifier { * Fire a change event to the listeners. */ protected void fireChangeEvent() { - ChangeListener[] array = listeners.toArray(new ChangeListener[0]); - ChangeEvent event = new ChangeEvent(this); - for (ChangeListener l : array) { - l.stateChanged(event); + EventObject event = new EventObject(this); + // Copy the list before iterating to prevent concurrent modification exceptions. + EventListener[] list = listeners.toArray(new EventListener[0]); + for (EventListener l : list) { + if ( l instanceof StateChangeListener ) { + ((StateChangeListener)l).stateChanged(event); + } } } diff --git a/src/net/sf/openrocket/rocketcomponent/ComponentChangeEvent.java b/src/net/sf/openrocket/rocketcomponent/ComponentChangeEvent.java index 60123e876..5a2a2e24f 100644 --- a/src/net/sf/openrocket/rocketcomponent/ComponentChangeEvent.java +++ b/src/net/sf/openrocket/rocketcomponent/ComponentChangeEvent.java @@ -1,8 +1,8 @@ package net.sf.openrocket.rocketcomponent; -import javax.swing.event.ChangeEvent; +import java.util.EventObject; -public class ComponentChangeEvent extends ChangeEvent { +public class ComponentChangeEvent extends EventObject { private static final long serialVersionUID = 1L; diff --git a/src/net/sf/openrocket/rocketcomponent/Configuration.java b/src/net/sf/openrocket/rocketcomponent/Configuration.java index 404e84c32..4a76df715 100644 --- a/src/net/sf/openrocket/rocketcomponent/Configuration.java +++ b/src/net/sf/openrocket/rocketcomponent/Configuration.java @@ -3,20 +3,19 @@ package net.sf.openrocket.rocketcomponent; import java.util.BitSet; import java.util.Collection; import java.util.Collections; +import java.util.EventListener; +import java.util.EventObject; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; -import javax.swing.event.EventListenerList; - import net.sf.openrocket.util.ArrayList; import net.sf.openrocket.util.BugException; import net.sf.openrocket.util.ChangeSource; import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.MathUtil; import net.sf.openrocket.util.Monitorable; +import net.sf.openrocket.util.StateChangeListener; /** @@ -34,7 +33,7 @@ public class Configuration implements Cloneable, ChangeSource, ComponentChangeLi private String motorConfiguration = null; - private EventListenerList listenerList = new EventListenerList(); + private List listenerList = new ArrayList(); /* Cached data */ @@ -199,26 +198,27 @@ public class Configuration implements Cloneable, ChangeSource, ComponentChangeLi //////////////// Listeners //////////////// @Override - public void addChangeListener(ChangeListener listener) { - listenerList.add(ChangeListener.class, listener); + public void addChangeListener(EventListener listener) { + listenerList.add(listener); } @Override - public void removeChangeListener(ChangeListener listener) { - listenerList.remove(ChangeListener.class, listener); + public void removeChangeListener(EventListener listener) { + listenerList.remove(listener); } protected void fireChangeEvent() { - Object[] listeners = listenerList.getListenerList(); - ChangeEvent e = new ChangeEvent(this); + EventObject e = new EventObject(this); this.modID++; boundsModID = -1; refLengthModID = -1; - - for (int i = listeners.length - 2; i >= 0; i -= 2) { - if (listeners[i] == ChangeListener.class) { - ((ChangeListener) listeners[i + 1]).stateChanged(e); + + // Copy the list before iterating to prevent concurrent modification exceptions. + EventListener[] listeners = listenerList.toArray(new EventListener[0]); + for (EventListener l : listeners) { + if ( l instanceof StateChangeListener ) { + ((StateChangeListener)l).stateChanged(e); } } } @@ -340,7 +340,7 @@ public class Configuration implements Cloneable, ChangeSource, ComponentChangeLi public Configuration clone() { try { Configuration config = (Configuration) super.clone(); - config.listenerList = new EventListenerList(); + config.listenerList = new ArrayList(); config.stages = (BitSet) this.stages.clone(); config.cachedBounds = new ArrayList(); config.boundsModID = -1; diff --git a/src/net/sf/openrocket/rocketcomponent/Rocket.java b/src/net/sf/openrocket/rocketcomponent/Rocket.java index 4115c87b6..d9dac38ad 100644 --- a/src/net/sf/openrocket/rocketcomponent/Rocket.java +++ b/src/net/sf/openrocket/rocketcomponent/Rocket.java @@ -2,15 +2,13 @@ package net.sf.openrocket.rocketcomponent; import java.util.Collection; import java.util.Collections; +import java.util.EventListener; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.UUID; -import javax.swing.event.ChangeListener; -import javax.swing.event.EventListenerList; - import net.sf.openrocket.gui.main.ExceptionHandler; import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.logging.LogHelper; @@ -20,6 +18,7 @@ import net.sf.openrocket.util.ArrayList; import net.sf.openrocket.util.Chars; import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.MathUtil; +import net.sf.openrocket.util.StateChangeListener; import net.sf.openrocket.util.UniqueID; @@ -43,7 +42,7 @@ public class Rocket extends RocketComponent { /** * List of component change listeners. */ - private EventListenerList listenerList = new EventListenerList(); + private List listenerList = new ArrayList(); /** * When freezeList != null, events are not dispatched but stored in the list. @@ -341,46 +340,48 @@ public class Rocket extends RocketComponent { */ public void resetListeners() { // System.out.println("RESETTING LISTENER LIST of Rocket "+this); - listenerList = new EventListenerList(); + listenerList = new ArrayList(); } public void printListeners() { - System.out.println("" + this + " has " + listenerList.getListenerCount() + " listeners:"); - Object[] list = listenerList.getListenerList(); - for (int i = 1; i < list.length; i += 2) - System.out.println(" " + ((i + 1) / 2) + ": " + list[i]); + System.out.println("" + this + " has " + listenerList.size() + " listeners:"); + int i =0; + for( EventListener l : listenerList ) { + System.out.println(" " + (i) + ": " + l); + i++; + } } @Override public void addComponentChangeListener(ComponentChangeListener l) { checkState(); - listenerList.add(ComponentChangeListener.class, l); + listenerList.add(l); log.verbose("Added ComponentChangeListener " + l + ", current number of listeners is " + - listenerList.getListenerCount()); + listenerList.size()); } @Override public void removeComponentChangeListener(ComponentChangeListener l) { - listenerList.remove(ComponentChangeListener.class, l); + listenerList.remove(l); log.verbose("Removed ComponentChangeListener " + l + ", current number of listeners is " + - listenerList.getListenerCount()); + listenerList.size()); } @Override - public void addChangeListener(ChangeListener l) { + public void addChangeListener(EventListener l) { checkState(); - listenerList.add(ChangeListener.class, l); + listenerList.add(l); log.verbose("Added ChangeListener " + l + ", current number of listeners is " + - listenerList.getListenerCount()); + listenerList.size()); } @Override - public void removeChangeListener(ChangeListener l) { - listenerList.remove(ChangeListener.class, l); + public void removeChangeListener(EventListener l) { + listenerList.remove(l); log.verbose("Removed ChangeListener " + l + ", current number of listeners is " + - listenerList.getListenerCount()); + listenerList.size()); } @@ -419,12 +420,11 @@ public class Rocket extends RocketComponent { } // Notify all listeners - Object[] listeners = listenerList.getListenerList(); - for (int i = listeners.length - 2; i >= 0; i -= 2) { - if (listeners[i] == ComponentChangeListener.class) { - ((ComponentChangeListener) listeners[i + 1]).componentChanged(e); - } else if (listeners[i] == ChangeListener.class) { - ((ChangeListener) listeners[i + 1]).stateChanged(e); + for ( EventListener l : listenerList ) { + if ( l instanceof ComponentChangeListener ) { + ((ComponentChangeListener) l ).componentChanged(e); + } else if ( l instanceof StateChangeListener ) { + ((StateChangeListener) l ).stateChanged(e); } } } finally { diff --git a/src/net/sf/openrocket/rocketcomponent/RocketComponent.java b/src/net/sf/openrocket/rocketcomponent/RocketComponent.java index bde01f655..fee3593f4 100644 --- a/src/net/sf/openrocket/rocketcomponent/RocketComponent.java +++ b/src/net/sf/openrocket/rocketcomponent/RocketComponent.java @@ -1,5 +1,14 @@ package net.sf.openrocket.rocketcomponent; +import java.awt.Color; +import java.util.ArrayDeque; +import java.util.Collection; +import java.util.Deque; +import java.util.EventListener; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; + import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.logging.LogHelper; import net.sf.openrocket.preset.ComponentPreset; @@ -14,15 +23,6 @@ import net.sf.openrocket.util.MathUtil; import net.sf.openrocket.util.SafetyMutex; import net.sf.openrocket.util.UniqueID; -import javax.swing.event.ChangeListener; -import java.awt.*; -import java.util.ArrayDeque; -import java.util.Collection; -import java.util.Deque; -import java.util.Iterator; -import java.util.List; -import java.util.NoSuchElementException; - public abstract class RocketComponent implements ChangeSource, Cloneable, Iterable { private static final LogHelper log = Application.getLogger(); @@ -1470,7 +1470,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab * @throws IllegalStateException - if the root component is not a Rocket */ @Override - public void addChangeListener(ChangeListener l) { + public void addChangeListener(EventListener l) { checkState(); getRocket().addChangeListener(l); } @@ -1484,7 +1484,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab * @param l Listener to remove */ @Override - public void removeChangeListener(ChangeListener l) { + public void removeChangeListener(EventListener l) { if (this.parent != null) { getRoot().removeChangeListener(l); } diff --git a/src/net/sf/openrocket/simulation/SimulationOptions.java b/src/net/sf/openrocket/simulation/SimulationOptions.java index e6e8f821a..7734ec5da 100644 --- a/src/net/sf/openrocket/simulation/SimulationOptions.java +++ b/src/net/sf/openrocket/simulation/SimulationOptions.java @@ -1,12 +1,11 @@ package net.sf.openrocket.simulation; import java.util.ArrayList; +import java.util.EventListener; +import java.util.EventObject; import java.util.List; import java.util.Random; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; - import net.sf.openrocket.aerodynamics.BarrowmanCalculator; import net.sf.openrocket.masscalc.BasicMassCalculator; import net.sf.openrocket.models.atmosphere.AtmosphericModel; @@ -19,6 +18,7 @@ import net.sf.openrocket.util.BugException; import net.sf.openrocket.util.ChangeSource; import net.sf.openrocket.util.GeodeticComputationStrategy; import net.sf.openrocket.util.MathUtil; +import net.sf.openrocket.util.StateChangeListener; import net.sf.openrocket.util.Utils; import net.sf.openrocket.util.WorldCoordinate; @@ -85,7 +85,7 @@ public class SimulationOptions implements ChangeSource, Cloneable { private boolean calculateExtras = true; - private List listeners = new ArrayList(); + private List listeners = new ArrayList(); @@ -386,7 +386,7 @@ public class SimulationOptions implements ChangeSource, Cloneable { public SimulationOptions clone() { try { SimulationOptions copy = (SimulationOptions) super.clone(); - copy.listeners = new ArrayList(); + copy.listeners = new ArrayList(); return copy; } catch (CloneNotSupportedException e) { throw new BugException(e); @@ -477,22 +477,25 @@ public class SimulationOptions implements ChangeSource, Cloneable { } @Override - public void addChangeListener(ChangeListener listener) { + public void addChangeListener(EventListener listener) { listeners.add(listener); } @Override - public void removeChangeListener(ChangeListener listener) { + public void removeChangeListener(EventListener listener) { listeners.remove(listener); } - private final ChangeEvent event = new ChangeEvent(this); + private final EventObject event = new EventObject(this); private void fireChangeEvent() { - ChangeListener[] array = listeners.toArray(new ChangeListener[0]); - for (int i = array.length - 1; i >= 0; i--) { - array[i].stateChanged(event); + // Copy the list before iterating to prevent concurrent modification exceptions. + EventListener[] list = listeners.toArray(new EventListener[0]); + for (EventListener l : list) { + if ( l instanceof StateChangeListener ) { + ((StateChangeListener)l).stateChanged(event); + } } } diff --git a/src/net/sf/openrocket/util/AbstractChangeSource.java b/src/net/sf/openrocket/util/AbstractChangeSource.java index 14109da0d..57664aed3 100644 --- a/src/net/sf/openrocket/util/AbstractChangeSource.java +++ b/src/net/sf/openrocket/util/AbstractChangeSource.java @@ -1,10 +1,9 @@ package net.sf.openrocket.util; +import java.util.EventListener; +import java.util.EventObject; import java.util.List; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; - import net.sf.openrocket.logging.LogHelper; import net.sf.openrocket.startup.Application; @@ -16,19 +15,19 @@ import net.sf.openrocket.startup.Application; public abstract class AbstractChangeSource implements ChangeSource { private static final LogHelper log = Application.getLogger(); - private final List listeners = new ArrayList(); + private final List listeners = new ArrayList(); - private final ChangeEvent event = new ChangeEvent(this); + private final EventObject event = new EventObject(this); @Override - public final void addChangeListener(ChangeListener listener) { + public final void addChangeListener(EventListener listener) { listeners.add(listener); log.verbose(1, "Adding change listeners, listener count is now " + listeners.size()); } @Override - public final void removeChangeListener(ChangeListener listener) { + public final void removeChangeListener(EventListener listener) { listeners.remove(listener); log.verbose(1, "Removing change listeners, listener count is now " + listeners.size()); } @@ -38,10 +37,12 @@ public abstract class AbstractChangeSource implements ChangeSource { * Fire a change event to all listeners. */ protected void fireChangeEvent() { - ChangeListener[] array = listeners.toArray(new ChangeListener[0]); - - for (ChangeListener l : array) { - l.stateChanged(event); + // Copy the list before iterating to prevent concurrent modification exceptions. + EventListener[] list = listeners.toArray(new EventListener[0]); + for (EventListener l : list) { + if ( l instanceof StateChangeListener ) { + ((StateChangeListener)l).stateChanged(event); + } } } } diff --git a/src/net/sf/openrocket/util/ChangeSource.java b/src/net/sf/openrocket/util/ChangeSource.java index 5d166cd54..f6669ef3a 100644 --- a/src/net/sf/openrocket/util/ChangeSource.java +++ b/src/net/sf/openrocket/util/ChangeSource.java @@ -1,6 +1,6 @@ package net.sf.openrocket.util; -import javax.swing.event.ChangeListener; +import java.util.EventListener; /** * An interface defining an object firing ChangeEvents. Why isn't this included in the Java API?? @@ -9,7 +9,7 @@ import javax.swing.event.ChangeListener; */ public interface ChangeSource { - public void addChangeListener(ChangeListener listener); - public void removeChangeListener(ChangeListener listener); + public void addChangeListener(EventListener listener); + public void removeChangeListener(EventListener listener); } diff --git a/src/net/sf/openrocket/util/StateChangeListener.java b/src/net/sf/openrocket/util/StateChangeListener.java new file mode 100644 index 000000000..2d5e5df97 --- /dev/null +++ b/src/net/sf/openrocket/util/StateChangeListener.java @@ -0,0 +1,10 @@ +package net.sf.openrocket.util; + +import java.util.EventListener; +import java.util.EventObject; + +public interface StateChangeListener extends EventListener { + + public void stateChanged( EventObject e ); + +}