2

我无法理解使用 UndoManager 的撤消/重做功能,并将其与 MVC 模型集成。

我不确定将各种方法放在哪里(在模型、视图或控件中),我仍然不确定如何使用撤消管理器。

我的控件类实现 UndoableEditListener 它创建:

private UndoManager manager = new UndoManager();

并在:

public void actionPerformed(ActionEvent e) {
   if (e.getActionCommand().equals("Undo")) {    
      try {
          manager.undo();   
      } catch (CannotUndoException ex) { 
          ex.printStackTrace(); 
      }
   }
}

我理解到这里,但其余的我不知道该怎么做。我知道我必须在模型和视图类中添加更多内容,但不确定在哪里。我必须有以下课程吗?

public class UndoAction extends AbstractAction {}

public void undoableEditHappened(UndoableEditEvent e) {

我只是在文本字段中放置一个整数,然后我希望能够撤消它。我在视图类的文本字段中设置了数字。我想以最简单的方式实现这一点,没有花哨的编码!这是我 assg 的一小部分,但我就是不能让它工作!!

==================================================== ======== 这是我的代码的更详细描述,也许它会有所帮助:

我有一个模型、视图和控制包。

控制有:ButtonGUIControl.java,它实现了两者

    ActionListener and 
    UndoableEditListener.


    final UndoManager manager = new UndoManager();

在 actionPerformed 方法中,它调用

    if (e.getActionCommand().equals("Undo")){

             try {

                    manager.undo();
                }

并在:

    public void undoableEditHappened(UndoableEditEvent evt) {
          manager.addEdit(evt.getEdit());

}

在视图中:扩展 JTextField 的 Grid.java 将在需要在 GUI 上显示数字的任何位置添加以下内容:(模型只是我的模型类的一个实例)

    getDocument().addUndoableEditListener(new ButtonGUIControl(model));

可能是因为 UndoManager 是在不同的包中创建的吗?我真的不知道如何调试这个了!!

如果有帮助,我可以发布我的整个代码。我想我不确定如何将它与我的 mvc 模型结构集成。

4

2 回答 2

3

退后一秒。这里的整个想法是用户将使用您的应用程序并对某些内容进行一系列更改。文本编辑器就是一个很好的例子。您可以插入字符和行,再次删除它们,用其他文本替换文本,滚动文本等。为了使用 MVC 支持这一点,您有一个保存状态的模型和一个显示状态的视图。

您的第一直觉可能是让视图直接访问模型,然后在每次用户进行更改时刷新视图,但是使用该实现撤消这些更改非常困难。相反,您可以在能够执行该更改并且以后可以撤消该更改的类中对用户可以进行的每种更改进行编码。

例如,插入文本的操作将由一个知道插入点的字符偏移量和要插入的字符串的类来实现。执行操作将在偏移处插入字符串,撤消操作将删除该插入点之后正确数量的字符。您将有一个不同的类来处理删除,另一个类来处理滚动等。

每次用户采取一些行动时,视图都会构造这些 UndoableEdit 类之一,并告诉实例自行运行(redo())。执行后,您将 UndoableEdit 放在 UndoableEdit 实例列表的末尾,这些实例代表用户到目前为止已采取的所有操作。这个列表可以很容易地支持任何顺序的撤消请求、重做请求和实际的编辑操作(导致更多的 UndoableEdit 被放在列表中)。

所以回到你的问题。如果您的应用需要支持撤消和重做,那么您需要实现一个 UndoManager,它只管理 UndoableEdit 的列表并根据需要执行撤消和重做。您还必须实现一大堆 UndoableEdits,一个用于您的用户将对 UI 执行的每种操作。至于听众,我看不出你真的需要这样做。

于 2012-10-07T21:55:30.970 回答
1
  1. 如果您只需要简单的撤消/重做,则可以按原样使用UndoManager,无需以任何方式对其进行子类化或自定义。
  2. JTextField(更具体地说,它的模型,Document)具有一些内置的撤消支持,这意味着您也不需要编写UndoableEdit实现,UndoableEdit 对象将自动为您创建(实际上AbstractDocument.DefaultDocumentEvent实现 UndoableEdit)。
  3. 完整的简单工作示例在这里
于 2012-10-07T22:39:41.043 回答