Java concentrate is there a way to shuffle jbutton

2019-09-20 03:18发布

问题:

I have been working on a memory game in java for about a week and a half know it is basically complete, But i am having a problem with randomizing my jbuttons across the panel they only appear in the list order. So what would be the best way to randomize or shuffle the images and values set to each button i have been wondering it is a static grid layout so i cannot change the position of them, I thought i sussed in a while ago when i got the images to change randomly on the board but i could not find out how to match the values along with the images so the game would function properly.

package concentrate;
import static concentrate.HighscoreManager.scores;
import static concentrate.Score.nameField;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*;
import java.util.logging.Logger;
import javax.swing.*;


public final class Concentrate extends JFrame implements ActionListener {  
    //below are all the variables declared for the gui and the game program itself
    private JFrame window = new JFrame("Concentrate");
    private static final int WINDOW_WIDTH = 330; 
    private static final int WINDOW_HEIGHT = 485; 
    private JButton exitBtn, scoresBtn;  
    ImageIcon ButtonIcon = createImageIcon("/resources/images/b1fv.gif");
    ImageIcon[] ImageArray = new ImageIcon[16];
    public static JButton[] gameBtn = new JButton[16]; 
    private ArrayList<Integer> gameList = new ArrayList<Integer>();  
    public static int Point = 46;
    private int counter = 0;   
    private int cards = 16;
    private int[] btnID = new int[2];   
    private int[] btnValue = new int[2];   
    private JLabel Score;  
    private JLabel Fail;  
    private Panel gamePnl = new Panel(); 
    private Panel buttonPnl = new Panel();   
    private Panel scorePnl = new Panel(); 
    private Icon[] iconSet;
    Random rand = new Random();

    //this function below creates the image icon to be displayed on each card/button when it is enabled
    protected static ImageIcon createImageIcon(String path) {
        java.net.URL imgURL = Concentrate.class.getResource(path);
        if (imgURL != null) {
            return new ImageIcon(imgURL);
        } else {
            System.err.println("Couldn't find file: " + path);
            return null;
        }
    }
    //update score checks and sets the score on the main board 
    public void updateScore() {
        Score.setText("Score: " + Point);
    }

    public Concentrate()
    { 
        //below is calling the create gui function and set variables for it width and close operation
        createGUI();  
        createpanels();  
        setArrayListText();
        window.setTitle("Concentrate"); 
        window.setDefaultCloseOperation(EXIT_ON_CLOSE); 
        window.setSize(WINDOW_WIDTH, WINDOW_HEIGHT); 
        window.setVisible(true);
        //below creates the button faces for when they are disabled it will display the icon
        gameBtn[0].setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/images/c1.gif")));
        gameBtn[1].setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/images/c2.gif")));
        gameBtn[2].setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/images/c3.gif")));
        gameBtn[3].setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/images/c4.gif")));
        gameBtn[4].setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/images/c5.gif")));
        gameBtn[5].setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/images/c6.gif")));
        gameBtn[6].setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/images/c7.gif")));
        gameBtn[7].setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/images/c8.gif")));
        gameBtn[8].setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/images/d1.gif")));
        gameBtn[9].setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/images/d2.gif")));
        gameBtn[10].setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/images/d3.gif")));
        gameBtn[11].setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/images/d4.gif")));
        gameBtn[12].setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/images/d5.gif")));
        gameBtn[13].setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/images/d6.gif")));
        gameBtn[14].setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/images/d7.gif")));
        gameBtn[15].setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/images/d8.gif")));   
    }

    //this is the create gui function which declares the gui variables and items to be set
    public void createGUI() 
    {       
        for (int i = 0; i < gameBtn.length; i++) 
        {      
            gameBtn[i] = new JButton(ButtonIcon);
            gameBtn[i].addActionListener(this); 
        }       
        Score = new JLabel("Score: " + Point);
        exitBtn = new JButton("Exit"); 
        exitBtn.addActionListener(this);
        scoresBtn = new JButton("Leaderboard");  
        scoresBtn.addActionListener(this);
    }    

    //createpanels sets diffrent panels within windows to add the buttons and score on organised from top, main and bottom
    public void createpanels()
    {
        gamePnl.setLayout(new GridLayout(4, 4)); 
        for (int i = 0; i < gameBtn.length; i++)
        {            
            gamePnl.add(gameBtn[i]);   
        }         
        buttonPnl.add(scoresBtn); 
        buttonPnl.add(exitBtn);
        window.setResizable(false);
        buttonPnl.setLayout(new GridLayout(1, 0));
        scorePnl.add(Score);
        scorePnl.setLayout(new GridLayout(1, 0));
        window.add(scorePnl, BorderLayout.NORTH);
        window.add(gamePnl, BorderLayout.CENTER);
        window.add(buttonPnl, BorderLayout.SOUTH);  
    }  


    // the function below checks the cards/buttons for when they are eqaul the same value
    public boolean sameValues() 
    {
        if (btnValue[0] == btnValue[1])
        {  
            return true;    
        }else{
            return false;    
        }
    }  


    @Override
    public void actionPerformed(ActionEvent e) 
    {    

            //this is the exit button displayed onthe bottomof the gui
            if (exitBtn == e.getSource()) 
            { 
                System.exit(0);
            } 
            //this is the button at the botto of the gui which calls on the leaderboard frame
            if (scoresBtn == e.getSource()) 
            {     
                new Leaderboard().setVisible(true);
            }    
            //this if statement checks for when the score is less than or equal to 0 exit the game
            if (Point <= 0)
            {  
               System.exit(0); 
            }  

            //within this for loop is what sets the cards/buttons out with the correct set values also
            for (int i = 0; i < gameBtn.length; i++) 
            {  

                if (gameBtn[i] == e.getSource()) 
                { 
                   /* gameBtn[i].setText("" + gameList.get(i));*/ 
                    gameBtn[i].setEnabled(false);
                    counter++;     
                    if (counter == 3) 
                    { 
                        //this if statement disables and hides the cards/buttons if they match
                        if (sameValues()) 
                        {    
                            gameBtn[btnID[0]].setEnabled(false); 
                            gameBtn[btnID[1]].setEnabled(false);
                            gameBtn[btnID[0]].setVisible(false); 
                            gameBtn[btnID[1]].setVisible(false);
                            cards = cards -2;
                        } 
                        else 
                        {  
                            //this else statement is for when a user fails to match the cards it will re-enable the cards and take off a point
                            gameBtn[btnID[0]].setEnabled(true); 
                            gameBtn[btnID[0]].setText("");
                            gameBtn[btnID[1]].setEnabled(true);
                            gameBtn[btnID[1]].setText("");
                            Point = Point -1;
                        }    
                        counter = 1;      
                    }        

                    //these if statements below set the gameBtns to a value when clicked and gets there value
                    if (counter == 1) 
                    {       
                        btnID[0] = i;   
                        btnValue[0] = gameList.get(i); 
                    }      
                    if (counter == 2) 
                    { 
                        btnID[1] = i;     
                        btnValue[1] = gameList.get(i);  
                    }   
                    //the if staement below brings up the nameprompt popup if the player wins the game
                    if (cards == 2){
                        NamePrompt promptForName = new NamePrompt();
                        promptForName.setVisible(true);
                    }
                }  
            }  
        updateScore();
    } 
    //below sets the values of the gameList to each button for example button 1 will have a value of one to match to
    public void setArrayListText()
    {
        for (int i = 0; i < 2; i++)
        {
            for (int ii = 1; ii < (gameBtn.length / 2) + 1; ii++)
            {
                gameList.add(ii);
            }
        }
    }

    private static final Logger LOG = Logger.getLogger(Concentrate.class.getName());

    public static void main(String[] args)
    {  
        Concentrate concentrate = new Concentrate();
    }
}

above is my main class which also builds the frame and sets the buttons along the panel i have the card icons stored in a resource folder and have defined which button each card icon is within the public concentrate() class

    gameBtn[0].setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/images/c1.gif")));
    gameBtn[1].setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/images/c2.gif")));
    gameBtn[2].setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/images/c3.gif")));
    gameBtn[3].setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/images/c4.gif")));
    gameBtn[4].setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/images/c5.gif")));
    gameBtn[5].setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/images/c6.gif")));
    gameBtn[6].setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/images/c7.gif")));
    gameBtn[7].setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/images/c8.gif")));
    gameBtn[8].setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/images/d1.gif")));
    gameBtn[9].setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/images/d2.gif")));
    gameBtn[10].setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/images/d3.gif")));
    gameBtn[11].setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/images/d4.gif")));
    gameBtn[12].setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/images/d5.gif")));
    gameBtn[13].setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/images/d6.gif")));
    gameBtn[14].setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/images/d7.gif")));
    gameBtn[15].setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/images/d8.gif"))); 

would have shown image of game but do not have enough reputation apologies if i have not been descriptive enough, I am fairly new to this but hope someone can be kind enough and take the time to help me out thanks.

回答1:

"So what would be the best way to randomize or shuffle the images and values set to each button"

Just use Collections.shuffle() to shuffle the array of buttons. It takes a List argument, but you can just use Arrays.toList(). After the array is shuffled, then re-layout the panel with the buttons.

See example

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import java.util.Collections;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class ShuffleButtons {

    private JButton[] buttons;
    private JPanel gridPanel;

    public ShuffleButtons() {
        gridPanel = new JPanel(new GridLayout(4, 4));
        buttons = getButtons(16);
        layoutButtons();

        JFrame frame = new JFrame("Shuffle Buttons");
        frame.add(gridPanel);
        frame.add(getResetButton(), BorderLayout.SOUTH);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public void shuffleButtons() {
        if (buttons != null) {
            Collections.shuffle(Arrays.asList(buttons));
            layoutButtons();
        }
    }

    public void layoutButtons() {
        gridPanel.removeAll();
        for (JButton button : buttons) {
            gridPanel.add(button);
        }
        gridPanel.revalidate();
        gridPanel.repaint();
    }

    private JButton[] getButtons(int size) {
        JButton[] buttons = new JButton[size];
        for (int i = 0; i < size; i++) {
            final JButton button = new JButton(" [ " + i + " ] ");
            button.addActionListener(new ActionListener(){
                public void actionPerformed(ActionEvent e) {
                    System.out.println("Button " + button.getText() + " pressed");
                }
            });
            buttons[i] = button;
        }
        return buttons;
    }

    private JButton getResetButton() {
        JButton button = new JButton("RESET");
        button.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                shuffleButtons();
            }
        });
        return button;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable(){
            public void run() {
                new ShuffleButtons();
            }
        });
    }
}