我正在尝试使用GridBagLayout在JPanel上定位组件,但我得到的输出完全偏离了我的预期。希望通过stackoverflow :)获得一些清晰的头脑清晰度。
下面我提供了一段代码和screentshot程序。我的问题是:
为什么JLabel Choose measure system to convert
不在Y-axis = 1
?据我所知,c.gridy=1
向下是一个像素,但标签卡在顶部,没有留下Frame标题的空格。而且,为什么它定位如此奇怪,即,不是真的在中心,也不是在开始?
为什么ComboBox
es From...
和To...
之间有这么大的空格,但ComboBox 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);
这是screentshot:
编辑:如果我更改代码:
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);
为什么改变一个组件的位置会影响一切,这让我很困惑?
答案 0 :(得分:3)
GridBagConstraints将帧设置为有效的网格。除非另有说明,否则网格中单元格的宽度和高度由单元格中的数据大小确定。因此,如果您想在单元格之间添加一些空格,我建议ipadx
和ipady
。您还可以使用anchor
来调整单元格中的数据。我还建议weightx
和weighty
调整实际的单元格大小。
所以想象一下像你当前的设置:
编辑:您的新GBC的样子示例。数字是(gridx,gridy)
答案 1 :(得分:2)
为什么
JLabel
选择要转换的度量系统不在Y-axis = 1
上?据我所知,c.gridy=1
向下一个像素
你自己感到困惑,c.gridy = 1
并没有将它放在1个像素的下方,而是放在下一行,但由于没有前一行,所以它需要第一行。有关参考,请参阅:GridBagConstraints#gridy
,其中包含以下内容:
指定组件显示区域顶部的单元格,其中最顶层的单元格为gridy = 0。值RELATIVE指定组件放置在添加此组件之前添加到容器的组件的正下方。
下一个问题:
而且,为什么它定位如此奇怪,即不是真正处于中心,也不是在开始?
它以自己的单元格为中心,如果你想将它放在JFrame
上,那么你可能需要在它自己的gridx = 1
和其他组件上创建它( 0和2)或根据你希望它看起来像... ... /
为什么ComboBoxes From ...和To ...之间有这么大的空间,但ComboBox To ...和TextField Enter值之间没有空格......?
这是因为你的程序因为第一个单元格上的大文本而给它所有额外的空间......
你可以这样:
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);
}
}
产生以下输出: