gridwidth和gridheight不起作用

时间:2018-04-27 20:06:43

标签: java layout gridbaglayout

我在java中玩GridBagLayout,我编写了以下代码,但它没有像我预期的那样工作 我预计第一个按钮将被放置在框架左上角的点(0,0)中 其次,我预计第二个按钮的高度和宽度将是第一个按钮高度和宽度的两倍,但它们不是。“ 这是输出:https://ibb.co/hDZPgx
这是代码:

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

public class GUIJframe extends JFrame {

    private JButton jb1 = new JButton("first");
    private JButton jb2 = new JButton("second");
    private JButton jb3 = new JButton("third");
    private GridBagConstraints gbc = new GridBagConstraints();
    private GridBagLayout gbl = new GridBagLayout();

    public GUIJframe () {
        jcb.addItem(names);
        setLocation(150,150);
        setSize(500,500);
        setLayout(gbl);
        addComponent(jb1,0,0,1,1);
        addComponent(jb2,1,0,2,2);
        addComponent(jb3,2,2,5,5);
        setVisible(true);
    }

    public void addComponent (Component component, int gridx,int gridy, int width, int height) {
        gbc.gridx = gridx;
        gbc.gridy = gridy;
        gbc.gridwidth = width;
        gbc.gridheight = height;
        gbl.setConstraints(component,gbc);
        add (component);
    }
}

1 个答案:

答案 0 :(得分:1)

  

我预计第二个按钮的高度和宽度将是第一个按钮高度和宽度的两倍

你的期望是错误的。

GridBagLayout单元格非常灵活。一列的宽度不依赖于其他列的宽度。它只取决于子组件的宽度(以及insets和ipadx,如果设置)。

如果一个组件占用两列,但这两列中没有其他任何列,则GridBagLayout没有理由扩展任何大于所需大小的列以适应该组件的首选宽度。

高度和GridBagLayout行也是如此。

要强制一个组件的大小是另一个组件的两倍,您将需要不同的布局。 SpringLayout可以做到,虽然它不容易使用。您可能会发现在“较小”组件上简单地add a ComponentListener更容易,并使用该组件的新大小作为“较大”组件preferred size的基础。

为了达到理想的效果,我会使用SpringLayout。

SpringLayout允许您创建名为Spring的约束,它们表示组件边缘,宽度和高度的大小调整范围。这些可能取决于其他组件的大小范围或容器的边缘。

SpringLayout layout = new SpringLayout();
setLayout(layout);

SpringLayout.Constraints jb1Constraints =
    new SpringLayout.Constraints(jb1);

SpringLayout.Constraints jb2Constraints =
    new SpringLayout.Constraints(
        Spring.sum(jb1Constraints.getX(), jb1Constraints.getWidth()),
        jb1Constraints.getY(),
        Spring.scale(jb1Constraints.getWidth(), 2),
        Spring.scale(jb1Constraints.getHeight(), 2));

SpringLayout.Constraints jb3Constraints =
    new SpringLayout.Constraints(
        Spring.sum(jb2Constraints.getX(),
                   Spring.scale(jb2Constraints.getWidth(), 0.5f)),
        Spring.sum(jb2Constraints.getY(), jb2Constraints.getHeight()),
        Spring.scale(jb1Constraints.getWidth(), 5),
        Spring.scale(jb1Constraints.getHeight(), 5));

add(jb1, jb1Constraints);
add(jb2, jb2Constraints);
add(jb3, jb3Constraints);

// Make container big enough to hold all components.

layout.putConstraint(
    SpringLayout.EAST, getContentPane(), 0,
    SpringLayout.EAST, jb3);

layout.putConstraint(
    SpringLayout.SOUTH, getContentPane(), 0,
    SpringLayout.SOUTH, jb3);

jb1的约束是最简单的:尊重该组件的最小尺寸,首选尺寸和最大尺寸。位置是(0,0)。

jb2的约束取决于jb1

的约束
  • jb2的x坐标的弹簧是jb1.x + jb1.width,它实际上是jb1的右边缘。
  • jb2与jb1具有相同的y(实际上是零)。
  • 宽度和高度是jb1的宽度和高度,按2缩放。

jb3的约束取决于jb2和jb1:

  • x坐标为jb2.x +(jb2.width÷2),即jb2的水平中心点。
  • y坐标是jb2.y + jb2.height,实际上是jb2的下边缘。
  • 宽度和高度是jb1的宽度和高度,按5缩放。

最后,SpringLayout与其他布局管理器的不同之处在于,它不会自动设置容器的大小,使其足够大以容纳所有子组件。我们必须自己做这项工作,使用SpringLayout.putConstraint将容器的右边缘(EAST)连接到jb3的右边缘,将容器的底边缘(SOUTH)连接到jb3的底边缘。