【问题标题】:gridwidth and gridheight aren't working网格宽度和网格高度不起作用
【发布时间】:2018-10-08 17:21:21
【问题描述】:

我正在使用 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);
    }
}

【问题讨论】:

    标签: java layout gridbaglayout


    【解决方案1】:

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

    你的期望是错误的。

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

    如果一个组件占据了两列,但其中任何一列都没有其他内容,则 GridBagLayout 没有理由将列扩展得比适应该组件的首选宽度所需的更大。

    高度和 GridBagLayout 行也是如此。

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

    为了达到你想要的结果,我会使用 SpringLayout。

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

    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 坐标的 Spring 为 jb1.x + jb1.width,实际上是 jb1 的右边缘。
    • jb2 的 y 与 jb1 相同(实际上为零)。
    • 宽度和高度是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 的底部边缘。

    【讨论】:

    • 让我澄清一下,我没有直接尝试让一个单元格的大小是另一个单元格的两倍,第一个按钮的宽度和高度都是 1,第二个按钮的宽度和高度都选择了 2,作为结果我预计在输出中,第二个按钮的高度和宽度将是第一个按钮大小的两倍,但它们不是那样的。
    • 我满足了这一期望。单元格的宽度或高度不同。第一列可以是100像素宽,第二列可以是30像素宽,第三列可以是零像素宽。这完全取决于布局中的组件。
    • 那么我该怎么做才能达到我的预期效果?我还希望第一个按钮出现在框架的左上角点 (0,0)。
    • 添加了 SpringLayout 示例。
    猜你喜欢
    • 2021-06-07
    • 1970-01-01
    • 1970-01-01
    • 2019-09-23
    • 1970-01-01
    • 2013-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多