我制作了一个自定义LayoutManager,在提供的空间中以均匀的正方形渲染组件,它通过使用以下方法来实现:
@Override
public void layoutContainer(Container parent) {
if(parent.getWidth() == 0) {
return;
}
int columns = parent.getWidth() / gridSizeWidth;
int x = 0, y = 0;
for(int i = 0; i < parent.getComponentCount(); i++) {
Component comp = parent.getComponent(i);
comp.setBounds(x * gridSizeWidth, y * gridSizeHeight, gridSizeWidth, gridSizeHeight);
if(++x == columns) {
x = 0;
y++;
}
}
System.out.println(parent.getClass().getSimpleName() + ": " + parent.getWidth());
}
当直接应用于JFrame时,这段代码可以正常工作,但如果我试图将它插入到JScrollPane中,那么它很快就会崩溃。
当它只被添加到JFrame并且看起来正确时,控制台读取:
TileScroller: 422
但是,当将它添加到JScrollPane中时。。。
TileScroller: 419
TileScroller: 26816
TileScroller: 1716224
TileScroller: 109838336
TileScroller: 419
TileScroller: 26816
TileScroller: 1716224
TileScroller: 109838336
TileScroller: 419
...
它非常快速地重复这一过程,并因快速更改布局而产生闪烁效果。据我所见,它正确地将每个组件放置在每个尺寸的正确位置,但问题是尺寸在波动。
这是我创建JScrollPane的代码。
JPanel modeIndividualTile = new JPanel();
JScrollPane tileScroller = new JScrollPane(tileSelector = new TileScroller(creator),
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
tileScroller.getVerticalScrollBar().setUnitIncrement(8);
modeIndividualTile.add(tileScroller);
// Custom layout manager that renders everything relatively to the designated values below. (20,65) will render at x=20% of width, y=65% of height.
rl.addComponent(frame, tileScroller, 20, 65, 80, 98);
造成这种情况的原因是什么?我该如何预防?
问题是因为preferredLayoutSize和minimumLayoutSize的inprompter实现。正确使用这些方法修复了它。