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.
This commit is contained in:
parent
4194479d0c
commit
1b309dd786
@ -1,18 +1,12 @@
|
|||||||
package net.sf.openrocket.document;
|
package net.sf.openrocket.document;
|
||||||
|
|
||||||
import java.awt.event.ActionEvent;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
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.DocumentChangeEvent;
|
||||||
import net.sf.openrocket.document.events.DocumentChangeListener;
|
import net.sf.openrocket.document.events.DocumentChangeListener;
|
||||||
import net.sf.openrocket.document.events.SimulationChangeEvent;
|
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.LogHelper;
|
||||||
import net.sf.openrocket.logging.TraceException;
|
import net.sf.openrocket.logging.TraceException;
|
||||||
import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
|
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.rocketcomponent.Rocket;
|
||||||
import net.sf.openrocket.startup.Application;
|
import net.sf.openrocket.startup.Application;
|
||||||
import net.sf.openrocket.util.ArrayList;
|
import net.sf.openrocket.util.ArrayList;
|
||||||
import net.sf.openrocket.util.BugException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class describing an entire OpenRocket document, including a rocket and
|
* 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 {
|
public class OpenRocketDocument implements ComponentChangeListener {
|
||||||
private static final LogHelper log = Application.getLogger();
|
private static final LogHelper log = Application.getLogger();
|
||||||
private static final Translator trans = Application.getTranslator();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The minimum number of undo levels that are stored.
|
* 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 */
|
/** Whether an undo error has already been reported to the user */
|
||||||
private static boolean undoErrorReported = false;
|
private static boolean undoErrorReported = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private final Rocket rocket;
|
private final Rocket rocket;
|
||||||
private final Configuration configuration;
|
private final Configuration configuration;
|
||||||
|
|
||||||
@ -72,7 +62,7 @@ public class OpenRocketDocument implements ComponentChangeListener {
|
|||||||
*/
|
*/
|
||||||
private LinkedList<Rocket> undoHistory = new LinkedList<Rocket>();
|
private LinkedList<Rocket> undoHistory = new LinkedList<Rocket>();
|
||||||
private LinkedList<String> undoDescription = new LinkedList<String>();
|
private LinkedList<String> undoDescription = new LinkedList<String>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The position in the undoHistory we are currently at. If modifications have been
|
* 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
|
* 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 String storedDescription = null;
|
||||||
|
|
||||||
|
|
||||||
|
private ArrayList<UndoRedoListener> undoRedoListeners = new ArrayList<UndoRedoListener>(2);
|
||||||
|
|
||||||
private File file = null;
|
private File file = null;
|
||||||
private int savedID = -1;
|
private int savedID = -1;
|
||||||
|
|
||||||
@ -96,11 +88,6 @@ public class OpenRocketDocument implements ComponentChangeListener {
|
|||||||
private final List<DocumentChangeListener> listeners =
|
private final List<DocumentChangeListener> listeners =
|
||||||
new ArrayList<DocumentChangeListener>();
|
new ArrayList<DocumentChangeListener>();
|
||||||
|
|
||||||
/* These must be initialized after undo history is set up. */
|
|
||||||
private final UndoRedoAction undoAction;
|
|
||||||
private final UndoRedoAction redoAction;
|
|
||||||
|
|
||||||
|
|
||||||
public OpenRocketDocument(Rocket rocket) {
|
public OpenRocketDocument(Rocket rocket) {
|
||||||
this(rocket.getDefaultConfiguration());
|
this(rocket.getDefaultConfiguration());
|
||||||
}
|
}
|
||||||
@ -112,9 +99,6 @@ public class OpenRocketDocument implements ComponentChangeListener {
|
|||||||
|
|
||||||
clearUndo();
|
clearUndo();
|
||||||
|
|
||||||
undoAction = new UndoRedoAction(UndoRedoAction.UNDO);
|
|
||||||
redoAction = new UndoRedoAction(UndoRedoAction.REDO);
|
|
||||||
|
|
||||||
rocket.addComponentChangeListener(this);
|
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.
|
* Clear the undo history.
|
||||||
*/
|
*/
|
||||||
@ -343,11 +317,8 @@ public class OpenRocketDocument implements ComponentChangeListener {
|
|||||||
undoHistory.add(rocket.copyWithOriginalID());
|
undoHistory.add(rocket.copyWithOriginalID());
|
||||||
undoDescription.add(null);
|
undoDescription.add(null);
|
||||||
undoPosition = 0;
|
undoPosition = 0;
|
||||||
|
|
||||||
if (undoAction != null)
|
fireUndoRedoChangeEvent();
|
||||||
undoAction.setAllValues();
|
|
||||||
if (redoAction != null)
|
|
||||||
redoAction.setAllValues();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -370,8 +341,7 @@ public class OpenRocketDocument implements ComponentChangeListener {
|
|||||||
undoDescription.set(undoPosition, nextDescription);
|
undoDescription.set(undoPosition, nextDescription);
|
||||||
}
|
}
|
||||||
|
|
||||||
undoAction.setAllValues();
|
fireUndoRedoChangeEvent();
|
||||||
redoAction.setAllValues();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -430,8 +400,7 @@ public class OpenRocketDocument implements ComponentChangeListener {
|
|||||||
" undoHistory.size=" + undoHistory.size() + " isClean=" + isCleanState());
|
" undoHistory.size=" + undoHistory.size() + " isClean=" + isCleanState());
|
||||||
if (!isUndoAvailable()) {
|
if (!isUndoAvailable()) {
|
||||||
logUndoError("Undo not available");
|
logUndoError("Undo not available");
|
||||||
undoAction.setAllValues();
|
fireUndoRedoChangeEvent();
|
||||||
redoAction.setAllValues();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (storedDescription != null) {
|
if (storedDescription != null) {
|
||||||
@ -468,8 +437,7 @@ public class OpenRocketDocument implements ComponentChangeListener {
|
|||||||
" undoHistory.size=" + undoHistory.size() + " isClean=" + isCleanState());
|
" undoHistory.size=" + undoHistory.size() + " isClean=" + isCleanState());
|
||||||
if (!isRedoAvailable()) {
|
if (!isRedoAvailable()) {
|
||||||
logUndoError("Redo not available");
|
logUndoError("Redo not available");
|
||||||
undoAction.setAllValues();
|
fireUndoRedoChangeEvent();
|
||||||
redoAction.setAllValues();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (storedDescription != null) {
|
if (storedDescription != null) {
|
||||||
@ -526,6 +494,22 @@ public class OpenRocketDocument implements ComponentChangeListener {
|
|||||||
|
|
||||||
/////// Listeners
|
/////// 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) {
|
public void addDocumentChangeListener(DocumentChangeListener listener) {
|
||||||
listeners.add(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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
8
src/net/sf/openrocket/document/UndoRedoListener.java
Normal file
8
src/net/sf/openrocket/document/UndoRedoListener.java
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
package net.sf.openrocket.document;
|
||||||
|
|
||||||
|
import java.util.EventListener;
|
||||||
|
|
||||||
|
public interface UndoRedoListener extends EventListener {
|
||||||
|
|
||||||
|
public void setAllValues();
|
||||||
|
}
|
@ -554,7 +554,7 @@ public class BasicFrame extends JFrame {
|
|||||||
menubar.add(menu);
|
menubar.add(menu);
|
||||||
|
|
||||||
|
|
||||||
Action action = document.getUndoAction();
|
Action action = UndoRedoAction.newUndoAction(document);
|
||||||
item = new JMenuItem(action);
|
item = new JMenuItem(action);
|
||||||
item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z, ActionEvent.CTRL_MASK));
|
item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z, ActionEvent.CTRL_MASK));
|
||||||
item.setMnemonic(KeyEvent.VK_U);
|
item.setMnemonic(KeyEvent.VK_U);
|
||||||
@ -562,8 +562,8 @@ public class BasicFrame extends JFrame {
|
|||||||
item.getAccessibleContext().setAccessibleDescription(trans.get("main.menu.edit.undo.desc"));
|
item.getAccessibleContext().setAccessibleDescription(trans.get("main.menu.edit.undo.desc"));
|
||||||
|
|
||||||
menu.add(item);
|
menu.add(item);
|
||||||
|
|
||||||
action = document.getRedoAction();
|
action = UndoRedoAction.newRedoAction(document);
|
||||||
item = new JMenuItem(action);
|
item = new JMenuItem(action);
|
||||||
item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Y, ActionEvent.CTRL_MASK));
|
item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Y, ActionEvent.CTRL_MASK));
|
||||||
item.setMnemonic(KeyEvent.VK_R);
|
item.setMnemonic(KeyEvent.VK_R);
|
||||||
|
104
src/net/sf/openrocket/gui/main/UndoRedoAction.java
Normal file
104
src/net/sf/openrocket/gui/main/UndoRedoAction.java
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -21,6 +21,7 @@ import net.sf.openrocket.document.Simulation;
|
|||||||
import net.sf.openrocket.file.GeneralRocketLoader;
|
import net.sf.openrocket.file.GeneralRocketLoader;
|
||||||
import net.sf.openrocket.file.RocketLoadException;
|
import net.sf.openrocket.file.RocketLoadException;
|
||||||
import net.sf.openrocket.file.motor.GeneralMotorLoader;
|
import net.sf.openrocket.file.motor.GeneralMotorLoader;
|
||||||
|
import net.sf.openrocket.gui.main.UndoRedoAction;
|
||||||
import net.sf.openrocket.l10n.ResourceBundleTranslator;
|
import net.sf.openrocket.l10n.ResourceBundleTranslator;
|
||||||
import net.sf.openrocket.masscalc.BasicMassCalculator;
|
import net.sf.openrocket.masscalc.BasicMassCalculator;
|
||||||
import net.sf.openrocket.masscalc.MassCalculator;
|
import net.sf.openrocket.masscalc.MassCalculator;
|
||||||
@ -96,8 +97,8 @@ public class IntegrationTest extends BaseTestCase {
|
|||||||
document = loader.load(is);
|
document = loader.load(is);
|
||||||
is.close();
|
is.close();
|
||||||
|
|
||||||
undoAction = document.getUndoAction();
|
undoAction = UndoRedoAction.newUndoAction(document );
|
||||||
redoAction = document.getRedoAction();
|
redoAction = UndoRedoAction.newRedoAction(document);
|
||||||
config = document.getSimulation(0).getConfiguration();
|
config = document.getSimulation(0).getConfiguration();
|
||||||
conditions = new FlightConditions(config);
|
conditions = new FlightConditions(config);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user