Implement undo/redo for tabbed JEditorPanes

981 views Asked by At

I'm developing a basic editor within my application, which allows to view several components within a JTabbedPane. Each tab holds a JScrollPane which contains a JEditorPane.

Now I would like to implement an undo and redo functionality. So if I press the undo or redo button in my toolbar or use the defined keystroke, I would like the UndoManager to undo or redo my last edit in the currently viewed document.

There are several Tutorials, like this one, on how to do this for a single document or text component but not for a full document stack. Do you have any ideas.

I tried the following. I implemented the UndoHandler, Undo and RedoAction like this, ...

class UndoHandler implements UndoableEditListener {

    public void undoableEditHappened(UndoableEditEvent e) {
        undoManager.addEdit(e.getEdit());
        undoAction.update();
        redoAction.update();
    }
}

class UndoAction extends AbstractAction {
    public UndoAction() {
        super("Undo");
        setEnabled(false);
    }

    public void actionPerformed(ActionEvent e) {
        try {
            undoManager.undo();
        } catch (CannotUndoException ex) {
            ex.printStackTrace();
        }

        update();
        redoAction.update();
    }

    protected void update() {
        if (undoManager.canUndo()) {
            setEnabled(true);
            putValue(Action.NAME, undoManager.getUndoPresentationName());
        } else {
            setEnabled(false);
            putValue(Action.NAME, "Undo");
        }
    }
}

class RedoAction extends AbstractAction {
    public RedoAction() {
        super("Redo");
        setEnabled(false);
    }

    public void actionPerformed(ActionEvent e) {
        try {
            undoManager.redo();
        } catch (CannotRedoException ex) {
            ex.printStackTrace();
        }

        update();
        undoAction.update();
    }

    protected void update() {
        if (undoManager.canRedo()) {
            setEnabled(true);
            putValue(Action.NAME, undoManager.getRedoPresentationName());
        } else {
            setEnabled(false);
            putValue(Action.NAME, "Redo");
        }
    }
}

... and assigned it to each document like this:

        // Fetch the under laying document ...
        ObjDocument doc = (ObjDocument) editor.getDocument();

        // ... and assign the undo listener.
        doc.addUndoableEditListener(undoHandler);

Thanks & Best regards

Andreas

1

There are 1 answers