GridBagLayout:最后一个组件影响网格宽度

时间:2013-09-06 16:26:47

标签: java swing grid width gridbaglayout

我遇到了Javas GridBagLayout的问题。

运行以下代码:

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;

import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;


public class Main extends JFrame{

    public static void main (String [] args){
        new Main(); 
    }

    public Main(){
        add(getPanel());
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
        setSize(600, 150);
    }

    private JPanel getPanel(){
        JPanel panel = new JPanel(new GridBagLayout());

        JLabel label1 = new JLabel("Label 1");
        JLabel label2 = new JLabel("Label 2");
        JLabel label3 = new JLabel("Label 3");

        JTextField area1 = new JTextField();
        JTextField area2 = new JTextField();

        JComboBox<String> box = new JComboBox<String>();
        box.addItem("One One One");
        box.addItem("Two Two Two");

        GridBagConstraints gbc = new GridBagConstraints();
        gbc.anchor = GridBagConstraints.WEST;
        gbc.insets = new Insets(10, 10, 10, 10);

        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.weightx = 0;
        panel.add(label1, gbc);

        gbc.gridx = 1;
        gbc.weightx = 1;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        panel.add(area1, gbc);

        gbc.gridx = 2;
        gbc.weightx = 0;
        gbc.fill = GridBagConstraints.NONE;
        panel.add(label2, gbc);

        gbc.gridx = 3;
        gbc.weightx = 1;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        panel.add(area2, gbc);

        gbc.gridx = 0;
        gbc.gridy = 1;
        gbc.fill = GridBagConstraints.NONE;
        gbc.weightx = 0;
        panel.add(label3, gbc);

        gbc.weightx = 1;
        gbc.gridx = 1;
        panel.add(box, gbc);

        return panel;
    }
}

生成以下窗口:

Problem with GridBagLayout Screenshot

但是两个JTextFields的宽度应该相同。

如果我不添加JComboBox,一切都很好:

enter image description here

我的问题是:为什么最后一个组件会影响先前组件的网格宽度?对我来说真正奇怪的是,如果JComboBox长度增加,正确的JTextField会变小。实际上,看起来左边的JTextField的长度等于右边JTextField的长度+ JComboBox的长度。 有两个长度相同的文本字段下一行中的JComboBox的诀窍是什么?

提前致谢!

2 个答案:

答案 0 :(得分:3)

根据GridBagLayout informations

  

基本上,GridBagLayout将组件放在矩形(单元格)中   网格,然后使用组件的首选大小来确定方式   细胞应该很大。

因为当您添加JComboBox时,首选尺寸大于JTextField s,x = 1处的网格将占JPanel中较大比例的地点,因为等于的weightx将根据他们的首选大小分享他们需要的地方。

这就是为什么添加JComboBox“会推动”gridx = 2。为避免这种情况,您可以在创建JTextField时确定多个列:

JTextField area1 = new JTextField(15);
JTextField area2 = new JTextField(15);

或添加占位符文本,以使JTextField的首选大小高于0。 如果你要做

box.setPreferredSize(area1.getPreferredSize());
panel.add(box, gbc);

您会注意到JComboBox几乎不可见,因为首选尺寸较小,而另一方面,会使您的面板在每一侧都相等。

我还建议您为每个组件使用新的GridBagConstraints,以避免在未将值重置为之前复制添加的组件的值。

答案 1 :(得分:0)

我在getPanel final中创建了变量,并在返回之前添加了此代码:

JButton button = new JButton(new AbstractAction("Debug") {
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("Label1: " + label1.getPreferredSize());
        System.out.println("Label2: " + label2.getPreferredSize());
        System.out.println("Label3: " + label3.getPreferredSize());
        System.out.println("Area1: " + area1.getPreferredSize());
        System.out.println("Area2: " + area2.getPreferredSize());
        System.out.println("Box: " + box.getPreferredSize());
    }
});
gbc.weightx = 0;
gbc.gridx = 3;
panel.add(button, gbc);

尝试一下,您会看到JTextField报告的首选宽度为~45(实际值取决于LAF,操作系统,字体等),而JComboBox是报告的优选宽度为~142。您可以通过将preferredSize JComboBox设置为较小的值来解决此问题。