我在代码中生成一些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上的文本设置为“-12”。即使JLabel看起来比文本宽得多,它也改变了它的大小,影响了其余的布局。
为什么会发生这种情况,我该怎么办才能阻止它?
答案 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
,否则以前的不合适大小没有变化。