2

我正面临 Java 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;
    }
}

产生以下窗口:

GridBagLayout 的问题截图

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

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

在此处输入图像描述

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

提前致谢!

4

2 回答 2

3

根据GridBagLayout 信息

本质上,GridBagLayout 将组件放置在网格中的矩形(单元格)中,然后使用组件的首选大小来确定单元格的大小。

由于当您添加 时JComboBox,它的首选尺寸大于您JTextField的 s,x=1 处的网格将占据较大比例的位置,JPanel因为weightx相等的将根据其首选尺寸共享他们需要的位置。

这就是为什么添加JComboBox“推动”gridx=2。为避免这种情况,您可以在创建列JTextField时决定它们的数量:

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

或添加占位符文本,使JTextFields 的首选大小大于 0。如果您要这样做

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

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

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

于 2013-09-06T17:13:26.533 回答
0

I made the variables in getPanel final and added this code before the return:

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);

Give it a try and you'll see that the JTextFields are reporting a preferred width of ~45 (the actual value depends on LAF, OS, fonts, etc) while the JComboBox is reporting a preferred width of ~142. You can resolve this by setting the preferredSize of JComboBox to a smaller value.

于 2013-09-06T16:52:47.217 回答