Home > Mobile >  JButtons not showing up after initialisation [Java Swing]
JButtons not showing up after initialisation [Java Swing]

Time:05-16


I know there are super many questions here on stack overflow about JElements not showing up, all because someone forgot to add a setVisible(true) at the end of the constructor. But at least I belive my problem is something different. I am currently creating a chess-game for college, and for that i have the
  • Game class: here all comes together
  • the abstract Piece class extending JButton in package Pieces
  • and a class for Each Piece (Rook, Bishop, ...) each extending Piece and being located in the Pieces package

before I write much more and it is a dumb error again, here the code: ```java import javax.swing.*; import Pieces.*;

import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener;

public class Game extends JFrame { private static final int width = 8; private static final int height = 8;

private static Piece clicked;

private static Piece[][] fields = new Piece[width][height];

private JPanel main = new JPanel();

public static void init(JPanel g) {
    for (int y = 0; y < fields.length; y  ) {
        for (int x = 0;  x < fields[y].length; x  ) {

            if (y == 1) fields[y][x] = new Pawn(x, y, true); //2nd or 7th row is filled with pawns
            else if (y == 6) fields[y][x] = new Pawn(x, y, false);
            else {
                fields[y][x] = new Empty(x,y,true);
            }

            fields[y][x].addActionListener(e -> {
                var p = (Piece) e.getSource();
                System.out.println(p.getX()   p.getY());
            });

            g.add(fields[y][x]);
        }
    }
}

public Game() {
    main.setBackground(Color.blue.darker());
    main.setLayout(new GridLayout(8,8));
    this.setSize(800,800);

    init(main);
    this.add(main);

    this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    this.setVisible(true);
}

public static void main(String[] args) {
    var g = new Game();
}

}

```java
package Pieces;

import javax.swing.*;

public abstract class Piece extends JButton {
    private int x;
    private int y;
    private final boolean isWhite;

    public Piece(int x, int y, boolean isWhite) {
        this.x = x;
        this.y = y;
        this.isWhite = isWhite;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public boolean isWhite() {
        return isWhite;
    }

    public boolean canMoveTo(int toX, int toY) {
        return true;
    }
}

each Piece-extending class is setup exactly like this:

package Pieces;

import java.awt.*;

public class Pawn extends Piece{
    public Pawn(int x, int y, boolean isWhite) {
        super(x, y, isWhite);
        this.setText(isWhite ? "Pawn" : "pawn");
    }
}

expected behavior:

  • open a window with 64 JButtons in it, displaying the name of the Piece they represent (there is indeed an Empty-class for non-used fields)

  • actual behavior:
  • opens a window with one button at the top left but first when i go over the fields with my cursor the butons start appering
    state 1:[state 1][1]
    state 2: [state 2][1]
  • CodePudding user response:

    You can't override getX and getY like this, these properties are used by the layout managers to layout the components.

    Instead, maybe make use of Point to store the virtual or "cell" position

    public static abstract class Piece extends JButton {
        private final boolean isWhite;
        private Point cell;
    
        public Piece(int x, int y, boolean isWhite) {
            cell = new Point(x, y);
            this.isWhite = isWhite;
        }
    
        public Point getCell() {
            return cell;
        }
    
        public boolean isWhite() {
            return isWhite;
        }
    
        public boolean canMoveTo(int toX, int toY) {
            return true;
        }
    }
    

    Runnable example...

    enter image description here

    import java.awt.Color;
    import java.awt.EventQueue;
    import javax.swing.JFrame;
    import java.awt.GridLayout;
    import java.awt.Point;
    import javax.swing.JButton;
    import javax.swing.JPanel;
    
    public class Main {
        public static void main(String[] args) {
            new Main();
        }
    
        public Main() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    JFrame frame = new JFrame();
                    frame.add(new BoardPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class BoardPane extends JPanel {
            private static final int width = 8;
            private static final int height = 8;
    
            private Piece clicked;
    
            private Piece[][] fields = new Piece[width][height];
    
            public BoardPane() {
                setBackground(Color.blue.darker());
                setLayout(new GridLayout(8, 8));
                buildBoard();
            }
    
            protected void buildBoard() {
                for (int y = 0; y < fields.length; y  ) {
                    for (int x = 0; x < fields[y].length; x  ) {
    
                        if (y == 1) {
                            fields[y][x] = new Pawn(x, y, true); //2nd or 7th row is filled with pawns
                        } else if (y == 6) {
                            fields[y][x] = new Pawn(x, y, false);
                        } else {
                            fields[y][x] = new Empty(x,y,true);
                        }
    
                        fields[y][x].addActionListener(e -> {
                            var p = (Piece) e.getSource();
                            System.out.println(p.getCell());
                        });
    
                        add(fields[y][x]);
                    }
                }
            }
        }
    
        public static abstract class Piece extends JButton {
            private final boolean isWhite;
            private Point cell;
    
            public Piece(int x, int y, boolean isWhite) {
                cell = new Point(x, y);
                this.isWhite = isWhite;
            }
    
            public Point getCell() {
                return cell;
            }
    
            public boolean isWhite() {
                return isWhite;
            }
    
            public boolean canMoveTo(int toX, int toY) {
                return true;
            }
        }
    
        public static class Pawn extends Piece {
            public Pawn(int x, int y, boolean isWhite) {
                super(x, y, isWhite);
                this.setText(isWhite ? "Pawn" : "pawn");
            }
        }
    
        public static class Empty extends Piece {
            public Empty(int x, int y, boolean isWhite) {
                super(x, y, isWhite);
                this.setText("X");
            }
        }
    }
    
    • Related