如何在GridBagLayout中使组件跨越多个单元格?

11

我需要为学校做这个:

GUI

这是我目前的代码:

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个单元格。


具体来说,是为了使文本字段和文本区域跨越2个单元格。为什么它们必须跨越两个单元格?在您的图片中,您有2列和5行。您需要改变的唯一一件事就是将按钮右对齐。为此,我想您需要调整锚点。请再次查看教程。 - camickr
我有三列。最后一个按钮在第三列。 - user2503535
这是我想要制作的网格:http://i.imgur.com/RXuoawF.png - user2503535
2
这可能是您对任务的理解,但是我已经说过没有必要使用3列。您只需要将按钮右对齐到第二列即可。如果任务的目标是创建3列并使用gridwidth约束进行操作,则可以这样做,但这不是必需的。我猜您的问题在于“文本”按钮的gridx=3。请记住,行/列从0开始计数,因此您正在尝试将按钮定位在第4列而不是第3列。 - camickr
2个回答

11

gbc.gridwidth是一个参数,允许组件跨越多个列。例如,如果您有3个列和4个行,并且您想要一个标签占据整个顶部行,则需要为标签分配第一个单元格,并设置gbc.gridwidth = 3;


10

我注意到您的代码中有一些问题。

  • 不要使用JFrame的setSize()方法,否则会导致异常行为。相反,让窗口根据其组件自动调整大小。如果您想要更大的窗口,请调整窗口内部的组件而不是窗口的大小。如果您真的想要调整组件的大小,则可以使用setPreferredSize或覆盖组件的getPreferredSize。因为GridBagLayout是其中一个尊重组件preferredSize的布局管理器。使用pack()方法来去除不必要的空间。

  • 不要继承JFrame,而是让您的UI类拥有一个主面板并将所有组件添加到该面板上。提供一个getter(例如getUI())以提取该类的UI。

  • 每当GridBagConstraints对象将被应用于另一个组件时,都要重新实例化它。这样更易读。

  • 使用insets在组件周围添加填充。

  • 不要重复使用同一引用来引用不同的组件。

  • 使用初始线程

  • 这不是标准的做法,但我发现在使用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);
            }
        });
    }

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接