2010-11-18 73 views
2

我有一个应用程序,带有一个JPanel和用户单击的按钮在面板上绘制形状。您可以对形状进行着色和调整大小,并在面板中移动它们。我将如何去实现撤消和重做这样的应用程序?我有一个Actions类,所有的动作都被实际执行。在这个类中,每个动作都是它自己的扩展AbstractAction的类。我的动作类基本上是一个嵌套类。Java中的撤消和重做操作事件

例如,这是我的动作类的一类:

private class RandomAction extends AbstractAction { 
    private static final long serialVersionUID = 1L; 
    public NewAction(String text, ImageIcon icon, String desc){ 
      super(text, icon); 
      putValue(SHORT_DESCRIPTION, desc); 
     } 
     public void actionPerformed(ActionEvent e) { 

     } 
    } 

当我再创建一个按钮,我要做的就是:

randButton = new JButton(Actions.RandomAction); 

回答

4

通常撤销/重做功能是通过实施完成一个堆栈。您可以实现自己的操作堆栈,以跟踪之前的X操作,然后每当用户撤消操作时就可以弹出。您可能还需要为重做功能保留一个类似的结构类型。所以当一个动作从撤销堆栈弹出时,首先需要进入重做堆栈。

如果您使用的是Java和NetBeans(尽管严格来说您不需要使用NetBeans IDE),但您可以查看NetBeans平台(可以单独下载)。我没有使用撤销/重做,但它确实提供了功能。

就我个人而言,我只是写一个包装用户可以做的任何“动作”的类,我已经看到你已经做了。现在只需要实现一个堆栈来跟踪这些操作,并且当一个弹出撤消堆栈时,您需要执行操作的“相反”操作。将项目放在重做堆栈上,所以当用户单击重做时,您可以简单地将动作从重做堆栈中弹出,让应用程序按照正常情况处理它。

+0

谢谢,我实际上正在考虑以这种方式实现它。 – sigfreik 2010-11-19 01:53:07

0

我同意尼科的帖子,我会补充说,可以使用一个堆栈来撤销/重做。

回到大学的时候,我写了一个数据流图编辑器,它需要完全撤消/重做功能。我创建了一个表示任何可能的用户操作的抽象Action类(使用Undo和Do方法),以及一个ActionStack,它包装所有执行操作的List并维护一个指向上次执行的Action的指针。撤消操作会将指针向下移动,并重做它们将其移动。所以如果用户执行10个动作,堆栈将包含动作1-10,指针指向动作#10。如果用户然后执行5次撤销,则堆栈上仍将有10次操作,但指针移回到操作#5。如果用户执行新的动作,则指针上方的所有动作(动作6-10)将被删除,新动作将被添加到堆栈的顶部,并相应地调整指针。

您描述的用户操作听起来不太复杂,但对于更复杂的操作,您可能希望允许它们由子操作组成。

+0

我正在为我当前项目的撤销/重做功能做同样的事情。 – almathie 2010-11-18 06:44:23

+0

我可能会尝试这种方式,因为它没有两个堆栈会使我的应用程序更加节省空间。 – sigfreik 2010-11-19 04:47:43