如何在Java中为MVC模型实现撤销/重做?

如何在Java中为MVC模型实现撤销/重做?,java,swing,model-view-controller,undo-redo,Java,Swing,Model View Controller,Undo Redo,我很难理解使用UndoManager的undo/redo函数,也很难将其与MVC模型集成 我不确定将各种方法放在模型、视图或控件中的何处 我仍然不知道如何使用撤销管理器 我的控件类实现了UndoableEditListener 它创造了: private UndoManager manager = new UndoManager(); 以及: public void actionPerformed(ActionEvent e) { if (e.getActionCommand().equ

我很难理解使用UndoManager的undo/redo函数,也很难将其与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 void undoableEditHappened(UndoableEditEvent evt) {
          manager.addEdit(evt.getEdit());
到目前为止我都明白,但剩下的我不知道该怎么办。我知道我必须在模型和视图类中添加更多内容,但不确定在哪里。 我必须上以下课程吗

public class UndoAction extends AbstractAction {}

public void undoableEditHappened(UndoableEditEvent e) {
我只是在文本字段中放置一个整数,然后我希望能够撤消此操作。我在视图类的文本字段中设置了该数字。我希望以最简单的方式实现此操作,无需编写花哨的代码!这是我屁股的一小部分,但我就是不能让它工作

========================================================== 下面是对我的代码的更详细描述,可能会有所帮助:

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

Contol有: ButtonGUIControl.java,它实现了

    ActionListener and 
    UndoableEditListener.


    final UndoManager manager = new UndoManager();
在actionPerformed方法中,它调用

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

             try {

                    manager.undo();
                }
以及:

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

他认为: java扩展了JTextField,它将在需要在GUI上显示数字的地方添加以下内容:model只是我的model类的一个实例

    getDocument().addUndoableEditListener(new ButtonGUIControl(model));
可能是因为UndoManager是在不同的包中创建的吗?我真的不知道如何调试这个了


如果有帮助的话,我可以发布我的全部代码。我想我不知道如何将它与我的mvc模型结构相结合。

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

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

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

每次用户执行某些操作时,视图都会构造这些UndoableEdit类中的一个,并告诉实例自己运行redo。执行后,将该UndoableEdit放在UndoableEdit实例列表的末尾,这些实例表示用户迄今为止采取的所有操作。这个列表可以很容易地支持撤销请求、重做请求和实际编辑操作的任何序列,从而将更多的UndoableEdit放到列表中


回到你的问题上来。如果你的应用程序需要支持撤消和重做,那么你需要实现一个UndoManager,它只管理UndoableEdit的列表,并根据需要执行撤消和重做。您还必须实现一系列可撤消的编辑,用户将对UI执行的每种操作都有一个可撤消的编辑。至于听众,我看不出你真的需要这么做。

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

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

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

每次用户执行某些操作时,视图都会构造这些UndoableEdit类中的一个,并告诉实例自己运行redo。执行后,将UndoableEdit置于 e UndoableEdit实例列表的结尾,这些实例表示用户迄今为止采取的所有操作。这个列表可以很容易地支持撤销请求、重做请求和实际编辑操作的任何序列,从而将更多的UndoableEdit放到列表中

回到你的问题上来。如果你的应用程序需要支持撤消和重做,那么你需要实现一个UndoManager,它只管理UndoableEdit的列表,并根据需要执行撤消和重做。您还必须实现一系列可撤消的编辑,用户将对UI执行的每种操作都有一个可撤消的编辑。至于一个听众,我看不出你真的需要这么做

如果您只需要简单的撤销/重做,您可以按原样使用,而不需要以任何方式对其进行子类化或自定义。 JTextField更具体地说,它的模型有一些内置的对撤销的支持,这意味着您也不需要编写实现,UndoableEdit对象将自动创建,以便您实际实现UndoableEdit。 完整的简单工作示例如下所示 如果您只需要简单的撤销/重做,您可以按原样使用,而不需要以任何方式对其进行子类化或自定义。 JTextField更具体地说,它的模型有一些内置的对撤销的支持,这意味着您也不需要编写实现,UndoableEdit对象将自动创建,以便您实际实现UndoableEdit。 完整的简单工作示例如下所示
这可能会有帮助这可能会有帮助Swing已经有了UndoManager类,不需要实现它:Swing已经有了UndoManager类,不需要实现它:感谢您的帮助。我试着修复我的代码,我认为它是正确的,但我仍然得到:javax.swing.undo.UndoManager.undommundown Source有办法找出问题的确切位置吗?我试着在manager.canUndo上打印了一个字,我再次收到了虚假的感谢!!我不明白,你有例外吗?无论如何,我建议你问一个关于新问题的新问题,用代码。如果你最初的问题得到了回答,你应该接受答案:是的,我在javax.swing.undo.undo.CannotUndoException中得到了一个异常:javax.swing.undo.UndoManager.UndoManager.java:411当我的程序调用:manager.undo时会发生这种情况;我还会问一个新问题:这里有一个到我的新问题的链接,谢谢你的帮助。我试着修复我的代码,我认为它是正确的,但我仍然得到:javax.swing.undo.UndoManager.undommundown Source有办法找出问题的确切位置吗?我试着在manager.canUndo上打印了一个字,我再次收到了虚假的感谢!!我不明白,你有例外吗?无论如何,我建议你问一个关于新问题的新问题,用代码。如果你最初的问题得到了回答,你应该接受答案:是的,我在javax.swing.undo.undo.CannotUndoException中得到了一个异常:javax.swing.undo.UndoManager.UndoManager.java:411当我的程序调用:manager.undo时会发生这种情况;我还将提出一个新问题:这里有一个指向我的新问题的链接