【问题标题】:Getting Java Layout Managers to Behave with JTextFields and JLabels让 Java 布局管理器与 JTextFields 和 JLabels 一起工作
【发布时间】:2015-02-04 10:39:17
【问题描述】:

我在让 Java 的 Swing 布局管理器正常运行时遇到了一些麻烦。这是我第一次尝试创建自己的 GUI,所以我可能只是错过了一些相当简单的东西,但我希望能提供任何建议。

我要创建的是一个自定义 JPanel,其中包含 JLabels 和 JTextFields 以允许用户输入 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 产生这个:

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

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);
        }
    }
}

这就是 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);
}

GridBagLayout 至少为我提供了我正在寻找的布局,但我无法弄清楚如何使 JTextFields 更宽。

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

【问题讨论】:

  • 您可以将 MinimumSize 设置为默认宽度,但这也不是最好的方法。
  • 1) 为了尽快获得更好的帮助,请发布MCVE(最小完整可验证示例)或SSCCE(简短、自包含、正确示例)。 2) 提供最小尺寸的 ASCII 艺术或简单的 GUI 布局图,如果可调整大小,则具有更大的宽度和高度。
  • 我很抱歉,我没有意识到我没有提供足够的信息。
  • 我已经设法解决了这个问题 - 显然删除 setPreferredSize 的代码已经使 FlowLayout 和 GridBagLayout 都能正常工作。 BoxLayout 看起来仍然很可怕,但现在无需担心。

标签: java swing gridbaglayout flowlayout boxlayout


【解决方案1】:

通常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()安排组件。

【讨论】:

  • 我是否认为 BorderLayout 不适用于我的 PingPanel,因为我试图将七个组件连续排列?
  • @lordchancellor 正确。 GridBagLayout 就是为此。您可以使用它创建非常复杂的自定义布局。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-02
相关资源
最近更新 更多