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

我在代码中生成一些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的宽度。 以下两个屏幕截图展示了我的意思(红色和蓝色边框用于调试目的):

更改JLabel文本之前的布局。

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

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

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

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

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

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

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

 slider.setFocusable(false); 

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

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

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

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

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

基于分配给每列中的组件的水平权重来分配左上空间。 权重总计,每列的百分比基于该列的总百分比确定。

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

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

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

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