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

    Aiuto con SwingWorker ed altro

    Ragazzi ho fatto un programmino in cui l'utente gioca a dadi con il computer. Ad ogni turno, chi ottiene il lancio migliore ottiene un punto. Dopo 10 turni chi ha più punti vince.
    Tralasciando che il codice che ho buttato giù non mi piace, perché ho capacità progettuali schifose (quindi si accettano consigli), vorrei trovare un modo elegante per aggiornare la grafica (testo della JLabel e della JTextArea) per mostrare all'utente l'andamento del gioco.
    Nella classe partita trovate una bozza di utilizzo di SwingWorker, che non so usare

    Il codice è questo:

    Dado

    codice:
    package giocodatiinterattivo;
    
    public class Dado {
    	
    	private int[] valori;
    	
    	public Dado() {
    		valori = new int[6];
    		valori[0] = 1;
    		valori[1] = 2;
    		valori[2] = 3;
    		valori[3] = 4;
    		valori[4] = 5;
    		valori[5] = 6;
    	}
    	
    	public int getNumeroCasuale() {
    		int indice = (int) (Math.random()*6);
    		return valori[indice];
    	}
    }
    Interfaccia

    codice:
    package giocodatiinterattivo;
    
    public class Interfaccia {
    	
    	private Partita partita;
    	private Game game;
    	
    	public Interfaccia(Game g, Partita p) {
    		game = g;
    		partita = p;
    	}
    	
    	public void aggiornaLabel(String text) {
    		game.getLabelDatiGioco().setText(text);
    	}
    	
    	public void aggiornaTextArea(String text) {
    		game.getTextArea().append(text);
    	}
    	
    	public void aggiornaButton(String text) {
    		game.getButton().setText(text);
    	}
    }
    Messaggio

    Questa classe nel codice non ancora la utilizzo, però volevo usarla per aggiornare la
    grafica tramite il metodo "aggiornaGrafica()" presente nella classe Partita.

    codice:
    package giocodatiinterattivo;
    
    public class Messaggio {
    	
    	private String mex;  //Testo 
    	private int id;      //Identifica quale componente grafico aggiornare
    	
    	public void setMessaggio(String mex) {
    		this.mex = mex;
    	}
    	
    	public void setId(int id) {
    		this.id = id;
    	}
    	
    	public String getMex() {
    		return mex;
    	}
    	
    	public int getId() {
    		return id;
    	}
    }
    Giocatore

    codice:
    package giocodatiinterattivo;
    
    public class Giocatore {
    	
    	private String nome;
    	private Dado dado;
    	
    	public Giocatore(String nome, Dado dado) {
    		this.nome = nome;
    		this.dado = dado;
    	}
    	
    	public int giocaDado() {
    		int res = dado.getNumeroCasuale();
    		return res;
    	}
    	
    	public String toString() {
    		return nome;
    	}
    }
    MyListener

    codice:
    package giocodatiinterattivo;
    
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    public class MyListener implements ActionListener {
    
    	private Partita partita;
    	private Game game;
    	
    	public MyListener(Game g, Partita p) {
    		partita = p;
    		game = g;
    	}
    	
    	public void actionPerformed(ActionEvent e) {
    		partita.giocoUtente();
    	}
    }
    Game

    codice:
    package giocodatiinterattivo;
    
    import java.awt.BorderLayout;
    import java.awt.Container;
    import java.awt.Dimension;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JTextArea;
    
    @SuppressWarnings("serial")
    public class Game extends JFrame {
    	
    	private JButton tiraDado;
    	private JLabel datiGioco;
    	private JPanel northPanel;
    	private JPanel centralPanel;
    	private JPanel southPanel;
    	private JTextArea textArea;
    	private MyListener listener;
    	private Partita partita;
    	private Giocatore giocatoreA;
    	private Giocatore giocatoreB;
    	private Interfaccia interfaccia;
    	private Dado dado;
    	
    	public static void main(String[]args) {
    		java.awt.EventQueue.invokeLater(new Runnable() {
                public void run() {
                    new Game().setVisible(true);
                }
            });
    	}
    	
    	public Game() {
    		System.out.println("NUOVA PARTITA\n");
    		initComponents();
    	}
    	
    	public void initComponents() {
            
            //Inizializzo i dati per il gioco
    		
            dado = new Dado();
            giocatoreA = new Giocatore("Andrea",dado);
            giocatoreB = new Giocatore("Loris",dado);
            Partita partita = new Partita(giocatoreA,giocatoreB);
            interfaccia = new Interfaccia(this,partita);
            partita.setInterfaccia(interfaccia);
            
            //Inizializzo i dati per l'interfaccia 
            
            Container c = this.getContentPane();
            c.setLayout(new BorderLayout());
            
            tiraDado = new JButton("Tira Dado");
            datiGioco = new JLabel();
            textArea = new JTextArea("Andamento del gioco\n");
            textArea.setEditable(false); 
            
            listener = new MyListener(this,partita);
            tiraDado.addActionListener(listener);
            
            northPanel = new JPanel();
            centralPanel = new JPanel();
            southPanel = new JPanel();
            
            northPanel.setPreferredSize(new Dimension(300,50));
            centralPanel.setPreferredSize(new Dimension(300,200));
            southPanel.setPreferredSize(new Dimension(300,50));
            
            northPanel.setLayout(new BorderLayout());
            centralPanel.setLayout(new BorderLayout());
            southPanel.setLayout(new BorderLayout());
            
            northPanel.add(datiGioco, BorderLayout.CENTER);
            centralPanel.add(textArea, BorderLayout.CENTER);
            southPanel.add(tiraDado, BorderLayout.CENTER);
            
            c.add(northPanel, BorderLayout.NORTH);
            c.add(centralPanel, BorderLayout.CENTER);
            c.add(southPanel, BorderLayout.SOUTH);
            
            setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
            setTitle("Dadi - By Stefano Loris");
            setResizable(false);
            setSize(300,300);
            setVisible(true);
    	}
    	
    	public Partita getPartita() {
    		return partita;
    	}
    	
    	public JLabel getLabelDatiGioco() {
    		return datiGioco;
    	}
    	
    	public JTextArea getTextArea() {
    		return textArea;
    	}
    	
    	public JButton getButton() {
    		return tiraDado;
    	}
    }
    Partita

    codice:
    package giocodatiinterattivo;
    
    import javax.swing.JOptionPane;
    import javax.swing.SwingWorker;
    
    public class Partita {
    
    	private int turniPassati;          
        private Giocatore giocatoreA;
        private Giocatore giocatoreB;
        private int puntiA;
        private int puntiB;
        private int giocataA;
        private int giocataB;
        private Interfaccia interfaccia;
        private int turno;                 //0: turno computer, 1: turno utente
        private boolean userHavePlayed;
        private Messaggio messaggio;
    	
    	public Partita(Giocatore a, Giocatore b) {
    		turniPassati = 0;
        	giocatoreA = a;
        	giocatoreB = b;
        	puntiA = 0;
        	puntiB = 0;
        	giocataA = 0;
        	giocataB = 0;
        	turno = 0;
        	userHavePlayed = false;
        	messaggio = new Messaggio();
        	//Chiamo la routine principale del gioco
        	game();
    	}
    	
    	public void setInterfaccia(Interfaccia interfaccia) {
    		this.interfaccia = interfaccia;
    	}
    	
    	private void game() {
    
    		if (isTurnoComputer()) {
    			/* user non ha giocato (inizio della mano) */
    			if (!userHavePlayed) {
    				giocoPc();
    			}
    			/* user ha già risposto al gioco pc: calcolo punti e vincitore */
    			else {
    				fineMano();
    			}
    		}
    		/* turno user */
    		else {
    			/* user non ha giocato (inizio della mano) */
    			if (!userHavePlayed) {
    				/*
    				 * non accade nulla serve il gioco dell'utente
    				 */
    			}
    			/* user ha giocato e attende risposta pc */
    			else {
    				giocoPc(); /* risposta pc */
    				fineMano(); /* punti e vincitore */
    			}
    		}
    	}
    	
    	private void giocoPc() {
    		int risultato = giocatoreA.giocaDado();
    		turniPassati++;
    		System.out.println("Il computer tira il dado ed ottiene " + risultato);
    		setPunti(0,risultato);
    		setTurnoUtente();
    	}
    	
    	public void giocoUtente() {
    		int risultato = giocatoreB.giocaDado();
    		turniPassati++;
    		System.out.println("Hai tirato il dado ed hai ottenuto " + risultato);
    		setPunti(1,risultato);
    		setUserHavePlayed();
    		setTurnoPc();
    		//Chiamo la routine del gioco principale
    		game();
    	}
    	
    	//Setta i valori intermedi ottenuti dal lancio del dado
        public void setPunti(int giocatore, int giocata) {
        	if(giocatore == 0) {
        		giocataA = giocata;
        	}
        	if(giocatore == 1) {
        		giocataB = giocata;
        	}
        }
        
      //Sono passati due turni. E' finita la mano. Aggiorna il punteggio dei giocatori.
        public void fineMano() {
        	
        	if(giocataA == giocataB) {
        		//interfaccia.aggiornaTextArea("Pareggio");
        		System.out.println("\nPareggio\n");
        		giocataA = 0;
        		giocataB = 0;   	
        		checkPartita();
        		userHavePlayed = false;
        	}
        	if(giocataA > giocataB) {
        		//interfaccia.aggiornaTextArea("\nVince la mano il giocatore " + giocatoreA.toString() + "\n");
        		System.out.println("\nIl computer ha vinto la mano.\n");
        		puntiA++;
        		giocataA = 0;
        		giocataB = 0;	
        		checkPartita();
        		userHavePlayed = false;
        	}
        	if(giocataA < giocataB) {
        		//interfaccia.aggiornaTextArea("\nVince la mano il giocatore " + giocatoreB.toString() + "\n");
        		System.out.println("\nHai vinto la mano.\n");
        		puntiB++;
        		giocataA = 0;
        		giocataB = 0;
        		checkPartita();
        		userHavePlayed = false;
        	}
        	
        	//Richiamo la routine principale del gioco
        	game();
        }
        
        private void checkPartita() {
        	if(this.getTurniPassati() == 10) {
    			decretaVincitore();		
    			int risposta = JOptionPane.showConfirmDialog(null,"Vuoi fare una nuova partita?",
    					"Fine Partita",JOptionPane.YES_NO_OPTION);
    			if(risposta == JOptionPane.YES_OPTION) {
    				Game game = new Game();
    			}
    			if(risposta == JOptionPane.NO_OPTION) {
    				System.exit(0);
    			}
    		}
        }
        
        //La partita è finita. Stampa il vincitore
        public void decretaVincitore() {
        	if(puntiA == puntiB) {
        		//interfaccia.aggiornaLabel("Pareggio!");
        		System.out.println("Pareggio\n");
        	}
        	if(puntiA > puntiB) {
        		//interfaccia.aggiornaLabel("Vince il giocatore: " + giocatoreA.toString() + " " + puntiA + " a " + puntiB);
        		System.out.println("Vince il computer " + puntiA + " a " + puntiB + "\n");
        	}
        	else
        		//interfaccia.aggiornaLabel("Vince il giocatore: " + giocatoreB.toString() + " " + puntiB + " a " + puntiA);
        		System.out.println("Hai vinto " + puntiB + " a " + puntiA + "\n");
        }
        
        private void aggiornaMessaggio(int id, String mex) {
        	messaggio.setId(id);
        	messaggio.setMessaggio(mex);
        }
        
    	private void aggiornaGrafica() {
    
    		SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {
    
    			@Override
    			protected Void doInBackground() throws Exception {
    				if(messaggio.getId() == 1) {
    					//Devo modificare la JTextArea
    					interfaccia.aggiornaTextArea(messaggio.getMex());
    				}
    				if(messaggio.getId() == 0) {
    					//Devo modificare la JLabel
    					interfaccia.aggiornaLabel(messaggio.getMex());
    				}
    				return null;
    			}
    		};
    		worker.execute();
    	}
        
        public void setUserHavePlayed() {
        	userHavePlayed = true;
        }
        
        private int getTurniPassati() {
        	return turniPassati;
        }
        
        public Interfaccia getInterfaccia() {
        	return interfaccia;
        }
        
        private void setTurnoUtente() {
        	turno = 1;
        }
        
        private void setTurnoPc() {
        	turno = 0;
        }
        
        public boolean isTurnoComputer() {
        	return turno == 0;
        }
    }
    C'è anche un problema logico. Quando l'utente sceglie di fare una nuova partita, il computer tira due volte il dado. Vi prego mi servono consigli

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Non ho letto tutto tutto ma 2 cose mi sono subito saltate all'occhio:

    1) non capisco (e non ne vedo il senso) perché hai usato uno SwingWorker oltretutto solo per aggiornare la interfaccia grafica. SwingWorker si usa per eseguire in background, in un thread separato, un lavoro potenzialmente "lungo" (I/O, networking, ecc..) e che solo sporadicamente, di tanto in tanto, deve aggiornare la interfaccia utente (e questo si fa con il suo publish e implementando process).
    Nel contesto di doInBackground non si deve aggiornare la interfaccia utente (come invece hai fatto tu) perché non sei nel contesto del EDT.

    2) il fatto che Game esponga dei metodi pubblici per fornire all'esterno dei suoi componenti, in genere denota un design discutibile e che fa un po' "acqua".
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    I computer sono incredibilmente veloci, accurati e stupidi.
    Gli uomini sono incredibilmente lenti, inaccurati e intelligenti.
    Insieme sono una potenza che supera l'immaginazione.

    A.Einstein

  4. #4
    Grazie schumy, ora vedo

    andbin, se provavo a fare da Partita: interfaccia.aggiornaTextArea("testo"); mi generava eccezione. Quindi non so, ho trovato questa SwingWorker che sembrava quasi fare al caso mio. Per la storia dei metodi get di game sono d'accordo. Dunque come potrei accedere ai componenti grafici senza quelle get?

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.