如何使组件跨越 GridBagLayout 中的多个单元格
Posted
技术标签:
【中文标题】如何使组件跨越 GridBagLayout 中的多个单元格【英文标题】:How can I make a component span multiple cells in a GridBagLayout 【发布时间】:2013-06-16 18:51:24 【问题描述】:我必须为学校做这个:
这是我目前的代码:
import javax.swing.*;
import java.awt.*;
public class AddressBookGui1 extends JFrame
public AddressBookGui1()
GridBagLayout gbl = new GridBagLayout();
GridBagConstraints gbc = new GridBagConstraints();
setLayout(gbl);
JLabel label;
JButton button;
JTextField textField;
JTextArea textArea = new JTextArea(10, 20);
gbc.weightx = 1;
label = new JLabel("text");
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0;
gbc.gridy = 0;
add(label ,gbc);
textField = new JTextField();
gbc.weightx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 1;
gbc.gridy = 0;
add(textField ,gbc);
label = new JLabel("text");
gbc.weightx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0;
gbc.gridy = 1;
gbc.gridwidth = 1;
add(label ,gbc);
textField = new JTextField();
gbc.weightx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 1;
gbc.gridy = 1;
gbc.gridwidth = 2;
add(textField, gbc);
label = new JLabel("text");
gbc.weightx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0;
gbc.gridy = 2;
gbc.gridwidth = 1;
add(label ,gbc);
textField = new JTextField();
gbc.weightx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 1;
gbc.gridy = 2;
gbc.gridwidth = 2;
add(textField, gbc);
label = new JLabel("text");
gbc.weightx = 1;
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0;
gbc.gridy = 3;
gbc.gridwidth = 1;
add(label ,gbc);
gbc.weightx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.anchor = GridBagConstraints.CENTER;
gbc.gridwidth = 2;
gbc.gridx = 1;
gbc.gridy = 3;
add(textArea, gbc);
gbc.weightx = 1;
button = new JButton("text");
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridwidth = 1;
gbc.gridx = 0;
gbc.gridy = 4;
add(button ,gbc);
gbc.weightx = 1;
button = new JButton("text");
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 3;
gbc.gridy = 4;
add(button ,gbc);
public static void main(String[] args)
AddressBookGui1 frame = new AddressBookGui1();
frame.setTitle("Address Book");
frame.setSize(400, 300);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
(我仍然需要处理填充和插入。我已经让它们在一个更简单的程序中工作,所以我想我已经掌握了这些东西)
我已经尝试了 GridBagLayout Oracle 教程,但我不确定我做错了什么。有人可以帮我让它看起来更像它应该的样子吗?专门使文本字段和文本区域跨越 2 个单元格。
【问题讨论】:
Specifically to make the text fields and text area span over 2 cells
- 为什么必须跨越两个单元格?在您的图片中,您有 2 列和 5 行。您唯一需要更改的是使按钮右对齐。为此,我想你需要和锚一起玩。再次查看教程。
我有 3 列。最后一个按钮在第 3 列中。
This is the grid I'm looking to make
这可能是您对作业的解释,但不需要我已经说过的 3 列。您只需要在第二列中右对齐按钮即可。如果分配的目标是创建 3 列并使用 gridwidth 约束,那很好,但这不是必需的。我猜你的问题是“文本”按钮的gridx=3
。请记住,行/列的偏移量为 0,因此您尝试将按钮定位在第 4 列,而不是第 3 列。
【参考方案1】:
gbc.gridwidth 是允许组件跨越多列的参数。例如,如果您有 3 列和 4 行并且您希望标签占据完整的顶行,那么您需要为标签分配第一个单元格。并设置 gbc.gridwidth = 3;
【讨论】:
【参考方案2】:我注意到你的代码的几件事。
不要使用 JFrame 的setSize()
。这将导致异常行为。
取而代之的是,让框架根据其大小自行调整大小
成分。如果您希望框架更大,请不要调整大小
框架,但其中的组件。你可以
setpreferredSize 或覆盖组件的 getpreferredsize 如果
您真正想要调整的是大小,因为 GridBagLayout 是那些尊重
组件的首选大小。使用pack()
删除不必要的
空间。
不要扩展 JFrame,让你的 UI 类有一个主面板和
在那里添加所有组件。为该面板提供一个吸气剂(例如
getUI()
) 用于提取该类的 UI。
始终重新实例化 GridBagConstraints 对象 将应用于另一个组件。这种方式更 可读。
使用 insets 在组件周围放置填充。
不要重复使用对不同组件的相同引用;
使用Initial Thread
这不是标准的,但我发现它在工作时非常有用
使用GridBagLayout
,在设置gbc的约束时,使其进入
按字母顺序。
为了解决您的问题,这里是修改后的代码,其中包含我指出的内容。
public class AddressBook
private JPanel pnlMain;
public AddressBook()
pnlMain = new JPanel();
pnlMain.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
JLabel lblName = new JLabel("Name");
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(0, 10, 0, 0);
gbc.weightx = 1;
pnlMain.add(lblName, gbc);
JTextField txtName = new JTextField();
gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridwidth = 3;
gbc.gridx = 1;
gbc.gridy = 0;
gbc.insets = new Insets(5, 0, 0, 10);
gbc.weightx = 1;
pnlMain.add(txtName, gbc);
JLabel lblPhone = new JLabel("Phone");
gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridwidth = 1;
gbc.gridx = 0;
gbc.gridy = 1;
gbc.insets = new Insets(0, 10, 0, 0);
gbc.weightx = 1;
pnlMain.add(lblPhone, gbc);
JTextField txtPhone = new JTextField();
gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridwidth = 3;
gbc.gridx = 1;
gbc.gridy = 1;
gbc.insets = new Insets(5, 0, 0, 10);
gbc.weightx = 1;
pnlMain.add(txtPhone, gbc);
JLabel lblEmail = new JLabel("Email");
gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridwidth = 1;
gbc.gridx = 0;
gbc.gridy = 2;
gbc.insets = new Insets(0, 10, 0, 0);
gbc.weightx = 1;
pnlMain.add(lblEmail, gbc);
JTextField txtEmail = new JTextField();
gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridwidth = 3;
gbc.gridx = 1;
gbc.gridy = 2;
gbc.weightx = 1;
gbc.insets = new Insets(5, 0, 0, 10);
pnlMain.add(txtEmail, gbc);
JLabel lblAddress = new JLabel("Address");
gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridwidth = 1;
gbc.gridx = 0;
gbc.gridy = 3;
gbc.insets = new Insets(0, 10, 0, 0);
gbc.weightx = 1;
pnlMain.add(lblAddress, gbc);
JTextArea txtAreaAddress = new JTextArea(10, 20);
JScrollPane pane = new JScrollPane(txtAreaAddress);
gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.NORTH;
gbc.fill = GridBagConstraints.BOTH;
gbc.gridwidth = 3;
gbc.gridx = 1;
gbc.gridy = 3;
gbc.insets = new Insets(5, 0, 0, 10);
gbc.weightx = 1;
pnlMain.add(pane, gbc);
JButton btnSave = new JButton("Save");
gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.WEST;
gbc.fill = GridBagConstraints.NONE;
gbc.gridwidth = 1;
gbc.gridx = 0;
gbc.gridy = 4;
gbc.insets = new Insets(10, 10, 10, 0);
gbc.weightx = 1;
pnlMain.add(btnSave, gbc);
JButton btnCancel = new JButton("Cancel");
gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.EAST;
gbc.gridwidth = 1;
gbc.gridx = 3;
gbc.gridy = 4;
gbc.insets = new Insets(10, 0, 10, 10);
gbc.weightx = 1;
pnlMain.add(btnCancel, gbc);
public JPanel getUI()
return pnlMain;
public static void main(String[] args)
SwingUtilities.invokeLater(new Runnable()
@Override
public void run()
JFrame frame = new JFrame("Address Book");
frame.getContentPane().add(new AddressBook().getUI());
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
);
【讨论】:
以上是关于如何使组件跨越 GridBagLayout 中的多个单元格的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 GridBagLayout 在 JPanel 中对齐组件中心?