注意
此处看到的 GUI 已得到改进,并已移至制作健壮、可调整大小的摆动象棋 GUI。
我将把动画GIF留在这里(因为它很可爱)和原始的,剥离的代码(只有125行代码,在另一个线程上看到的最终代码是218 LOC)。
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.border.*;
public class ChessBoardWithColumnsAndRows {
private final JPanel gui = new JPanel(new BorderLayout(3, 3));
private JButton[][] chessBoardSquares = new JButton[8][8];
private JPanel chessBoard;
private final JLabel message = new JLabel(
"Chess Champ is ready to play!");
private static final String COLS = "ABCDEFGH";
ChessBoardWithColumnsAndRows() {
initializeGui();
}
public final void initializeGui() {
// set up the main GUI
gui.setBorder(new EmptyBorder(5, 5, 5, 5));
JToolBar tools = new JToolBar();
tools.setFloatable(false);
gui.add(tools, BorderLayout.PAGE_START);
tools.add(new JButton("New")); // TODO - add functionality!
tools.add(new JButton("Save")); // TODO - add functionality!
tools.add(new JButton("Restore")); // TODO - add functionality!
tools.addSeparator();
tools.add(new JButton("Resign")); // TODO - add functionality!
tools.addSeparator();
tools.add(message);
gui.add(new JLabel("?"), BorderLayout.LINE_START);
chessBoard = new JPanel(new GridLayout(0, 9));
chessBoard.setBorder(new LineBorder(Color.BLACK));
gui.add(chessBoard);
// create the chess board squares
Insets buttonMargin = new Insets(0,0,0,0);
for (int ii = 0; ii < chessBoardSquares.length; ii++) {
for (int jj = 0; jj < chessBoardSquares[ii].length; jj++) {
JButton b = new JButton();
b.setMargin(buttonMargin);
// our chess pieces are 64x64 px in size, so we'll
// 'fill this in' using a transparent icon..
ImageIcon icon = new ImageIcon(
new BufferedImage(64, 64, BufferedImage.TYPE_INT_ARGB));
b.setIcon(icon);
if ((jj % 2 == 1 && ii % 2 == 1)
//) {
|| (jj % 2 == 0 && ii % 2 == 0)) {
b.setBackground(Color.WHITE);
} else {
b.setBackground(Color.BLACK);
}
chessBoardSquares[jj][ii] = b;
}
}
//fill the chess board
chessBoard.add(new JLabel(""));
// fill the top row
for (int ii = 0; ii < 8; ii++) {
chessBoard.add(
new JLabel(COLS.substring(ii, ii + 1),
SwingConstants.CENTER));
}
// fill the black non-pawn piece row
for (int ii = 0; ii < 8; ii++) {
for (int jj = 0; jj < 8; jj++) {
switch (jj) {
case 0:
chessBoard.add(new JLabel("" + (ii + 1),
SwingConstants.CENTER));
default:
chessBoard.add(chessBoardSquares[jj][ii]);
}
}
}
}
public final JComponent getChessBoard() {
return chessBoard;
}
public final JComponent getGui() {
return gui;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
@Override
public void run() {
ChessBoardWithColumnsAndRows cb =
new ChessBoardWithColumnsAndRows();
JFrame f = new JFrame("ChessChamp");
f.add(cb.getGui());
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
// ensures the frame is the minimum size it needs to be
// in order display the components within it
f.pack();
// ensures the minimum size is enforced.
f.setMinimumSize(f.getSize());
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}
笔记
- 棋盘左侧有列,上方有一行 由9x9提供 。网格布局的第一个单元格是没有文本的标签。
GridLayout
- 为了简化游戏逻辑,我们维护了一个单独的8x8按钮数组。
- 为了允许键盘功能,我们使用棋盘位置的按钮。这也提供了内置的焦点指示。删除按钮的边距以允许它们缩小到图标的大小。将 添加到按钮,它将同时响应键盘和鼠标事件。
ActionListener
- GUI左侧的小号意味着该区域是“保留供将来使用”的。我们可以用它来显示捕获的棋子列表,在推广棋子时选择棋子的选择器,游戏统计信息,...
?
- 棋子图像是从代码和标记问答的示例图像中获得的,而示例图像又是由标签中的“填充”Unicode字符开发的。
使用图像更简单,而填充Unicode字符更通用,并且“更轻”。也就是说,要支持3种不同尺寸的3种不同棋子样式的4种不同颜色,则需要36个单独的精灵表!