La mia domanda è relativa a SwingUtilities.invokeLater
. Quando dovrei usarlo? Devo utilizzare ogni volta che ho bisogno di aggiornare i componenti della GUI? Cosa fa esattamente? Esiste un'alternativa perché non sembra intuitiva e aggiunge un codice apparentemente non necessario?SwingUtilities.invokeLater
risposta
Devo utilizzare ogni volta che ho bisogno di aggiornare i componenti della GUI?
No, se siete già sul filo evento dispatch (EDT), che è sempre il caso quando si risponde a utente iniziati gli eventi come i clic e selezioni. (I actionPerformed
metodi, ecc, sono sempre chiamati dalla EDT.)
Se siete non sul EDT comunque e vuole fare aggiornamenti GUI (se si desidera aggiornare la GUI da qualche thread del timer, oppure da un po 'di thread di rete, ecc.), è necessario programmare l'aggiornamento che deve essere eseguito dall'EDT. Ecco a cosa serve questo metodo.
L'oscillazione è fondamentalmente non sicura. Ad esempio, tutte le interazioni con quell'API devono essere eseguite su un singolo thread (l'EDT). Se hai bisogno di fare gli aggiornamenti della GUI da un altro thread (thread del timer, thread di networking, ...) devi usare metodi come quello che hai citato (SwingUtilities.invokeLater, SwingUtilities.invokeAndWait, ...).
@ Jens: il che significa che posso farne a meno se sono sullo stesso thread (Swing) o faccio cose in fase di esecuzione. – FadelMS
Bene, "o fare le cose in fase di esecuzione" non è molto preciso. Se fai cose in runtime, in, per esempio, in un thread del timer, allora no, non puoi fare a meno di questo tipo di metodi. – aioobe
Grazie aioobe, capito. – FadelMS
Ogni applicazione swing ha almeno 2 filetti:
- Il thread principale che esegue l'applicazione
- L'EDT (Event Dispacciamento Thread) è un filo che aggiorna l'interfaccia utente (così l'interfaccia utente non si blocca).
Se si desidera aggiornare l'interfaccia utente, è necessario eseguire il codice all'interno dell'EDT. Metodi come SwingUtilities.invokeLater, SwingUtilities.invokeAndWait, EventQueue.invokeLater, EventQueue.invokeAndWait consentono di eseguire codice da EDT.
semplice e facile da capire, grazie – Yahya
La maggior parte degli eventi avviati dall'utente (clic, tastiera) si troveranno già nell'EDT in modo da non dover utilizzare SwingUtilities per questo. Questo copre molti casi, ad eccezione del thread main() e dei thread worker che aggiornano l'EDT.
non più, _all_ – kleopatra
Bene, un utente può aggiornare un file che viene monitorato da un thread che aggiorna la GUI. –
hmm ...che non conta come un evento avviato dall'utente (diretto, dove è la regola): l'utente aggiorna il file (all'interno di swing, su EDT) e lo salva (facendo clic su un pulsante, su EDT), che attiva un sistema operativo notifica di evento di aggiornamento file (fuori swing, fuori EDT), la notifica raggiunge il monitor (fuori EDT) che è responsabile dell'aggiornamento della GUI su EDT – kleopatra
La mia domanda questa volta è relativa a
SwingUtilities.invokeLater
: Quando dovrei usarlo?
La chiave per capire è che Java ha un thread separato (EDT) che gestisce gli eventi relativi allo Swing.
È necessario utilizzare invokeLater()
per visualizzare l'JFrame
principale di un'applicazione desktop (ad esempio), invece di provare a farlo nel thread corrente. Creerà inoltre il contesto per la chiusura graduale dell'applicazione in un secondo momento.
Questo è tutto per la maggior parte delle applicazioni.
Devo utilizzare ogni volta che ho bisogno di aggiornare i componenti della GUI? Cosa fa esattamente?
No.Se si modifica un componente della GUI, verrà attivato un evento registrato per la successiva spedizione da parte di Swing. Se c'è un listener per questo evento, il thread EDT lo chiamerà da qualche parte lungo la strada. Non è necessario utilizzare invokeLater()
, è sufficiente impostare correttamente i listener sui componenti.
Ricordare che questo thread è lo stesso schema per il disegno di trame ecc. Sullo schermo. Quindi, gli ascoltatori non dovrebbero eseguire compiti complessi/lunghi/intensi della CPU, altrimenti lo schermo si bloccherà.
Esiste un'alternativa perché non sembra intuitivo e aggiunge codice apparentemente non necessario?
Non è necessario scrivere codice più che visualizzare l'applicazione con invokeLater()
+ ascoltatori a cui è interessato il componente. Il resto è gestito da Swing.
Swing is single threaded and all changes to the GUI must be done on EDT
Utilizzo base per invokeLater()
metodi principali dovrebbero essere sempre avvolti in
invokeLater()
in ritardo (ma in modo asincrono) azione/evento alla fine del
EventQueue
,Se EDT non esiste, è necessario creare un nuovo EDT utilizzando
invokeLater()
. È possibile verificare conif (SwingUtilities.isEventDispatchThread()) {...
Esiste
invokeAndWait()
, ma fino ad oggi ho (solo mio punto di vista) non riesce a trovare un motivo per l'utilizzo diinvokeAndWait()
invece diinvokeLater()
, salvo modifiche duro nella GUI (JTree & JTable), ma solo con Substance L&F (eccellente per le prove di coerenza di eventi sul EDT)roba di base: Concurrency in Swing
Tutto l'output da operazioni in background deve essere avvolto in
invokeLater()
- 1. Java: debugging con SwingUtilities.invokeLater()
- 2. Cosa fa SwingUtilities.invokeLater?
- 3. EventQueue.invokeLater vrs SwingUtilities.invokeLater
- 4. Funzione simile SwingUtilities.invokeLater in Android?
- 5. Java - Differenza tra SwingWorker e SwingUtilities.invokeLater()
- 6. Perché la GUI rimane bloccata anche dopo aver usato SwingUtilities.invokeLater?
- 7. battente con barra di avanzamento
- 8. Java Flusso di esecuzione - il metodo sovrascritto viene eseguito prima del costruttore
- 9. Che cos'è $ sign in Java? Si prega di dare un'occhiata nel codice Java sotto
- 10. Best practice per avviare un'applicazione swing
- 11. C'è un modo per impostare due o più thread di invio eventi (EDT)?
- 12. modello per bloccare utente Java Swing nel thread di lavoro
- 13. Come far funzionare lo sfondo in JComponent personalizzato?
- 14. Il codice non funziona quando si esegue normalmente, ma funziona in debug (eclissi)
- 15. Java's Swing Threading
- 16. Come inviare un messaggio dal server al client
- 17. JLabel dipinge punti
- 18. Swing - MaskFormatter - Immettere i numeri da destra del campo di testo
- 19. Unit test su un componente Swing
- 20. Impossibile modificare la dimensione del blocco in BorderLayout
- 21. JScrollPane non appare quando lo si utilizza su un JPanel
- 22. Aggiornamento della GUI da un altro thread in java (swing)
- 23. Perché il modello di threading Swing è considerato sbagliato e come dovrebbe essere?
- 24. JComboBox su Windows 7 presenta artefatti di rendering
- 25. Perché la mia eccezione Java non stampa una traccia di stack quando viene lanciata all'interno di SwingWorker?
- 26. Perché mai cambiare il notificante a ricevere un evento di modifica
- 27. JLabel html testo ignora setFont
- 28. JLabel dipinge il nuovo testo su quello vecchio, dopo che il testo impostato viene chiamato
- 29. Come selezionare tutto il testo nella cella JTable durante la modifica ma non durante la digitazione?
- 30. Come impostare JSplitPane-Divider comprimere/espandere stato?
È l'equivalente di 'Control.BeginInvoke'. – SLaks
@SLaks Significa che se ho un thread non devo usarlo? – FadelMS
@FadelMS, poiché i framework Swing generano un thread (EDT), avrai sempre quel thread. (* Non * hai un "message-checking" -loop che elabora i click-utente ecc, giusto? Allora come vengono chiamati i vari metodi 'actionPerformed'? Per l'EDT!) Quindi quando dici di avere * uno * thread, dovrei interpretare questo come * solo * ha l'EDT (cioè, hai gettato una GUI e caduto dal limite del metodo principale). In tal caso, NO, * non * sarà necessario utilizzare 'invokeLater'. Tuttavia non sarà possibile eseguire alcuna elaborazione di "background". Se lo fai, bloccherai completamente la GUI ... – aioobe