出现滚动条时,包含JPanel的JScrollPane调整大小
JScrollPane
在Java应用程序中使用时,我遇到了一个小问题。
我有JScrollPane
一个JPanel
。这JPanel
被动态地与按钮(垂直排序),其可以是任何宽度的更新。的JPanel
自动调整其宽度最大的JButton
部件内部。
现在,当出现垂直滚动条时,它会占用my右侧的一些空间JPanel
,这将导致最大的按钮无法完全显示。除了显示整个按钮之外,我不想使用水平滚动条。
JPanel
当滚动条出现时,是否有办法调整我的大小,使其很好地显示在我的按钮旁边?还是有其他方法可以使滚动条出现在我的旁边JPanel
?
提前致谢!
:这是我的问题的演示。将窗口调整为较小的高度时,右侧按钮的一小部分将被覆盖。
import java.awt.BorderLayout;import java.awt.EventQueue;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import java.awt.GridLayout;
/**
* @author Dylan Kiss
*/
public class Demo {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
JFrame myFrame = new JFrame("Demo");
JPanel sideBar = new JPanel();
JPanel centerPanel = new JPanel();
centerPanel.add(new JLabel("This is the center panel."));
JPanel buttonContainer = new JPanel();
JButton myButton = null;
for (int i = 0; i < 20; i++) {
buttonContainer.setLayout(new GridLayout(20, 1, 0, 0));
myButton = new JButton("This is my button nr. " + i);
buttonContainer.add(myButton);
}
sideBar.setLayout(new BorderLayout(0, 0));
JScrollPane scrollPane = new JScrollPane(buttonContainer);
sideBar.add(scrollPane);
myFrame.getContentPane().add(sideBar, BorderLayout.WEST);
myFrame.getContentPane().add(centerPanel, BorderLayout.CENTER);
myFrame.setLocationByPlatform(true);
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myFrame.pack();
myFrame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
回答:
这是一个简单的解决方案:
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视口内的视图大小应始终等于首选大小。在我看来,视图大小应该与视口的实际大小进行比较,而不是其首选大小。
以上是 出现滚动条时,包含JPanel的JScrollPane调整大小 的全部内容, 来源链接: utcz.com/qa/419618.html