2012-10-07 56 views
3

我无法理解使用UndoManager的撤销/重做功能,并将其与MVC模型集成在一起。如何在Java中为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) { 

我只是把一个文本框一个整数,然后我希望能够撤消this.I设置在视图class.I文本字段数量都想达致这可能是最简单的方法,没有花哨的编码!这是我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()); 

}

在查看: Grid.java,它扩展了JTextField将新增如下,无论它需要在GUI上显示一个数字:(模型只是我的模型类的实例)

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

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

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

+0

这可能会有帮助http://www.java-tips.org/java-se-tips/javax.swing.undo/how-to-add-undo-和-reoo-to-a-text-comp.html –

回答

3

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

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

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

每当用户采取一些行动时,视图将构造这些UndoableEdit类之一,并告诉实例自己运行(重做( ))。一旦执行,您将该UndoableEdit放在UndoableEdit实例列表的末尾,该实例表示用户迄今采取的所有操作。这个列表可以很容易地支持任何撤消请求,重做请求和实际编辑操作(导致更多的UndoableEdit放在列表中)。

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

+0

Swing已经有一个UndoManager类,不需要实现它:http://docs.oracle.com/javase/6/docs/api/javax/swing/undo /UndoManager.html – lbalazscs

2
  1. 如果您只需要简单的撤销/重做,您可以按原样使用UndoManager,您不需要以任何方式进行子类化或定制。
  2. JTextField中(更具体的模型中,Document)有一些内置的撤销,这意味着你不需要任何写UndoableEdit实现支持,UndoableEdit中的对象将被自动地为您创建(实际上AbstractDocument.DefaultDocumentEvent实现UndoableEdit中的) 。
  3. 全部简单工作的例子是here
+0

感谢您的帮助。我试图修复我的代码,我认为它的权利,除了我仍然得到: javax.swing.undo.UndoManager.undo(未知源) 有没有办法找出问题的确切位置?我试过打印 manager.canUndo()和我得到假 再次感谢! – greg

+0

我不明白,你是否得到例外?无论如何,我建议你用代码问一个关于新问题的新问题。如果你原来的问题得到回答,你应该接受的答案:) – lbalazscs

+0

是的,我得到一个异常: javax.swing.undo.CannotUndoException \t在javax.swing.undo.UndoManager.undo(的UndoManager。 java:411) 它发生在我的程序调用时: manager.undo(); 我还会问一个新问题:) – greg