我正在构建一个用于战术的小棋盘,这将是反射(reflection)兴趣(编程和国际象棋)的一种有趣的方式。
我目前面临的一个问题(虽然已解决)是保持板的纵横比为 1:1。
Board
扩展了 JPanel
。由于限制问题,我选择保持电路板的物理尺寸而不是渲染尺寸。这将导致实际使用时操作速度更快。
我希望它看起来像什么,并且已经实现:
我实现这一目标的方式看起来很黑客,并且按照 Skeet 标准来说是很糟糕的代码(谢谢基于 Skeet 的人)。
public Frame() {
final JFrame frame = new JFrame("Chess");
final JPanel content = new JPanel(new BorderLayout());
final JPanel boardConfine = new JPanel(new BorderLayout());
final Board board = new Board();
boardConfine.addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
int min = Math.min(boardConfine.getWidth(), boardConfine.getHeight());
int xBuffer = (boardConfine.getWidth() - min) / 2;
int yBuffer = (boardConfine.getHeight() - min) / 2;
board.setBounds(xBuffer, yBuffer, min, min);
}
});
boardConfine.add(board, BorderLayout.CENTER);
content.setBackground(new Color(205, 205, 205));
content.add(boardConfine, BorderLayout.CENTER);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setContentPane(content);
frame.pack();
frame.setVisible(true);
}
如上所示,我手动设置了板的大小和位置。即使我已经详尽地声明不应该这样做,但我找不到可行的解决方案。我需要电路板填充尽可能大的区域,同时保持纵横比。
如果您可以提供任何建议(代码或概念),我真的感谢您花时间帮助我解决这个精英难题。
最佳答案
虽然不是完整的解决方案,但下面的示例缩放了板以填充封闭容器的最小尺寸。调整框架大小以查看效果。
附录:理想的解决方案是 Creating a Custom Layout Manager ,您可以在其中访问封闭容器的几何形状,并且 setBounds()
可以保持所需的 1:1 纵横比。 GridLayout 的变体可能是合适的。可以直接计算网格坐标,如图here .
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
* @see https://stackoverflow.com/a/19531648/230513
*/
public class Test {
private static class MyPanel extends JPanel {
private static final int N = 8;
private static final int TILE = 48;
@Override
public Dimension getPreferredSize() {
return new Dimension(N * TILE, N * TILE);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.gray);
int w = this.getWidth();
int h = this.getHeight();
int tile = Math.min(w, h) / N;
for (int row = 0; row < N; row++) {
for (int col = 0; col < N; col++) {
if ((row + col) % 2 == 0) {
g.fillRect(col * tile, row * tile, tile, tile);
}
}
}
}
}
private void display() {
JFrame f = new JFrame("Test");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new MyPanel());
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new Test().display();
}
});
}
}
关于java - 通过以缓冲区居中来保持组件尺寸,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19528766/