Visualizzazione dei risultati da 1 a 8 su 8
  1. #1
    Utente di HTML.it
    Registrato dal
    Nov 2011
    Messaggi
    4

    Stampare il risultato di un thread in un JTextField

    Salve a tutti ho questo problema:
    praticamente vorrei fare un applicazione che mi simuli il gioco del lotto, però la mia applicazione deve essere multi-thread. in particolare ho 3 classi :
    1- Produttore che mi produce la sequenza casuale dei numeri
    2- Urna dove vengono messi i risultati del thread produttore
    3- Consumatore che mi restituisce i risultati

    ora il mio problema è: quando vado a fare la classe GUI come posso fare per stampare i dati del consumatore su un JTextArea??

    Questo è il codice della classe Gui :

    codice:
    public class Gui extends JFrame{
    	public JButton bottone;
    	public JTextField jTextField1;
    	public Gui(){
    		bottone = new JButton("ESTRAZIONE DEL LOTTO");
    		jTextField1 = new JTextField();	
    	}
    	public void init(){		
    		getContentPane().setLayout(new GridLayout());
    		getContentPane().add(bottone);
    	    getContentPane().add(jTextField1);
    	    jTextField1.setFocusable(false);
    
    	    bottone.addActionListener ( new java.awt.event.ActionListener () { 
    	         public void actionPerformed ( ActionEvent e ) { 
    	        	Urna u = new Urna(5);
    	 			Producer p = new Producer(u,1);
    	 			Consumer c = new Consumer(u,1);
    	 			Thread t1 = new Thread(p);
    	 			Thread t2 = new Thread(c);
    
    	 			t1.start();
    	 			t2.start();
    	 			jTextField1.setText(t2.
    	 					toString());
    	         } 
    	       }) ; 
    	}
    }


    Ho pensato di richiamare il metodo toString ma ovviamente se lo chiamo sul thread mi viene richiamato il metodo toString della classe, il quale mi stampa nome,priorità e il gruppo di appartenenza e cioè tutt'altro di quello che desidero!!!

    HELP ME!!!!! :help:

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284

    Re: Stampare il risultato di un thread in un JTextField

    Originariamente inviato da orres21
    codice:
    	 			t1.start();
    	 			t2.start();
    	 			jTextField1.setText(t2.
    	 					toString());
    No, non va.
    A parte che così prendi una "descrizione" dell'oggetto Thread ... che non centra nulla con quello che fa il "lavoro" del thread. Ma comunque hai appena fatto partire i thread, le start non sono bloccanti, quindi in quel punto non prenderesti proprio nulla di utile.

    Poi vedo che di Urna istanzi 1 oggetto e lo fai usare sia a Producer che a Consumer (che eseguono in thread separati). Questo porta al fatto che la classe Urna deve essere scritta per gestire correttamente la sincronizzazione tra i thread.

    Comunque per tornare alla tua questione, la regola fondamentale in Swing è che l'accesso alla interfaccia grafica (ai vari componenti, layout, ecc...) va fatto (salvo casi particolari che sono abbastanza ben documentati), solo ed esclusivamente nel contesto del EDT (event dispatch thread). Non nel contesto di un altro thread.

    Quindi nel thread del consumatore fare (avendo il riferimento jTextField1):
    jTextField1.setText(......);

    sarebbe inappropriato.

    Però può sempre far passare la esecuzione di un pezzetto di codice nel contesto del EDT, ed è appunto la prassi comune.

    C'è solo una questione: la classe Consumer non l'hai postata ... non so dove l'hai definita e come è fatta. In sostanza: che cosa "sa" della interfaccia utente?

    In Consumer puoi fare in modo che esso possa avere (in qualunque modo) un riferimento o al text field o alla istanza di Gui?
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Utente di HTML.it
    Registrato dal
    Nov 2011
    Messaggi
    4
    Poi vedo che di Urna istanzi 1 oggetto e lo fai usare sia a Producer che a Consumer (che eseguono in thread separati). Questo porta al fatto che la classe Urna deve essere scritta per gestire correttamente la sincronizzazione tra i thread.
    La sincronizzazione dei thread la faccio utilizzando synchronized per i metodi.

    C'è solo una questione: la classe Consumer non l'hai postata ... non so dove l'hai definita e come è fatta. In sostanza: che cosa "sa" della interfaccia utente?
    questa è la classe

    codice:
    public class Consumer implements Runnable{
    	
    	private int delay;
    	private Urna buffer;
    	
    	public Consumer (Urna buffer,int delay ){
    		this.delay=delay;
    		this.buffer=buffer;
    	}
    
    	public void run() {
    		for(int i=0;i<5;i++){
    			int info = buffer.remove();
    			System.out.println(info);
    			try {
    				Thread.sleep(delay);
    			}catch (InterruptedException ex){
    				ex.getMessage();
    			}
    		}
    	}
    
    }
    quindi non conosce niente dell'interfaccia...

    In Consumer puoi fare in modo che esso possa avere (in qualunque modo) un riferimento o al text field o alla istanza di Gui?
    quindi devo creare un oggetto Gui e poi da li, arrivare al jTextField e cont setText inserire le info giusto??

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da orres21
    La sincronizzazione dei thread la faccio utilizzando synchronized per i metodi.
    Corretto per quanto hai detto.

    Originariamente inviato da orres21
    quindi non conosce niente dell'interfaccia...
    Per quanto vedo, sì. È separata dalla classe Gui quindi così come è non ha alcun "appiglio" per fare qualcosa sulla interfaccia grafica.

    Originariamente inviato da orres21
    quindi devo creare un oggetto Gui e poi da li, arrivare al jTextField e cont setText inserire le info giusto??
    La istanza di Gui la creerai da qualche altra parte (non hai postato il main() ma immagino farai come si fa di solito, cioè con SwingUtilities.invokeLater per far eseguire la creazione della interfaccia nel EDT). Quindi di Gui non devi creare nulla all'interno di Consumer.

    Pertanto:
    1) Passi a Consumer (es. dal costruttore) il riferimento al tuo oggetto Gui (che in quel actionPerformed è Gui.this ). I campi in Gui dovrebbero essere tenuti private. E dovresti mettere un metodo pubblico es. setRisultato(....)

    oppure

    2) Passi a Consumer il riferimento diretto al campo JTextField.

    oppure

    3) Per una maggior "astrazione" definisci una interface es. RicevitoreRisultato che dovrà essere implementata da Gui. RicevitoreRisultato avrà il metodo astratto es. setRisultato(....). E Consumer riceverà un riferimento di tipo RicevitoreRisultato.
    Questo è praticamente lo stesso scenario di 1) ma con la differenza che c'è una maggiore astrazione: Consumer non "sa" di Gui ma solo di un RicevitoreRisultato.
    Se vuoi in inglese: ResultReceiver

    E in ogni caso, qualunque cosa scegli, il setText sul text field va fatto nel contesto del EDT, quindi va usato il solito SwingUtilities.invokeLater(Runnable).
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  5. #5
    Utente di HTML.it
    Registrato dal
    Nov 2011
    Messaggi
    4
    GRAZIE ho risolto!!!!
    cmq ora ho 1 altro problema e cioè visto che ho 11 ruote come faccio a far partire il thread 11 volte??

  6. #6
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da orres21
    cmq ora ho 1 altro problema e cioè visto che ho 11 ruote come faccio a far partire il thread 11 volte??
    Un Thread, una volta avviato non può essere più ri-avviato, nemmeno dopo che il run() eseguito dal thread è terminato. Bisogna istanziare un nuovo java.lang.Thread e farlo partire con start().

    Comunque la questione che non hai precisato è l'esatta sequenza/parallelismo che ci deve essere:

    1) 11 producer e 11 consumer che girano con il massimo parallelismo possibile (per le risorse a disposizione)? Quindi ci sarebbero 11 urne contemporaneamente, mi pare logico.

    2) 1 producer + 1 consumer per volta e per lanciare la prossima coppia di producer/consumer devi attendere la terminazione di entrambi i producer/consumer precedenti? Qui ci potrebbe essere anche solo una sola urna per volta (o ricrei una Urna oppure se Urna lo permette la riusi).

    3) Un altro scenario a metà tra le possibilità 1 e 2?

    Capisco che magari stai iniziando con Java o con i thread ma questi aspetti dovrebbero essere perlomeno un pochino chiari a te, se vuoi lavorarci.

    E comunque, se sicuro che debba essere tutto così "macchinoso"? Se si tratta di un esercizio "didattico" che ti è stato assegnato, allora chiaramente è ok.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  7. #7
    Utente di HTML.it
    Registrato dal
    Nov 2011
    Messaggi
    4
    codice:
    Un Thread, una volta avviato non può essere più ri-avviato, nemmeno dopo che il run() eseguito dal thread è terminato. Bisogna istanziare un nuovo java.lang.Thread e farlo partire con start().
    si questo lo sapevo però volevo sapere come potevo fa partire più volte lo stesso thread

    codice:
    Capisco che magari stai iniziando con Java o con i thread ma questi aspetti dovrebbero essere perlomeno un pochino chiari a te, se vuoi lavorarci.
    ovviamente ma sono all'inizio quindi penso che un pò di difficoltà ci sono

    codice:
    E comunque, se sicuro che debba essere tutto così "macchinoso"? Se si tratta di un esercizio "didattico" che ti è stato assegnato, allora chiaramente è ok.
    ovviamente è un esercizio didattico!!!

    ps ti ringrazio per la tua disponibilità

    pps in bocca al lupo per Java Champion

  8. #8
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da orres21
    si questo lo sapevo però volevo sapere come potevo fa partire più volte lo stesso thread
    Appunto istanziando più java.lang.Thread. Che potrebbero anche usare lo stesso oggetto Runnable o differenti Runnable. In generale dipende dallo "stato" che i Runnable devono avere e gestire (e ci possono essere questioni di eventuale sincronizzazione se fosse lo stesso oggetto Runnable).

    Originariamente inviato da orres21
    ovviamente è un esercizio didattico!!!
    Ok.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

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.