Home > OS >  Attempting to change grid size based on which RadioButton is selected - Java Swing GUI - SOS board g
Attempting to change grid size based on which RadioButton is selected - Java Swing GUI - SOS board g

Time:04-11

This project revolves around a game that is a variation of TicTacToe called SOS. One of the requirements is that the game grid needs to have two size options. The smaller grid is 5x5 and the larger is 8x8.

My goal is to have the grid size change based off which radio button is selected. In my code below I have a commented out method to change the GRID_SIZE variable based off which radio button is selected. But it does not work where it is currently and I am struggling to come up with the solution. The other problem related to the grid size changing that I think I'll have is, I do not believe the way I create the grid now will allow for it to change live as the radio buttons are pushed.

I will need to be keeping track of what gets played in each cell of the grid (whether a player is placing an S or an O) So my thought is maybe there is a better way to create the grid for both the GUI and as a storage method for the moves played.

This project is my first java project and first GUI project of this depth. It is also the major project for one of my last classes to graduate so I'm taking this seriously and could really use the help. I know my code is probably not great, I'm here to improve so any help is welcomed.

package practice;

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


@SuppressWarnings({ "serial", "unused"})
public class SOS_GUI extends JFrame {

    public int GRID_SIZE = 8;

    public Grid grid; 


    public SOS_GUI() {
    
        GameBoard();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack(); 
        setTitle("SOS Practice");
        this.setLocationRelativeTo(null);
        setVisible(true);  
    }


    public void GameBoard(){
    
        // CONTENT PANE FOR HOLDING ALL GUI COMPONENTS
        Container ContentPane = getContentPane();
    
        // PANEL FOR GAME GRID
        JPanel gameBoardCanvas = new JPanel();  
        gameBoardCanvas.setLayout(new GridLayout(GRID_SIZE, GRID_SIZE));
        for (int x = 0; x < GRID_SIZE; x  ) {
            for (int y = 0; y < GRID_SIZE; y  ) {
                final Grid cell = new Grid(x, y);
                gameBoardCanvas.add(cell);
            }
        }
    
    
        // FOUR PANELS SURROUNDING GAME GRID
        JPanel TopPanel = new JPanel();
        JPanel BottomPanel = new JPanel();
        JPanel LeftPanel = new JPanel();
        JPanel RightPanel = new JPanel();
    
        JLabel SpacerLabel = new JLabel("  ||   ");
    
        // GAME MODE OOPTIONS - SIMPLE OR GENERAL
        JLabel GameModeLabel = new JLabel("Game Mode :");
        JRadioButton SimpleGameButton = new JRadioButton("Simple", true);
        JRadioButton GeneralGameButton = new JRadioButton("General");
        ButtonGroup GameModeButtons = new ButtonGroup();
        GameModeButtons.add(SimpleGameButton);
        GameModeButtons.add(GeneralGameButton);
    
        // BOARD SIZE BUTTONS - SMALL(5X5) OR LARGE(8X8)
        JLabel SizeOptionLabel = new JLabel("Board Size :");
        JRadioButton SmallGridButton = new JRadioButton("Small", true);
        JRadioButton LargeGridButton = new JRadioButton("Large");
        ButtonGroup GridSizeButtons = new ButtonGroup();
        GridSizeButtons.add(SmallGridButton);
        GridSizeButtons.add(LargeGridButton);
    
        // PLAY LETTER SETTINGS
        JRadioButton PlayS_Button = new JRadioButton("S", true);
        JRadioButton PlayO_Button = new JRadioButton("O");
        ButtonGroup PlayLetterButtons = new ButtonGroup();
        PlayLetterButtons.add(PlayS_Button);
        PlayLetterButtons.add(PlayO_Button);
    
        //  BLUE PLAYER SETTINGS
        JLabel BluePlayerLabel = new JLabel("Blue Player");
        JRadioButton BlueHumanButton = new JRadioButton("Human", true);
        JRadioButton BlueComputerButton = new JRadioButton("Computer");
        ButtonGroup BluePlayerButtons = new ButtonGroup();
        BluePlayerButtons.add(BlueHumanButton);
        BluePlayerButtons.add(BlueComputerButton);
        
        // RED PLAYER SETTINGS
        JLabel RedPlayerLabel = new JLabel("Red Player");
        JRadioButton RedHumanButton = new JRadioButton("Human");
        JRadioButton RedComputerButton = new JRadioButton("Computer", true);
        ButtonGroup RedPlayerButtons = new ButtonGroup();
        RedPlayerButtons.add(RedHumanButton);
        RedPlayerButtons.add(RedComputerButton);
    
    
        // ADDING COMPONENTS TO TOP PANEL
        TopPanel.add(GameModeLabel);
        TopPanel.add(SimpleGameButton);
        TopPanel.add(GeneralGameButton);
        TopPanel.add(SpacerLabel);
        TopPanel.add(SizeOptionLabel);
        TopPanel.add(SmallGridButton);
        TopPanel.add(LargeGridButton);
    
        // ADDING COMPONENTS TO BOTTOM PANEL
        BottomPanel.add(PlayS_Button);
        BottomPanel.add(PlayO_Button);
    
        // ADDING COMPONENTS TO LEFT PANEL
        LeftPanel.add(BluePlayerLabel);
        LeftPanel.add(BlueHumanButton);
        LeftPanel.add(BlueComputerButton);
    
        // ADDING COMPONENTS TO RIGHT PANEL
        RightPanel.add(RedPlayerLabel);
        RightPanel.add(RedHumanButton);
        RightPanel.add(RedComputerButton);
    
        // ADDING PANELS TO CONTENT PANE
        ContentPane.setLayout(new BorderLayout());
        ContentPane.add(TopPanel, BorderLayout.NORTH);
        ContentPane.add(BottomPanel, BorderLayout.SOUTH);
        ContentPane.add(LeftPanel, BorderLayout.WEST);
        ContentPane.add(RightPanel, BorderLayout.EAST);
        ContentPane.add(gameBoardCanvas, BorderLayout.CENTER);
        TopPanel.setPreferredSize(new Dimension(50, 50));
        BottomPanel.setPreferredSize(new Dimension(50, 50));
        LeftPanel.setPreferredSize(new Dimension(100, 100));
        RightPanel.setPreferredSize(new Dimension(100, 100));
        ContentPane.setPreferredSize(new Dimension(550, 500));
    }


    // CLASS SETTING UP HOW THE GRID WILL BE CREATED
    class Grid extends JPanel {
        public static final int CELL_SIZE = 1;
        private int xPos;
        private int yPos;
        public JLabel gridLabel;

        public Grid (int x, int y) {
            xPos = x;
            yPos = y;
            gridLabel = new JLabel("");
            gridLabel.setFont(new Font("Serif", Font.BOLD, 40));
            add(gridLabel);
            setOpaque(true);
            setLayout(new FlowLayout());
            setBorder(BorderFactory.createBevelBorder(CELL_SIZE));
            setBackground(new Color(200, 200, 200));
            setPreferredSize(new Dimension(CELL_SIZE, CELL_SIZE));
        }
    }



    /* POSSIBLE FUNCTION TO SET GRID_SIZE BASED OFF RADIO BUTTON INPUT? DOESNT WORK HERE
    public getGridSize() {
        if (GameBoard().SmallGridButton.isSelected() == true) {
            GRID_SIZE = 5;
        }
        else if (GameBoard().LargeGridButton.isSelected() == true) {
            GRID_SIZE = 8;
        }
        return GRID_SIZE;
    }
    */


    public static void main(String[] args) {
        new SOS_GUI(); 
    }

} 

screenshot of the smaller 5x5 grid screenshot of larger 8x8 grid

CodePudding user response:

Again, I suggest that if you want to use components as your grid cell, that you either swap views (JPanels) using a CardLayout, or you swap out the grid cells when a JRadioButton is pressed.

I suggest:

  • Adding an ActionListener to the JRadioButton to be notified when it is pressed.
  • If you will swap components, then create a JPanel to hold the grid cells, say called gridHolder, and remove all components when the button is pressed.
  • Then add a new GridLayout layout manager to this JPanel, with constraints set depending on whih JRadioButton has been pressed.
  • Then re-adding grid cell components to this holder JPanel
  • Then relaying out all components in the GUI and resizing it by calling pack() on the top-level window, here a JFrame.
  • In the example below, I use JLabels to hold the grid cells since it is trivial to add text to these.
  • I store the row and column of each grid cell using the .putClientProperty(...) method and likewise can retrieve values using the .getClientProperty(...) method.
  • I call createGrid(...) in the constructor to create the grid with the default, small, size.
  • I call the same method whenever a JRadioButton has been pressed.

For example:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.*;
import javax.swing.border.BevelBorder;

@SuppressWarnings("serial")
public class SosGrid2 extends JPanel {
    private static final int SMALL_SIZE = 5;
    private static final int LARGE_SIZE = 8;
    private static final String[] SIZES = { "Small", "Large" };
    private static final Dimension CELL_SIZE = new Dimension(60, 60);
    private static final Color GRID_BG = new Color(200, 200, 200);
    private static final String ROW = "row";
    private static final String COL = "col";
    private JPanel gridHolder = new JPanel();
    private ButtonGroup gridSizeGroup = new ButtonGroup();

    public SosGrid2() {
        JPanel radioButtonPanel = new JPanel();

        for (String size : SIZES) {
            JRadioButton radioButton = new JRadioButton(size);
            radioButton.setSelected(size.equals(SIZES[0]));
            radioButton.setActionCommand(size);
            gridSizeGroup.add(radioButton);
            radioButtonPanel.add(radioButton);
            radioButton.addActionListener(e -> radioListener());
        }

        createGrid(SMALL_SIZE);

        setLayout(new BorderLayout());
        add(gridHolder);
        add(radioButtonPanel, BorderLayout.PAGE_END);
    }

    private void createGrid(int gridSize) {
        gridHolder.removeAll();
        gridHolder.setLayout(new GridLayout(gridSize, gridSize));
        for (int row = 0; row < gridSize; row  ) {
            for (int col = 0; col < gridSize; col  ) {
                JLabel gridCell = createGridCell(row, col);
                gridHolder.add(gridCell);
            }
        }
    }
    
    // factory method to create grid cell JLabels.
    private JLabel createGridCell(int row, int col) {
        JLabel label = new JLabel("", SwingConstants.CENTER);
        label.setFont(label.getFont().deriveFont(Font.BOLD, 32f));
        label.setOpaque(true);
        label.setBackground(GRID_BG);
        label.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
        label.setPreferredSize(CELL_SIZE);
        label.putClientProperty(ROW, row);
        label.putClientProperty(COL, col);
        label.addMouseListener(new MyMouseListener());
        
        return label; 
    }
    
    private class MyMouseListener extends MouseAdapter {
        @Override
        public void mousePressed(MouseEvent e) {
            JLabel gridCell = (JLabel) e.getSource();
            int row = (int) gridCell.getClientProperty(ROW);
            int col = (int) gridCell.getClientProperty(COL);
            String message = String.format("Row: %d, Col: %d", row, col);
            String title = "Cell Pressed";
            int type = JOptionPane.PLAIN_MESSAGE;
            JOptionPane.showMessageDialog(SosGrid2.this, message, title, type);
            
            String text = gridCell.getText();
            if (text.isEmpty()) {
                gridCell.setText("X");
            } else {
                gridCell.setText("");
            }
        }
    }

    private void radioListener() {
        ButtonModel btnModel = gridSizeGroup.getSelection();
        if (btnModel != null) {
            int gridSize = btnModel.getActionCommand().equals(SIZES[0]) ? SMALL_SIZE : LARGE_SIZE;
            createGrid(gridSize);
            Window jframe = SwingUtilities.getWindowAncestor(this);
            jframe.pack();
            jframe.setLocationRelativeTo(null);
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            SosGrid2 mainPanel = new SosGrid2();

            JFrame frame = new JFrame("GUI");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(mainPanel);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }
}
  • Related