我在JPanel
中有一个简单的国际象棋棋盘,GridLayout(8,8)
为布局管理员。
我正在尝试为字段的列名和行号添加面板。
现在我已经创建了另一个以BorderLayout
为布局管理器的面板,在此面板中,我在BorderLayout.CENTER
中添加了该面板。在董事会旁边,我在GridLayout(0,8)
中添加了BorderLayout.SOUTH
的面板,在GridLayout(8,0)
中添加了一个BorderLayout.WEST
的面板。行号完全放在电路板旁边,因为左侧JPanel中的行数与电路板中的行数相匹配,但列名称(A,B,C,D,E,F,G,H)在由于BorderLayout.WEST
中的JPanel,因此未正确放置棋盘下的JPanel。
如何制作带侧板的合适棋盘以显示字段编号/名称?
我尝试将南面板的布局设置为GridLayout(0,9)
并将第一个字段设置为空,但左面板的宽度不等于电路板中的每个字段,因此这不是一个好的解决方法
答案 0 :(得分:19)
此处显示的GUI已得到改进并移至Making a robust, resizable Swing Chess 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);
}
}
GridLayout
提供。网格布局的第一个单元格是没有文本的标签。ActionListener
,它将响应键盘和鼠标事件。?
意味着该区域“保留供将来使用”。我们可能会用它来显示被捕获的棋子的列表,在推广棋子时选择棋子的选择器,游戏统计数据,......