【问题标题】:How to center JPanel with dynamic size如何以动态大小居中 JPanel
【发布时间】:2012-11-22 20:20:05
【问题描述】:

我需要显示棋盘。我有一个扩展 JPanel 的 BoardPanel 类和一个包含 BoardPanel 的 GamePanel(也扩展 JPanel)类。 GamePanel 填充所有应用程序框架。

我希望 BoardPanel 始终是一个正方形,其大小等于 GamePanel 的宽度和高度的最小值(如果 GamePanel 的宽度大于高度,则左侧和右侧应该有空白区域,如果较小,则应该有空白区域顶部和底部)。 BoardPanel 应该显示在父面板的中心也很重要。

我是这样写的:

public GamePanel() {
    setLayout(new BorderLayout(0, 0));
    boardPanel = new BoardPanel(...);
    this.add(boardPanel, BorderLayout.CENTER);
    ...
}

在 BoardPanel 中:

public void paintComponent(Graphics g) {
    super.paintComponent(g);
    int size = Math.min(this.getParent().getHeight(), this.getParent().getWidth());
    this.setSize(size, size);
    ...
}

它调整大小很好,但棋盘总是显示在GamePanel的左上角(所有空白区域都显示在bot或右边),我不知道如何修复它。

有什么帮助吗?提前致谢!

【问题讨论】:

    标签: java swing layout resize jpanel


    【解决方案1】:

    使用 GridBagLayout 将其居中。

    import java.awt.*;
    import javax.swing.*;
    
    public class CenteredPanel {
    
        public static void main(String[] args) {
            Runnable r = new Runnable() {
                @Override
                public void run() {
                    JPanel gui = new JPanel(new GridBagLayout());
                    JPanel square = new SquarePanel();
                    square.setBackground(Color.RED);
                    gui.add(square);
    
                    JFrame f = new JFrame("SquareBoard");
                    f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                    f.setLocationByPlatform(true);
                    f.add(gui);
                    f.setMinimumSize(new Dimension(400,100));
                    f.pack();
                    f.setVisible(true);
                }
            };
            SwingUtilities.invokeLater(r);
        }
    }
    
    class SquarePanel extends JPanel {
        @Override
        public Dimension getPreferredSize() {
            Container c = this.getParent();
            int size = Math.min(c.getHeight(), c.getWidth());
            Dimension d = new Dimension(size,size);
            return d;
        }
    }
    

    【讨论】:

    • @DavidKroukamp 关于首选尺寸的非常好的建议。当我注意到你在 55 分钟前说过的话时,我正要说同样的话。 :)
    • 谢谢。很有帮助的答案。
    【解决方案2】:
    • 不需要new BorderLayout(0,0),只需使用BorderLayout的默认构造函数

    • 不要调用setSize(),而是像这样覆盖getPreferredSize()JPanel

      @Override
      public void getPreferredSize() {
      
              int size = Math.min(this.getParent().getHeight(), this.getParent().getWidth());
      
             return new Dimension(size,size);
      }
      
    • 在您的paintComponent 中工作也不是一件好事,因为这应该仅用于绘画。

    如果上述方法不起作用,我建议您使用SSCCE 来说明您可能遇到的具体问题

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-06
      • 1970-01-01
      • 2012-07-20
      • 1970-01-01
      • 2013-08-22
      相关资源
      最近更新 更多