如何使用GridBagConstraints创建布局?

时间:2012-01-26 04:49:08

标签: java swing gridbaglayout

我想像我这样布局我的JPane:

-------
|     |
|     |
|     |
-------
|     |
-------

这样,顶部比底部更大/更高(顶部包含另一个JPanel并使用Graphics对象显示图像,而底部也包含另一个JPanel但使用Graphics对象绘制一些线条和文字。)

我听说最好的方法是使用GridBagLayout和GridBagConstraints。

我正在试图找出GridBagConstraints的相应属性,我遇到了一些困难。这就是我到目前为止......

对于顶部,我有:

gridx = 0
gridy = 0
weighty = 1.0; // expand downwards, because the bottom should never expand in the Y direction
fill = GridBagConstraints.BOTH

对于底部,我有:

gridx = 0
gridy = 1
fill = GridBagConstraints.HORIZONTAL
anchor = GridBagConstraints.PAGE_END

不幸的是,所有最终都会出现一个大的灰色矩形(我的应用程序有白色背景) - 没有图像加载,没有行/文本出现。

我该怎么办?我应该调整什么?

我已经阅读了一些教程,但它看起来真的很混乱,我在第一个应用程序中使用它,但现在当我尝试这样做时,它似乎对我不起作用。

3 个答案:

答案 0 :(得分:5)

一般来说,对于gridbag布局

  • 如果您需要组件比例,则必须为其比例方向指定权重,布局管理器将忽略您为该方向设置的任何大小(宽度/高度)。

  • 如果您不想要组件比例,则组件必须定义其大小(如果需要,您可以在java的文档中深入研究此主题)。对于底部面板,您需要至少给出一个首选高度。

这可以满足您的期望

pnlTop.setBackground(Color.WHITE);
pnlBottom.setBackground(Color.BLUE);

// Because you don't want the bottom panel scale, you need to give it a height.
// Because you want the bottom panel scale x, you can give it any width as the
// layout manager will ignore it.
pnlBottom.setPreferredSize(new Dimension(1, 20));


getContentPane().setLayout(new GridBagLayout());
GridBagConstraints cst = new GridBagConstraints();
cst.fill = GridBagConstraints.BOTH;
cst.gridx = 0;
cst.gridy = 0;
cst.weightx = 1.0; // --> You miss this for the top panel
cst.weighty = 1.0;
getContentPane().add(pnlTop, cst);

cst = new GridBagConstraints();
cst.fill = GridBagConstraints.HORIZONTAL;
cst.gridx = 0;
cst.gridy = 1;
cst.weightx = 1.0; // You miss this for the bottom panel
cst.weighty = 0.0;
getContentPane().add(pnlBottom, cst);

此外,如果你想使用gridbag布局,我建议你试试painless-gridbag库http://code.google.com/p/painless-gridbag/(我是那个库的作者)。它并没有为你解决这个问题(因为你的问题是关于在gridbag布局中管理组件的大小)但它会为你节省大量的打字并使你的代码更容易维护

pnlBottom.setPreferredSize(new Dimension(1, 20));

PainlessGridBag gbl = new PainlessGridBag(getContentPane(), false);
gbl.row().cell(pnlTop).fillXY();
gbl.row().cell(pnlBottom).fillX();
gbl.done();

答案 1 :(得分:2)

从您的问题中不确定,也许会帮助您达到70%,低于30%

import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;

public class BorderPanels extends JFrame {

    private static final long serialVersionUID = 1L;

    public BorderPanels() {
        getContentPane().setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        JPanel panel1 = new JPanel();
        Border eBorder = BorderFactory.createEtchedBorder();
        panel1.setBorder(BorderFactory.createTitledBorder(eBorder, "70pct"));
        gbc.gridx = gbc.gridy = 0;
        gbc.gridwidth = gbc.gridheight = 1;
        gbc.fill = GridBagConstraints.BOTH;
        gbc.anchor = GridBagConstraints.NORTHWEST;
        gbc.weightx = gbc.weighty = 70;
        getContentPane().add(panel1, gbc);
        JPanel panel2 = new JPanel();
        panel2.setBorder(BorderFactory.createTitledBorder(eBorder, "30pct"));
        gbc.gridy = 1;
        gbc.weightx = 30;
        gbc.weighty = 30;
        gbc.insets = new Insets(2, 2, 2, 2);
        getContentPane().add(panel2, gbc);
        pack();
    }

    public static void main(String[] args) {
        new BorderPanels().setVisible(true);
    }
}

答案 2 :(得分:0)

如果您可以使用第3方图书馆,您也可以考虑FormLayout。它允许您指定每行的高度和调整大小行为。

我没有测试过这个,但是

FormLayout layout = new FormLayout( 
 "pref", //columns
 "50dlu:grow(0.2)","25dlu:grow(0.1)" //rows
);

可能会成功。有关语法的更多信息,请参阅the JGoodies Forms pdf