Visualizzazione dei risultati da 1 a 2 su 2
  1. #1

    [JAVA] Swing e il Thread che non fa il thread....

    Ciao a tutti,
    ho un problema sul quale sto sbattendo la testa da una giornata senza venirne a capo;
    il pratica, ho una GUI strutturata con un CardLayout, che mi serve per un wizard in cui l'utente viene guidato a connettere e scaricare i dati da un dispositivo seriale.

    Il problema è proprio quando viene visualizzata la finestra "Scarica i dati" con il button "inizia": comportamento desiderato:

    Arrivo alla finestra "Scarica i dati"
    premo "inizia"
    esce una Dialog chiamata "attendi" con una progress bar indeterminata
    quando il download finisce, la dialog va via e mi permette di premere il button "inizia analisi sui dati" della pagina "Analisi Dati"

    Come cerco di raggiungere il comportamento desiderato (non riuscendoci)

    Ho creato la classe Attesa che ha il metodo run per generare la finestra e visualizzarla, e il metodo ferma che fa un dispose per chiudere la finestra;
    ho creato la classe "ComLauncher" che estende SwingWorker con un metodo doInBackground che avvia la classe preposta all'invio e la ricezione dei comandi via seriale (ci sono due thread all'interno di questa classe, un sender e un receiver, ma non penso sia importante adesso)

    Quando viene visualizzato il frame "scarica dati, eseguo questa chiamata di funzioni (provo a usare il tag PHP spero funzioni che già sono stato cazziato da lele una volta :-) )
    Codice PHP:

    Attesa att
    =new Attesa();
    System.out.println("ho creato una istanza di ATTESA");            
    att.start();
    System.out.println("Ho avviato l'istanza di attesa, avvio il ComLauncher");
    cl.doInBackground();
    System.out.println("Ho avviato il ComLauncher, stoppo attesa");
                                
    att.ferma();
    System.out.println("Attesa stoppata"); 
    Ottengo che viene visualizzata la finestra con la barra ma è freezata, la barra non viene visualizzata, per il resto il comportamento è quello desiderato.

    L'output su system.out è il seguente:
    ho creato una istanza di ATTESA
    Ho avviato l'istanza di attesa, avvio il ComLauncher
    prima di setvisible <-----------

    Attendi: sto scaricando i dati XX [XX sono i secondi, stampa questo messaggio per ogni secondo che è in download)

    Ho avviato il comlancher, stoppo attesa
    dopo setvisible <-------------
    Attesa stoppata
    Penso che il problema sia nelle due istruzioni segnate dalla freccia: quando viene eseguito lo start su "attesa", il run() si ferma prima dell'ultima istruzione, ossia una "setvisible(true)" della finestra con la barra, qui il controllo viene ceduto allo swingworker che scarica i dati, e, quando finisce, riprende l'esecuzione il thread con la finestra e la progress bar che però viene subito stoppata.

    Il mio problema è che il thread Attesa non si comporta da Thread... dovrebbe procedere indipendentemente dagli altri? e perchè stoppa l'esecuzione e si freeza in attesa del thread di download dei dati?

    Forse ho "intuito" il problema..siccome il thread contiene elementi grafici, viene messo in coda alla lista di eventi grafici dell'EDT, che è bloccato..ma per quale motivo è bloccato? E perchè si sblocca dopo che il ComLauncher ha finito? non dovrebbe procedere esso in "background"?

    Spero che qualcuno di buona volontà mi dia una mano Non so più cosa fare.
    Modificando ComLauncher facendo sì che estenda Thread anche lui, il comportamento che ottengo è quello desiderato tranne che la finestrella con la progressbar non viene chiusa al termine del download dei dati...allora ho modificato il metodo "ferma" inserendo un this.stop
    e inserendo nel codice principale una istruzione di join sul ComLauncher in modo che l'esecuzione del thread principale (e quindi dell'esecuzione di attesa.ferma() ) sia subordinata alla terminazione del thread di download dei dati.... sono tornato alla situazione precedente, ossia barra freezata (e qua ci potrebbe stare, perchè se l'EDT è sospeso in attesa che termini il download dei dati, non può mostrarmi la barra...)

    In definitiva, come risolvo? Se servono altri dettagli, chiedete pure...

    Grazie per l'attenzione

  2. #2
    UPDATE:

    ho risolto nel modo forse più corretto: la finestra con la progress bar l'ho fatta generare alla classe ComLauncher che è uno Swing Worker..la finestra viene creata sull'evento de lcmabio di stato del ComLauncher, quando passa da PENDING a STARTED; quando ha terminato i suoi calcoli, il ComLauncher passa a DONE, e lì viene invocato un dispose sulla finestra.

    E' bastato aggiungere un ascoltatore al ComLauncher ed implementare la semplice logica di rilevazione di cambio di stato.

    Una nota: quando si deve chiamare il metodo principale di uno SwingWorker (il compito che è scritto nel doInBackground), va richiamato con
    Codice PHP:
    istanzaSwingWorker.execute() 
    e non con
    Codice PHP:
    istanzaSwingWorker.doInBackground 
    Se è fatto con la seconda opzione, non viene notificato il cambio di stato.

    In pratica, è come se si invocasse un Thread con
    Codice PHP:
    istanzaThread.run() 
    invece di

    Codice PHP:
    istanzaThread.start() 
    Per ulteriori informazioni, ci sono

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.