2010-01-30 9 views
5

Ich entwickle einen einfachen WYSIWYG RTF Editor in Java und habe ein kleines Problem. Ich muss in der Lage sein, die Auswahlschaltflächen für die Stilauswahl (z. B. fett, kursiv, unterstrichen) mit der Textauswahl des Benutzers zu synchronisieren. Wenn z. B. die aktuelle Textauswahl leer ist, werden die Umschalttasten für Fett, Kursiv und Unterstrichen nicht ausgewählt. Wenn der Benutzer jedoch fett und unterstrichenen Text auswählt, werden die Umschalttasten für Fettdruck und Unterstreichen ausgewählt.JTextPane Synchronize Style Auswahl UI Problem

Jetzt bin ich mir ziemlich sicher, dass JTextPane.getInputAttributes() mir die Auswahl Attribute ich möchte, aber es gibt ein Problem mit dem Abhören für Caret Update-Ereignisse. Das Problem ist, dass der Caret-Listener, der an die JTextPane angehängt ist, scheinbar NACH dem Wechsel des Eingabeattributs aufgerufen wird. Die Auswahl ist also immer einen Schritt zurück. Das heißt, ich muss den Text zweimal auswählen, bevor die Umschalttasten aktualisiert werden!

Der wichtige Code ist hier:

textPane.addCaretListener(new CaretListener() { 

     @Override 
     public void caretUpdate(CaretEvent e) { 
      syncAttributesWithUI(textPane.getInputAttributes()); 
     } 
    }); 

Und:

private void syncAttributesWithUI(AttributeSet attributes) { 
    boldButton.setSelected(StyleConstants.isBold(attributes)); 
    italicButton.setSelected(StyleConstants.isItalic(attributes)); 
    underlineButton.setSelected(StyleConstants.isUnderline(attributes)); 
} 

Vielen Dank im Voraus!

+0

Wurde Ihre Frage beantwortet? Wenn nicht, erwägen Sie post einen SSCCE –

Antwort

1

Die CaretListener hört auf Ihre textPane, aber die vorhandenen Attribute für die Auswahl sind in Ihrem Document. Sie können die Methoden CaretEvent verwenden, um den ausgewählten Teil von Document zu finden und Ihre Schaltflächen basierend auf den dort gefundenen Stilen zu konditionieren. Leider kann die Auswahl inkohärent sein, z. Teil fett und teilweise kursiv. Eine übliche Vorgehensweise besteht darin, anzunehmen, dass der Benutzer eine vollständig neue Gruppe von Attributen auf die gesamte Auswahl anwenden möchte.

+0

Die Methode, die Sie vorschlagen, ist tatsächlich, was ich ursprünglich tat. Ich würde jedes einzelne Zeichenelement der Auswahl abrufen und die Schnittmenge des Attributs finden, um zu bestimmen, was die Benutzeroberfläche wiedergeben soll. Aber dann erkannte ich, dass 1) die getInputAttributes() -Methode dies bereits zu tun scheint und 2) Meine Methode kann nicht bestimmen, welcher Stil angewendet wird, wenn das Caret an die letzte Position im Dokument verschoben wird, bis der Benutzer eine Eingabe ausgelöst hat. Natürlich kann ich das wohl herausfinden, indem ich den Charakterstil an (Endposition - 1) ausarbeite, aber ich hoffte, dass es einen saubereren Weg gibt :( – S73417H

+0

Ich würde erwarten, dass der Benutzer die Attribute von 'getInputAttributes() 'unverändert zu bleiben, wenn der Caret am Ende ist. – trashgod

0

Sie könnten versuchen, die Synchronisierung zu verschieben, so dass die anderen Änderungen zuerst passieren könnten:

@Override 
public void caretUpdate(CaretEvent e) { 
    SwingUtilities.invokeLater(new Runnable() { 
     @Override 
     public void run() { 
      syncAttributesWithUI(textPane.getInputAttributes()); 
     } 
    }); 
} 

(Haftungsausschluss: Erraten von der Spitze von meinem Kopf - ich eigentlich nicht einen Test schreiben, um zu bestätigen)