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

    Delay tra eventi generati da un solo click!

    Dovrei riuscire a popolare dopo aver premuto un pulsante, due righe di una tabella.
    Le due righe, dovranno essere popolate a distanza di qualche secondo l'una dall'altra.

    Questo è quello che vorrei:

    • premo pulsante
    • viene popolata la prima riga
    • aspetta 3 secondi
    • viene popolata la la seconda riga


    Quello che invece attualemente accade:


    • premo pulsante
    • Attende tre secondi
    • vengono popolate la prima e la seconda riga contemporaneamente



    codice:
      private void SendResetActionPerformed(java.awt.event.ActionEvent evt) 
    
    {                                          
                int B = 10;
                TableColumn tcol;
                
                GregorianCalendar gc = new GregorianCalendar();
                int month = gc.get(java.util.Calendar.MONTH);
                int year = gc.get(java.util.Calendar.YEAR);
                int day = gc.get(java.util.Calendar.DAY_OF_MONTH);
                int hour = gc.get(java.util.Calendar.HOUR_OF_DAY);
                int min = gc.get(java.util.Calendar.MINUTE);
                int sec = gc.get(java.util.Calendar.SECOND);
                int doy = gc.get(java.util.Calendar.DAY_OF_YEAR);
                
                String ann_mes = (year + "-" + "0" + (month + 1) + "-" + day + "");
                String oraminsec = ((hour) - 2 + ":" + min + ":" + sec + "  ");
    
       //popolo la prima tabella
             
                for (int i = 0; i < main.getJTable().getRowCount(); i++) {
                    if (main.getJTable().getValueAt(i, 0) == null) {
                        index = i;
                        break;
                    }
                }
                main.getJTable().setValueAt("String1", index, 0);
                main.getJTable().setValueAt("String2", index, 1);
    
          try {
                
                Thread.sleep(3000);
       //popolo la prima tabella
                for (int i = 0; i < main.getJTable().getRowCount(); i++) {
                    if (main.getJTable().getValueAt(i, 0) == null) {
                        index1 = i;
                        break;
                    }
          
                main.getJTable().setValueAt("String3", index1, 0);
                main.getJTable().setValueAt("String4", index1, 1);
    
                   } catch (InterruptedException ex) {
                Logger.getLogger(this.class.getName()).log(Level.SEVERE, null, ex);
            }
    Grazie a chi vorrà rispondermi.
    Ultima modifica di marcotto68; 12-02-2014 a 18:02

  2. #2
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,328
    Questo accade perchè stai facendo fare tutto il lavoro al EDT (Event Dispatch Thread) e non va bene.
    Il metodo SendResetActionPerformed() (che immagino sia il metodo chiamato dal ActionListener) viene richiamato nel contesto del EDT.

    Questo metodo dovrebbe fare il minor lavoro possibile perchè, finchè lui non ha finito (quindi, finchè non sono trascorsi i 3 secondi), l'interfaccia grafica rimane congelata.... e si risveglierà solo al termine.

    Quindi, sposta tutto il contenuto di quel metodo dentro ad un thread.
    Fai in modo che il thread non modifichi l'interfaccia grafica direttamente, ma attraverso l'EDT (quindi richiamando un metodo della classe "principale" da uno SwingUtilities.invokeLater()).
    Fai in modo che quel metodo crei il thread e lo faccia partire

    E tutto funzionerà.

    Ti consiglio di guardare altre discussioni che parlano dello stesso "problema", ovvero il trattamento dello scambio di informazioni fra thread e EDT (che è un thread).

    http://forum.html.it/forum/showthrea...readid=1550779
    http://forum.html.it/forum/showthrea...readid=1550623

    ed altri... cerca "EDT" nel forum Java.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  3. #3
    E' molto complicato per me capire quello che hai scritto. Naturalmente dipende dalla mia ignoranza. Proverò a leggere qualcosa ma non ti nego che le difficoltà sono molte... proverò! Grazie per tutto.

  4. #4
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,328
    Capisco le difficoltà, ma per programmare le GUI è necessario conoscere come funzionano e, soprattutto, capire il meccanismo di threading di Swing.

    Qui è il punto di partenza: http://docs.oracle.com/javase/tutori...ncy/index.html

    Detto molto grossolanamente, in un'applicazione Swing, oltre al initial thread che è il primo thread che fa partire l'applicazione, vi è un importante thread: l'EDT. Questo thread è colui che si occupa di disegnare l'interfaccia grafica delle applicazioni Swing e di notificare tutti i listener che vengono coinvolti. All'interno di questo thread vengono "accodati" tutti gli eventi che coinvolgono il disegno dei componenti: quindi, quando un componente necessita di essere ridisegnato, aggiornato, ecc, viene depositato un "messaggio" nella coda di questo thread. Questo thread, quindi, prende in carico un messaggio e svolge il lavoro, poi passa al successivo e svolge il lavoro, ecc.

    Quando tu fai clic su un pulsante, viene depositato un messaggio (in realtà ne vengono depositati tanti, ma guardiamo al concetto) che dice: caro EDT, ridisegna il pulsante (per far vedere che è premuto) e informa tutti i listener che questo pulsante è stato premuto. Allora l'EDT si prende tutti i listener di quel pulsante (compreso il tuo) e cominica ad eseguire il metodo actionPerformed() di ciascuno di essi, in cascata. Arriva al tuo listener e che fa? Esegue il tuo codice. Ovvero: fa tutti i suoi calcoli sulla data, va a prendersi i valori della tabella poi accoda due messaggi per la modifica di due celle, poi attende 3 secondi, quindi accoda altri due messaggi di modifica di altre celle ed infine termina, rendendosi disponibile per il prossimo messaggio in coda.

    Come puoi vedere, quando tu vai a modificare un componente (setti il testo delle celle della tabella, in questo caso), ciò che viene fatto è "accodare dei messaggi per l'EDT"... ma l'EDT è già impegnato a fare il lavoro che tu gli hai detto di fare. Quindi, le modifiche vere e proprie le potrà fare (e tu le vedrai) solo quando lui avrà finito di fare quelle operazioni e sarà pronto a prenderne in carico delle altre... e tra queste operazioni che tu gli stai dicendo di fare c'è quella Sleep(3000)! Quindi lui diventerà "libero di fare le altre operazioni" solo dopo che sono trascorsi quei 3 secondi.

    Ecco perchè il lavoro da far fare all'actionPerformed() (ma più in generale a tutto ciò che è di pertinenza del EDT) deve essere il più snello possibile perchè mentre l'EDT è impegnato ad eseguire quel codice, non può occuparsi di altro e l'intera interfaccia utente non è più responsiva (non viene aggiornata e non risponde agli eventi).

    Quindi, se ci sono elaborazioni "pesanti" (o, quanto meno, "time-consuming", ovvero che richiedono TEMPO... hai presente quello sleep di 3 secondi?) vanno fatte fare ad un altro thread (che può lavorare in parallelo).

    Ovviamente questa è solo una minima parte, non esaustiva e non dettagliata, del funzionamento della "concorrenza" in Swing. Molti altri dettagli li trovi nel documento che ti ho elencato, ma già questo dovrebbe darti un'idea generale del funzionamento.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  5. #5
    Grazie Lele, come al solito sei riuscito a spiegare cose complicate in maniera semplicissima. Grazie ai tuoi consigli sono ruscito alla fine a risolvere il mio problema. Ho capito comunque che lo studio dei Threads va affrontato in maniera seria!
    Domani se riesco posto la soluzione adottata, da te suggerita. Grazie ancora.

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.