2009-07-24 11 views
7

L'interfaccia utente di Swing Java non si sta aggiornando/ridipingendo come pensavo. L'app invia un messaggio XMPP e riceve una risposta su un thread diverso. Tale risposta viene elaborata e l'interfaccia utente viene aggiornata per riflettere le informazioni contenute nel messaggio.Interfaccia utente Swing non aggiornata dopo l'utilizzo di invokeLater

Quando si riceve la risposta, aggiorno un componente JPanel utilizzando

javax.swing.SwingUtilities.invokeLater(new Runnable() { 
    public void run() { /* execute logic to update panel */ } 
}); 

E 'stato abbastanza un momento da quando ho sviluppato in Java, ma in base alla mia ricerca invokeLater linea accoda il eseguibile per l'esecuzione del Thread GUI. Tuttavia, la mia GUI non si aggiorna finché non faccio qualcos'altro nell'app che causa un ridisegno, come il ridimensionamento della finestra. Cosa mi manca? Dopo la logica per l'aggiornamento del pannello, ho provato varie combinazioni di invalidate() e repaint(), ma il risultato è sempre lo stesso - la GUI non si aggiorna fino a quando, ad esempio, non ridimensiono la finestra.

MODIFICA: Quando dico di aggiornare il pannello, in particolare sto facendo un removeAll() e poi aggiungo una manciata di JLabels.

risposta

14

Dopo l'aggiunta/rimozione di componenti da un pannello si dovrebbe usare:

giorni
panel.revalidate(); // this works 99% of the time 
panel.repaint(); // sometimes needed. 

altre cose come validate(), invalidate(), ecc, è rimasto da AWT credo e prorogare() fa un lavoro migliore ed è stato aggiunto specificamente per Swing.

+0

Vorrei aggiornarlo, migliaia di volte. – JCasso

2

Se si intende "aggiorna il pannello" in cui si aggiungono o si rimuovono componenti, è consigliabile utilizzare invalidate() o revalidate() in modo che il gestore di layout rilevi le modifiche.

Vedere here per un problema simile.

2

Se si aggiungono o si rimuovono componenti da un pannello durante la gestione degli eventi della GUI (come i listener di azioni), chiamare il numero doLayout() dovrebbe risolvere il problema. Ho trovato quando la GUI non si aggiorna, chiamando validate(), doLayout() e repaint() tende a sistemare le cose.

+1

in realtà non si dovrebbe chiamare direttamente doLayout() e chiamare invece revalidate(). – Stroboskop

+0

@Stroboskop anche se non dovresti, la documentazione dice "Questo di solito viene chiamato quando il componente viene convalidato." e le mie esperienze suggeriscono che quando si aggiungono e si rimuovono componenti da un contenitore durante la gestione degli eventi, questo metodo non viene chiamato da revalidate(). – Peter

+0

Giusto. Dal momento che tutto ciò accade in EventQueue, ci sono buone probabilità che il flag di rinnovo non venga guardato fino a quando non hai finito. Ma avrei immaginato che una chiamata a ridipingere() avrebbe attivato sia la verniciatura che il layout più avanti ... – Stroboskop

Problemi correlati