java-lib-fw/src/main/java/de/synolo/lib/fw/cmd/UndoManager.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);
}
}