首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

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

2012-09-17 
JAVA 实现Undo/Redo(撤销/恢复)一Undo/Redo是软件的一个常用功能,Java 在swing中提供了Undo包, 提供了对JT

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;
    }
}

热点排行