Durante l'utilizzo di un toolkit widget, è importante comprendere il modello di thread sottostante utilizzato per la lettura e la distribuzione degli eventi della GUI della piattaforma. L'implementazione del thread UI influisce sulle regole che le applicazioni devono seguire nell'utilizzo di thread Java nel codice.
Al di sotto di ogni applicazione GUI, indipendentemente dalla lingua o dal toolkit UI in uso, la piattaforma del sistema operativo rileva gli eventi della GUI e li colloca nelle code di eventi dell'applicazione. Sebbene i meccanismi differiscano leggermente a seconda della piattaforma del sistema operativo, i principi di base sono identici. Non appena l'utente fa clic con il mouse, immette caratteri o visualizza finestre, la piattaforma genera gli eventi GUI dell'applicazione, quali i clic del mouse, la selezione di tasti o gli eventi di aggiornamento di una finestra e determina la finestra e l'applicazione che devono ricevere ciascun evento, inserendolo nella coda degli eventi dell'applicazione.
La struttura sottostante a ogni applicazione GUI con finestre costituisce un ciclo di eventi. Una volta inizializzate, le applicazioni avviano un ciclo che legge semplicemente gli eventi della GUI dalla coda ed agisce di conseguenza. Perché il sistema GUI continui a interagire con l'utente, è necessario operare con rapidità durante la gestione di uno di questi eventi.
Le lunghe operazioni attivate dagli eventi UI devono essere eseguite in un thread separato in modo che il thread del ciclo di eventi possa chiudersi rapidamente e recuperare il successivo evento della coda dell'applicazione. Tuttavia, l'accesso ai widget e all'API della piattaforma da altri thread deve essere controllato applicando un blocco e una serializzazione. Un'applicazione che non segue le regole, può generare chiamate al sistema operativo non riuscite o, peggio, il blocco dell'intero sistema GUI.
SWT segue il modello di threading supportato direttamente dalle piattaforme. L'applicazione esegue il ciclo di eventi nel thread principale e distribuisce gli eventi direttamente da tale thread, Il thread UI è il thread nel quale viene creato il Display. Tutti gli altri widget devono essere creati nel thread UI.
Poiché tutto il codice di eventi viene avviato dal thread dell'interfaccia utente dell'applicazione, il codice che gestisce gli eventi può accedere liberamente ai widget per eseguire chiamate grafiche senza richiedere tecniche speciali. Tuttavia, l'applicazione è responsabile della duplicazione dei thread di calcolo durante l'esecuzione di lunghe operazioni in risposta a un evento.
Nota: SWT attiva una SWTException per tutte le chiamate effettuate da un thread non UI che devono essere eseguite dal thread dell'interfaccia utente.
Il thread principale per un'applicazione SWT, incluso il ciclo di eventi, presenta la seguente struttura:
public static void main(String[] args) { Display display = new Display (); Shell shell = new Shell (display); shell.open (); // avviare il ciclo di eventi. Si verificherà un'interruzione quando l'utente avrà eseguito // un'operazione per eliminare la finestra. while (!shell.isDisposed ()) { if (!display.readAndDispatch()) display.sleep(); } display.dispose (); }
Dopo aver creato i widget e aperto la shell, l'applicazione legge e distribuisce gli eventi dalla coda del sistema operativo fino all'eliminazione della finestra shell. In assenza di eventi disponibili nella coda, la visualizzazione deve rimanere inattiva in maniera che le altre applicazioni possano essere eseguite.
SWT fornisce metodi di accesso speciali per chiamare widget e codice grafico da un thread di background.
Le applicazioni che desiderano richiamare un codice UI da un thread non UI devono fornire un eseguibile che richiami il codice UI. Per eseguire questi eseguibili nel thread dell'interfaccia utente, vengono utilizzati i metodi syncExec(Runnable) e asyncExec(Runnable) nella classe Display.
Il seguente frammento di codice illustra il modello per l'utilizzo di questi metodi:
// eseguire calcoli impegnativi ... // aggiornare ora la UI. Poiché non è necessario attendere il risultato, // usare async. display.asyncExec (new Runnable () { public void run () { if (!myWindow.isDisposed()) myWindow.redraw(); } }); // eseguire adesso altri calcoli ...
Si consiglia di verificare se il widget è stato eliminato dall'eseguibile quando si utilizza
asyncExec. Poiché in un thread UI vengono eseguite altre azioni tra la chiamata a asyncExec
e
l'esecuzione, non si può essere sicuri dello stato dei widget al momento dell'effettiva esecuzione
dell'eseguibile.
Le regole di threading sono molto chiare quando si esegue una nuova implementazione di un'applicazione SWT, in quanto è possibile controllare la creazione del ciclo di eventi e la decisione di duplicare i thread di calcolo nell'applicazione.
Le cose possono essere più complicate quando si aggiunge codice di plugin al workbench. Le seguenti regole possono essere considerate "regole di attivazione" quando si utilizzano classi UI della piattaforma, anche se da rilascio a rilascio ci possono essere eccezioni a queste regole: