当文本发生变化时,如何阻止JLabel更改其大小?

时间:2012-06-05 12:13:09

标签: java swing jlabel resize gridbaglayout

我在代码中生成一些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);
}

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

The layout before changing the JLabel text.

The layout after changing the bottom JLabel text. Notice how the label has gotten bigger.

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

为什么会发生这种情况,我该怎么办才能阻止它?

4 个答案:

答案 0 :(得分:5)

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

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

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

编辑:顺便说一下,为了摆脱焦点组件周围那些令人讨厌的虚线,你可以把它设置为不可聚焦:

slider.setFocusable(false);

答案 1 :(得分:1)

只有在GridBagLayout中没有组件水平填充其包时,set-the-preferred-size解决方案才有效。

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

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

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

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

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

根据剩余空间所需的空间确定列大小。因此,如果列中的所有组件都没有重量,那么您将不会留下任何空间,因此无法获得动态更改。

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

答案 2 :(得分:0)

使用JLabel#setPreferredSize(Dimension)显式设置标签的首选尺寸。

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

答案 3 :(得分:0)

label.setPreferredSize(new Dimension(width, height));

这是我找到使其工作的唯一途径。设置Minimum和/或Maximum对我没有任何帮助。另外,对于Java 8的我来说,我需要使用Dimension,否则以前的不合适大小没有变化。