Search code examples
javaswingjpanelsizing

JPanel sizing inside Another JPanel


I really need help with this. I have been having problems resizing the gameBoardPanel JPanel that is added the the main Panel. Everything I have tried including resizing it has not helped, I basically want to add the gameBoardPanel at 400x400 to the main panel (which is 400x500), leaving me 400x100 of space for other buttons e.x return to menu, etc. Any help would be much appreciated!

Thanks!

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import javax.swing.*;

public class SliderPractice extends JFrame implements ActionListener {

    private int numberOfRows, mode;
    private JPanel gameBoardPanel, menuPanel, main; //create a panel to add to JFRAME
    private int emptyIndex; //Variable will track the empty spot
    private int moves = 0;
    JButton[] buttons, compareButtons;
    private JLabel radioButtons, radioButtons1;
    private ButtonGroup radioButtonGroup1, radioButtonGroup2;
    private JButton start, displayInstructions = new JButton(); //buttons on start panel
    private JTextArea title;
    private JRadioButton easy, medium, hard, extreme, three, four, five, six; //Radio buttons allow user to only select 1 of 3

    public SliderPractice()
    {
        super("Slider! - By: Michel V.");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(400,400);  //Overall size of grid but window
                           //is resizable by default. Layout
                           //Manager takes care of the necessary scaling.

        setResizable(false); //set resizable false for menu
        menu(); //calling menu
    }

    public void actionPerformed(ActionEvent e) { //when an action is performed

        if (e.getSource().equals(start)){ //Start button
            startUp(); //starts up game
        }

        for(int i = 0 ; i < buttons.length; i++) //checks for all the game buttons if any were pressed
        {
            if(e.getSource() == buttons[i]) //if a specific game button is pressed
            {
                if(isNextTo(i, emptyIndex)==true) //calling isNextTo to make sure its beside one another
                {
                    swapPieces(i); //if its beside, swap pieces and increase number of moves
                    moves++;
                }
            }
        }

        if(win()){ //if Win == true

            int select = JOptionPane.showConfirmDialog(this, "You won with " + moves + " moves! Play same settings again(Y/N)?\n                     Or press cancel to exit!");
            //Yes clicked - Play again
            if (select == JOptionPane.YES_OPTION){
                scramble();
                moves = 0;
            }//no picked, resetGUI!
            else if (select == JOptionPane.NO_OPTION){
                resetGUI();
            }//if Cancel or closed is picked, exit program
            else if (select == JOptionPane.CANCEL_OPTION){
                System.exit(0);
            }
            else if (select == JOptionPane.CLOSED_OPTION){
                System.exit(0);
            }
        }
    }

    public void gamePanel(int numberRows){

        numberOfRows = numberRows;
        buttons = new JButton[numberOfRows*numberOfRows];  //Make room for as many buttons as needed for picked number of Rows
        compareButtons = new JButton[numberOfRows*numberOfRows];

        Font f = new Font("Arial", Font.BOLD, 22);
        Color[] colours = {Color.red, Color.green};

        gameBoardPanel = new JPanel();
        gameBoardPanel.setLayout(new GridLayout(numberOfRows,numberOfRows,5,5)); // 4x4 grid with 5 pixel 
                                                           // vert/horz dividers
        gameBoardPanel.setBackground(Color.white); //Allows empty space to be black

        for (int i = 0; i < buttons.length; i++)  //From i is 0 to 15
        {
            int colourIndex = 0;  //Start with Orange

            compareButtons[i] = new JButton("" + i);
            buttons[i] = new JButton("" + i);  //Constructor sets text on new buttons
            buttons[i].setSize(100,100);  //Button size, but don't really need this line
                                          //line since we are using Layout Manager
            if (numberOfRows %2 ==0){
                if (i % 2 == 0)        //Alternate orange and white for evens and odds
                    colourIndex = 1;
                if ((i/4)%2 == 0)
                    colourIndex = 1-colourIndex;
            }
            else{
                if(i % 2 == 0)
                    colourIndex = 1;
            }

            buttons[i].setBackground(colours[colourIndex]);
            buttons[i].setForeground(Color.white);   //Text colour
            buttons[i].setFont(f);
            buttons[i].addActionListener(this);   //Set up ActionListener on each button
            gameBoardPanel.add(buttons[i]);    //Add buttons to the grid layout of 
                                               //gameBoardPanel
        }

        emptyIndex=(numberOfRows*numberOfRows-1);
        buttons[emptyIndex].setVisible(false);
    }

    public void menu(){

        Font f = new Font("Arial", Font.BOLD, 26);
        Font t = new Font("Trebuchet MS", Font.BOLD, 13);
        Color[] colours = {Color.red, Color.green};
        /*--- JPanel for Start Menu ---*/
        menuPanel = new JPanel();
        menuPanel.setLayout(null);
        menuPanel.setBackground(colours[0]);
        menuPanel.setVisible(true);
        //Title
        title = new JTextArea("Michel's Slider \n       Game!");
        title.setLineWrap(true);
        title.setWrapStyleWord(true);
        title.setBounds(100, 10, 250, 60);
        title.setFont(f);
        title.setBorder(BorderFactory.createEmptyBorder());
        title.setBackground(colours[0]);
        title.setEditable(false);
        title.setEnabled(false);
        title.setDisabledTextColor(Color.BLACK);
        //Label for radio buttons
        radioButtons = new JLabel("Choose the difficulty for this game:");
        radioButtons.setFont(new Font("Trebuchet MS", Font.BOLD, 17));
        radioButtons.setBounds(50, 155, 400, 20);
        //Radio buttons to select picture to play with
        easy = new JRadioButton("Easy");
        easy.setBackground(colours[0]);
        easy.setBounds(15, 178, 100, 20);
        easy.setActionCommand("Mode 1");
        easy.setFont(t);
        easy.setSelected(true); //Default selection
        medium = new JRadioButton("Medium");
        medium.setBackground(colours[0]);
        medium.setBounds(120, 178, 100, 20);
        medium.setFont(t);
        hard = new JRadioButton("Hard");
        hard.setBackground(colours[0]);
        hard.setBounds(215, 178, 100, 20);
        hard.setFont(t);
        extreme = new JRadioButton("Extreme");
        extreme.setBackground(colours[0]);
        extreme.setBounds(310, 178, 100, 20);
        extreme.setFont(t);
        //Add radio buttons to a group
        radioButtonGroup1 = new ButtonGroup();
        radioButtonGroup1.add(easy);
        radioButtonGroup1.add(medium);
        radioButtonGroup1.add(hard);
        radioButtonGroup1.add(extreme);

        radioButtons1 = new JLabel("Choose the size for this game:");
        radioButtons1.setFont(new Font("Trebuchet MS", Font.BOLD, 17));
        radioButtons1.setBounds(68, 100, 400, 20);
        //Radio buttons to select picture to play with
        three = new JRadioButton("3x3");
        three.setBackground(colours[0]);
        three.setBounds(15, 124, 110, 20);
        three.setActionCommand("Mode 1");
        three.setFont(t);
        three.setSelected(true); //Default selection
        four = new JRadioButton("4x4");
        four.setBackground(colours[0]);
        four.setBounds(120, 124, 100, 20);
        four.setFont(t);
        five = new JRadioButton("5x5");
        five.setBackground(colours[0]);
        five.setBounds(215, 124, 100, 20);
        five.setFont(t);
        six = new JRadioButton("6x6");
        six.setBackground(colours[0]);
        six.setBounds(310, 124, 100, 20);
        six.setFont(t);
        //Add radio buttons to a group
        radioButtonGroup2 = new ButtonGroup();
        radioButtonGroup2.add(three);
        radioButtonGroup2.add(four);
        radioButtonGroup2.add(five);
        radioButtonGroup2.add(six);


        //Start game button
        start = new JButton("Start Game");
        start.addActionListener(this);
        start.setBounds(110, 290, 170, 35);
        start.setBackground(colours[1]);
        start.setFont(new Font("Trebuchet MS", Font.BOLD, 22));
        //Instructions button
        displayInstructions = new JButton("Instructions");
        displayInstructions.addActionListener(this);
        displayInstructions.setBounds(130, 335, 130, 20);
        displayInstructions.setBackground(colours[1]);
        displayInstructions.setFont(new Font("Trebuchet MS", Font.BOLD, 17));

        //Add components to start panel
        menuPanel.add(start);
        menuPanel.add(displayInstructions);
        menuPanel.add(title);
        menuPanel.add(easy);
        menuPanel.add(medium);
        menuPanel.add(hard);
        menuPanel.add(extreme);
        menuPanel.add(radioButtons);
        menuPanel.add(three);
        menuPanel.add(four);
        menuPanel.add(five);
        menuPanel.add(six);
        menuPanel.add(radioButtons1);
        /*--- End Start Menu JPanel ---*/   
        add(menuPanel);
        setVisible(true);
    }

    public static void main(String[] args) {

        new SliderPractice();               //Run constructor for class
    }


    private void swapPieces(int btnIndex)   //Send along button that was pushed
    {
        buttons[emptyIndex].setText(buttons[btnIndex].getText());  //Move over text
                                                                   //to blank button
        buttons[btnIndex].setVisible(false); //Turn off visibility of button that was pushed
                                             //and background will show through as black
        buttons[emptyIndex].setVisible(true);//Turn on visibility of the old blank button
        emptyIndex = btnIndex;               //Update the emptyIndex to the button that was
                                             //pushed.
    }

    private boolean isNextTo(int choice, int blankButton)
    {
        if(choice/numberOfRows==blankButton/numberOfRows){
            if(Math.abs(choice-blankButton)==1) return true;
        }
        else if(Math.abs(choice/numberOfRows-blankButton/numberOfRows)==1) {
            if(Math.abs(choice-blankButton)==numberOfRows) { 
                return true;
            }
        }
        return false;
    }

    private boolean win()
    {
        int count = 0;

        for (int i = 0; i < buttons.length; i++)  //From i is 0 to 15
        {
            if(buttons[i].getText().equals(compareButtons[i].getText()))
            {
                count++;
            }
            else{
                break;
            }
        }

        if (count == (numberOfRows*numberOfRows-1))
            return true;
        else
            return false;
    }

    private void scramble()
    {
        int s = 0;
        int g;
        int max = (int) Math.pow(numberOfRows, mode);

        while (s<max)
        {
            g = (int) ((Math.random()*(numberOfRows*numberOfRows))-1);

            if(isNextTo(g, emptyIndex)==true)
            {
                swapPieces(g);
                s++;
            }
        }
    }

    private void startUp(){

        int size = 0;

        //Set image on button according to radio button selection
        if (three.isSelected()){
            size = 3;
        }

        else if (four.isSelected()){
            size = 4;
        }

        else if (five.isSelected()){
            size = 5;
        }

        else if (six.isSelected()){
            size = 6;
        }

        if (easy.isSelected()){
            mode = 2;
        }

        else if (medium.isSelected()){
            mode = 3;
        }

        else if (hard.isSelected()){
            mode = 4;
        }

        else if (extreme.isSelected()){
            mode = 5;
        }

        gamePanel(size);

        setSize(400, 500);
        gameBoardPanel.setEnabled(false);
        //Switch panels from start panel to main panel
        main = new JPanel();
        menuPanel.setVisible(false);
        remove(menuPanel);
        main.add(gameBoardPanel);
        main.setSize(400, 400);
        main.setBackground(Color.white);
        add(main);
        setResizable(true);
        //Shuffle Pieces
        scramble();
    }

    private void resetGUI(){
        numberOfRows = 0;
        moves = 0;
        emptyIndex = 0;
        setResizable(false);
        setSize(400,400);
        remove(gameBoardPanel);
        add(menuPanel);
        menu();
        mode = 0;
    }
}

Solution

  • It's really hard to understand what you want to achieve. You want to make room to which buttons at the bottom?? How is the screen supposed to look like?

    Anyway, i think you should use different panels and layoutmanagers to solve your problem, and what I think can help you best is the BorderLayout.

    If you want your gameBoardPanel to fully fit the window when the game starts, you could change your code to something like this at the end of your startUp() method:

        //Switch panels from start panel to main panel
        main = new JPanel(new BorderLayout());
        menuPanel.setVisible(false);
        remove(menuPanel);
        main.add(gameBoardPanel, BorderLayout.CENTER);
    
        JPanel buttonsPanel = new JPanel();
        buttonsPanel.setPreferredSize(new Dimension(400, 100));
        main.add(buttonsPanel, BorderLayout.SOUTH);