GridBagLayout 面板展开忽略 BoxLayout 的垂直粘附



在下面的例子中,我有一个带有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);
    }
}

因为"GridBagConstraints"的"anchor"属性默认为"CENTER"。如果内部面板中的空间大于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(默认值)时,griddbaglayout会在其单元格网格和容器边缘之间放置任何额外的空间"

这可能是因为GridBagLayout是一个痛苦的屁股,你应该考虑使用其他布局管理器。或者,您可能需要设置组件的水平和垂直对齐。看看JComponentsetAlignmentXsetAlignmentY。每当我有错误的组件,那是因为我没有对齐所有的东西。

虽然Kavka的答案解决了使用锚点在面板顶部有A的要求,但我相信在BoxLayout面板中声明的垂直胶水实际上没有做任何事情。因此,我将对此进行扩展,以贡献我在griddbaglayouts中使用权重和垂直粘合的方法。

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

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

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

如果所有权重都为零,则单元格的网格和

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

所以,如果你想使用一些垂直胶水来填充空单元格,你需要确保在你想要它扩展的方向上给胶水组件一个非零权重。我将单独使用griddbaglayout,因此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);
    }
}

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

相关内容

  • 没有找到相关文章

最新更新