1

I am trying to teach myself more about graphics in Java. To do this I'm trying to build a chess game. I've hit my first roadblock at making the board. My thought here is that I would have a extension of JComponent called "Square" that would be my container for both the color of the board square and the piece on that square (if any). To start with I haven't attempted to include any representation of the piece yet, just the square colors. Later on I hope to have an abstract "Pieces" class that is extended by multiple subclasses representing all the different types of pieces, and add those to each Square as applicable.

When I execute the following, I only get one black square in the upper left hand corner.

ChessBoardTest.java

public class ChessBoardTest {
public static void main(String[] args) {
    ChessBoard Board = new ChessBoard();
    Board.Display();
}

}

ChessBoard.java

public class ChessBoard extends JFrame {

public static final int FRAME_WIDTH  = 500;
public static final int FRAME_HEIGHT = 500;

// Declare instance variables
private Square[][] square = new Square[rows][cols];
private final static int rows = 8;
private final static int cols = 8;


public ChessBoard() {
    
}

public void Display() {
    JPanel Board_Layout = new JPanel();
    Board_Layout.setLayout(new GridLayout(8,8));
    for(int i=0;i<8;i++)
    {
         for(int j=0;j<8;j++)
         {
             if((i+j) % 2 == 0) {
                 square[i][j] = new Square(1);
                 Board_Layout.add(square[i][j]);
             } else {
                 square[i][j] = new Square(0);
                 Board_Layout.add(square[i][j]);
             }
             
         }
    }
    setTitle("Chess Mod");
    setSize(FRAME_WIDTH, FRAME_HEIGHT);
    setResizable(false);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    add(Board_Layout);
    setVisible(true);
}


public void messageBox(String pMessage) {
    JOptionPane.showMessageDialog(this, pMessage, "Message", JOptionPane.PLAIN_MESSAGE);
}

}

Square.java

public class Square extends JComponent {

private int color;

public Square(int c) {
    this.color=c;
}

public void paintComponent(Graphics g) {
    super.paintComponent(g);
    
    if (this.color == 1) {
        g.setColor(new Color(0,0,0));
    } else {
        g.setColor(new Color(255,255,255));
    }
    
    g.fillRect(this.getX(), this.getY(), this.getWidth(), this.getHeight());
}

}
user2355903
  • 593
  • 2
  • 8
  • 29
  • 2
    Generally, you create a logical model of a chessboard and draw that logical model on a single drawing JPanel. The Oracle tutorial, [Performing Custom Painting](https://docs.oracle.com/javase/tutorial/uiswing/painting/index.html) will show you how. – Gilbert Le Blanc Aug 10 '21 at 21:56
  • 1) *"teach myself more about graphics in Java. To do this I'm trying to build a chess game"* Note that a [simple chessboard](https://stackoverflow.com/q/21142686/418556) can be made entirely with standard components. Unless this is intended to add functionality beyond that (e.g. to animate moves of chess pieces), there are better choices for a 'custom painted game'. 2) If custom painting is necessary, it's often better to use a `JPanel` that a `JComponent`. 3) There is no good case here for extending `JFrame`. Just use a standard 'out of the box' frame. .. – Andrew Thompson Aug 11 '21 at 01:32
  • .. 4) See [Detection/fix for the hanging close bracket of a code block](http://meta.stackexchange.com/q/251795/155831) for a problem I could no longer be bothered fixing. Please [edit] the question to add 4 space chars ahead of the closing `}` at the end of the code. – Andrew Thompson Aug 11 '21 at 01:32

1 Answers1

2

I only get one black square in the upper left hand corner.

That's mainly because of the following call:

g.fillRect(this.getX(), this.getY(), this.getWidth(), this.getHeight());

getX() returns the horizontal pixel offset/location of the Component which is invoked upon, relative to the Container that contains that Component. getY() accordingly returns the vertical pixel offset/location of the Component which is invoked upon, relative to the Container that contains the Component.

getWidth() and getHeight() return the size of the Component.

So imagine that the Component at row with index 2 and column with index 3, will have its coordinates at about x == 3 * w / 8 and y == 2 * h / 8 where w and h is the size (width and height respectively) of the parent Container (ie the Board_Layout panel). Let's assume that Board_Layout has a size of 300x300 when you show the graphical user interface... This means that the Square at the location I mentioned will only paint the region which starts at x == 112 and y == 75 and expands at one 8th of the width (and height) of Board_Layout (because there are 8 rows and 8 columns in the grid). But the size of the Square itself is also at one 8th of the width (and height) of Board_Layout, ie about 37x37. So the painted region which starts and expands from the location 112,75 will not be shown at all (because it lies completely outside the Square's size).

Only the top left Square will have some paint on it because its bounds in the parent happen to intersect the drawn region.

To fix this, the location given at the Graphics object should be relative to each Square and not its parent Board_Layout. For example:

g.fillRect(0, 0, getWidth(), getHeight());
gthanop
  • 3,035
  • 2
  • 10
  • 27