91 lines
2.1 KiB
Java
91 lines
2.1 KiB
Java
package de.synolo.lib.fw.cmd;
|
|
|
|
import java.util.Stack;
|
|
|
|
import javafx.beans.property.ReadOnlyBooleanProperty;
|
|
import javafx.beans.property.ReadOnlyBooleanWrapper;
|
|
|
|
public class UndoManager {
|
|
|
|
private Stack<Command> undoStack;
|
|
private Stack<Command> redoStack;
|
|
|
|
private ReadOnlyBooleanWrapper undoAvailalableProperty = new ReadOnlyBooleanWrapper(false);
|
|
private ReadOnlyBooleanWrapper redoAvailalableProperty = new ReadOnlyBooleanWrapper(false);
|
|
|
|
private int max;
|
|
|
|
public UndoManager(int maxCommands) {
|
|
this.max = maxCommands;
|
|
this.undoStack = new Stack<>();
|
|
this.redoStack = new Stack<>();
|
|
}
|
|
|
|
public UndoManager() {
|
|
this(100);
|
|
}
|
|
|
|
public int getMaxCommands() { return this.max; }
|
|
public void setMaxCommands(int max) { this.max = max; }
|
|
|
|
public boolean isUndoAvailable() {
|
|
return !this.undoStack.isEmpty();
|
|
}
|
|
public ReadOnlyBooleanProperty undoAvailableProperty() { return this.undoAvailalableProperty.getReadOnlyProperty(); }
|
|
|
|
public boolean isRedoAvailable() {
|
|
return !this.redoStack.isEmpty();
|
|
}
|
|
public ReadOnlyBooleanProperty redoAvailableProperty() { return this.redoAvailalableProperty.getReadOnlyProperty(); }
|
|
|
|
public void execute(Command cmd) {
|
|
Command last = null;
|
|
|
|
if(!this.undoStack.isEmpty() && (last = this.undoStack.peek()) != null) {
|
|
if(last.isCollapsable(cmd)) {
|
|
last.collapse(cmd);
|
|
return;
|
|
}else {
|
|
this.redoStack.clear();
|
|
this.undoStack.push(cmd);
|
|
}
|
|
}else if(cmd.isUndoable()) {
|
|
this.redoStack.clear();
|
|
this.undoStack.push(cmd);
|
|
}
|
|
if(this.undoStack.size() > this.max) {
|
|
this.undoStack.remove(0);
|
|
}
|
|
cmd.execute();
|
|
update();
|
|
|
|
}
|
|
|
|
public void undo() {
|
|
System.out.println("undo...");
|
|
if(isUndoAvailable()) {
|
|
Command cmd = this.undoStack.pop();
|
|
this.redoStack.push(cmd);
|
|
cmd.undo();
|
|
}
|
|
update();
|
|
}
|
|
|
|
public void redo() {
|
|
if(isRedoAvailable()) {
|
|
Command cmd = this.redoStack.pop();
|
|
this.undoStack.push(cmd);
|
|
cmd.redo();
|
|
}
|
|
update();
|
|
}
|
|
|
|
private void update() {
|
|
this.undoAvailalableProperty.set(isUndoAvailable());
|
|
this.redoAvailalableProperty.set(isRedoAvailable());
|
|
System.out.println(this.undoStack);
|
|
}
|
|
|
|
|
|
}
|