Hide specific actions from Swing Cancel Manager

I am trying to write a JTextPane that supports some kind of coloring: when the user types the text, I run some code that colors the text according to a specific algorithm. It works well.

The problem is that paint operations are logged by the undo manager (DefaultDocumentEvent with EventType.CHANGE). Therefore, when the user clicks the Cancel button, the coloring disappears. Only with the second cancellation request does the text itself roll back.

(Note that the coloring algorithm is somewhat slow, so I cannot color the text as it is inserted).

If I try to prevent CHANGE events from occurring in the undo manager, I get an exception after several undo requests: this is because the contents of the document do not match the expected undo object.

Any ideas?

+5
source share
4 answers

You can intercept CHANGE changes and wrap them in another UndoableEdit, the method isSignificant()returns falsebefore adding it to UndoManager. Each Undo command then rolls back the last INSERT or REMOVE changes, as well as every CHANGE change that has occurred since then.

, , , , JTextPane/StyledDocument/etc. . , , . ( ) , , , , , .

, Swing JTextComponent, View Document. , JEdit, javax.swing.text, , .

+1

CHANGE ?

UndoManager lastEdit(). die() , CHANGE ?

+1

, . StyledDocuments, , , , .

, .

,

+1

. :

private class UndoManagerFix extends UndoManager {

    private static final long serialVersionUID = 5335352180435980549L;

    @Override
    public synchronized void undo() throws CannotUndoException {
        do {
            UndoableEdit edit = editToBeUndone();
            if (edit instanceof AbstractDocument.DefaultDocumentEvent) {
                AbstractDocument.DefaultDocumentEvent event = (AbstractDocument.DefaultDocumentEvent) edit;
                if (event.getType() == EventType.CHANGE) {
                    super.undo();
                    continue;
                }
            }
            break;
        } while (true);

        super.undo();
    }

    @Override
    public synchronized void redo() throws CannotRedoException {
        super.redo();
        int caretPosition = getCaretPosition();

        do {
            UndoableEdit edit = editToBeRedone();
            if (edit instanceof AbstractDocument.DefaultDocumentEvent) {
                AbstractDocument.DefaultDocumentEvent event = (AbstractDocument.DefaultDocumentEvent) edit;
                if (event.getType() == EventType.CHANGE) {
                    super.redo();
                    continue;
                }
            }
            break;
        } while (true);

        setCaretPosition(caretPosition);
    }

}

JTextPane, .

0

All Articles