GridBagLayout 组件大小取决于 JFrame 大小

GridBagLayout component size is dependent on JFrame size

提问人:B3NII 提问时间:10/22/2023 更新时间:10/22/2023 访问量:18

问:

我有以下程序(我的实际程序的简化版本):

我的面板 .java:

public class MyPanel extends JPanel{
    
    private JLayeredPane layeredPane;

    public MyPanel(int width, int height){
        Dimension dimension = new Dimension(width, height);

        layeredPane = new JLayeredPane();
        layeredPane.setPreferredSize(dimension);
        layeredPane.setBounds(0, 0, width, height);

        setPreferredSize(dimension);
        setBounds(0, 0, width, height);
        setBorder(BorderFactory.createLineBorder(Color.red));
    }
}

主 .java:

public class Main{

    private static int WIDTH = 500;
    private static int HEIGHT = 300;

    private static JFrame frame;

    public static void main(String[] args){
        initFrame();
        addPanels();
        frame.setVisible(true);
    }

    private static void initFrame(){
        frame = new JFrame();
        frame.setPreferredSize(new Dimension(WIDTH, HEIGHT));
        frame.setBounds(0, 0, WIDTH, HEIGHT);
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.setLayout(new GridBagLayout());
    }

    private static void addPanels(){
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.fill = GridBagConstraints.BOTH;

        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.gridheight = 2;
        MyPanel panel1 = new MyPanel(200, 300);
        frame.add(panel1, gbc);

        gbc.gridx = 1;
        gbc.gridy = 0;
        gbc.gridheight = 1;
        MyPanel panel2 = new MyPanel(300, 200);
        frame.add(panel2, gbc);

        gbc.gridx = 1;
        gbc.gridy = 1;
        gbc.gridheight = 1;
        MyPanel panel3 = new MyPanel(300, 100);
        frame.add(panel3, gbc);
    }
}

期望:

我想创建一个 500x300 大小的 JFrame,其中包含 GridBagLayout。我想将此布局分为 2 列,进一步将右列水平分为 2 个部分。我的目标是借助设置添加到布局中的 MyPanel 组件的 preferredSize-s 来精确设置单元格大小。

这整个想法基于 GridBagLayout 的 Oracle 文档:

实质上,GridBagLayout 将组件放置在网格中的矩形(单元格)中,然后使用组件的首选大小来确定单元格的大小。

来源: https://docs.oracle.com/javase/tutorial/uiswing/layout/gridbag.html


问题:

GridBagLayout 似乎为自己添加了“外边距”,我无法以某种方式将手动调整大小的组件放入 JFrame 中......缩小它。运行上面的代码会产生如下结果:enter image description here

该图显示了以给定大小呈现的 500x300 JFrame,但组件与手动设置的大小不匹配。

但是,如果我将 and 值增加到以下值:WIDTHHEIGHT

private static int WIDTH = 1000;
private static int HEIGHT = 600;

我得到这个结果:enter image description here

这一次,所有 MyPanel 组件都以给定的大小呈现,但 JFrame 太大了。我希望组件以给定的大小填充整个 JFrame。


问题:

是什么原因导致的?如何在不遇到此问题的情况下手动设置组件的大小?

笔记:

我知道这些变量,但我的目标是防止布局管理器设置组件的大小,使这些选项看起来并不理想。GridBagConstraints.weightx/y

非常感谢每一个帮助!

Java Swing 用户界面 大小 GridBagLayout

评论

1赞 Gilbert Le Blanc 10/22/2023
您对 Swing GUI 的概念是落后的。您可以确定各个 Swing 组件的大小,并使用 Swing 布局管理器来调整结果 和 的大小。你不应该关心(在合理范围内)最终的大小是多少。它有标题栏和侧边距等装饰,你没有考虑到。JPanelsJFrameJFrameJFrame
0赞 B3NII 10/22/2023
你是对的,我完全误解了布局管理器的用途。我设法通过删除 JFrame 上的 setPreferredSize 和 setBounds 方法调用来解决这个问题,它就像一个魅力。谢谢!

答:

1赞 B3NII 10/22/2023 #1

感谢 @Gilbert Le Blanc 的有用评论,我能够修复我的代码。

删除

frame.setPreferredSize(new Dimension(WIDTH, HEIGHT));
frame.setBounds(0, 0, WIDTH, HEIGHT);

来自 Main.java 的行和方法末尾的调用解决了这个问题。frame.pack();main

这个问题是由我对布局管理器的误解引起的。您不需要设置 的确切大小,只需在 GridBagLayout 中设置我的组件。GridBagLayout 管理器将处理其余部分,并根据其中的组件设置我的帧大小。JFrame