JFrame
uses BorderLayout
默认情况下,这意味着默认只管理一张图像/CENTER
位置。
See 如何使用边框 http://docs.oracle.com/javase/tutorial/uiswing/components/border.html更多细节。
该解决方案实际上很困难,因为您需要能够对布局、图像和电路板的尺寸做出保证
您也许可以使用GridLayout
or GridBagLayout
,但是您需要有“空”填充组件才能使布局正确扩展,这可能会很麻烦
也许更好的解决方案是使用自定义绘画方法,它可以让您控制图像的放置位置。
在 AWT 和 Swing 中绘画 http://www.oracle.com/technetwork/java/painting-140037.html and 进行定制绘画 http://docs.oracle.com/javase/tutorial/uiswing/painting/更多细节
下面的例子简单地利用了GridBagLayout
,它允许您覆盖组件(以各种不同的方式)。这个例子使得boardLabel
所有其他部分的容器,但是,因为这样GridBagLayout
有效,这不是绝对要求
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Chess {
public static void main(String[] args) {
new Chess();
}
public Chess() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
}
public class TestPane extends JPanel {
public TestPane() throws IOException {
BufferedImage board = ImageIO.read(getClass().getResource("/board.png"));
BufferedImage knight = ImageIO.read(getClass().getResource("/Knight.png"));
setLayout(new BorderLayout());
JLabel boardLabel = new JLabel(new ImageIcon(board));
add(boardLabel);
boardLabel.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
for (int row = 0; row < 8; row++) {
gbc.gridy = row;
for (int col = 0; col < 8; col++) {
gbc.gridx = col;
boardLabel.add(filler(), gbc);
}
}
JLabel knightLabel = new JLabel(new ImageIcon(knight));
gbc.gridx = 3;
gbc.gridy = 4;
boardLabel.add(knightLabel, gbc);
}
protected JComponent filler() {
JLabel filler = new JLabel() {
@Override
public Dimension getPreferredSize() {
return new Dimension(50, 50);
}
};
return filler;
}
}
}
通过这样的设置,您可以简单地使用GridBagConstraint
's gridx
and gridy
值作为直接单元地址(无需计算像素位置)。
由于布局管理器的工作方式,您还需要提供一个空单元格组件