Frage

Ich versuche, eine JTextPane zu schreiben, die eine Art von Färbung unterstützt: wenn der Benutzer den Text eingeben, ich einige Code leite die Farben der Text zu einem bestimmten Algorithmus entsprechend. Das funktioniert gut.

Das Problem ist, dass die Färbung Operationen mit dem Undo-Manager (a DefaultDocumentEvent mit EventType.CHANGE) registriert sind. Also, wenn der Benutzer klickt rückgängig machen verschwindet die Färbung. Erst auf den zweiten Undo Anforderung der Text selbst zurückgerollt.

(Beachten Sie, dass die Färbung Algorithmus etwas langsam ist, so kann ich nicht die Farbe des Textes, wie es eingesetzt wird).

Wenn ich versuche, die Änderungsereignisse zu verhindern, dass das Erreichen des Undo-Managers ich eine Ausnahme erhalten, nachdem mehrere Anfragen rückgängig machen. Dies liegt daran, dass die Dokumentinhalte nicht konform sind, was das undoable-Bearbeitungsobjekt erwartet

Irgendwelche Ideen?

War es hilfreich?

Lösung

Sie könnten die CHANGE Änderungen abfangen und jedes in einem anderen UndoableEdit deren isSignificant() Methode gibt false wickeln, bevor es an die UndoManager Zugabe. Dann wird jeder Befehl Undo wird die letzte INSERT rückgängig zu machen oder zu bearbeiten ENTFERNT sowie jede Änderung bearbeiten, die seitdem aufgetreten.

Letztendlich denke ich, dass der Styling Mechanismus von JTextPane / StyledDocument / etc vorgesehen finden. ist auch für diese Art der Sache beschränkt. Es ist langsam, es zu viel Speicher verwendet, und es basiert auf dem gleichen Element Baum, der im Auge zu behalten die lexikalische Struktur des Dokuments verwendet wird. Es ist in Ordnung (ich glaube) für Anwendungen, in denen die Stile durch den Benutzer, wie Textverarbeitung angewendet werden, aber nicht für eine Syntax-Highlighter, der die Stile ständig während der Benutzer tippt aktualisiert hat.

Es gibt mehrere Beispiele gibt den Syntax-Hervorhebung Editoren basierend auf kundenspezifischen Implementierungen der Swing-JTextComponent, View und Document Klassen. Einige, wie JEdit, neu implementieren praktisch das gesamte javax.swing.text Paket, aber ich glaube nicht, dass Sie so weit gehen müssen.

Andere Tipps

Wie versuchen Sie die CHANGE Ereignisse vom Erreichen der Undo-Manager zu verhindern?

Können Sie die UndoManager eine nicht senden Zuletzt geändert (). Die () rufen Sie uns sofort nach der Änderung die Warteschlange gestellt wird?

Ich kann nur annehmen, wie Sie den Text Färbung tun. Wenn Sie es in den StyledDocuments tun ändern Attribut Methode Zeichen, das Sie den Rückgängig-Hörer bekommen kann und es vorübergehend für diese Operation aus dem Dokument abzumelden und dann, sobald die Farbänderung finshed hat, dann können Sie den Hörer neu registrieren.

sollte in Ordnung sein für das, was Sie versuchen, es zu tun.

Hoffnung, die hilft

Ich habe gerade durch dieses Problem. Hier ist meine Lösung:

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);
    }

}

Es ist eine innere Klasse in meiner benutzerdefinierten JTextPane, so kann ich die Position der Einfügemarke auf Redo beheben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top