java中的undo,redo,delete功能

时间:2010-01-12 18:21:53

标签: java swing awt

我需要编写这3个函数,但是我遇到了重做并删除了。当没有重做任何东西并且我不知道如何编写删除功能时,重做显示错误。谢谢

撤消

public class Undo extends AbstractAction {

private MyCanvas myCanvas;

public Undo(MyCanvas myCanvas) {
    this.myCanvas = myCanvas;
    this.putValue(NAME, "Undo");
    this.putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke("ctrl Z"));
    this.putValue(SMALL_ICON, new ImageIcon(Main.class.getResource("/icons/Undo24.gif")));
}

public void actionPerformed(ActionEvent e) {
    if (!myCanvas.commands.isEmpty()) {

        Command cmd = myCanvas.commands.pop();
        cmd.undo();
        myCanvas.undoneCommands.add(cmd);
        myCanvas.repaint();
    }
            else
                System.out.println();
}
}

重做

public class Redo extends AbstractAction {

private MyCanvas myCanvas;

public Redo(MyCanvas myCanvas) {
    this.myCanvas = myCanvas;
    this.putValue(NAME, "Redo");
    this.putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke("ctrl Y"));
    this.putValue(SMALL_ICON, new ImageIcon(Main.class.getResource("/icons/Redo16.gif")));
}

public void actionPerformed(ActionEvent e) {
    //if (!myCanvas.commands.isEmpty()) {
        Command cmd = myCanvas.undoneCommands.pop();
        cmd.execute();
        myCanvas.commands.add(cmd);
        myCanvas.repaint();
    //}
        //   else
               System.out.println();
}
}

3 个答案:

答案 0 :(得分:1)

我相信你会想看看command pattern

在Head First Design Patterns一书中也有一篇很好的文章。

答案 1 :(得分:1)

这是一个难以解决的问题 - 如果它很容易就会出现在图书馆中。

一种方法是让每个“行动”都成为一个班级。例如,“添加文本”类可能会在给定位置向屏幕添加许多字符。在您完成时键入并将其推入堆栈时创建此对象(可能是您希望每个角色有一个对象。

诀窍在于每个“Action”还有一个可以自行撤消的撤销方法。所以重复的undos只是一个actionStack.pop()。undo();

通过这种方式,删除功能将知道它应该删除当前选择的文本。它会记录自己删除的位置和文本并放在堆栈中。如果您要将其称为撤消,则只需将文本放回文档中即可。

看起来你正试图沿着这些方向做某事,但没有为可以影响文档的每种类型的动作创建不同的对象(AddCharacter,Delete,EraseDocument,...)。这是可行的 - 这是你用非OO语言的方式,但它不容易或干净 - 例如,你必须存储任意元数据,如删除的文本,你删除它的位置等等。进入堆栈的某些部分。

当你把它分解成小动作时,它变得非常有趣和轻松......

答案 2 :(得分:0)

我写了一个简单的Java Undo / Redo框架。没有外部依赖,它是完全免费的。 Try it out