GridBagLayout中的JPanel不保持比例(weightx)

时间:2015-11-19 11:29:52

标签: java swing layout-manager gridbaglayout

我有以下情况。我用GridBagLayout创建了一个JPanel,其比例如下。我想直截了当,之后我会添加更多组件。现在我有类似

的东西
------------------------------------
|LABEL 45%  | LABEL 10% | LABEL 45%|
------------------------------------

每个标签水平和垂直占用1个单元格(gridwidth / height = 1)

重量(x)为0.45,0.1和0.45(从左到右)

权重(y)为0.0

所有标签都填写GBC.HORIZONTAL,锚点为WEST,WEST,EAST。

JPanel topPanel = new JPanel(new GridBagLayout());

    topPanel.add(new JLabel("1"), new GridBagConstraints(
        0, 0, 1, 1, 0.45, 0.0, GridBagConstraints.WEST,
        GridBagConstraints.HORIZONTAL, INSETS_0PX, 0, 0));
    topPanel.add(new JLabel("2"), new GridBagConstraints(
        1, 0, 1, 1, 0.1, 0.0, GridBagConstraints.WEST,
        GridBagConstraints.BOTH, INSETS_0PX, 0, 0));
    topPanel.add(new JLabel("3"), new GridBagConstraints(
        2, 0, 1, 1, 0.45, 0.0, GridBagConstraints.EAST,
        GridBagConstraints.HORIZONTAL, INSETS_0PX, 0, 0));

此时一切正常,第一个标签与正确的标签获得完全相同的空间(可用宽度的45%,另一个获得10%)。完美。

但是当我尝试添加一个标签(左/右),另一个带有GridBagLayout的JPanel时,比例不会按照定义来保存。

在左边我想添加一个JPanel,定义如下

----------------------
|JLabel..............|
|--------------------|
|JTextArea...........|
|....................|
----------------------

JLabel的权重为0.0(对于x / y),WEST锚点和填充NONE

JTextArea - 权重1.0(x),1.0,WEST锚点,填充BOTH(为了延伸)

myPanel = new JPanel(new GridBagLayout());
myPanel.add(new JLabel("TITLE", new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
        GridBagConstraints.WEST, GridBagConstraints.NONE, INSETS_0PX, 0, 0));
myPanel.add(new JTextArea(5,25), new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0,
        GridBagConstraints.WEST, GridBagConstraints.BOTH, INSETS_0PX, 0, 0));

在右边,我想添加一个带有GridBagLayout的JPanel,它包含另外两个带有GridBagLaouts的JPanel(现在没有必要描述如何定义)。

- >因此,在我添加左侧面板而不是标签时,它会占据屏幕的大约60%(这是不对的,它应该达到45%)。

你能发现什么是错的吗?我没有想法

LE:这是一个简单的例子

public class Example extends JFrame {

public Example() {
    init();
}

private JPanel createPanel(Component comp) {
    JPanel topPanel = new JPanel(new GridBagLayout());

    topPanel.add(comp, new GridBagConstraints(
        0, 0, 1, 1, 0.45, 0.0, GridBagConstraints.WEST,
        GridBagConstraints.HORIZONTAL, new Insets(0,0,0,0), 0, 0));
    topPanel.add(new JLabel("2"), new GridBagConstraints(
        1, 0, 1, 1, 0.1, 0.0, GridBagConstraints.WEST,
        GridBagConstraints.BOTH, new Insets(0,0,0,0), 0, 0));
    topPanel.add(new JLabel("3"), new GridBagConstraints(
        2, 0, 1, 1, 0.45, 0.0, GridBagConstraints.EAST,
        GridBagConstraints.HORIZONTAL, new Insets(0,0,0,0), 0, 0));

    return topPanel;
}

private JPanel getPanelWithLabel() {
    return createPanel(new JLabel("1"));
}

private JPanel getPanelWithPanel() {
    JPanel myPanel = new JPanel(new GridBagLayout());
    myPanel.add(new JLabel("TITLE"), new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
            GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,0,0,0), 0, 0));
    myPanel.add(new JTextArea(5,25), new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0,
            GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(0,0,0,0), 0, 0));
    return createPanel(myPanel);
}

private void init() {
    setTitle("Simple example");
    setSize(800, 200);
    setLocationRelativeTo(null);
    setDefaultCloseOperation(EXIT_ON_CLOSE);

    JPanel panel = new JPanel(new BorderLayout());
    panel.add(getPanelWithLabel(), BorderLayout.CENTER);
//panel.add(getPanelWithPanel(), BorderLayout.CENTER);

    add(panel);
    setVisible(true);
}

public static void main(String[] args) {

    EventQueue.invokeLater(new Runnable() {

        @Override
        public void run() {
            Example ex = new Example();
        }
    });

}
}

3 个答案:

答案 0 :(得分:1)

问题在于JTextArea

的行

25行宽于 45%时,它会消耗殆尽。

我没有使用25,而是使用容器的WIDTHmyPanel

解决方案

myPanel.add(new JTextArea(5,myPanel.WIDTH), new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0,
                GridBagConstraints.WEST, GridBagConstraints.BOTH, INSETS_0PX, 0, 0));

输出

enter image description here

修改

由于这种方法的尺寸仍然不同。我尝试先创建一个JPanel并将JLabel添加到其中。

解决方案

JPanel threeCont = new JPanel(new GridBagLayout());
threeCont.add(new JLabel("3"), new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
        GridBagConstraints.WEST, GridBagConstraints.NONE, INSETS_0PX, 0, 0));
// We add myPanel and two(JLabel) to topPanel first and than the below.
topPanel.add(threeCont, new GridBagConstraints(
    2, 0, 1, 1, 0.45, 0.0, GridBagConstraints.EAST,
    GridBagConstraints.HORIZONTAL, INSETS_0PX, 0, 0));

输出

System.out.println("First Panel's Size : " + myPanel.getSize());
System.out.println("Second Panel's Size : " +two.getSize());
System.out.println("Third Panel's Size : " +threeCont.getSize());

控制台

First Panel's Size : java.awt.Dimension[width=441,height=96]
Second Panel's Size : java.awt.Dimension[width=98,height=96]
Third Panel's Size : java.awt.Dimension[width=441,height=16]

完整代码

public static void main(String[]a) {
    JFrame fr = new JFrame();
    fr.setSize(new Dimension(1000,1000));
    fr.setLocationRelativeTo(null);
    JPanel topPanel = new JPanel(new GridBagLayout());
    Insets INSETS_0PX = new Insets(0,0,0,0);
    JLabel one = new JLabel("1");
    JLabel two = new JLabel("2");
    one.setBackground(Color.yellow);
    two.setBackground(Color.blue);

    JPanel myPanel = new JPanel(new GridBagLayout());
    myPanel.add(new JLabel("TITLE"), new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
            GridBagConstraints.WEST, GridBagConstraints.NONE, INSETS_0PX, 0, 0));
    myPanel.add(new JTextArea(5,myPanel.WIDTH), new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0,
            GridBagConstraints.WEST, GridBagConstraints.BOTH, INSETS_0PX, 0, 0));

    JPanel threeCont = new JPanel(new GridBagLayout());
    threeCont.add(new JLabel("TITLE"), new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
            GridBagConstraints.WEST, GridBagConstraints.NONE, INSETS_0PX, 0, 0));

    topPanel.add(myPanel, new GridBagConstraints(
        0, 0, 1, 1, 0.45, 0.0, GridBagConstraints.WEST,
        GridBagConstraints.HORIZONTAL, INSETS_0PX, 0, 0));

    topPanel.add(two, new GridBagConstraints(
        1, 0, 1, 1, 0.1, 0.0, GridBagConstraints.WEST,
        GridBagConstraints.BOTH, INSETS_0PX, 0, 0));

    topPanel.add(threeCont, new GridBagConstraints(
        2, 0, 1, 1, 0.45, 0.0, GridBagConstraints.EAST,
        GridBagConstraints.HORIZONTAL, INSETS_0PX, 0, 0));


    fr.add(topPanel);

    fr.setVisible(true);

    System.out.println("First Panel's Size : " + myPanel.getSize());
    System.out.println("Second Panel's Size : " +two.getSize());
    System.out.println("Third Panel's Size : " +threeCont.getSize());
}

答案 1 :(得分:0)

我认为你应该将文本区域添加到滚动窗格中 - 例如新的JScrollPane(新的JTextArea(5,25))而不是新的JTextArea(5,25)...如果你是添加文本区域没有滚动窗格,网格包布局将尝试将单元格拉伸到由文本区域构造函数中的行设置的宽度,而不是将权重设置为给定单元格到网格包结构中。

答案 2 :(得分:0)

weightX约束适用于可用的额外空间。

因此为每个组件分配了它的优先级。然后,如果窗口中有额外的空间,则按指定的百分比分配空间。

因此,如果您的组件的首选大小为:

45,10,45

你将面板的宽度增加100,你会得到:

90,20,90。

但如果你从首选尺寸开始:

150,20,100

并将面板的宽度增加100,您将得到:

195,30,145

因此,如果您始终希望应用该比率,则每个组件的首选大小也必须符合您的要求。

选项可能是使用Relative Layout。它将忽略首选大小,并根据每个组件的相对约束分配大小。