Java GridBagLayout 上的组件定位

Java component positioning on GridBagLayout

我正在尝试使用 GridBagLayout 在 JPanel 上定位组件,但我得到的输出与我的预期完全不同。希望通过 Whosebug 中的 brilliant-minded ppl 获得一些清晰度:)。

下面我提供了一段代码和程序截图。我的问题是:

  1. 为什么 JLabel Choose measure system to convert 不在 Y-axis = 1 上?据我所知,c.gridy=1 向下一个像素,但标签卡在顶部,框架标题没有留下 space。而且,为什么它的位置如此奇怪,即不在中心,也不在开始?

  2. 为什么ComboBoxFrom...To...之间有这么大的space,而没有space组合框 To...TextField Enter value here...?

代码如下:

    JPanel container = new JPanel();
    container.setLayout(new GridBagLayout());
    getContentPane().add(container, BorderLayout.NORTH);
    TitledBorder outputCenter;
    GridBagConstraints c = new GridBagConstraints();

    label = new JLabel("Choose measure system to convert");
    label.setFont(new Font("Times New Roman", Font.PLAIN, 20));
    c.gridx = 0;
    c.gridy = 1;
    container.add(label, c);

    fromList = new JComboBox<String>(convertFrom); 
    c.gridx = 0;
    c.gridy = 2;
    container.add(fromList, c);

    toList = new JComboBox<String>(convertTo);
    c.gridx = 1;
    c.gridy = 2;
    container.add(toList, c);

    //Field where user enters the value to be converted
    input = new JTextField("Enter value here...");
    input.setPreferredSize(new Dimension(150,30));;
    input.setEditable(true);
    input.setBackground(Color.WHITE);
    input.setBorder(BorderFactory.createLineBorder(Color.BLACK));
    input.addMouseListener(new MouseAdapter(){
        public void mouseClicked(MouseEvent e){
            input.setText("");}});
    c.gridx = 2;
    c.gridy = 2;
    container.add(input, c); 

这是屏幕截图:

编辑:如果我更改代码:

    label = new JLabel("Choose measure system to convert");
    label.setFont(new Font("Times New Roman", Font.PLAIN, 20));
    c.gridx = 0; 
    c.gridy = 1;
    container.add(label, c);

    label = new JLabel("Choose measure system to convert");
    label.setFont(new Font("Times New Roman", Font.PLAIN, 20));
    c.gridx = 1; // changed this line
    c.gridy = 1;
    container.add(label, c); 

结果是这样的:

这让我很困惑,为什么改变一个组件的位置会影响一切?

GridBagConstraints 将框架设置为有效的网格。默认情况下,网格中单元格的宽度和高度由单元格中数据的大小决定,除非另有说明。因此,如果您想添加一些 space in-between 个单元格,我建议使用 ipadxipady。您还可以利用 anchor 调整单元格中的数据。我还建议 weightxweighty 来调整实际的单元格大小。

想象一下您当前的设置是这样的:

编辑:您的新 GBC 外观示例。数字是 (gridx,gridy)

Why the JLabel Choose measure system to convert is not on Y-axis = 1? As to my knowledge, c.gridy=1 is one pixel downward

你自己弄糊涂了,c.gridy = 1 不是将它向下定位 1 个像素,而是在下一行,但由于没有前一行,所以它位于第一行。供参考,请参阅:GridBagConstraints#gridy,内容如下:

Specifies the cell at the top of the component's display area, where the topmost cell has gridy=0. The value RELATIVE specifies that the component be placed just below the component that was added to the container just before this component was added.

下一题:

And also, why is it positioned so weird, i.e., not really in the center, nor in the start?

它以自己的单元格为中心,如果您想将它以 JFrame 为中心,那么您可能需要自己创建它 gridx = 1 并将其余组件放在另一个单元格上一个(0 和 2)或根据您希望它看起来像使其跨越 2 列或更多列...

Why is there such a big space between ComboBoxes From... and To..., but there is no space between ComboBox To... and TextField Enter value here...?

这是因为第一个单元格上的大文本,你的程序给了它所有额外的space...

你可以有这样的东西:

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;
import javax.swing.SwingUtilities;

public class GridBagLayoutExample {
    private JFrame frame;
    private JPanel pane;
    private JLabel label;
    private JTextField field;
    private JComboBox<String> box1;
    private JComboBox<String> box2;
    private GridBagConstraints gbc;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new GridBagLayoutExample()::createAndShowGui);
    }

    private void createAndShowGui() {
        frame = new JFrame(getClass().getSimpleName());

        pane = new JPanel();
        pane.setLayout(new GridBagLayout());

        gbc = new GridBagConstraints();

        label = new JLabel("Choose measure system to convert");

        box1 = new JComboBox<>(new String[] {"From..."});
        box2 = new JComboBox<>(new String[] {"To..."});

        field = new JTextField(10);

        gbc.insets = new Insets(5, 5, 5, 5); //We add extra space at top, left, bottom, right of each component

        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.gridwidth = 3; //We make our text to span 3 cells
        pane.add(label, gbc);

        gbc.gridy = 1;
        gbc.gridwidth = 1; //We return the spanning to 1 single cell
        pane.add(box1, gbc);

        gbc.gridx = 1;
        pane.add(box2, gbc);

        gbc.gridx = 2;
        pane.add(field, gbc);

        frame.add(pane);
        frame.pack();
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

产生以下输出: