metodo invokeAndWait in SwingUtilities

Si prega di spiegare il metodo invokeAndWait () in SwingUtilities. Non riesco a capirlo. Spiegalo molto chiaramente. Sarebbe di grande aiuto se provassi con un esempio.

Modificato per aggiungere l’espansione di @ noob alla domanda:

Cosa non è chiaro su questo ?

Ecco un esempio di utilizzo modificato:

import javax.swing.SwingUtilities; public class InvokeAndWaitStuff { public static void main(String[] args) { final Runnable doHelloWorld = new Runnable() { public void run() { System.out.println("Hello World on " + Thread.currentThread()); } }; Thread appThread = new Thread() { public void run() { try { SwingUtilities.invokeAndWait(doHelloWorld); } catch (Exception e) { e.printStackTrace(); } System.out.println("Finished on " + Thread.currentThread()); } }; appThread.start(); } } 

Produzione:

 Hello World on Thread[AWT-EventQueue-0,6,main] Finished on Thread[Thread-0,5,main] 

E perché è così importante ?:

Fa sì che doHelloWorld.run () sia eseguito in modo sincrono nel thread di invio dell’evento AWT. Questa chiamata si blocca fino a quando non sono stati elaborati tutti gli eventi AWT in sospeso e (quindi) restituisce doHelloWorld.run (). Questo metodo deve essere utilizzato quando un thread dell’applicazione deve aggiornare la GUI.

Per quanto ne so, questo è fondamentalmente un collo di bottiglia che costringe gli aggiornamenti della GUI ad essere eseguiti in modo sincrono da un singolo thread, piuttosto che in modo asincrono da più thread, il che può potenzialmente essere pericoloso.

Per capire cosa fa invokeAndWait() , devi prima capire il modello evento / thread di Swing.

Fondamentalmente, tutto ciò che riguarda la GUI in qualche modo deve avvenire su un singolo thread . Questo perché l’esperienza dimostra che una GUI multi-thread è imansible da ottenere.

In Swing, questo thread GUI speciale è chiamato Thread di invio eventi o EDT . Viene avviato non appena viene visualizzato un componente di livello superiore di Swing ed è basicamente un thread di lavoro con una coda FIFO di oggetti evento che viene eseguita una dopo l’altra.

Quando una GUI Swing deve essere disegnata o aggiornata, JRE inserisce un evento nella coda EDT. Le azioni dell’utente che provocano la chiamata agli ascoltatori vengono avviate come eventi nella coda EDT. E (questa è la parte importante) tutto ciò che fa il programma che cambia la GUI (come registrare ascoltatori, aggiungere / rimuovere componenti GUI o modificare i dati del modello che la GUI mostra) deve essere collocato nella coda EDT, o la GUI può ottenere corrotti.

E ora per il completamento: invokeAndWait() posiziona il Runnable si passa ad esso nella coda degli eventi EDT e attende fino a quando l’EDT lo ha eseguito. Questo dovrebbe essere usato quando un thread non-GUI deve fare qualcosa che influisce sulla GUI, ma deve anche aspettare che venga effettivamente fatto prima che possa continuare. Se vuoi solo fare qualcosa che influisce sulla GUI, ma non ti interessa quando è finito, dovresti invece usare invokeLater() .

Ho avuto un problema simile in una JTable. Il programma è stato bloccato da qualche parte nel metodo “scrollRectToVisible”. Ho sostituito la chiamata avvolgendola in una chiamata invokeLater. InvokeAndWait non ha risolto il mio problema di blocco.

  SwingUtilities.invokeLater(new Runnable() { @Override public void run() { table.scrollRectToVisible(r); } });