这是一个简单而不漂亮的解决方案:
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
编辑:
我认为这可能不适合你的情况.这是一个更好的解决方案,虽然它有很多样板:
private class ButtonContainerHost extends JPanel implements Scrollable {
private static final long serialVersionUID = 1L;
private final JPanel buttonContainer;
public ButtonContainerHost(JPanel buttonContainer) {
super(new BorderLayout());
this.buttonContainer = buttonContainer;
add(buttonContainer);
}
@Override
public Dimension getPreferredScrollableViewportSize() {
Dimension preferredSize = buttonContainer.getPreferredSize();
if (getParent() instanceof JViewport) {
preferredSize.width += ((JScrollPane) getParent().getParent()).getVerticalScrollBar()
.getPreferredSize().width;
}
return preferredSize;
}
@Override
public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
return orientation == SwingConstants.HORIZONTAL ? Math.max(visibleRect.width * 9 / 10, 1)
: Math.max(visibleRect.height * 9 / 10, 1);
}
@Override
public boolean getScrollableTracksViewportHeight() {
if (getParent() instanceof JViewport) {
JViewport viewport = (JViewport) getParent();
return getPreferredSize().height < viewport.getHeight();
}
return false;
}
@Override
public boolean getScrollableTracksViewportWidth() {
return true;
}
@Override
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
return orientation == SwingConstants.HORIZONTAL ? Math.max(visibleRect.width / 10, 1)
: Math.max(visibleRect.height / 10, 1);
}
}
它实现了Scrollable以完全控制滚动,通过跟踪视口高度来确保按钮在空间可用时展开,并在任何时候将垂直滚动条的宽度添加到首选宽度.它可以在垂直滚动条可见时展开,但无论如何看起来都很糟糕.像这样用它:
scrollPane = new JScrollPane(new ButtonContainerHost(buttonContainer));
在我看来,由于javax.swing.ScrollPaneLayout中可能存在错误,因此需要使用此解决方法:
if (canScroll && (viewSize.height > extentSize.height)) {
prefWidth += vsb.getPreferredSize().width;
}
这里,extentSize设置为视口的首选大小,viewSize设置为viewport.getViewSize().这似乎不正确,AFAIK视口内视图的大小应始终等于首选大小.在我看来,视图大小应该与视口的实际大小而不是其首选大小进行比较.