GridBagLayout 中的锚约束不起作用

Anchor constraint in GridBagLayout not working

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

public class GBLClumpingExample extends JFrame{

    GBLClumpingExample(){
        GridBagLayout g = new GridBagLayout();
        GridBagConstraints gv = new GridBagConstraints();

        GridBagLayout b = new GridBagLayout();
        GridBagConstraints gc = new GridBagConstraints();

        setVisible(true);
        setSize(720,720);
        setLayout(g);

        JPanel p = new JPanel();
        p.setLayout(b);
        gv.fill = GridBagConstraints.BOTH;
        add(p,gv);
        
        Label l1 = new Label("Label 1");
        Label l2 = new Label("Label 2");
        Label l3 = new Label("Label 3");
        Label l4 = new Label("Label 4");
        Label l5 = new Label("Label 5");
        
        gc.weightx =1.0;
        gc.weighty = 1.0;
        gc.gridx= 1;
        gc.gridy= 1;
        gc.anchor = GridBagConstraints.PAGE_START;
        gc.gridx= -1;
        gc.gridy= 0;
        p.add(l1,gc);
        gc.anchor = GridBagConstraints.SOUTH;
        p.add(l2,gc);
        gc.anchor = GridBagConstraints.EAST;
        p.add(l3,gc);
        gc.anchor = GridBagConstraints.WEST;
        p.add(l4,gc);
        gc.anchor = GridBagConstraints.CENTER;
        p.add(l5,gc);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public static void main(String[] args){
        GBLClumpingExample e = new GBLClumpingExample();
    }
}

我正在尝试使用 GridBagLayout,但可能无法正常工作。

这是我的代码,我不知道哪里出了问题,但是 GridBagConstraints 的锚点约束不起作用,它们只是聚集在一起。

如果我正确理解了这个布局的意图(我不是确定我理解)那么这可以使用BorderLayout.

这里有更多的宽度和高度:

带标题的边框只是为了提供对用于放置组件的约束的快速视觉参考。 (spacer) 仅添加到中心行的 3 个标签,以显示完整的 TitledBorder

代码如下:

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

public class BLNotClumpingExample {

    private JComponent ui = null;

    BLNotClumpingExample() {
        initUI();
    }

    public void initUI() {
        if (ui!=null) return;

        ui = new JPanel(new BorderLayout(10,10));
        ui.setBorder(new EmptyBorder(4,4,4,4));
        
        ui.add(getLabel("Label 1", "PAGE_START"), BorderLayout.PAGE_START);
        ui.add(getLabel("Label 2", "PAGE_END"), BorderLayout.PAGE_END);
        ui.add(getLabel("Label 3 (spacer)", "LINE_END"), BorderLayout.LINE_END);
        ui.add(getLabel("Label 4 (spacer)", "LINE_START"), BorderLayout.LINE_START);
        ui.add(getLabel("Label 5 (spacer)", "CENTER"), BorderLayout.CENTER);
    }
    
    private JLabel getLabel(String text, String constraint) {
        JLabel l = new JLabel(text, SwingConstants.CENTER);
        l.setBorder(new TitledBorder(constraint));
        return l;
    }

    public JComponent getUI() {
        return ui;
    }

    public static void main(String[] args) {
        Runnable r = () -> {
            try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (Exception useDefault) {
            }
            BLNotClumpingExample o = new BLNotClumpingExample();
            
            JFrame f = new JFrame(o.getClass().getSimpleName());
            f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            f.setLocationByPlatform(true);
            
            f.setContentPane(o.getUI());
            f.pack();
            f.setMinimumSize(f.getSize());
            
            f.setVisible(true);
        };
        SwingUtilities.invokeLater(r);
    }
}

您正在将组件添加到面板 p,然后使用 add(p,gv); 将其添加到框架(到其内容窗格)。 gv 中的约束已经用 gv.fill = GridBagConstraints.BOTH; 初始化,但它的 weightxweighty 保留在它们的初始零。因此,此面板将保持其首选大小,不会收到额外的 space,因此它没有额外的 space 可分配给自己的内容。

由于所有标签都具有相同的大小,因此当没有额外的 space.

时,它们的锚点没有效果

换行时

gv.fill = GridBagConstraints.BOTH;

gv.fill = GridBagConstraints.BOTH;
gv.weightx = 1;
gv.weighty = 1;

你会看到锚点的效果。或者,您可以去掉附加面板。还有其他冗余操作。您可以将代码简化为:

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

public class GBAnchorExample extends JFrame{
    GBAnchorExample() {
        Container c = super.getContentPane();
        c.setLayout(new GridBagLayout());
        GridBagConstraints gc = new GridBagConstraints();
        gc.weightx = gc.weighty = 1.0;

        JLabel l1 = new JLabel("Label 1");
        JLabel l2 = new JLabel("Label 2");
        JLabel l3 = new JLabel("Label 3");
        JLabel l4 = new JLabel("Label 4");
        JLabel l5 = new JLabel("Label 5");

        gc.anchor = GridBagConstraints.PAGE_START;
        c.add(l1,gc);
        gc.anchor = GridBagConstraints.SOUTH;
        c.add(l2,gc);
        gc.anchor = GridBagConstraints.EAST;
        c.add(l3,gc);
        gc.anchor = GridBagConstraints.WEST;
        c.add(l4,gc);
        gc.anchor = GridBagConstraints.CENTER;
        c.add(l5,gc);
        super.setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public static void main(String[] args) {
        GBAnchorExample e = new GBAnchorExample();
        e.setSize(720,720);
        e.setVisible(true);
    }
}

为了可视化锚点的实际效果,您可以将 main 方法更改为

public static void main(String[] args){
    GBAnchorExample e = new GBAnchorExample();
    Component grid = new JComponent() {
        @Override
        protected void paintComponent(Graphics g) {
            g.setColor(Color.GREEN);
            int w = getWidth(), h = getHeight();
            for(int i = 1; i < 5; i++) {
                int x = (int)(w/5.0*i);
                g.drawLine(x, 0, x, h);
            }
        }
    };
    e.setGlassPane(grid);
    grid.setVisible(true);
    e.setSize(720,720);
    e.setVisible(true);
}

这将绘制一个绿色网格以显示包含标签的逻辑单元格,因此很明显锚点如何影响标签在其单元格中的位置。