5

我正在代码中生成一些 JComponents 并使用 GridBag 布局来排列它们。我的布局由 12 行和 3 列组成,每行由一个 JSlider、一个 JCheckBox 和一个 JLabel 组成。这是我用来生成 UI 的代码:

final int NUM_MOTORS = 12;

// This is the panel I'm adding the components to.
pnlMotorSliders.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();

for (int i = 0; i < NUM_MOTORS; ++i) {
    c.gridy = i;

    // Create the slider
    JSlider slider = new JSlider(SwingConstants.HORIZONTAL, 10, 4085, 10);
    c.fill = GridBagConstraints.HORIZONTAL;
    c.gridx = 0;
    c.weightx = 0.9;
    pnlMotorSliders.add(slider, c);

    // Create the checkbox
    JCheckBox checkBox = new JCheckBox();
    checkBox.setOpaque(true);
    checkBox.setBackground(Color.blue);
    c.fill = GridBagConstraints.NONE;
    c.gridx = 1;
    c.weightx = 0.1;
    pnlMotorSliders.add(checkBox, c);

    // Create the current label
    JLabel label = new JLabel("0");
    label.setBorder(BorderFactory.createLineBorder(Color.red));
    c.fill = GridBagConstraints.HORIZONTAL;
    c.gridx = 2;
    c.weightx = 0.2;
    pnlMotorSliders.add(label, c);
}

我遇到的问题是,当我在任何 JLabels 中设置文本时,它们会改变它们的宽度并影响布局的其余部分,即使我设置的文本的宽度看起来比JLabel 的宽度。以下两个屏幕截图演示了我的意思(红色和蓝色边框用于调试目的):

更改 JLabel 文本之前的布局。

更改底部 JLabel 文本后的布局。 注意标签是如何变大的。

我已将底部 JLabel 上的文本设置为“-12”。尽管 JLabel 看起来比文本宽得多,但它已经改变了它的大小,影响了布局的其余部分。

为什么会发生这种情况,我能做些什么来防止它发生?

4

4 回答 4

5

您可以通过设置最小、首选和最大尺寸来固定标签的尺寸:

label.setMinimumSize(width, height);
label.setPreferedSize(width, height);
label.setMaximumSize(width, height);

还要确保将 GridBagConstraints#fill 设置为 NONE,尽管我不确定这是否仍然必要(我认为是)。

编辑:顺便说一句,要摆脱聚焦组件周围的那些讨厌的虚线,您可以将其设置为不可聚焦:

slider.setFocusable(false);
于 2012-06-05T12:24:16.567 回答
2

设置首选大小的解决方案仅在您没有组件水平填充它们在 GridBagLayout 中的包时才有效。

另一种解决方案是删除您在 GridBagLayout 的该列中放置在组件上的权重。然后,您可以手动控制列宽。这样做的一种简单方法(在设计时)是将 JLabel 放置在具有零高度和您想要的特定宽度的列中。

为什么是这样?您需要深入了解 GridBagLayout 的工作原理:

GridBagLayout 根据所需空间调整其列的大小,然后使用权重分配“剩余”空间,以便生成的列宽加起来等于面板的总宽度。每列所需的空间是通过查找该列中最宽的组件来计算的。

每个组件所需的空间是通过询问它想要的宽度来确定的。在您的情况下,带有“0”的 JLabel 小于带有“-12”的 JLabel,因此该列正在改变大小。

剩余空间是根据分配给每列中组件的水平权重分配的。对权重进行总计,每列的百分比是根据该列占总数的百分比确定的。

列大小是根据所需空间加上剩余空间确定的。因此,如果列中的所有组件都没有权重,那么您将不会获得任何剩余空间,因此不会获得动态变化。

第三种解决方案是不使用 GridBagLayout。

于 2013-04-04T12:32:46.187 回答
0

使用明确设置标签的首选大小JLabel#setPreferredSize(Dimension)

这样,您锁定了组件的大小,并告诉布局管理器不要调整它的大小。

于 2012-06-05T12:19:47.563 回答
0
label.setPreferredSize(new Dimension(width, height));

这是我能找到使它工作的唯一方法。设置 aMinimum和/或 aMaximum对我没有任何作用。另外,对我来说,在 java 8 上我需要使用 a Dimension,或者对以前的不合适的大小没有任何变化。

于 2018-11-14T01:31:00.463 回答