我正在使用 Swing 下棋。
对于板(JPanel)我正在使用
new GridLayout(8, 8)
然后我添加64个方块(JPanel)。
在每个 Square 中,我都有一个 JLabel 用于代数符号(A8、A7...),这个标签的位置很好。
问题来自另一个包含图片的 JLabel,这个不是垂直居中的,我怎样才能将这个 JLabel 居中在正方形中?。
这是 Square 的代码:
package org.victorpiles.escacs.client.gui;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
/**
* @author Víctor Piles
*/
public class Square extends JPanel {
private static final String PIECE_ICON_PATH = "client/src/main/resources/pieces/";
private static final Color LIGHT_COLOR = new Color(118, 150, 86, 255);
private static final Color DARK_COLOR = new Color(238, 238, 210, 255);
private final int position;
public Square(int position) {
super(new BorderLayout());
setAlgebraicNotationLabel(position);
this.position = position;
setBackground(getSquareColor(position));
}
private void setAlgebraicNotationLabel(int position) {
JLabel squarePosition = new JLabel(getAlgebraicNotation(position));
squarePosition.setBorder(new EmptyBorder(5, 5, 5, 5));
add(squarePosition, BorderLayout.PAGE_END);
}
/**
* Calcula el color adequat per a la casella, basant-se en la seua posició.
*
* @param position La posició de la casella.
*
* @return El color de la casella: {@link #LIGHT_COLOR clar} o {@link #DARK_COLOR fosc}.
*/
private Color getSquareColor(int position) {
int row = position / 8;
int column = position % 8;
return (row + column) % 2 != 0 ? LIGHT_COLOR : DARK_COLOR;
}
/**
* Calcula la notació algebraica per a la casella, basant-se en la seua posició.
*
* @param position La posició de la casella.
*
* @return La notació algebraica per a la casella.
*/
private String getAlgebraicNotation(int position) {
int row = 8 - (position / 8);
char column = (char) ('a' + (position % 8));
return ("" + column + row).toUpperCase();
}
public void updatePiece(char piece) {
removeAll();
BufferedImage pieceImage;
if (piece == '-') {
return;
}
String fileName = PIECE_ICON_PATH + piece + ".png";
try {
pieceImage = ImageIO.read(new File(fileName));
System.out.println(position + " -> " + pieceImage.getHeight());
} catch (IOException e) {
// TODO: 20/3/23 Manejar excepció
throw new RuntimeException(e);
}
/* Actualitza la casella */
setAlgebraicNotationLabel(position);
add(new JLabel(new ImageIcon(pieceImage)));
validate();
}
}
图像没有垂直居中,因为其他 JLabel 占据了空间的一部分
这就是布局管理器的工作方式。组件在 2D 空间中分配位置。所以如果图像是 60 X 60,那么符号标签将显示在图像下方,而不是图像上方。
如果想要在图片标签上显示批注标签,那么需要在图片标签中添加批注标签。
您需要将图像标签定义为类中的实例变量。在你的构造函数中你会做这样的事情:
imageLabel = new ImageLabel();
imageLabel.setLayout( new BorderLayout() );
add( imageLabel );
setAlgebraicNotationLabel(position);
...
在
setAlgebraicNotationLabel(...)
方法中,您将使用:
//add(squarePosition, BorderLayout.PAGE_END);
imageLabel.add(squarePosition, BorderLayout.PAGE_END);
将符号标签添加到图像标签,而不是面板
您的
updatePiece(...)
方法也需要更改为使用setIcon(...)
方法来更新图像标签的Icon
,而不是每次都创建一个新标签。
我是这样做的:
我在图像标签的 PAGE_END 添加符号标签,为此图像标签布局为
setLayout(new BorderLayout());
private JLabel getAlgebraicNotationLabel(int position) {
JLabel notationLabel = new JLabel(getAlgebraicNotation(position));
notationLabel.setBorder(new EmptyBorder(0, 5, 5, 0));
return notationLabel;
}
public void updatePiece(char piece) {
removeAll();
BufferedImage pieceImage;
if (piece == '-') {
return;
}
String fileName = PIECE_ICON_PATH + piece + ".png";
try {
pieceImage = ImageIO.read(new File(fileName));
} catch (IOException e) {
// TODO: 20/3/23 Manejar excepció
throw new RuntimeException(e);
}
/* Actualitza la casella */
JLabel squareLabel = new JLabel(new ImageIcon(pieceImage));
squareLabel.setLayout(new BorderLayout());
squareLabel.add(getAlgebraicNotationLabel(position),BorderLayout.PAGE_END);
add(squareLabel);
validate();
}
最终结果: