2

在下面的示例中,我有一个带有 BoxLayout 的 JPanel,其中包含另一个带有 GridBagLayout 的 JPanel。

通过添加垂直胶水,我希望内面板的内容被“粘合”到外面板的顶部。

但我在中间看到标签“A”。如果我删除 GridBagLayout,A 会显示在顶部。为什么会这样?

import javax.swing.*;
import java.awt.*;

public class Test {
    public static void main(String[] args) {
        JPanel contentPane = new JPanel();        

        JFrame frame = new JFrame();
        frame.setContentPane(contentPane);

        contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));

        JPanel gridBagPanel = new JPanel();
        gridBagPanel.setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.fill = GridBagConstraints.NONE;

        gridBagPanel.add(new JLabel("A"), gbc);
        contentPane.add(gridBagPanel);
        contentPane.add(Box.createVerticalGlue());

        frame.setSize(800, 200);
        frame.setVisible(true);
    }
}
4

3 回答 3

3

因为 的anchor属性的默认值GridBagConstraintsCENTER。如果内部面板中的空间大于 JLabel 的首选大小,则 JLabel 将相对于内部面板中的可用空间居中(因为您将填充设置为 NONE)。

您可以使用锚值NORTHWEST将标签粘贴到面板顶部:

GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.NONE;
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.weighty = 1;
gbc.weightx = 1;

您还需要根据 Java 文档设置权重:“除非您为 weightx 或 weighty 指定至少一个非零值,否则所有组件都会在其容器的中心聚集在一起。这是因为当权重为 0.0(默认),GridBagLayout 会在其单元格网格和容器边缘之间放置任何额外的空间。

于 2011-12-29T18:40:48.220 回答
1

这可能是因为GridBagLayout很麻烦,您应该考虑使用其他布局管理器。或者您可能需要设置组件的水平和垂直对齐方式。看看setAlignmentX和。setAlignmentY_ JComponent每当我有行为不端的组件时,那是因为我没有将所有内容都对齐。

于 2011-12-29T18:30:49.737 回答
0

尽管Kavka 的答案通过使用锚点解决了在面板顶部放置 A 的要求,但我相信 BoxLayout Panel 中声明的垂直粘合实际上并没有做任何事情。因此,我将对此进行扩展,以贡献我对在 GridBagLayouts 中使用权重和垂直粘合的想法。

由于 GridBagLayout 是一个复杂的布局,可能有不止一个原因,但正如 Kavka 已经指出的那样:

从默认值 0.0 修改为weightx非零是关键。weighty

正如GridBagConstraints 的 Java 教程文档中所指出的,在GridBagLayout的 JavaDoc 的描述部分和GridBagConstraints的 JavaDoc 中的具体参数描述中。

如果所有的权重都为零,则所有额外的空间都会出现在单元格的网格之间,并且

  • 对于weightx,额外的空间出现在左右边缘之间。
  • 对于重量来说,额外的空间出现在顶部和底部边缘之间。

因此,如果您想使用一些垂直胶水来填充空单元格,您需要确保在您希望它扩展的方向上为胶水组件赋予非零权重。我将仅使用 GridBagLayout,因此该gridy参数将允许我定义组件的垂直分布。

以原始代码为示例基础并对其进行一些扩展,以展示垂直粘合与权重相结合的能力。此代码将 A 定位在距面板顶部 20% 的位置,在调整大小时保持此比例:

import javax.swing.*;
import java.awt.*;

public class Test {
    public static void main(String[] args) {   
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel gridBagPanel = new JPanel();
        gridBagPanel.setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();

        gbc.gridy = 0;
        gbc.weighty = 0.2;
        gridBagPanel.add(Box.createVerticalGlue(), gbc);
        gbc.gridy = 1;
        gbc.weighty = 0;
        gridBagPanel.add(new JLabel("A"), gbc);
        gbc.gridy = 2;
        gbc.weighty = 0.8;
        gridBagPanel.add(Box.createVerticalGlue(), gbc);

        frame.setContentPane(gridBagPanel);
        frame.setSize(800, 200);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

有关胶水如何工作的详细信息,请参阅有关如何使用 BoxLayout 的 Java 教程,填充部分

于 2014-05-07T14:03:52.530 回答