Il tutorial ufficiale: Lesson: Concurrency in Swing
Ma non c'è tantissimo. Cerca in rete "swing edt" e trovi tonnellate di roba.![]()
Andrea, Senior Java developer – SCJP 5 (91%) • SCWCD 5 (94%)
Java Versions Cheat Sheet
Grazie, ho visto ma devo ancora entrare nell ottica.
Ho visto che c'e' anche la progressbar (lho usata anni fa in visual basic, ma qua è diverso).
ho visto degli esempi tipo quest:
ma non so come implementarlo con la mia finestracodice:import javax.swing.JOptionPane; import javax.swing.JProgressBar; import javax.swing.SwingUtilities; public class SetProgressBar extends Thread { private final int DELAY = 100; private JProgressBar progressBar; public SetProgressBar(JProgressBar bar) { progressBar = bar; } @Override public void run() { int minimum = progressBar.getMinimum(); int maximum = progressBar.getMaximum(); Runnable runner = new Runnable() { @Override public void run() { int value = progressBar.getValue(); progressBar.setValue(value + 1); } }; for (int i = minimum; i < maximum; i++) { try { SwingUtilities.invokeLater(runner); Thread.sleep(DELAY); } catch (InterruptedException ex) { JOptionPane.showMessageDialog(null, ex.getMessage()); } } }
Ci sono diversi aspetti da comprendere bene, che riassumo:
- Il EDT è il thread che si occupa del disegno dei componenti Swing e degli eventi. È uno solo e quindi chiaramente fa tutto in sequenza, una cosa per volta. Se sta disegnando (aggiornando) un componente Swing a video, non sta dispacciando eventi ... e se sta dispacciando un evento (es. invocazione di un tuo actionPerformed) non sta disegnando nulla.
- Se devi fare elaborazioni "lunghe", quasi sicuramente le farai partire a seguito di un evento (es. actionPerformed per un pulsante o menù), quindi sei nel EDT. Non lo devi tenere tu "impegnato" per troppo tempo, altrimenti la tua interfaccia è congelata e non responsiva. Pertanto dovresti far partire l'elaborazione in un nuovo thread separato.
- Se usi il multi-threading, devi avere ben chiare, in generale, le questioni su concorrenza, sincronizzazione, "visibilità" delle modifiche ecc.... E in particolare tenere presente che Swing non è in generale thread-safe. Sono pochissime (note e documentate) le operazioni che puoi fare sulla interfaccia utente da un altro thread che non è il EDT. Pertanto nel contesto di un tuo thread non devi accedere direttamente alla interfaccia utente. Non devi fare get/setXyz sui componenti, add/remove/ecc.. su contenitori, ecc...
- Se da un thread non EDT vuoi aggiornare la interfaccia utente, la soluzione tipica è far passare la esecuzione di un pezzetto di codice (incapsulato in Runnable) nel contesto del EDT. È quel Runnable che vedi nell'esempio, passato al invokeLater. invokeLater parcheggia solo il Runnable nella coda degli eventi e ritorna subito. Il EDT appena è libero (e lo è quasi immediatamente, se appunto non lo impegni tu), prenderà quel Runnable e ne invocherà il suo run(), quindi lì dentro puoi aggiornare la UI perché sei nel EDT.
Andrea, Senior Java developer – SCJP 5 (91%) • SCWCD 5 (94%)
Java Versions Cheat Sheet