2010-01-30 4 views
5

Sto sviluppando un semplice editor WYSIWYG RTF in Java e ho un piccolo problema. Devo essere in grado di sincronizzare i pulsanti di selezione della selezione di stile (come grassetto, corsivo, sottolineato) alla selezione del testo dell'utente. Ad esempio, se la selezione del testo corrente è semplice, i pulsanti di selezione grassetto, corsivo e sottolineato non sono selezionati, ma quando l'utente seleziona del testo in grassetto e sottolineato, i pulsanti di selezione grassetto e sottolineato sono selezionati.JTextPane Sincronizza l'interfaccia utente di selezione stile Problema

Ora sono abbastanza sicuro che lo JTextPane.getInputAttributes() mi ottenga gli attributi di selezione che desidero ma c'è un problema con l'ascolto di eventi di aggiornamento caret. Il problema è che l'ascoltatore di caret collegato allo JTextPane sembra essere chiamato DOPO che si verifica la modifica dell'attributo di input. Quindi la selezione è sempre un passo indietro. Cioè, devo selezionare il testo due volte prima che i pulsanti di commutazione siano aggiornati!

Il codice importante è:

textPane.addCaretListener(new CaretListener() { 

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

E:

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

Grazie in anticipo!

+0

La tua domanda ha risposta? In caso contrario, considera un SSCCE –

risposta

1

CaretListener sta ascoltando il tuo textPane, ma gli attributi esistenti per la selezione sono nel tuo Document. È possibile utilizzare i metodi CaretEvent per trovare la parte selezionata di Document e condizionare i pulsanti in base agli stili trovati lì. Sfortunatamente, la selezione potrebbe essere incoerente, ad es. parte in grassetto e parte in corsivo. Una pratica comune è quella di presumere che l'utente desideri applicare un set di attributi completamente nuovo all'intera selezione.

+0

Il metodo che suggerisci è in effetti ciò che stavo facendo in origine. Otterrei ogni singolo elemento del carattere della selezione e troverò l'intersezione dell'insieme di attributi per determinare cosa deve riflettere l'interfaccia utente. Ma poi mi sono reso conto che 1) Il metodo getInputAttributes() sembra farlo già, e 2) Il mio metodo non può determinare quale stile viene applicato se il cursore viene spostato nell'ultima posizione nel documento finché l'utente non ha attivato un input. Ovviamente posso probabilmente determinarlo elaborando lo stile del carattere in (end position - 1), ma speravo che ci fosse un modo più pulito :( – S73417H

+0

Mi aspetterei che l'utente desideri gli attributi restituiti da 'getInputAttributes() 'di rimanere inalterato quando il cursore è alla fine. – trashgod

0

Si potrebbe provare a rinviare la sincronizzazione, in modo che le altre modifiche potrebbero accadere prima:

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

(Diniego: Indovinare dalla parte superiore della mia testa - non ho in realtà scrivere un test per confermare)