Java 理解网格布局约束

Java 理解网格布局约束,java,swing,layout-manager,gridbaglayout,Java,Swing,Layout Manager,Gridbaglayout,我对swing比较陌生,我正试图弄清楚它到底是如何工作的。如果我错了,请告诉我 我已经大致了解了放置组件所需的gridx和gridy。您需要至少n个值(gridx,gridy)来创建nxn网格。例如,(5,5)、(3,3)、(4,9)、(3,10)将创建一个3x4网格空间(4行,3列),其中使用上述(gridx,gridy)的组件分别放置在单元格(3,2)、(1,2)、(2,3)、(1,4)中 weightx和weighty似乎有两个函数,weightx和weighty的>0值会将网格单元拉伸到

我对swing比较陌生,我正试图弄清楚它到底是如何工作的。如果我错了,请告诉我

我已经大致了解了放置组件所需的gridx和gridy。您需要至少n个值(gridx,gridy)来创建nxn网格。例如,(5,5)、(3,3)、(4,9)、(3,10)将创建一个3x4网格空间(4行,3列),其中使用上述(gridx,gridy)的组件分别放置在单元格(3,2)、(1,2)、(2,3)、(1,4)中

weightx和weighty似乎有两个函数,weightx和weighty的>0值会将网格单元拉伸到边缘(否则它会居中),我们还可以将比例设置为组件的大小-因此,如果一个组件的gridx=0.1,另一个组件的gridx=0.2,则后一个组件的宽度可能会增加一倍。但是,在按比例分配构件时,构件的最小默认宽度和高度将得到遵守

填充是将零部件拉伸到单元边缘所必需的。如果没有填充,构件将保持在中心

但是在这种情况下,我们可以使用锚点来定位组件,比如说沿着单元的西北角,而不是中心

插入在单元边缘内创建一堵空间墙

ipadx和ipady推送包含单元格的列或行的边界

但是我不能很好地理解gridwidth和gridheight是如何工作的

考虑下面的示例。在单元格b1(3,2)、b2(1,1)、b3(2,3)、b4(4,4)中放置了4个按钮 4x4网格空间

如何使按钮(如b2或b4)占据其所在单元格的整行或整列?

import javax.swing.*;
import java.awt.*;
//import java.awt.event.*;
public class Swing29a
{
public static void main(String[] args)
{
JFrame f1= new JFrame("GridBag Layout Test");

f1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f1.setResizable(true);
f1.setLocation(200,100);
f1.setSize(800,800);

JPanel p1 = new JPanel();
p1.setBackground(Color.black);
f1.add(p1);


JButton b1= new JButton("Button 1");
b1.setBackground(Color.white);

JButton b2= new JButton("Button 2");
b2.setBackground(Color.white);

JButton b3= new JButton("Button 3");
b3.setBackground(Color.white);

JButton b4= new JButton("Button 4");
b4.setBackground(Color.white);



GridBagLayout gm1= new GridBagLayout();
p1.setLayout(gm1);
GridBagConstraints cns =new GridBagConstraints();

cns.gridx=5;
cns.gridy=5;
cns.weightx=0.1;
cns.weighty=0.1;
cns.fill=GridBagConstraints.BOTH;

p1.add(b1,cns);

cns.gridx=3;
cns.gridy=3;
p1.add(b2,cns);


cns.gridx=4;
cns.gridy=9;
p1.add(b3,cns);

cns.gridx=7;//3;
cns.gridy=10;
cns.gridheight=3;
cns.weightx=0.2;
cns.weighty=0.2;
//cns.weightx=10.0;
//cns.weighty=9.0;    
//cns.ipadx=50;
//cns.ipady=50;
p1.add(b4,cns);

f1.setVisible(true);

}
}
编辑: 这里是指向图像的链接


我希望任何按钮都能够填充整行或整列,或者一行至少包含2个单元格。

gridwidth、gridheight

指定
单元格中的列数(用于gridwidth)或行数(用于gridheight)
添加了这些约束的组件可以占用组件的显示区域。默认值为
1

因此,如果网格为(
rxc
);一行中有
C
个单元格。如果您想让一个组件占据该特定行的所有单元格,只需将
GridBigConstraint.gridWidth
设置为
C

使用
GridBagConstraints.rements
指定组件是其行(用于gridwidth)或列(用于gridheight)中的最后一个组件


本教程中已经有一个很好的书面示例:

您的意思是这样的

import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class GridBagTest {

    public static void main(String[] args) {
        JFrame f1 = new JFrame("GridBag Layout Test");

        f1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f1.setResizable(true);
        f1.setLocation(200, 100);
        f1.setSize(800, 800);

        JPanel p1 = new JPanel();
        p1.setBackground(Color.black);
        f1.add(p1);

        JButton b1 = new JButton("Button 1");
        b1.setBackground(Color.white);

        JButton b2 = new JButton("Button 2");
        b2.setBackground(Color.white);

        JButton b3 = new JButton("Button 3");
        b3.setBackground(Color.white);

        JButton b4 = new JButton("Button 4");
        b4.setBackground(Color.white);

        GridBagLayout gm1 = new GridBagLayout();
        p1.setLayout(gm1);
        GridBagConstraints cns = new GridBagConstraints();

        cns.gridx = 5;
        cns.gridy = 5;
        cns.weightx = 0.1;
        cns.weighty = 0.1;
        cns.fill = GridBagConstraints.BOTH;

        p1.add(b1, cns);

        cns.gridx = 3;
        cns.gridy = 3;
//        cns.gridheight = GridBagConstraints.REMAINDER;
        cns.gridwidth = 3;
        p1.add(b2, cns);

        cns.gridheight = 1;
        cns.gridwidth = 1;
        cns.gridx = 4;
        cns.gridy = 9;
        p1.add(b3, cns);

        cns.gridx = 6;
        cns.gridy = 3;
        cns.gridheight = 7;
        cns.weightx = 0.2;
        cns.weighty = 0.2;
//        cns.gridheight = 4;
        p1.add(b4, cns);

        f1.setVisible(true);

    }
}

gridwidth
基本上告诉
GridBagLayout
组件应该扩展多少列(默认值为1)。这将始终正确扩展

gridheight
也会这样做,希望它总是向下展开

已更新

GridBagLayout
功能非常强大,但即便如此,有时也有局限性

为了实现像……这样的目标

最简单的选择是添加一个“填充”组件,例如

cns.gridx = 3;
cns.gridy = 9;
cns.gridwidth = 1;
JPanel pnl = new JPanel();
pnl.setOpaque(false);
p1.add(pnl, cns);

我说我想要或多或少像这样的东西:

多亏了所有的澄清,我或多或少能够做到这一点。 我用了一个超透明的按钮。 以下是输出图像:

下面是代码

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

public class GridBagTest2 
{

    public static void main(String[] args) {
        JFrame f1 = new JFrame("GridBag Layout Test");

        f1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f1.setResizable(true);
        f1.setLocation(200, 100);
        f1.setSize(800, 800);

        JPanel p1 = new JPanel();
        p1.setBackground(Color.black);
        f1.add(p1);

        JButton b1 = new JButton("Button 1");
        b1.setBackground(Color.white);

        JButton b2 = new JButton("Button 2");
        b2.setBackground(Color.white);

        JButton b3 = new JButton("Button 3");
        b3.setBackground(Color.white);

        JButton b4 = new JButton("Button 4");
        b4.setBackground(Color.white);

        JButton b5 = new JButton("        ");
        b5.setBackground(Color.white);
        b5.setBorderPainted(false);
        b5.setOpaque(false);

        JLabel lb1 = new JLabel("");
        //lb1.setOpaque(true);

        GridBagLayout gm1 = new GridBagLayout();
        p1.setLayout(gm1);
        GridBagConstraints cns = new GridBagConstraints();

        cns.gridx = 5;
        cns.gridy = 5;
        cns.weightx = 0.1;
        cns.weighty = 0.1;
        cns.fill = GridBagConstraints.BOTH;

        p1.add(b1, cns);

        cns.gridx = 3;
        cns.gridy = 3;

        cns.gridwidth = 3;
        p1.add(b2, cns);

        cns.gridheight = 1;
        cns.gridwidth = 1;
        cns.gridx = 4;
        cns.gridy = 9;
        p1.add(b3, cns);

        cns.gridx = 7;
        cns.gridy = 3;
        cns.gridheight = 8;
        cns.weightx = 0.2;
        cns.weighty = 0.2;

        p1.add(b4, cns);


        cns.gridx = 3;
        cns.gridy = 10;
        cns.gridheight=1;
        cns.gridwidth = 1;
        cns.weightx = 0.1;
        cns.weighty = 0.1;
        p1.add(b5, cns);


        f1.setVisible(true);

    }
}
我想我终于明白了gridwidth和gridheight是如何工作的了。他们从左到右,从上到下工作。它们也会因缺少空行或空列中的支撑组件而崩溃


然而,仍然有一些问题我不明白。如果使用透明标签(lb1)而不是透明按钮b5,则列的尺寸将发生变化。此外,为什么b4的宽度不是其他按钮的两倍,尽管重量是其他按钮的两倍

添加描述您的需求的图片将更有助于理解您的问题。请制作一个,并将其链接到您的问题1)对代码块使用一致且符合逻辑的缩进。代码的缩进旨在帮助人们理解程序流程。2) 提供GUI的ASCII艺术,因为它应该以最小的大小显示,并且(如果可以调整大小)具有额外的宽度/高度。gridWidth/gridHeight=GridBagConstraints。REMAINDER@sage:我没有足够的声誉来发布图片@程序员:你能修改上面的代码来表达你的观点吗?仅凭那一句话,我无法理解。事实上,我甚至试过GridBagConstraints.rements。它不起作用了!谢谢你的回答,圣人。但这并不能解决我的问题。我已经给出了完整的代码。为什么不运行它,然后发布修改后的代码?@user3015246,将图像上传到托管站点,并将其链接到您的问题。我们会为您附上的好的,请稍等。我已经看过并检查过了。但我的问题是,为什么要随机指定单元格?随机是什么意思?OP代码的问题是,他使用gridx和gridy指定单元格有点超出我的想象:(@madprogrammer:是的,这正是我想要的类型。我的代码怎么了?等等,我想你改变了按钮4的位置。还有按钮1。这也不是我想要的。基本上,
btn4
被定位在列的底部,为了填充列,它需要放在顶部。然后你需要提供相应的信息。)调整
gridWidth
gridHeight
值,以便它们填充适当数量的列和行。记住,即使没有大小,也仍然需要包含一行或一列…“等等,我想你更改了按钮4的位置。这不是我想要的”-如果你想要这种效果,你别无选择,这就是它的工作原理…你必须适应。你不能告诉
GridBagLayout
向后填充,只能向前填充。。。