当前位置: 首页 > 面试题库 >

出现滚动条时,包含JPanel的JScrollPane调整大小

龙涵蓄
2023-03-14
问题内容

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视口内的视图大小应始终等于首选大小。在我看来,视图大小应该与视口的实际大小进行比较,而不是其首选大小。



 类似资料:
  • 我有一个JScrollPane,其中包含一个JPanel,该JPanel包含一组JPanels。 集合大小可以更改,这就是为什么我把它放在JScrollPane中的原因。 由于某种原因,无论我做什么,旋钮都不会出现在卷轴上。 正如您所看到的,主JPanel(预览)确实有一个布局。我读到如果布局为空,可能会发生这种情况。 有人知道怎么解决这个吗? null 这是我的代码:

  • 我有一个基本的JFrame--它包含一个JTable(由NetBeans swing GUI builder自动添加的JScrollPane包围,我希望保留滚动窗格)。 当从按钮单击实例化框架时,JTable中的行数可能会根据它是从哪个按钮打开的而改变。我想调整JTable的大小,这样如果只有2行,它就不会因为有额外的空间而看起来很傻。包含JTable的JScrollPane似乎是给我带来问题的原

  • 我有一个类可以画一些非常简单的图形,比如直线、圆和矩形。线条可以动态扩展,有时当它们扩展到超出分辨率时,如果没有滚动条,就无法看到。因此,我已经将JScrollPane添加到JFrame中,但不幸的是,尽管已经调用了布局管理器,但滚动条还是无法滚动。 这是我所拥有的:-一个绘制组件(线条、矩形、圆形)的类-一个设置JFrame/JScrollPane的类 这是我的GUI类的摘录代码: 通过上面的代

  • 问题内容: 我想要实现以下目标: 我能获得的最接近的是以下(伪)代码: 每当我想添加组件时,就将它们添加到内部容器中: ....等 我面临以下问题: 我让布局管理器负责所有UI元素的大小。所以最好不要使用任何.setxxSize()方法。一个JTextArea,包含大量文本,将使用所有需要的空间(垂直和水平)。完全没问题。每当调整框架的大小时,JTextArea都会增长,这仍然是可以的。但是每当我

  • 使用Java,我用GridBagLayout创建一个表单。GUI在一个J面板中,它在一个添加到JFrame的scrollPane中。 我希望带有GUI的JPanel的大小是固定的,以防止表单被拉伸,但是,我希望JScrollPanel可以根据用户的喜好调整大小。(类似于MS Paint,画布是我的JPanel)。我想要防止表单被拉伸的原因是因为我希望它能够打印,并且从我现在的方式来看,打印的表单几

  • 问题内容: 我需要在JScrollPane中内容的 左侧 放置一个滚动条。是否可以在没有单独的JScrollBar组件的情况下完成?也许只是通过设置一些对齐方式? 问题答案: 通过反复试验,我发现 像魅力一样运作。