读书人

JAVA 兑现Undo/Redo(撤销/恢复)一

发布时间: 2012-09-17 12:06:51 作者: rapoo

JAVA 实现Undo/Redo(撤销/恢复)一
Undo/Redo是软件的一个常用功能,Java 在swing中提供了Undo包, 提供了对JTextComponent组件的Undo/Redo支持。但是除了文本处理以外的Undo/Redo一般要自己实现,而且即使是文本处理的Undo/Redo, 好像也有些不足,例如输入时Undo/Redo是一个一个字符的,如果要做到WORD的一次一串字符撤销/恢复,也要自己实现。最近,研究了一下Undo包, 发现它的类还是比较复杂的。那么,能用简单的方法实现自己的Undo/Redo系统吗?网上的答案一般是用Command模式, 但很难看到简单易懂的实现方式。这里,本文试图通过自己的理解实现一个简单的Undo/Redo系统。

一, Undoable和Command接口

要实现Undo/Redo功能,要实现Undoable和Command接口。

public interface Undoable {

public void undo();

public void redo();

public boolean canUndo();

public boolean canRedo();

}

public interface Command {

public void execute();
}

二, UndoableCommand抽象类

在Undoable和Command接口基础上封装一个抽象类,为了简单起见,没有让它显式implements Undoable和Command接口。

UndoableCommand类的主要功能:

封装了一个boolean 变量 canUndo, 因为一个Command只有canUndo和canRedo两种状态,当Undo和Redo的时候要完成相应boolean值的切换。

Undo后只能Redo, Redo后只能Undo, 错误的调用会抛出异常。

提供抽象方法 command()和restore(), 由子类来实现Undo/Redo的逻辑。

提供boolean方法canAppendWith(UndoableCommand other), 当一些Command需要一起Undo,Redo时由子类override

import javax.swing.undo.CannotRedoException;
import javax.swing.undo.CannotUndoException;

public abstract class UndoableCommand {

protected boolean canUndo;

protected abstract void command();

protected abstract void restore();

public void execute() {
command();
setCanUndo(true);
}

protected void unExecute() {
restore();
setCanUndo(false);
}

public void undo() {
if (!canUndo()) {
throw new CannotUndoException();
}
unExecute();
}

public void redo() {
if (!canRedo()) {
throw new CannotRedoException();
}
execute();
}

public boolean canUndo() {
return canUndo;
}

public boolean canRedo() {
return !canUndo;
}

protected void setCanUndo(boolean canUndo) {
this.canUndo = canUndo;
}

protected boolean canAppendWith(UndoableCommand other) {
return false;
}
}

读书人网 >编程

热点推荐