Ok, ma questa è solo la "buona" pratica di far partire tutto, fin dall'inizio, nel EDT (Event Dispatch Thread). Cioè vale in generale nelle applicazioni Swing.Originariamente inviato da ziz
ho modificato come segue il main:
codice:public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { REMExtractorGui gui = new REMExtractorGui(); gui.buildGUI(); } }); }
Sì, se il lavoro impiega (potenzialmente) molto tempo, devi eseguirlo in un thread separato, per non tenere "impegnato" troppo a lungo il EDT, cosa che causerebbe il "congelamento" della tua interfaccia utente.Originariamente inviato da ziz
Alla pressione di un bottone, partono lettura del file, ordinamento dei risultati e creazione del file Excel.
Ho capito che devo utilizzare un thread anche in questo secondo metodo per lasciare l'elaborazione della grafica al thread principale di Swing, ma non mi è molto chiara la logica. Se lancio in un thread a parte il mio estrattore, come faccio a recuperare le eccezioni e a far visualizzare i relativi pop-up? Mi sto perdendo qualcosa?
Nel contesto di un altro thread però non devi accedere direttamente alla interfaccia utente (quindi niente setText, setTitle, contenitore.add(componente), ecc...). Salvo poche operazioni, ben note e documentate che sono thread-safe, per il resto Swing non è thread-safe e l'accesso alla interfaccia utente va fatto solo nel EDT.
Nessuno però vieta, nel tuo thread a parte, di usare invokeLater/invokeAndWait di SwingUtilities per far eseguire un pezzetto di codice nel EDT che permetterebbe di fare appunto quel "qualcosa" (es. un label.setText o un dialog.setTitle) in modo appropriato e sicuro per Swing.
Il punto è che se nel tuo thread ti ritrovi a dover fare innumerevoli volte e in vari punti dei invokeLater/invokeAndWait e magari solo per aggiornare la stessa cosa, evidentemente il design non è granché e devi cambiarlo ...
Da Java 6 in javax.swing c'è SwingWorker, è una classe apposta per far eseguire qualcosa in un thread separato ma con la possibilità di avere dei "punti" di incontro con il EDT senza dover ripetere ogni volta gli invokeXXX. Per usare SwingWorker devi però comprendere bene il suo workflow (ci sono documentazione/tutorial ufficiali).
Se SwingWorker non puoi/vuoi usarlo, allora devi realizzare tu un design che permetta di separare bene le cose, facendo in modo che sia semplice (per il thread) aggiornare la interfaccia utente in modo appropriato e senza troppo codice ripetitivo.
Se ad esempio ti servisse fare N lavori diversi ma tutti hanno in comune il fatto di usare quella stessa dialog di monitor della attività, allora puoi creare una classe base che crea la dialog, crea il thread e offre i servizi (in modo thread-safe) per aggiornarla, in modo che una sottoclasse deve solo definire il "lavoro" specifico e richiamare quei metodi di servizio.
Ripeto: qui si va più su questioni di "design" delle classi che altro.
Se vuoi un esempio, chiedi.