让Java布局管理器使用JTextFields和JLabel

时间:2015-02-04 10:39:17

标签: java swing gridbaglayout flowlayout boxlayout

我在使用Java的Swing布局管理器时遇到一些麻烦。这是我第一次尝试创建自己的GUI,所以我可能只是错过了一些相当简单的东西,不过我会很感激任何可以提供的建议。

我想要创建的是一个包含JLabel和JTextFields的自定义JPanel,允许用户输入一个IP地址(因此四个JTextFields与三个JLabel包含一个'。')

我发现很难找到一个可以按照我的意愿设置它的布局管理器;我已经尝试了Flow和Box布局,因为这些都没有用,我也尝试了一个GridBag,我认为这可能是矫枉过正,但即使这样做也不行。

这是启动课程的代码:

public class PingPanel extends JPanel {
    private JLabel[] dotLabels;
    private JTextField[] pingFields;

    public PingPanel() {
        Dimension dim = getPreferredSize();
        dim.width = 400;
        setPreferredSize(dim);

        dotLabels = new JLabel[3];
        for (int i = 0; i < dotLabels.length; i++) {
            dotLabels[i] = new JLabel(".");
        }

        pingFields = new JTextField[4];
        for (int i = 0; i < pingFields.length; i++) {
            pingFields[i] = new JTextField(3);
        }

        Border panelBorder = BorderFactory.createLineBorder(Color.BLACK);
        setBorder(panelBorder);

        //setupFlow();
        //setupBox();
        //setupGridBag();

我只将面板的宽度设置为400以尝试显示所有内容(正如您稍后会看到的那样,我也没有太多运气。我知道有些经理无论如何都会忽略首选尺寸,这可能就是为什么它不起作用的原因。我创建了三种方法来尝试不同的布局管理器;在这里,他们产生的效果是:

public void setupFlow() {
    for (int p = 0; p < pingFields.length; p++) {
        if (p == dotLabels.length) {
            add(pingFields[p]);
            System.out.println(p + " (Final Column)");
        }

        else {
            add(pingFields[p]);
            add(dotLabels[p]);
            System.out.println(p);
        }
    }
}

FlowLayout产生了这个:

FlowLayout

这是我想要的最接近的样子,但我不确定为什么我只得到一个JTextField和一个Label。

public void setupBox() {
    Container pingBox = Box.createHorizontalBox();

    for (int p = 0; p < pingFields.length; p++) {
        if (p == dotLabels.length) {
            pingBox.add(pingFields[p]);
            System.out.println(p + " (Final Column)");
        }

        else {
            pingBox.add(pingFields[p]);
            pingBox.add(dotLabels[p]);
            System.out.println(p);
        }
    }
}

Box Layout

这就是BoxLayout给我的。我完全不知道我是如何搞砸这个的!

public void setupGridBag() {
    setLayout(new GridBagLayout());
    GridBagConstraints gc = new GridBagConstraints();

    gc.gridy = 0;
    gc.gridx = 0;
    gc.weightx = 1.0;
    gc.weighty = 1.0;
    gc.fill = GridBagConstraints.HORIZONTAL;

    add(pingFields[0], gc);

    gc.gridx++;
    add(dotLabels[0], gc);

    gc.gridx++;
    add(pingFields[1], gc);

    gc.gridx++;
    add(dotLabels[1], gc);

    gc.gridx++;
    add(pingFields[2], gc);

    gc.gridx++;
    add(dotLabels[2], gc);

    gc.gridx++;
    add(pingFields[3], gc);
}

GridBag

GridBagLayout至少为我提供了我正在寻找的布局,但是我还没有弄清楚如何使JTextField更宽。

所以我们有 - 我确定我的绿色让我错过了一些明显的东西,但如果有人有任何想法,我会非常感激。

1 个答案:

答案 0 :(得分:0)

通常GridBagLayout就是你所追求的。将其视为基于网格的布局,并为每个组件定制对齐;此外,每个组件都可以占用多个列和行,从而实现完全自定义设置。

我得到了一些示例代码,如下所示:

    GridBagLayout gridBagLayout = new GridBagLayout();
    gridBagLayout.columnWidths = new int[] {30, 30, 60, 60, 60, 30, 30};
    gridBagLayout.rowHeights = new int[] {18, 18, 18, 18, 18, 18, 18, 18, 18};
    gridBagLayout.columnWeights = new double[] {0.1, 0.1, 0.2, 0.2, 0.2, 0.1, 0.1};
    gridBagLayout.rowWeights = new double[] {0.125, 0.125, 0.1, 0.1, 0.1, 0.1, 0.1, 0.125, 0.125};
    setLayout(gridBagLayout);

    JLabel labelLong = new JLabel("Long");
    labelLong.setForeground(Color.DARK_GRAY);
    labelLong.setFont(DisplayConstants.FONT_PANEL_LABEL_BOLD);
    GridBagConstraints gbc_labelLong = new GridBagConstraints();
    gbc_labelLong.insets = new Insets(0, 0, 5, 5);
    gbc_labelLong.gridx = 0;
    gbc_labelLong.gridy = 0;
    add(labelLong, gbc_labelLong);

    JLabel labelShort = new JLabel("Short");
    labelShort.setForeground(Color.DARK_GRAY);
    labelShort.setFont(DisplayConstants.FONT_PANEL_LABEL_BOLD);
    GridBagConstraints gbc_labelShort = new GridBagConstraints();
    gbc_labelShort.insets = new Insets(0, 0, 5, 0);
    gbc_labelShort.gridx = 6;
    gbc_labelShort.gridy = 0;
    add(labelShort, gbc_labelShort);

如果你只是在一个简单的布局之后,那么BorderLayout就是你要做的。将固定尺寸组件放在侧面,将主要组件放在中心位置。

另外,值得一提的是,Java使用每个组件的setPreferredSize()来指定其他大小参数,因此GUI布局将尽力满足每个组件的首选大小。在构造完成后调用JFrame.pack()来安排组件。