19

到目前为止,我设法尽可能避免使用GridBagLayout(手动代码),但这次我无法避免它,我正在阅读 SUN 的教程GridBagLayout 到目前为止它进展不顺利。我想我误解了一些东西。
例如,我尝试以下代码(类似于 SUN 帖子中的代码):

public class MainFrame extends JFrame { 


    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    MainFrame frame = new MainFrame();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame
     */
    public MainFrame() {
        super();
        setBounds(100, 100, 500, 375);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        Container mainContainer = getContentPane();

        mainContainer.setLayout(new GridBagLayout());       

        //add label
        JLabel someLabel = new JLabel("Label 1:");
        GridBagConstraints constraints = new GridBagConstraints();

        constraints.gridx = 0;
        constraints.gridy = 0;
        //constraints.anchor = GridBagConstraints.FIRST_LINE_START;
        //constraints.weightx = 0.5;
        mainContainer.add(someLabel, constraints);      

        JTextField someText = new JTextField(30);

        constraints = new GridBagConstraints();

        constraints.gridx = 1;
        constraints.gridy = 0;
        constraints.weightx = 0.5;
        mainContainer.add(someText, constraints);

        //
    }

}

我在框架的中心得到一个并排的标签和文本字段。
但我期待它们会出现在左上角,因为标签的 gridx 和 gridy 为 0。
即使我设置constraints.anchor = GridBagConstraints.FIRST_LINE_START;仍然相同的结果。
我在这里错了吗?
来自太阳的帖子:

指定组件左上角的行和列。最左列的地址为 gridx=0,顶行的地址为 gridy=0。

4

5 回答 5

16

添加constraints.weighty = 1;到 JLabel 约束和constraints.anchor = GridBagConstraints.NORTHWEST;TextField 约束。

编辑:

来自 Oracle 的GridBagLayout 指南

较大的数字表示组件的行或列应该获得更多空间。对于每一列,权重与为该列中的组件指定的最高权重 x 相关,每个多列组件的权重在组件所在的列之间以某种方式拆分。类似地,每一行的权重与指定的最高权重有关该行中的组件。额外的空间倾向于朝向最右边的列和底行。

于 2011-09-01T19:28:43.270 回答
14

您需要在 Swing 教程中进一步阅读weightX/weightY它声明的部分:

除非您为 weightx 或 weighty 指定至少一个非零值,否则所有组件都会在其容器的中心聚集在一起。

您指定了 weightX 但未指定 weightY。

编辑,它比我想象的要复杂。看来您还需要指定:

constraints.anchor = GridBagConstraints.FIRST_LINE_START;

除了重量之外,这两个组件。

于 2011-09-01T19:29:15.940 回答
3

您可以通过使用技巧来实现这一点,在您的行之后添加一个虚拟组件并将其扩展以填充垂直空间。您也可以重复使用约束,无需创建新对象:

编辑:好的,忘记诀窍:(正确的方法是 Deon Botha 和 BenCole 说,我已经使用锚更新了我的代码

不要接受这个答案,接受 Deon 的或 Ben 的

public class MainFrame extends JFrame { 
    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    MainFrame frame = new MainFrame();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

public MainFrame() {
    super();
    setBounds(100, 100, 500, 375);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    Container mainContainer = getContentPane();
    mainContainer.setLayout(new GridBagLayout());       

    JLabel someLabel = new JLabel("Label 1:");
    JTextField someText = new JTextField(30);

    GridBagConstraints constraints = new GridBagConstraints();
    constraints.anchor = GridBagConstraints.FIRST_LINE_START;

    constraints.gridx = 0;
    constraints.gridy = 0;    
    constraints.weightx = 1.0;
    mainContainer.add(someLabel, constraints);      

    constraints.gridx = 1;                       
    constraints.weightx = 1.0;
    constraints.weighty = 1.0;        
    mainContainer.add(someText, constraints);                       
}
}
于 2011-09-01T19:24:42.923 回答
1

我可能不会直接回答您的问题,但相信我,您应该使用 IDE 对布局进行尝试和错误。我个人建议使用 Netbeans。您可以在那里拖放,然后查看属性。起初,您会在属性检查器中给出一些默认值,因此自动生成的代码更少。但是,一旦你开始使用布局,你就可以看到代码并很好地理解你做了什么。

于 2011-09-01T19:25:59.697 回答
1

这对我有用:

public class NewJFrame extends javax.swing.JFrame {

    public NewJFrame() {
        initComponents();
    }

    @SuppressWarnings("unchecked")
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        jPanel2 = new javax.swing.JPanel();
        jComboBox3 = new javax.swing.JComboBox();
        jComboBox4 = new javax.swing.JComboBox();
        jComboBox5 = new javax.swing.JComboBox();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setBackground(new java.awt.Color(255, 204, 51));
        setMinimumSize(new java.awt.Dimension(800, 600));
        getContentPane().setLayout(null);

        jPanel2.setLayout(new java.awt.GridBagLayout());

        jComboBox3.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.weightx = 1.0;
        jPanel2.add(jComboBox3, gridBagConstraints);

        jComboBox4.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.weightx = 1.0;
        jPanel2.add(jComboBox4, gridBagConstraints);

        jComboBox5.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        jPanel2.add(jComboBox5, gridBagConstraints);

        getContentPane().add(jPanel2);
        jPanel2.setBounds(30, 40, 150, 260);

        pack();
    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new NewJFrame().setVisible(true);
            }
        });
    }

    private javax.swing.JComboBox jComboBox3;
    private javax.swing.JComboBox jComboBox4;
    private javax.swing.JComboBox jComboBox5;
    private javax.swing.JPanel jPanel2;
}
于 2015-09-27T20:34:53.840 回答