0

I'm trying to get my first UndoManager work, but I got a problem with the prototype. I don't understand why the following code provides only one single undo.

When I change the text, click undo and change the text again, another undo won't do anything. Where is the catch?

import java.awt.*;
import javax.swing.*;

public class IComeUndone
{
    public static void main(String[] args)
    {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        final JTextArea textArea = new JTextArea(20, 40);
        textArea.setText("Back here");
        f.add(textArea);
        final UndoManager undoManager = new UndoManager();
        textArea.getDocument().addUndoableEditListener(undoManager);
        undoManager.setLimit(1000);
        JButton undoB = new JButton("Undo");
        undoB.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                undoManager.end();
                if(undoManager.canUndo())
                {
                    undoManager.undo();
                }
                textArea.requestFocus();
            }
        });
        f.add(undoB, BorderLayout.PAGE_END);
        f.pack();
        f.setVisible(true);
    }
}

Update: When I comment out the undoManager.end(); line, it works fine, but each click on undo does only undo one single edit, like one typed letter. I wanted to undo a group of single edits, so that the undoManager.end(); makes sense at this point. But I can't restart the tracking of single edits after undo has been clicked the first time. (Hope you can understand)

fachexot
  • 491
  • 1
  • 8
  • 24
  • How is your MyUndoManager implemented? – ioreskovic Jul 13 '12 at 13:11
  • It is an inner class, just scroll down the code snippet. But it makes no difference to the common `UndoManager`. – fachexot Jul 13 '12 at 13:13
  • How is this determined `undoManager.canUndo()` looks like its returning false. – Rob Wagner Jul 13 '12 at 13:15
  • Java-API: Returns true if edits may be undone. If end has been invoked, this returns the value from super. Otherwise this returns true if there are any edits to be undone (editToBeUndone returns non-null). – fachexot Jul 13 '12 at 13:18
  • Skimming through the [api docs](http://docs.oracle.com/javase/6/docs/api/javax/swing/undo/UndoManager.html#end()). Aren't you supposed to call `.end()` after `.undo()`? – Spoike Jul 13 '12 at 13:18
  • Also why are you subclassing UndoManager? Doesn't the default implementation work? – Spoike Jul 13 '12 at 13:21
  • I subclassed it for further understanding, but I modified the code snippet in the question now.. – fachexot Jul 13 '12 at 13:22
  • No, the `.end()` has to be called before `.undo()` because it indicates that a group of undoable edits is done now, and all of them should be undone with the one call of `.undo()` below. – fachexot Jul 13 '12 at 13:26
  • [This code sample](http://www.java2s.com/Code/Java/Swing-JFC/TheuseofUndoManager.htm) does it a bit different from yours but might help you. – Spoike Jul 13 '12 at 13:30
  • Thanks Spoike, but unfortunately this is not what I want. I updated my question above. My problem is that I want to group little edits to one single undo with `.end()`. That's why I'm asking. – fachexot Jul 13 '12 at 13:33

1 Answers1

0

Interesting one, it seems that once you call end() it converts the UndoManager into a CompoundEdit and then there is more work that you have to do. The following link has as example: http://tips4java.wordpress.com/2008/10/27/compound-undo-manager/

Sticks
  • 402
  • 3
  • 9