Aggiornare JLabel durante esecuzione Thread

di il
1 risposte

Aggiornare JLabel durante esecuzione Thread

Ciao a tutti!

Sto svolgendo il seguente esercizio:

"Scrivere un programma Java dotato di interfaccia grafica che implementa una slot machine a 5 dischi ciascuno dotato di 10 simoboli dallo 0 al 9. Il giocatore inizia la partita con un credito pari a 100. Ogni giocata costa 1 credito.
Le combinazioni danno il punteggio positivo o negativo:
9 9 9 9 9 -> +100
8 8 8 8 8 -> +75
7 7 7 7 7 -> +50
6 6 6 6 6 -> -50
5 5 5 5 5 -> -75
0 0 0 0 0 -> -100
Coppia di numeri uguali -> +10
Tris di numeri uguali -> +20
Coppia di numeri uguale e tris di numeri uguali (full) -> +30
Numeri uguali nelle posizioni 0 2 4 e numeri uguali nelle posizioni 1 e 3 -> +40
Scala dalla posizione 0 a quella 4 -> Raddoppio del credito
Scala dalla posizione 4 a quella 0 -> Dimezzamento del credito
Il gioco termina quando il giocatore perde tutto o preme l'apposito pulsante.

Realizzare la simulazione dei dischi utilizzando un thread per implementare la rotazione (far variare le velocita' casualmente bloccando prima il disco in posizione 0 ed alla fine quello in posizione 4."

Il codice che ho realizzato finora è questo:
import java.awt.*;
import javax.swing.*;

public class SlotMachineTest
{
    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                SlotMachineFrame frame = new SlotMachineFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setVisible(true);
            }
        });
    }
}

public class Rullo
{
    private int numero;
    private int contatore;
        
    public int getNumero()
    {
        return numero;
    }
    
    public void setNumero(int valore)
    {
        this.numero = valore;
    }
    
    public int getContatore ()
    {
        return contatore;
    }
    
    public void setContatore (int c)
    {
        this.contatore = c;
    }
            
}

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class SlotMachineFrame extends JFrame
{
    public static final int WIDTH = 300;
    public static final int HEIGHT = 300;
    
    private JLabel giocatore;
    private JLabel creditoGiocatore;
    private JLabel domandaPuntata;
    private JLabel numero1;
    private JLabel numero2;
    private JLabel numero3;
    private JLabel numero4;
    private JLabel numero5;
    
    private JPanel infoGiocatore;
    private JPanel menuPuntata;
    private JPanel rulli;
    
    private JTextField puntata;
   
    private JButton pulsanteRulli;
    private JButton esci;
    
    private int contatore;
  
    
    public SlotMachineFrame()
    {
        setTitle("$$$ SLOT MACHINE $$$");
        setSize (WIDTH,HEIGHT);
        
        giocatore = new JLabel ("Giocatore: ");
        creditoGiocatore = new JLabel("100");
        pulsanteRulli = new JButton ("GIOCA!");
        domandaPuntata = new JLabel ("Quanto vuoi puntare?");
        esci = new JButton ("Esci");
        
        menuPuntata = new JPanel();
        puntata = new JTextField(3);
        menuPuntata.add(domandaPuntata);
        menuPuntata.add(puntata);
        add(menuPuntata,BorderLayout.NORTH);
        
        puntata.addActionListener(new inseriscoPuntata());
        pulsanteRulli.setEnabled(false);
        
        esci.addActionListener(new ActionListener ()
        {
            public void actionPerformed (ActionEvent event)
            {
                System.exit(0);
            }
        });
        
        infoGiocatore = new JPanel();
        infoGiocatore.add(giocatore);
        infoGiocatore.add(creditoGiocatore);
        infoGiocatore.add(pulsanteRulli);
        infoGiocatore.add(esci);
        add(infoGiocatore,BorderLayout.SOUTH);
        
        numero1 = new JLabel("0");
        numero2 = new JLabel("0");
        numero3 = new JLabel("0");
        numero4 = new JLabel("0");
        numero5 = new JLabel("0");
        

        rulli = new JPanel();
        rulli.add(numero1);
        rulli.add(numero2);
        rulli.add(numero3);
        rulli.add(numero4);
        rulli.add(numero5);
        
        add(rulli,BorderLayout.CENTER);
        
        //if (pulsanteRulli.isEnabled()==true)
        //{
         //   System.out.println("Hai cliccato GIOCA!");
            pulsanteRulli.addActionListener(new cliccoPulsante());
        //}
    }
    
    private class inseriscoPuntata implements ActionListener
    {
        public void actionPerformed (ActionEvent event)
        {
            try
            {
                int puntataInt = Integer.parseInt(puntata.getText());
                int credito = Integer.parseInt(creditoGiocatore.getText());
                
                if (puntataInt <= credito)
                {
                    pulsanteRulli.setEnabled(true);
                }
                
                else
                {
                    JOptionPane.showMessageDialog(rootPane, "Non hai abbastanza"
                            + "credito!");
                }
            }
            catch (Exception e)
            {
                JOptionPane.showMessageDialog(rootPane, "Valore digitato non"
                        + "valido!");
            }
        }
    }
        
    private class cliccoPulsante implements ActionListener
    {
            public void actionPerformed(ActionEvent event)
            {
                pulsanteRulli.setEnabled(false);
                Rullo rulloNumeriRandom = new Rullo();
                rulloNumeriRandom.setContatore(0);
                
                Runnable r = new RulloNumeri(rulloNumeriRandom);
                Thread t = new Thread (r);
                t.start();
                
                while (t.isAlive())
                {
                    switch (rulloNumeriRandom.getContatore())
                    {
                        case 1: numero1.setText(""+rulloNumeriRandom.getNumero());
                            break;
                        case 2: numero2.setText(""+rulloNumeriRandom.getNumero());
                            break;
                        case 3: numero3.setText(""+rulloNumeriRandom.getNumero());
                            break;
                        case 4: numero4.setText(""+rulloNumeriRandom.getNumero());
                            break;
                        case 5: numero5.setText(""+rulloNumeriRandom.getNumero());
                            break;
                    }
                }
                pulsanteRulli.setEnabled(true);
            }
    }
}

public class RulloNumeri implements Runnable
{
    private int random;
    private Rullo rullo;
    private int c=1;
    
    public RulloNumeri (Rullo rulloNumeriRandom)
    {
        this.rullo = rulloNumeriRandom;
    }
    public void run()
    {
        try
        {
            for (int i=0; i<5; i++)
            {
                rullo.setContatore(c);
                System.out.println("C vale: "+c);
                random = (int) (Math.random() * 9) + 1;
                rullo.setNumero(random);
                System.out.println("numero estratto e': " + rullo.getNumero());
                c++;
                Thread.sleep((int) (Math.random() * 3000) + 1);
            }

        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}
Il problema è questo: vorrei far aggiornare le JLabel "numero" nella classe SlotMachineFrame ogni volta che viene generato un numero casuale dalla random nella classe RulloNumeri (1° numero estratto -> si aggiorna numero1; 2° numero estratto -> si aggiorna numero2 ecc. ecc.). La soluzione dello switch/case che ho usato funziona in parte: le JLabel vengono aggiornate ma tutte assieme, alla conclusione del thread principale. Inoltre, l'intera applicazione si "blocca" durante l'esecuzione del thread, cioè rende impossibile l'esecuzione di qualunque altra azione, ad esempio, la pressione del pulsante "Esci". Il thread, in parole povere, prende il controllo di tutta l'applicazione. Al momento non riesco a trovare una soluzione valida. Qualche suggerimento?

Grazie in anticipo per l'aiuto!

1 Risposte

  • Re: Aggiornare JLabel durante esecuzione Thread

    Ho completato il programma. Adesso è funzionante, ma ho un dubbio sul procedimento.

    Questo è il codice:
    import java.awt.*;
    import javax.swing.*;
    
    public class SlotMachineTest
    {
        public static void main(String[] args)
        {
            EventQueue.invokeLater(new Runnable()
            {
                public void run()
                {
                    SlotMachineFrame frame = new SlotMachineFrame();
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setVisible(true);
                }
            });
        }
    }
    
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    
    public class SlotMachineFrame extends JFrame
    {
        public static final int WIDTH = 300;
        public static final int HEIGHT = 200;
        
        private JLabel giocatore;
        private JLabel creditoGiocatore;
        private JLabel numero1;
        private JLabel numero2;
        private JLabel numero3;
        private JLabel numero4;
        private JLabel numero5;
        private JLabel luck;
        private JPanel infoGiocatore;
        private JPanel rulli;
       
        private JButton pulsanteRulli;
        private JButton esci;
        
        public SlotMachineFrame()
        {
            setTitle("$$$ SLOT MACHINE $$$");
            setSize (WIDTH,HEIGHT);
            
            giocatore = new JLabel ("Credito Giocatore: ");
            creditoGiocatore = new JLabel("100");
            pulsanteRulli = new JButton ("GIOCA!");
            
            esci = new JButton ("Esci");
            esci.addActionListener(new esci());
            
            infoGiocatore = new JPanel();
            infoGiocatore.add(giocatore);
            infoGiocatore.add(creditoGiocatore);
            infoGiocatore.add(pulsanteRulli);
            infoGiocatore.add(esci);
            add(infoGiocatore,BorderLayout.SOUTH);
            
            numero1 = new JLabel("0");
            numero1.setFont(new Font("Arial", Font.BOLD, 70));
            numero2 = new JLabel("0");
            numero2.setFont(new Font("Arial", Font.BOLD, 70));
            numero3 = new JLabel("0");
            numero3.setFont(new Font("Arial", Font.BOLD, 70));
            numero4 = new JLabel("0");
            numero4.setFont(new Font("Arial", Font.BOLD, 70));
            numero5 = new JLabel("0");
            numero5.setFont(new Font("Arial", Font.BOLD, 70));
            luck = new JLabel ("Tieni le dita incrociate!");
            luck.setFont(new Font ("Arial", Font.BOLD, 25));
            luck.setForeground(Color.RED);
            luck.setVisible(false);
            
            rulli = new JPanel();
            rulli.add(numero1);
            rulli.add(numero2);
            rulli.add(numero3);
            rulli.add(numero4);
            rulli.add(numero5);
            rulli.add(luck);
            
            add(rulli,BorderLayout.CENTER);
            
            pulsanteRulli.addActionListener(new cliccoPulsante());
        }
             
        private class cliccoPulsante implements ActionListener
        {
                public void actionPerformed(ActionEvent event)
                {
                    if (Integer.parseInt(creditoGiocatore.getText())>0)
                    {
                        numero1.setText("0");
                        numero2.setText("0");
                        numero3.setText("0");
                        numero4.setText("0");
                        numero5.setText("0");
                        int creditoTemp = Integer.parseInt(creditoGiocatore.getText());
                        creditoTemp--;
                        creditoGiocatore.setText(""+creditoTemp);
                        pulsanteRulli.setEnabled(false);
                        Runnable r = new RulloNumeri(numero1, numero2,
                                numero3, numero4, numero5, pulsanteRulli, 
                                creditoGiocatore, luck);
                        Thread t = new Thread (r);
                        t.start();
                    }
                    else
                    {
                        JOptionPane.showMessageDialog(rootPane, "Non hai abbastanza credito");
                        System.exit(0);
                    }
                }              
        }
        
        private class esci implements ActionListener
        {
            public void actionPerformed (ActionEvent event)
            {
                System.exit(0);
            }
        }
    }
    
    import javax.swing.*;
    
    public class RulloNumeri implements Runnable
    {
        private int random;
        private int c = 1;
        private JLabel rullo1;
        private JLabel rullo2;
        private JLabel rullo3;
        private JLabel rullo4;
        private JLabel rullo5;
        private JLabel creditoGiocatore;
        private JButton pulsanteRulli;
        private JLabel luck;
        private boolean full = false;
        private boolean tris = false;
        private boolean allEqual = false;
        
        public RulloNumeri (JLabel numero1, JLabel numero2,
                JLabel numero3, JLabel numero4, JLabel numero5, JButton pulsanteRulli,
                JLabel creditoGiocatore, JLabel luck)
        {
            rullo1 = numero1;
            rullo2 = numero2;
            rullo3 = numero3;
            rullo4 = numero4;
            rullo5 = numero5;
            this.pulsanteRulli = pulsanteRulli;
            this.creditoGiocatore = creditoGiocatore;
            this.luck = luck;
        }
        
        public void run()
        {
            try
            {
                luck.setVisible(true);
                
                for (int i=0; i<5; i++)
                {
                    Thread.sleep((int) (Math.random() * 3000) + 1);
                    random = (int) (Math.random() * 9);
                    switch (c)
                    {
                        case 1: rullo1.setText(""+random);
                        break;
                        case 2: rullo2.setText(""+random);
                        break;
                        case 3: rullo3.setText(""+random);
                        break;
                        case 4: rullo4.setText(""+random);
                        break;
                        case 5: rullo5.setText(""+random);
                        break;
                    }
                    c++;
                }
                controllaVincita();
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
        
        private void controllaVincita ()
        {   
            // TUTTI 9
            if ((rullo1.getText().equals("9"))&&(rullo2.getText().equals("9"))&&
                    (rullo3.getText().equals("9"))&&(rullo4.getText().equals("9"))
                    &&(rullo5.getText().equals("9")))
            {
                int creditoTemp = Integer.parseInt(creditoGiocatore.getText());
                creditoTemp=creditoTemp+100;
                creditoGiocatore.setText(""+creditoTemp);
                allEqual = true;
                JOptionPane.showMessageDialog(rullo1, "Tutti 9! Hai vinto 100 crediti!");
            }
    
            //TUTTI 8
            if ((rullo1.getText().equals("8"))&&(rullo2.getText().equals("8"))&&
            (rullo3.getText().equals("8"))&&(rullo4.getText().equals("8"))
            &&(rullo5.getText().equals("8")))
            {
                int creditoTemp = Integer.parseInt(creditoGiocatore.getText());
                creditoTemp=creditoTemp+75;
                creditoGiocatore.setText(""+creditoTemp);
                allEqual = true;
                JOptionPane.showMessageDialog(rullo1, "Tutti 8! Hai vinto 75 crediti!");
            }
    
            // TUTTI 7
            if ((rullo1.getText().equals("7"))&&(rullo2.getText().equals("7"))&&
            (rullo3.getText().equals("7"))&&(rullo4.getText().equals("7"))
            &&(rullo5.getText().equals("7")))
            {
                int creditoTemp = Integer.parseInt(creditoGiocatore.getText());
                creditoTemp=creditoTemp+50;
                creditoGiocatore.setText(""+creditoTemp);
                allEqual = true;
                JOptionPane.showMessageDialog(rullo1, "Tutti 7! Hai vinto 50 crediti!");
            }
    
            // TUTTI 6
            if ((rullo1.getText().equals("6"))&&(rullo2.getText().equals("6"))&&
            (rullo3.getText().equals("6"))&&(rullo4.getText().equals("6"))
            &&(rullo5.getText().equals("6")))
            {
                int creditoTemp = Integer.parseInt(creditoGiocatore.getText());
                creditoTemp=creditoTemp-50;
                creditoGiocatore.setText(""+creditoTemp);
                allEqual = true;
                JOptionPane.showMessageDialog(rullo1, "Tutti 6! Perdi crediti!");  
            }
    
            //TUTTI 5
            if ((rullo1.getText().equals("5"))&&(rullo2.getText().equals("5"))&&
            (rullo3.getText().equals("5"))&&(rullo4.getText().equals("5"))
            &&(rullo5.getText().equals("5")))
            {
                int creditoTemp = Integer.parseInt(creditoGiocatore.getText());
                creditoTemp=creditoTemp-75;
                creditoGiocatore.setText(""+creditoTemp);
                allEqual = true;
                JOptionPane.showMessageDialog(rullo1, "Tutti 5! Perdi 75 crediti!");
            }
    
            //TUTTI 0
            if ((rullo1.getText().equals("0"))&&(rullo2.getText().equals("0"))&&
            (rullo3.getText().equals("0"))&&(rullo4.getText().equals("0"))
            &&(rullo5.getText().equals("0")))
            {
                int creditoTemp = Integer.parseInt(creditoGiocatore.getText());
                creditoTemp=creditoTemp-100;
                creditoGiocatore.setText(""+creditoTemp);
                allEqual = true;
                JOptionPane.showMessageDialog(rullo1, "Tutti 0! Perdi 100 crediti!");
            }
    
            // Scala crescente da 0 a 4
            if ((Integer.parseInt(rullo1.getText()) == (Integer.parseInt(rullo2.getText())-1))
                    && ((Integer.parseInt(rullo2.getText()))==(Integer.parseInt(
                    rullo3.getText())-1))&& (Integer.parseInt(rullo3.getText()) == 
                    (Integer.parseInt(rullo4.getText())-1)) && ((Integer.parseInt
                    (rullo4.getText()) == (Integer.parseInt(rullo5.getText())-1))))
            {
                int creditoTemp = Integer.parseInt(creditoGiocatore.getText());
                creditoTemp=creditoTemp*2;
                creditoGiocatore.setText(""+creditoTemp);
                JOptionPane.showMessageDialog(rullo1, "Scala crescente! Raddoppi i tuoi crediti!");
            }
    
            // Scala crescente da 4 a 0
            if ((Integer.parseInt(rullo1.getText()) == (Integer.parseInt(rullo2.getText())+1))
                    && ((Integer.parseInt(rullo2.getText()))==(Integer.parseInt(
                    rullo3.getText())+1))&& (Integer.parseInt(rullo3.getText()) == 
                    (Integer.parseInt(rullo4.getText())+1)) && ((Integer.parseInt
                    (rullo4.getText()) == (Integer.parseInt(rullo5.getText())+1))))
            {
                int creditoTemp = Integer.parseInt(creditoGiocatore.getText());
                creditoTemp=creditoTemp/2;
                creditoGiocatore.setText(""+creditoTemp);
                JOptionPane.showMessageDialog(rullo1, "Scala decrescente! Dimezzi i tuoi crediti!");
            }
            
            if (allEqual == false)
            {
                // Full
                if (((rullo1.getText().equals(rullo2.getText())) && (rullo3.
                        getText().equals(rullo4.getText())) && (rullo4.getText()
                    .equals(rullo5.getText()))) || ((rullo1.getText().equals(rullo2.
                            getText())) && (rullo2.getText().equals(rullo3.getText()
                            )) && (rullo4.getText().equals(rullo5.getText()))))
                {
                    int creditoTemp = Integer.parseInt(creditoGiocatore.getText());
                    creditoTemp=creditoTemp+30;
                    creditoGiocatore.setText(""+creditoTemp);
                    JOptionPane.showMessageDialog(rullo1, "Full! Hai vinto 30 crediti!");
                    full = true;
                }
            }
            
            if ((full == false) && (allEqual == false))
            {
                // Tris di numeri uguali
                if (((rullo1.getText().equals(rullo2.getText())) && (rullo2.getText
                    ().equals(rullo3.getText()))) || ((rullo3.getText().equals(rullo4.
                    getText())) && (rullo4.getText().equals(rullo5.getText()))) ||
                    (((rullo2.getText().equals(rullo3.getText())) && (rullo3.getText().
                equals(rullo4.getText())))))
                {
                    int creditoTemp = Integer.parseInt(creditoGiocatore.getText());
                    creditoTemp=creditoTemp+20;
                    creditoGiocatore.setText(""+creditoTemp);
                    JOptionPane.showMessageDialog(rullo1, "Tris! Hai vinto 20 crediti!");
                    tris = true;
                }
                
                // Coppia di numeri uguali
                if (tris == false)
                {
                    if ((rullo1.getText().equals(rullo2.getText())) || (rullo2.getText().
                            equals(rullo3.getText())) || (rullo3.getText().equals(rullo4.
                            getText())) || (rullo4.getText().equals(rullo5.getText())))
                    {
                        int creditoTemp = Integer.parseInt(creditoGiocatore.getText());
                        creditoTemp=creditoTemp+10;
                        creditoGiocatore.setText(""+creditoTemp);
                        JOptionPane.showMessageDialog(rullo1, "Coppia! Hai vinto 10 crediti!");
                    }
                }
                
                // Numeri uguali in 1,3,5 e 2,4
                if (((rullo1.getText().equals(rullo3.getText())) && (rullo3.getText().
                    equals(rullo5.getText())) && rullo2.getText().equals(rullo4.
                    getText())))
                {
                    int creditoTemp = Integer.parseInt(creditoGiocatore.getText());
                    creditoTemp=creditoTemp+40;
                    creditoGiocatore.setText(""+creditoTemp);
                    JOptionPane.showMessageDialog(rullo1, "Full alternato! Hai vinto 40 crediti!");
                }
            }
            
            luck.setVisible(false);
            pulsanteRulli.setEnabled(true);
        }
    }
    E' formalmente corretto verificare la vincita ed aggiornare le JLabel nella classe RulloNumeri? Mi sono visto costretto a fare così perchè non sono riuscito a trovare un sistema per gestire la cosa nella classe SlotMachineFrame.

    Che ne dite?
Devi accedere o registrarti per scrivere nel forum
1 risposte