From 1b309dd786a7e126b6be7e52edcfd07fd381b45b Mon Sep 17 00:00:00 2001 From: Kevin Ruland Date: Wed, 21 Dec 2011 16:23:47 +0000 Subject: [PATCH] Refactor UndoRedoAction out of OpenRocketDocument and move into gui packages. Added interface UndoRedoListener so the OpenRocketDocument can send notification to the Undo/Redo buttons when the state of the undo stack changes. --- .../document/OpenRocketDocument.java | 133 ++++-------------- .../openrocket/document/UndoRedoListener.java | 8 ++ .../sf/openrocket/gui/main/BasicFrame.java | 6 +- .../openrocket/gui/main/UndoRedoAction.java | 104 ++++++++++++++ test/net/sf/openrocket/IntegrationTest.java | 5 +- 5 files changed, 142 insertions(+), 114 deletions(-) create mode 100644 src/net/sf/openrocket/document/UndoRedoListener.java create mode 100644 src/net/sf/openrocket/gui/main/UndoRedoAction.java diff --git a/src/net/sf/openrocket/document/OpenRocketDocument.java b/src/net/sf/openrocket/document/OpenRocketDocument.java index 9cd3d841a..cafc98f33 100644 --- a/src/net/sf/openrocket/document/OpenRocketDocument.java +++ b/src/net/sf/openrocket/document/OpenRocketDocument.java @@ -1,18 +1,12 @@ package net.sf.openrocket.document; -import java.awt.event.ActionEvent; import java.io.File; import java.util.LinkedList; import java.util.List; -import javax.swing.AbstractAction; -import javax.swing.Action; - import net.sf.openrocket.document.events.DocumentChangeEvent; import net.sf.openrocket.document.events.DocumentChangeListener; import net.sf.openrocket.document.events.SimulationChangeEvent; -import net.sf.openrocket.gui.util.Icons; -import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.logging.LogHelper; import net.sf.openrocket.logging.TraceException; import net.sf.openrocket.rocketcomponent.ComponentChangeEvent; @@ -21,7 +15,6 @@ import net.sf.openrocket.rocketcomponent.Configuration; import net.sf.openrocket.rocketcomponent.Rocket; import net.sf.openrocket.startup.Application; import net.sf.openrocket.util.ArrayList; -import net.sf.openrocket.util.BugException; /** * Class describing an entire OpenRocket document, including a rocket and @@ -37,7 +30,6 @@ import net.sf.openrocket.util.BugException; */ public class OpenRocketDocument implements ComponentChangeListener { private static final LogHelper log = Application.getLogger(); - private static final Translator trans = Application.getTranslator(); /** * The minimum number of undo levels that are stored. @@ -54,8 +46,6 @@ public class OpenRocketDocument implements ComponentChangeListener { /** Whether an undo error has already been reported to the user */ private static boolean undoErrorReported = false; - - private final Rocket rocket; private final Configuration configuration; @@ -72,7 +62,7 @@ public class OpenRocketDocument implements ComponentChangeListener { */ private LinkedList undoHistory = new LinkedList(); private LinkedList undoDescription = new LinkedList(); - + /** * The position in the undoHistory we are currently at. If modifications have been * made to the rocket, the rocket is in "dirty" state and this points to the previous @@ -87,6 +77,8 @@ public class OpenRocketDocument implements ComponentChangeListener { private String storedDescription = null; + private ArrayList undoRedoListeners = new ArrayList(2); + private File file = null; private int savedID = -1; @@ -96,11 +88,6 @@ public class OpenRocketDocument implements ComponentChangeListener { private final List listeners = new ArrayList(); - /* These must be initialized after undo history is set up. */ - private final UndoRedoAction undoAction; - private final UndoRedoAction redoAction; - - public OpenRocketDocument(Rocket rocket) { this(rocket.getDefaultConfiguration()); } @@ -112,9 +99,6 @@ public class OpenRocketDocument implements ComponentChangeListener { clearUndo(); - undoAction = new UndoRedoAction(UndoRedoAction.UNDO); - redoAction = new UndoRedoAction(UndoRedoAction.REDO); - rocket.addComponentChangeListener(this); } @@ -322,16 +306,6 @@ public class OpenRocketDocument implements ComponentChangeListener { } - public Action getUndoAction() { - return undoAction; - } - - - public Action getRedoAction() { - return redoAction; - } - - /** * Clear the undo history. */ @@ -343,11 +317,8 @@ public class OpenRocketDocument implements ComponentChangeListener { undoHistory.add(rocket.copyWithOriginalID()); undoDescription.add(null); undoPosition = 0; - - if (undoAction != null) - undoAction.setAllValues(); - if (redoAction != null) - redoAction.setAllValues(); + + fireUndoRedoChangeEvent(); } @@ -370,8 +341,7 @@ public class OpenRocketDocument implements ComponentChangeListener { undoDescription.set(undoPosition, nextDescription); } - undoAction.setAllValues(); - redoAction.setAllValues(); + fireUndoRedoChangeEvent(); } @@ -430,8 +400,7 @@ public class OpenRocketDocument implements ComponentChangeListener { " undoHistory.size=" + undoHistory.size() + " isClean=" + isCleanState()); if (!isUndoAvailable()) { logUndoError("Undo not available"); - undoAction.setAllValues(); - redoAction.setAllValues(); + fireUndoRedoChangeEvent(); return; } if (storedDescription != null) { @@ -468,8 +437,7 @@ public class OpenRocketDocument implements ComponentChangeListener { " undoHistory.size=" + undoHistory.size() + " isClean=" + isCleanState()); if (!isRedoAvailable()) { logUndoError("Redo not available"); - undoAction.setAllValues(); - redoAction.setAllValues(); + fireUndoRedoChangeEvent(); return; } if (storedDescription != null) { @@ -526,6 +494,22 @@ public class OpenRocketDocument implements ComponentChangeListener { /////// Listeners + public void addUndoRedoListener( UndoRedoListener listener ) { + undoRedoListeners.add(listener); + } + + public void removeUndoRedoListener( UndoRedoListener listener ) { + undoRedoListeners.remove(listener); + } + + private void fireUndoRedoChangeEvent() { + UndoRedoListener[] array = undoRedoListeners.toArray(new UndoRedoListener[0]); + for (UndoRedoListener l : array) { + l.setAllValues(); + } + + } + public void addDocumentChangeListener(DocumentChangeListener listener) { listeners.add(listener); } @@ -544,73 +528,4 @@ public class OpenRocketDocument implements ComponentChangeListener { - /** - * Inner class to implement undo/redo actions. - */ - private class UndoRedoAction extends AbstractAction { - public static final int UNDO = 1; - public static final int REDO = 2; - - private final int type; - - // Sole constructor - public UndoRedoAction(int type) { - if (type != UNDO && type != REDO) { - throw new IllegalArgumentException("Unknown type = " + type); - } - this.type = type; - setAllValues(); - } - - - // Actual action to make - @Override - public void actionPerformed(ActionEvent e) { - switch (type) { - case UNDO: - log.user("Performing undo, event=" + e); - undo(); - break; - - case REDO: - log.user("Performing redo, event=" + e); - redo(); - break; - } - } - - - // Set all the values correctly (name and enabled/disabled status) - public void setAllValues() { - String name, desc; - boolean actionEnabled; - - switch (type) { - case UNDO: - //// Undo - name = trans.get("OpenRocketDocument.Undo"); - desc = getUndoDescription(); - actionEnabled = isUndoAvailable(); - this.putValue(SMALL_ICON, Icons.EDIT_UNDO); - break; - - case REDO: - ////Redo - name = trans.get("OpenRocketDocument.Redo"); - desc = getRedoDescription(); - actionEnabled = isRedoAvailable(); - this.putValue(SMALL_ICON, Icons.EDIT_REDO); - break; - - default: - throw new BugException("illegal type=" + type); - } - - if (desc != null) - name = name + " (" + desc + ")"; - - putValue(NAME, name); - setEnabled(actionEnabled); - } - } } diff --git a/src/net/sf/openrocket/document/UndoRedoListener.java b/src/net/sf/openrocket/document/UndoRedoListener.java new file mode 100644 index 000000000..4f7900ea6 --- /dev/null +++ b/src/net/sf/openrocket/document/UndoRedoListener.java @@ -0,0 +1,8 @@ +package net.sf.openrocket.document; + +import java.util.EventListener; + +public interface UndoRedoListener extends EventListener { + + public void setAllValues(); +} diff --git a/src/net/sf/openrocket/gui/main/BasicFrame.java b/src/net/sf/openrocket/gui/main/BasicFrame.java index 417b67e64..04175fe59 100644 --- a/src/net/sf/openrocket/gui/main/BasicFrame.java +++ b/src/net/sf/openrocket/gui/main/BasicFrame.java @@ -554,7 +554,7 @@ public class BasicFrame extends JFrame { menubar.add(menu); - Action action = document.getUndoAction(); + Action action = UndoRedoAction.newUndoAction(document); item = new JMenuItem(action); item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z, ActionEvent.CTRL_MASK)); item.setMnemonic(KeyEvent.VK_U); @@ -562,8 +562,8 @@ public class BasicFrame extends JFrame { item.getAccessibleContext().setAccessibleDescription(trans.get("main.menu.edit.undo.desc")); menu.add(item); - - action = document.getRedoAction(); + + action = UndoRedoAction.newRedoAction(document); item = new JMenuItem(action); item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Y, ActionEvent.CTRL_MASK)); item.setMnemonic(KeyEvent.VK_R); diff --git a/src/net/sf/openrocket/gui/main/UndoRedoAction.java b/src/net/sf/openrocket/gui/main/UndoRedoAction.java new file mode 100644 index 000000000..08c31c7e7 --- /dev/null +++ b/src/net/sf/openrocket/gui/main/UndoRedoAction.java @@ -0,0 +1,104 @@ +package net.sf.openrocket.gui.main; + +import java.awt.event.ActionEvent; + +import javax.swing.AbstractAction; + +import net.sf.openrocket.document.OpenRocketDocument; +import net.sf.openrocket.document.UndoRedoListener; +import net.sf.openrocket.gui.util.Icons; +import net.sf.openrocket.l10n.Translator; +import net.sf.openrocket.logging.LogHelper; +import net.sf.openrocket.startup.Application; +import net.sf.openrocket.util.BugException; + +/** + * Inner class to implement undo/redo actions. + */ +public class UndoRedoAction extends AbstractAction implements UndoRedoListener { + + // Use Factory mechanism because we want to register the new instance as an + // UndoRedoListener. + public static UndoRedoAction newUndoAction( OpenRocketDocument document ) { + UndoRedoAction undo = new UndoRedoAction( UNDO, document ); + document.addUndoRedoListener(undo); + return undo; + } + + public static UndoRedoAction newRedoAction( OpenRocketDocument document ) { + UndoRedoAction redo = new UndoRedoAction( REDO, document ); + document.addUndoRedoListener(redo); + return redo; + } + + private static final LogHelper log = Application.getLogger(); + private static final Translator trans = Application.getTranslator(); + + private static final int UNDO = 1; + private static final int REDO = 2; + + private final int type; + + private final OpenRocketDocument document; + + // Sole constructor + private UndoRedoAction(int type, OpenRocketDocument document) { + this.document = document; + if (type != UNDO && type != REDO) { + throw new IllegalArgumentException("Unknown type = " + type); + } + this.type = type; + setAllValues(); + } + + + // Actual action to make + @Override + public void actionPerformed(ActionEvent e) { + switch (type) { + case UNDO: + log.user("Performing undo, event=" + e); + document.undo(); + break; + + case REDO: + log.user("Performing redo, event=" + e); + document.redo(); + break; + } + } + + + // Set all the values correctly (name and enabled/disabled status) + public void setAllValues() { + String name, desc; + boolean actionEnabled; + + switch (type) { + case UNDO: + //// Undo + name = trans.get("OpenRocketDocument.Undo"); + desc = document.getUndoDescription(); + actionEnabled = document.isUndoAvailable(); + this.putValue(SMALL_ICON, Icons.EDIT_UNDO); + break; + + case REDO: + ////Redo + name = trans.get("OpenRocketDocument.Redo"); + desc = document.getRedoDescription(); + actionEnabled = document.isRedoAvailable(); + this.putValue(SMALL_ICON, Icons.EDIT_REDO); + break; + + default: + throw new BugException("illegal type=" + type); + } + + if (desc != null) + name = name + " (" + desc + ")"; + + putValue(NAME, name); + setEnabled(actionEnabled); + } +} diff --git a/test/net/sf/openrocket/IntegrationTest.java b/test/net/sf/openrocket/IntegrationTest.java index 860e7f277..af73af34c 100644 --- a/test/net/sf/openrocket/IntegrationTest.java +++ b/test/net/sf/openrocket/IntegrationTest.java @@ -21,6 +21,7 @@ import net.sf.openrocket.document.Simulation; import net.sf.openrocket.file.GeneralRocketLoader; import net.sf.openrocket.file.RocketLoadException; import net.sf.openrocket.file.motor.GeneralMotorLoader; +import net.sf.openrocket.gui.main.UndoRedoAction; import net.sf.openrocket.l10n.ResourceBundleTranslator; import net.sf.openrocket.masscalc.BasicMassCalculator; import net.sf.openrocket.masscalc.MassCalculator; @@ -96,8 +97,8 @@ public class IntegrationTest extends BaseTestCase { document = loader.load(is); is.close(); - undoAction = document.getUndoAction(); - redoAction = document.getRedoAction(); + undoAction = UndoRedoAction.newUndoAction(document ); + redoAction = UndoRedoAction.newRedoAction(document); config = document.getSimulation(0).getConfiguration(); conditions = new FlightConditions(config);