UndoManager.java
/**
* UndoManager管理命令的撤销和重做操作,使用栈结构保存命令历史。
*
* <p>实现了命令模式中的命令管理器角色,支持:
* <ul>
* <li>执行命令并保存到撤销栈</li>
* <li>撤销最近执行的命令</li>
* <li>重做最近撤销的命令</li>
* <li>检查是否可以撤销/重做</li>
* </ul>
*
* <p>典型用法:
* <pre>{@code
* UndoManager undoManager = new UndoManager();
* Command cmd = new AddShapeCommand(shapes, new Circle(10,10,5));
* undoManager.executeCommand(cmd); // 执行并保存命令
* if (undoManager.canUndo()) {
* undoManager.undo(); // 撤销命令
* }
* if (undoManager.canRedo()) {
* undoManager.redo(); // 重做命令
* }
* }</pre>
*
* @author DeepSeek-Coder
* @version 1.0
* @see Command 命令接口
* @see AddShapeCommand 添加图形命令
* @see MoveShapeCommand 移动图形命令
* @since 2025-06-24
*/
package com.example.renderer.command;
import java.util.Stack;
import java.util.Objects;
/**
* 撤销管理器,管理命令的撤销和重做操作
*/
public class UndoManager {
private final Stack<Command> undoStack = new Stack<>();
private final Stack<Command> redoStack = new Stack<>();
private int maxHistorySize = 100; // 默认最大历史记录数
/**
* 设置最大历史记录数
* @param size 最大历史记录数
*/
public void setMaxHistorySize(int size) {
this.maxHistorySize = size;
}
/**
* 清除所有历史记录
*/
public void clearHistory() {
undoStack.clear();
redoStack.clear();
}
/**
* 执行命令并保存到撤销栈。
*
* @param cmd 要执行的命令(非null)
* @author Aider+DeepSeek
* @since 2025-06-24
*/
/**
* 执行命令并保存到撤销栈。
*
* @param cmd 要执行的命令(非null)
* @throws NullPointerException 如果cmd参数为null
* @author Aider+DeepSeek
* @since 2025-06-24
*/
public void executeCommand(Command cmd) {
Objects.requireNonNull(cmd, "Command cannot be null");
cmd.execute();
if (undoStack.size() >= maxHistorySize) {
undoStack.remove(0); // 移除最旧的命令
}
undoStack.push(cmd);
redoStack.clear();
}
/**
* 撤销最近执行的命令。
*
* @author Aider+DeepSeek
* @since 2025-06-24
*/
public void undo() {
if (!undoStack.isEmpty()) {
Command cmd = undoStack.pop();
cmd.undo();
redoStack.push(cmd);
}
}
/**
* 重做最近撤销的命令。
*
* @author Aider+DeepSeek
* @since 2025-06-24
*/
public void redo() {
if (!redoStack.isEmpty()) {
Command cmd = redoStack.pop();
cmd.execute();
undoStack.push(cmd);
}
}
/**
* 检查是否可以执行撤销操作。
*
* @return 如果撤销栈不为空返回true,否则返回false
* @author Aider+DeepSeek
* @since 2025-06-24
*/
public boolean canUndo() {
return !undoStack.isEmpty();
}
/**
* 检查是否可以执行重做操作。
*
* @return 如果重做栈不为空返回true,否则返回false
* @author Aider+DeepSeek
* @since 2025-06-24
*/
public boolean canRedo() {
return !redoStack.isEmpty();
}
}