Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 13
  1. #1
    Utente di HTML.it
    Registrato dal
    Nov 2007
    Messaggi
    327

    [JAVA] java.awt.event.ActionEvent + multithread ?

    Ciao ragazzi!
    Mi scuso anticipatamente per il titolo, ma non so bene quale sia il mio problema.. spero di non essere andato troppo lontano.

    Ho creato questo codice:
    codice:
    private void button(java.awt.event.ActionEvent evt) {
            // TODO add your handling code here:
                while(true)
                {jTextArea1.append("ciao \n");}
        }
    Mi piacerebbe dunque creare un loop infinito non appena clicco in un apposito pulsante e riversare l'output verso una jTextArea1. Tuttavia ciò non avviene, non viene stampato nulla, è come se, finchè non si esce dal while, la stampa non possa avvenire.
    Ho verificato che effettivamente è così, infatti se impongo una condizione d'uscita, non appena questa si verifica la stampa avviene (MA NON PASSO PASSO, TUTTA DI BOTTO ALLA FINE).
    Facendo ricerche in rete e nel forum ho capito che si tratta di un problema di multithread, non ne avevo mai sentito parlare, mi sono documentato un pò ma non sono riuscito a venirne a capo... mi date una mano?

    Grazie in anticipo a chiunque voglia aiutarmi

  2. #2
    Ciao playbasfa,
    Il probleama è appunto una questione di Thread, perchè il Thread che si occupa di disegnare/aggiornare l'interfaccia è lo stesso che ti richiama le azioni che vengono effettuate da essa.
    Per risolvere il problema la metodologia migliore e quella di un SwingWorker.
    Ciao

  3. #3
    Utente di HTML.it
    Registrato dal
    Nov 2007
    Messaggi
    327
    Grazie per la risposta anzitutto.
    Ho appena approfondito l'argomento e ciò che mi è stato richiesto è o di implementare la classe Runnable o di estendere Thread.
    Tuttavia non riesco ancora a venirne a capo..

  4. #4
    Se ti è stato richiesto allora devi per forza farlo.....
    Anche se non è corretta inquanto utilizzando un thread estreno l'EDT non sa come gestirlo...
    Bando alle ciance e implementiamo il metodo con un thread...
    codice:
    import java.awt.BorderLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JScrollPane;
    import javax.swing.JTextArea;
    import javax.swing.SwingUtilities;
    
    public class Test extends JFrame implements ActionListener
    {
    	private final JTextArea jTextArea1;
    
    	public Test()
    	{
    		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		this.setLayout(new BorderLayout());
    		jTextArea1 = new JTextArea();
    		JScrollPane jScrollPane = new JScrollPane(jTextArea1);
    		this.add(jScrollPane);
    		JButton actionButton = new JButton("START");
    		actionButton.addActionListener(this);
    		this.add(actionButton, BorderLayout.NORTH);
    		this.pack();
    	}
    
    	@Override
    	public void actionPerformed(ActionEvent e)
    	{
    		Thread thread = new Thread(new Runnable()
    		{
    
    			@Override
    			public void run()
    			{
    				while (true)
    				{
    					jTextArea1.append("ciao \n");
    
    				}
    			}
    		});
    		thread.start();
    
    	}
    
    	public static void main(String[] args)
    	{
    
    		SwingUtilities.invokeLater(new Runnable()
    		{
    
    			@Override
    			public void run()
    			{
    				Test test = new Test();
    				test.setVisible(true);
    			}
    		});
    	}
    }
    il codice importante è questo:
    codice:
    Thread thread = new Thread(new Runnable()
    		{
    
    			@Override
    			public void run()
    			{
    				while (true)
    				{
    					jTextArea1.append("ciao \n");
    
    				}
    			}
    		});
    		thread.start();
    Come vedi vado a creare un nuovo Thread a cui passo un oggetto Runnable che implementa la logica applicativa. Ovviamente qui io ho usato un inner class ma puoi benissimo (Anzi consiglio) di creare una classe a parte che implementa runnable....

  5. #5
    Utente di HTML.it
    Registrato dal
    Nov 2007
    Messaggi
    327
    .

  6. #6
    Utente di HTML.it
    Registrato dal
    Nov 2007
    Messaggi
    327
    Grazie ancora per il tuo aiuto
    Allora, ho esteso Thread piuttosto che implementare Runnable perchè in quel modo non mi riusciva, credo di esserci, però forse non sono entrato nel meccanismo teorico del Multithread.

    Ti spiego cosa volevo fare e ti faccio vedere cosa ho fatto:

    1) Volevo poter premere il pulsante e visualizzare in output il ping proprio come se fossimo nella shell, implementando però il multithread.

    2) Ecco cosa ho fatto:
    Pulsante
    codice:
    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
            // TODO add your handling code here:
            pingthread obj=new pingthread(jTextArea2); 
            obj.run();
        }
    Classe che implementa il multithread
    codice:
    public class pingthread extends Thread {
    
        javax.swing.JTextArea jTextField1;
        javax.swing.JTextArea jTextArea1;
        BufferedReader in;
    
        public pingthread(javax.swing.JTextArea a) {
    
            jTextArea1 = a;
            try {
                Process p = Runtime.getRuntime().exec("ping www.google.com");
                in = new BufferedReader(new InputStreamReader(p.getInputStream()));
            } catch (IOException e) {
            }
        }
    
        @Override
        public void run() {
            try {
                String line = in.readLine();
                jTextArea1.append(line.concat("\n"));
            } catch (IOException e) {
            }
        }
    }
    Il risultato è che premendo il tasto ricevo solo il primo rigo di ping, questo tutte le volte che lo premo..

  7. #7
    Mi sembra anche giusto che avviene ciò....
    Il primo problema sta nell'implementazione del metodo run in quanto devi effettuare un ciclo sull'input ricevuto per poter stampare tutto il contenuto dell'input stesso.
    Anche implementando quest'ultimo cmq non avresti il risultato voluto in quanto vedresti stampato nella textArea solo alla fine del thread inquanto nel actionPerformed del bottone avvii il Thread richiamando il metodo Run più tosto che il metodo start.
    Quindi per prima cosa modifichiamo l'action:
    codice:
    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
            // TODO add your handling code here:
            pingthread obj=new pingthread(jTextArea2); 
            //obj.run(); Metodo sincrono
            obj.start(); //Metodo asicrono
        }
    E infine implementiamo correttamente il metodo Run:
    codice:
    @Override
    		public void run()
    		{
    			try
    			{
    				String line = null;
    				while ((line = in.readLine()) != null)
    				{
    					jTextArea1.append(line.concat("\n"));
    				}
    			}
    			catch (IOException e)
    			{
    				e.printStackTrace();
    			}
    			finally
    			{
    				try
    				{
    					in.close();
    				}
    				catch (IOException e)
    				{
    					// IGNORED EXCEPTION
    				}
    			}
    		}

  8. #8
    Utente di HTML.it
    Registrato dal
    Nov 2007
    Messaggi
    327
    Mmmm non ho capito.. c'è qualcosa che non va...
    Hai implementato un nuovo metodo run() però non lo chiami mai (l'hai commentato).
    Poi hai aggiunto la chiamata a start() che non è stato implementato da nessuna parte.

    Ho provato a fare quanto dici (togliendo il commento alla chiamata a Run() pensando fosse un errore di battitura) ma non stampa nulla e il pulsante rimane premuto.

  9. #9
    Allora come avevo intuito ti mancano un pò le basi....
    Prima di tutto questo link contiene la documentazione sull'oggetto Thread.
    Per quanto riguarda i tuoi dubbi:
    Hai implementato un nuovo metodo run() però non lo chiami mai (l'hai commentato).
    Il metodo run di un thread non va mai richiamato direttamente, in quanto esso e un metodo sincrono (cioè il chiamante attende finché tale metodo non si conclude...) e quindi l'interfaccia grafica ti rimane bloccata.
    Poi hai aggiunto la chiamata a start() che non è stato implementato da nessuna parte.
    Il metodo start è implementato nella Classe Thread che tu estendi per creare e definire un Thread. Esso non fà altro che richiamare il metodo run() del Thread, ma con l'unica e sostanziale differenza che tale metodo è asincrono cioè non aspetta che il metodo run venga eseguito ma ritorna subito il controllo al chiamante e "dopo" chiama il metodo Run.
    Ciao

  10. #10
    Utente di HTML.it
    Registrato dal
    Nov 2007
    Messaggi
    327
    E già, mi mancano completamente le basi su quest'argomento, mi è stato chiesto di realizzare questa cosa adoperando il multithread dandolo non dico per scontato ma quasi, quando invece di multithread non avevo mai sentito parlare.

    Sto provando a leggere documentazione e quant'altro ma non mi sta risultando per nulla semplice, anzi, ostico.

    Ho implementato il codice per come mi hai consigliato e funziona perfettamente anche se non capisco perchè.

    Quando creo l'oggetto obj, invocando il costruttore, parte il ping, e fin qui ci siamo.

    Ma cosa accade di preciso invocando start() che richiama run()?
    Come fa ad avvenire la stampa simultaneamente al ping?
    O meglio, come questo si rapporta in termini temporali la stamap con il ping che sta avvenendo da un altra parte? Come fanno a dialogare per decidere chi debba avvenire prima e chi dopo e con che lasso di tempo si alternano?

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.