我遇到了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;
}
}
生成以下窗口:
但是两个JTextFields的宽度应该相同。
如果我不添加JComboBox,一切都很好:
我的问题是:为什么最后一个组件会影响先前组件的网格宽度?对我来说真正奇怪的是,如果JComboBox长度增加,正确的JTextField会变小。实际上,看起来左边的JTextField的长度等于右边JTextField的长度+ JComboBox的长度。 有两个长度相同的文本字段和下一行中的JComboBox的诀窍是什么?
提前致谢!
答案 0 :(得分:3)
基本上,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
设置为较小的值来解决此问题。