I would create a separate board class and override the paintComponent
method to draw the actual grid.
Then I would give the board a grid layout and add panels to hold the checkers.
There is an issue with the margin of the checker, but that may be due to the size of the panels. You can mess around with this. I fixed this by applying a border layout to the panel.
Finally, avoid using "magic numbers". Try to declare some instance variables inside your classes and pass their value in via the constructor or some setter/mutator methods.

Application.java
package game.checkers;
import java.awt.*;
import java.lang.reflect.InvocationTargetException;
import javax.swing.SwingUtilities;
public class Application implements Runnable {
public static final String APP_NAME = "Checkers Game";
private GameFrame gameFrame;
private GameBoard checkerBoard;
@Override
public void run() {
initialize();
Checker redChecker = new Checker(50, Color.RED);
Checker greenChecker = new Checker(50, Color.GREEN);
Checker blueChecker = new Checker(50, Color.BLUE);
checkerBoard.placeChecker(redChecker, 1, 5);
checkerBoard.placeChecker(greenChecker, 2, 4);
checkerBoard.placeChecker(blueChecker, 3, 3);
redChecker.addMouseListener(new CheckerMouseListener(redChecker));
greenChecker.addMouseListener(new CheckerMouseListener(greenChecker));
blueChecker.addMouseListener(new CheckerMouseListener(blueChecker));
}
protected void initialize() {
gameFrame = new GameFrame(APP_NAME);
checkerBoard = new GameBoard(8, 8);
checkerBoard.setPreferredSize(new Dimension(400, 400));
gameFrame.setContentPane(checkerBoard);
gameFrame.pack();
gameFrame.setVisible(true);
}
public static void main(String[] args) {
try {
SwingUtilities.invokeAndWait(new Application());
} catch (InvocationTargetException | InterruptedException e) {
e.printStackTrace();
}
}
}
GameFrame.java
package game.checkers;
import javax.swing.JFrame;
public class GameFrame extends JFrame {
private static final long serialVersionUID = 6797487872982059625L;
public GameFrame(String title) {
super(title);
this.setResizable(false);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
GameBoard.java
package game.checkers;
import java.awt.*;
import javax.swing.JPanel;
public class GameBoard extends JPanel {
private static final long serialVersionUID = 5777309661510989631L;
private static final Color[] DEFAULT_TILE_COLORS = new Color[] { Color.LIGHT_GRAY, Color.WHITE };
private BoardZone[][] zones;
private Color[] tileColors;
private int rows;
private int cols;
public int getRows() {
return rows;
}
public void setRows(int rows) {
this.rows = rows;
}
public int getCols() {
return cols;
}
public void setCols(int cols) {
this.cols = cols;
}
public GameBoard(int rows, int cols, Color[] tileColors) {
super();
this.rows = rows;
this.cols = cols;
this.tileColors = tileColors;
initialize();
}
public GameBoard(int rows, int cols) {
this(rows, cols, DEFAULT_TILE_COLORS);
}
protected void initialize() {
this.setLayout(new GridLayout(rows, cols, 0, 0));
generateZones();
}
private void generateZones() {
this.setLayout(new GridLayout(rows, cols, 0, 0));
this.zones = new BoardZone[rows][cols];
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
this.add(zones[row][col] = new BoardZone());
}
}
}
public void placeChecker(Checker checker, int row, int col) {
zones[row][col].add(checker);
}
public Checker getChecker(int row, int col) {
return (Checker) zones[row][col].getComponent(0);
}
public void removeChecker(Checker checker, int row, int col) {
zones[row][col].remove(checker);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
int tileWidth = this.getWidth() / cols;
int tileHeight = this.getHeight() / rows;
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
int x = col * tileWidth;
int y = row * tileHeight;
g.setColor(tileColors[(row + col) % 2]);
g.fillRect(x, y, tileWidth, tileHeight);
}
}
}
}
Checker.java
package game.checkers;
import java.awt.*;
import javax.swing.JComponent;
public class Checker extends JComponent {
private static final long serialVersionUID = -4645763661137423823L;
private int radius;
private Color color;
public int getRadius() {
return radius;
}
public void setRadius(int radius) {
this.radius = radius;
}
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
public String getHexColor() {
return String.format("#%06X", getColor() == null ? 0 : getColor().getRGB());
}
public Checker(int radius, Color color) {
super();
this.setPreferredSize(new Dimension(radius, radius));
this.radius = radius;
this.color = color;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (this.radius <= 0 || this.color == null) {
return; // Do not draw it.
}
g.setColor(this.color);
g.fillOval(0, 0, this.radius - 1, this.radius - 1);
}
}
BoardZone.java
package game.checkers;
import java.awt.BorderLayout;
import javax.swing.JPanel;
public class BoardZone extends JPanel {
private static final long serialVersionUID = 8710283269464564251L;
public BoardZone() {
this.setOpaque(false);
this.setLayout(new BorderLayout());
}
}
CheckerMouseListener.java
package game.checkers;
import java.awt.event.*;
public class CheckerMouseListener implements MouseListener {
private Checker target;
public CheckerMouseListener(Checker target) {
this.target = target;
}
private String getCheckerName() {
String hexCode = target.getHexColor();
switch (hexCode) {
case "#FFFF0000":
return "RED";
case "#FF00FF00":
return "GREEN";
case "#FF0000FF":
return "BLUE";
default:
return hexCode;
}
}
@Override
public void mouseReleased(MouseEvent e) {
System.out.println("Released click over " + getCheckerName() + " checker.");
}
@Override
public void mousePressed(MouseEvent e) {
System.out.println("Pressed on " + getCheckerName() + " checker.");
}
@Override
public void mouseExited(MouseEvent e) {
System.out.println("Finished hovering over " + getCheckerName() + " checker.");
}
@Override
public void mouseEntered(MouseEvent e) {
System.out.println("Began hovering over " + getCheckerName() + " checker.");
}
@Override
public void mouseClicked(MouseEvent e) {
System.out.println("Clicked on " + getCheckerName() + " checker.");
}
}