Я не вижу ничего плохого в использовании JPanels. Вот моя реализация:
Сначала ChessSquare, это одна ячейка на доске:
public class ChessSquare extends JPanel{
int x,y;
public ChessSquare(int x, int y){
super();
this.setPreferredSize(new Dimension(50,50));
this.setBorder(BorderFactory.createLineBorder(Color.black));
this.x = x;
this.y = y;
}
}
Теперь панель основной платы:
public class ChessPanel extends JPanel{
JPanel positions[][] = new JPanel[8][8];
ChessSquare move[] = new ChessSquare[2];
public ChessPanel(){
initComponents();
}
private void initComponents(){
setLayout(new GridLayout(8,8));
for(int i=0;i<positions.length;i++){
for(int j=0;j<positions[i].length;j++){
ChessSquare square = new ChessSquare(i,j);
square.addMouseListener(new MouseListener(){
public void mouseClicked(MouseEvent me) {
ChessSquare cs = (ChessSquare)me.getComponent();
if(isValidMove(cs)){
System.out.println("Valid move!");
System.out.println("x1: "+move[0].x+" y1: "+move[0].y);
System.out.println("x2: "+move[1].x+" y2: "+move[1].y);
System.out.println("");
resetMove();
}
}
//Other mouse events
});
positions[i][j] = square;
add(square);
}
}
}
private boolean isValidMove(ChessSquare square){
//here you would check if the move is valid.
if(move[0] == null){
move[0] = square;
return false; //first click
}else{
move[1] = square;
}
//Other chess rules go here...
return true;
}
private void resetMove(){
move = new ChessSquare[2];
}
}
Мы сохраняем матрицу JPanel для представления доски и массив ChessSquare для представления текущего хода. В isValidMove()
мы проверяем, завершен ли текущий ход (оба квадрата были нажаты, таким образом, массив перемещения уже имеет один элемент) Когда ход завершен, мы сбрасываем ход и начинаем снова.