【问题标题】:GridBagLayout and FlowLayout: Components appearing at unexpected positionsGridBagLayout 和 FlowLayout:组件出现在意外位置
【发布时间】:2014-05-06 00:50:53
【问题描述】:

1.关于 GridBagLayout 的问题:- 尽管为所有组件设置了 gridx=0;,但它们都在父组件的中心对齐。 请告诉我如何解决它,并请告诉我为什么会发生这种意外行为。

2。关于 FlowLayout 的问题:-

  1. 在示例的开头,一个面板(添加到父级的顶部 带有 GridBagLayout 的面板)正在使用 FlowLayout。根据 文档中,构造函数FlowLayout(FlowLayout.LEFT, 5, 5)FlowLayout.LEFT 用于对齐,接下来的两个int 是 对于hgapvgap我正在使用左对齐,但仍然两者都使用 按钮出现在中间。请告诉我为什么?

  2. 所有组件的垂直插入比预期的要多得多。 为什么会这样?相同的 5 值不会导致侧面有太多的插入:s

示例代码:-

Card(){

        setLayout(new GridBagLayout());

        JPanel panelBtns= new JPanel();
        panelBtns.setLayout(new FlowLayout(FlowLayout.LEFT, 10, 5));
        JButton emailBtn= new JButton("a");
        JButton saveBtn= new JButton("b");
        panelBtns.add(emailBtn);
        panelBtns.add(saveBtn);
        GridBagConstraints c= new GridBagConstraints();
        c.gridx=0;
        c.gridy=0;
        c.insets= new Insets(5,5,5,5);
        c.weightx=1;
        c.weighty=1;
        add(panelBtns, c);

        JLabel labelTitle= new JLabel("Title");
        labelTitle.setFont(new Font("calibri", Font.PLAIN, 12));
        c= new GridBagConstraints();
        c.gridx=0;
        c.gridy=1;
        c.insets=new Insets(5,5,5,5);
        c.weightx=0.35;
        c.weighty=1;
        add(labelTitle, c);

        JTextField textField= new JTextField();
        Border border = BorderFactory.createLineBorder(Color.GRAY);
        textField.setBorder(BorderFactory.createCompoundBorder(border, 
                    BorderFactory.createEmptyBorder(2,2,2,2)));
        c= new GridBagConstraints();
        c.gridx=0;
        c.gridy=2;
        c.insets= new Insets(5,5,5,5);
        c.fill=c.HORIZONTAL;
        c.weightx= 1;
        c.weighty=1;
        add(textField,c); 

        JLabel bodyLabel= new JLabel("Detail");
        bodyLabel.setFont(new Font("calibri", Font.PLAIN, 12));
        c= new GridBagConstraints();
        c.gridx=0;
        c.gridy=3;
        c.insets=new Insets(5,5,5,5);
        c.weightx=1;
        c.weighty=1;
        add(bodyLabel, c);

        JTextArea textArea= new JTextArea();
        Border border1 = BorderFactory.createLineBorder(Color.GRAY);
        textArea.setBorder(BorderFactory.createCompoundBorder(border1, 
                    BorderFactory.createEmptyBorder(2,2,2,2)));
        c= new GridBagConstraints();
        c.gridx=0;
        c.gridy=4;
        c.insets= new Insets(5, 5, 5,5);
        c.fill=c.BOTH;
        c.weightx=1;
        c.weighty=10;
        add(textArea,c);

    }


编辑:-

我更改了 insets 的值,但 组件上方和下方的不需要的 inset 仍然存在...这里看起来几乎没问题,因为我在此屏幕截图中使用了较小的帧大小,但是当框架更大,它看起来很丑而且错位。

我希望panelBtnstitleLabel 之间的差距更小,而textFielftitleLabel 之间的差距更小……bodyLabeltextArea 也是如此。

c.insets= new Insets(2,2,0,2); // panelBtns
c.insets=new Insets(0,5,0,5); //titleLabel
c.insets= new Insets(0,5,0,5); //textField
c.insets=new Insets(0,5,0,5); //bodyLabel
c.insets= new Insets(0, 5, 5,5); //textArea

【问题讨论】:

    标签: java swing user-interface gridbaglayout flowlayout


    【解决方案1】:

    关于 GridBagLayout 的问题:- 尽管设置了 gridx=0;对于所有 组件,它们都在父组件的中心对齐。 请告诉我如何解决它,请告诉我为什么会这样 发生意外行为。

    这是GridBagLayout 的默认行为。您需要使用GridBagConstrints#fill 和/或GridBagConstrints#anchor(可能还有GridBagConstrints#weightx)的组合来更改组件占用给定单元格可用空间的方式

    只需将c.anchor = GridBagConstraints.WEST; 添加到bodyLayoutlabelTitle 约束...

    在示例的开头,一个面板(添加到父级的顶部 带有 GridBagLayout 的面板)正在使用 FlowLayout。根据 文档,在构造函数 FlowLayout(FlowLayout.LEFT, 5, 5) 中, FlowLayout.LEFT 用于对齐,接下来的两个 int 用于 hgap 和 vgap。我正在使用左对齐,但两个按钮仍然出现在 中心。请告诉我为什么?

    这是因为GridBagLayout 正在放置按钮位于布局中心的JPanel

    如果添加panelBtns.setBorder(new LineBorder(Color.RED)),您可以实际测试并看到这一点,您会看到panelBtns 占用的空间刚好足以让按钮可见(包括布局管理器的填充)

    尝试将c.fill = GridBagConstaints.HORIZONTAL 添加到按钮面板的约束中

    更新

    我更改了 insets 的值,但 上下都有一个不需要的 inset 组件仍然存在...这里看起来几乎没问题,因为 我为这个屏幕截图使用了一个小帧大小,但是当帧是 更大,它看起来丑陋和错位。

    我希望panelBtnstitleLabel 之间的差距更小,并且 在textFielftitleLabel 之间,甚至更小... bodyLabeltextArea 也是如此。

    从除JTextArea 之外的所有内容中删除weighty 约束。您应该知道weighty/x 是从 0 到 1 的度量值,它表示组件在其父级中应占用的可用空间百分比。

    这些权重(大部分)平均分布在没有足够空间容纳所有请求的地方。也就是说,如果您提供两个等于 1 的权重,它们将被赋予相等的数量(大约 50%)。

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.FlowLayout;
    import java.awt.Font;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.Insets;
    import javax.swing.BorderFactory;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JTextArea;
    import javax.swing.JTextField;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    import javax.swing.border.Border;
    
    public class TestLayout1 {
    
        public static void main(String[] args) {
            new TestLayout1();
        }
    
        public TestLayout1() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    }
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new BorderLayout());
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            public TestPane() {
                setLayout(new GridBagLayout());
    
                JPanel panelBtns = new JPanel();
                panelBtns.setLayout(new FlowLayout(FlowLayout.LEFT, 10, 5));
                JButton emailBtn = new JButton("a");
                JButton saveBtn = new JButton("b");
                panelBtns.add(emailBtn);
                panelBtns.add(saveBtn);
                GridBagConstraints c = new GridBagConstraints();
                c.gridx = 0;
                c.gridy = 0;
    //            c.insets = new Insets(5, 5, 5, 5);
                c.insets= new Insets(2,2,0,2); // panelBtns
                c.weightx = 1;
                c.fill = GridBagConstraints.HORIZONTAL;
    //            c.weighty = 1;
                add(panelBtns, c);
    
                JLabel labelTitle = new JLabel("Title");
                labelTitle.setFont(new Font("calibri", Font.PLAIN, 12));
                c = new GridBagConstraints();
                c.gridx = 0;
                c.gridy = 1;
    //            c.insets = new Insets(5, 5, 5, 5);
                c.insets=new Insets(0,5,0,5); //titleLabel
                c.weightx = 0.35;
                c.anchor = GridBagConstraints.WEST;
    //            c.weighty = 1;
                add(labelTitle, c);
    
                JTextField textField = new JTextField();
                Border border = BorderFactory.createLineBorder(Color.GRAY);
                textField.setBorder(BorderFactory.createCompoundBorder(border,
                        BorderFactory.createEmptyBorder(2, 2, 2, 2)));
                c = new GridBagConstraints();
                c.gridx = 0;
                c.gridy = 2;
    //            c.insets = new Insets(5, 5, 5, 5);
                c.insets= new Insets(0,5,0,5); //textField
                c.fill = GridBagConstraints.HORIZONTAL;
                c.weightx = 1;
    //            c.weighty = 1;
                add(textField, c);
    
                JLabel bodyLabel = new JLabel("Detail");
                bodyLabel.setFont(new Font("calibri", Font.PLAIN, 12));
                c = new GridBagConstraints();
                c.gridx = 0;
                c.gridy = 3;
                c.insets=new Insets(0,5,0,5); //bodyLabel
    //            c.insets = new Insets(5, 5, 5, 5);
                c.anchor = GridBagConstraints.WEST;
                c.weightx = 1;
    //            c.weighty = 1;
                add(bodyLabel, c);
    
                JTextArea textArea = new JTextArea();
                Border border1 = BorderFactory.createLineBorder(Color.GRAY);
                textArea.setBorder(BorderFactory.createCompoundBorder(border1,
                        BorderFactory.createEmptyBorder(2, 2, 2, 2)));
                c = new GridBagConstraints();
                c.gridx = 0;
                c.gridy = 4;
    //            c.insets = new Insets(5, 5, 5, 5);
                c.insets= new Insets(0, 5, 5,5); //textArea
                c.fill = GridBagConstraints.BOTH;
                c.weightx = 1;
                c.weighty = 1;
                add(textArea, c);
            }
        }
    
    }
    

    【讨论】:

    • 非常感谢。这解决了 90% 的问题。只有一个问题仍然存在,如果您想回答,我已经编辑了我的问题。再次感谢您!
    • 尝试从 panelBtns 中删除 c.weighty 约束
    • @Zarah 我没有查看代码,但我怀疑它已经被规范化或减少到它的最大值
    • a 将占用 剩余 可用空间的 100%,权重与剩余的空间有关;) - 假设没有其他东西也需要 100% 的空间也,然后它在它们之间被划分
    • 我认为它可能会标准化为 0.750.25
    猜你喜欢
    • 2015-08-21
    • 1970-01-01
    • 1970-01-01
    • 2020-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多