出现滚动条时,包含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

回到顶部