Home > Enterprise >  How to Randomize Placement of a JLabel on a GridLayout of JButtons?
How to Randomize Placement of a JLabel on a GridLayout of JButtons?

Time:12-15

I am trying to make a chessboard, that will randomize the place of its pieces throughout the board.

Below is what I have so far

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

public class ChessBoard extends JFrame {

    JLayeredPane layeredpane;
    JPanel chessboard;
    JButton[][] chessboardButtons;
    Color black;
    JLabel [][] chessboardLabels;

    UIManager Ui;


    ChessBoard() {
        Dimension Size = new Dimension(600, 600);

        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        pack();
        setResizable(true);
        setLocationRelativeTo(null);
        setVisible(true);
        setSize(600, 600);
        setTitle("Chess Board");

        layeredpane = new JLayeredPane();
        getContentPane().add(layeredpane);
        layeredpane.setPreferredSize(Size);

        chessboard = new JPanel();
        layeredpane.add(chessboard, JLayeredPane.DEFAULT_LAYER);
        chessboard.setLayout(new GridLayout(8, 8));
        chessboard.setPreferredSize(Size);
        chessboard.setBounds(0, 0, Size.width, Size.height);

        Ui = new UIManager();
        chessboardButtons = new JButton[8][8];
        black = Color.black;


        ButtonHandler handler = new ButtonHandler();
        for (int i = 0; i < 8; i  ) {
            for (int j = 0; j < 8; j  ) {
                chessboardButtons[i][j] = new JButton();
                chessboardButtons[i][j].setBorderPainted(false);

                if ((i   j) % 2 != 0) {
                    chessboardButtons[i][j].setBackground(black);
                    chessboardButtons[i][j].setOpaque(true);
                }
                chessboard.add(chessboardButtons[i][j]);
                chessboardButtons[i][j].addActionListener(handler);

            }
        }

        chessboardLabels = new JLabel[8][8];
        for (int i = 0; i < 8; i  ) {
            for (int j = 0; j < 8; j  ) {
                chessboardLabels[i][j] = new JLabel();
                chessboardLabels[i][j].setFont(new Font("Ariel", Font.BOLD, 20));
                chessboardLabels[i][j].setText("H");
                chessboardLabels[i][j].setHorizontalAlignment(JLabel.CENTER);
                chessboardLabels[i][j].setVerticalAlignment(JLabel.CENTER);
                chessboardLabels[i][j].setOpaque(true);
                chessboardButtons[i][j].add(chessboardLabels[i][j]);

                if(chessboardButtons[i][j].getBackground() == Color.black) {
                    chessboardLabels[i][j].setBackground(Color.black);
                    chessboardLabels[i][j].setForeground(Color.white);
                }

            }
        }









    }


    private class ButtonHandler implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            if (e.getSource() == chessboardButtons[0][0]) {
                System.out.println("Button 0,0");
            }
            if (e.getSource() == chessboardButtons[0][1]) {
                System.out.println("Button 0,1");
            }

        }
    }
}

Right now I have the letter H filling all my buttons. What I need it to do is to:

  1. limit the number of "H"'s there are on the board to be 32, 16 "White" and 16 "black" and
  2. randomize the placement throughout the board.

Any ideas will be helpful!

CodePudding user response:

I tried exactly this years ago, and I ran into several problems. One of the biggest is that dragging a piece from one square (JComponent) to another hard to do, because each JComponent has its bounds, and its Graphics clipping prevents you from drawing outside of these bounds. There are workarounds, like adding an Image to a higher level in the JLayeredPane, but this is still very hard to get right.

You really want to make you GUI a custom JComponent/JPanel that draws the whole board and can get mouse events across the whole board.

But before that, the right place to start is by creating a ChessModel that encapsulates the logic of the game. If you do that first and test it thoroughly, adding a GUI on top of that is easier than the other way around.

public class ChessModel {
  char[][] board = new char[8][8];
  
  ...
  public Point[] getPossibleMoves(Point pieceLocation) {
   ...
  }
}

CodePudding user response:

  1. Create an ArrayList with 64 Integers numbered from 0 - 63
  2. Use Collections.shuffle(...) to shuffle the numbers randomly
  3. Take the first 16 values from the ArrayList and add white pieces to the board based on the integer value.
  4. Take the next 16 values from the ArrayList and add the black pieces to the board.

CodePudding user response:

First, I would start by decoupling parts of the system, this will provide you with a lot more flexibility.

For example, you want to decouple the "visual" from the "virtual". Components aren't managed in a "grid", instead, they are maintained in a list, so, you want some way you can quickly and easily ascertain the location of various components on the screen and how the relate to the "virtual" concept of the game or grid.

This is at the core concept of "model-view-controller", where the model represents a "grid" of "pieces" and the view is used to visually represent the model to the user. So you end up with a little bit of translation going on.

Now, you can do something like...

int row = (value / 8);
int col = (value % 8);

which, given a component index, will give you the row/col that they represent, but I'm also lazy

  • Related