Search code examples
javaswinguser-interfacejpanelgrid-layout

jButtons doesn't add correctly


For better reference I'm doing match3 (candy crush type) game.

public class BoardGraphics extends JPanel {
public static final int WIDTH = 400;
public static final int HEIGHT = 400;
private static final Color COLOR = new Color(0xFF0000); //0xF1E4CB

private final Board board;

public BoardGraphics(Board board){
    this.setBackground( COLOR );
    this.setSize(HEIGHT, WIDTH);
    this.setLayout(new GridLayout(board.getHeight(), board.getWidth(), 0, 0));
    this.board = board;
    setVisible(true);
    drawElements();
}
    private void drawElements(){
    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 2; j++) {
            Point p = new Point(i, j);
            //Point p = new Point(1, 2);

            ImageIcon icon = null;
            try {
                BufferedImage img = null;
                img = ImageIO.read(new File(System.getProperty("user.dir") + "/assets/img/gem_" + board.getElement(p).getTileColor().toString() + ".gif"));

                icon = new ImageIcon(img);

                JButton btn = new JButton(icon);
                btn.setVisible(true);
                btn.setOpaque(false);
                btn.setContentAreaFilled(false);
                btn.setBorderPainted(false);
                btn.setSize(50, 50);
                if (i == 1) {
                    btn.setLocation(100, 100); // <- i did this for testing. with this i see 2 gems
                }
                this.add(btn);

            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        }
    this.revalidate();
    this.repaint();
    }
}

and jFrame code here:

public class GameGraphics extends JFrame {
private final int WIDTH = 600;
private final int HEIGHT = 800;

private Game game = new Game();

public GameGraphics() {
    setTitle("SwitchElements");
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setSize(HEIGHT, WIDTH);
    setLocationRelativeTo(null);
    setVisible(true);
    setResizable(false);

    drawBoard();
}

private void drawBoard(){
    // 0xF1E4CB
    BoardGraphics board = new BoardGraphics(game.getGameBoard());
    System.out.println((WIDTH-BoardGraphics.WIDTH)/2);
    board.setLocation( (HEIGHT-BoardGraphics.HEIGHT)/2, (WIDTH-BoardGraphics.WIDTH)/2);

    this.add( board );

    this.repaint();
}
}

the thing is that I tried everything. But jButtons doesn't stack according to grid. it seems that all of them adds into one place


Solution

  • "But jButtons doesnt stack according to grid. it seems that all of them adds into one place"

    Since you never answered my question/comment asking what Board is, I'll make an assumption. (Correct me if I'm wrong)

    Look at your GridLayout construction

    new GridLayout(board.getHeight(), board.getWidth(), 0, 0)
    

    Assuming Board is some kind of container, let's say of dimension 300, 300.

    With your GridLayout constructor, you're saying that there should be 300 rows and 300 columns. There's only four iterations total in both your loops, so you only have 4 buttons. The layout is mapped to 9000 available spaces. So yes, all your buttons will only be placed in the top left of the grid (the first four) position, and the rest of the 8996 empty spaces will be an empty space the size of the largest button.


    What you can do to see the buttons add correctly to the grid is pass a couple arguments to your drawElements() method to ensure the iterations are the same as the layout params.

    private void drawElements(int rows, int cols) {
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
        ....
    }
    

    Then call it like

    public public BoardGraphics(Board board){
    
        int rows = ...
        int cols = ...
        setLayout(new GridLayout(rows, cols, 0, 0));
        drawElements(rows, cols);
    

    Also you should avoid using setSize() and setLocation() for your components. You should be using layout managers and let them do the sizing and locating for you. You can read Laying out Components Within a Container to learn more about the different layouts available.