Java 仅在必要时在FlowLayout中显示滚动条

Java 仅在必要时在FlowLayout中显示滚动条,java,swing,user-interface,Java,Swing,User Interface,我将重新表述我的问题:** 当有足够的空间通过扭曲显示所有项目时,如何防止在FlowLayout中启用Java滚动条 ** 下面是我试图实现的目标的屏幕截图: 请注意,滚动条在不需要时被禁用。 当您调整窗口大小时,如果某些项目在视图平面外,则应显示滚动条 另外,我知道称为文档和web的东西。默认的滚动条策略是根据需要设置的,但我记得必须考虑FlowLayout间隙,以便最初获得偶数。如果你延伸这个例子,你会看到水平滚动条消失了 更新:它并没有真正解决您的问题,但它显示了我是如何实现可滚动的。

我将重新表述我的问题:**

当有足够的空间通过扭曲显示所有项目时,如何防止在FlowLayout中启用Java滚动条

**

下面是我试图实现的目标的屏幕截图:

请注意,滚动条在不需要时被禁用。

当您调整窗口大小时,如果某些项目在视图平面外,则应显示滚动条


另外,我知道称为文档和web的东西。

默认的滚动条策略是根据需要设置的,但我记得必须考虑
FlowLayout
间隙,以便最初获得偶数。如果你延伸这个例子,你会看到水平滚动条消失了

更新:它并没有真正解决您的问题,但它显示了我是如何实现
可滚动的
。我想去掉
setPreferredSize()
,即使图像只是一个占位符。这篇文章讨论了
FlowLayout
的工作原理

import javax.swing.*;
import java.awt.*;
import java.util.Random;

public class ImageScrollTest extends JPanel implements Scrollable {

    private static final int N = 8;
    private static final int W = 120;
    private static final int H = 100;
    private final FlowLayout layout = new FlowLayout();
    private final int hGap = layout.getHgap();
    private final int vGap = layout.getVgap();
    private final Dimension size;

    // Show n of N images in a Scrollable FlowLayout
    public ImageScrollTest(int n) {
        setLayout(layout);
        for (int i = 0; i < N; i++) {
            this.add(new ImagePanel());
        }
        size = new Dimension(n * W + (n + 1) * hGap, H + 2 * vGap);
    }

    @Override
    public Dimension getPreferredScrollableViewportSize() {
        return size;
    }

    @Override
    public int getScrollableUnitIncrement(
        Rectangle visibleRect, int orientation, int direction) {
        return getIncrement(orientation);
    }

    @Override
    public int getScrollableBlockIncrement(
        Rectangle visibleRect, int orientation, int direction) {
        return getIncrement(orientation);
    }

    private int getIncrement(int orientation) {
        if (orientation == JScrollBar.HORIZONTAL) {
            return W + hGap;
        } else {
            return H + vGap;
        }
    }

    @Override
    public boolean getScrollableTracksViewportWidth() {
        return false;
    }

    @Override
    public boolean getScrollableTracksViewportHeight() {
        return false;
    }

    private static class ImagePanel extends JPanel {

        private static final Random rnd = new Random();
        private Color color = new Color(rnd.nextInt());

        public ImagePanel() {
            this.setBackground(color);
            this.setBorder(BorderFactory.createLineBorder(Color.blue));
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(W, H);
        }
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                createAndShowGUI();
            }
        });
    }

    private static void createAndShowGUI() {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        ImageScrollTest ist = new ImageScrollTest(N / 2);
        JScrollPane sp = new JScrollPane(ist);
        sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
        f.add(sp);
        f.pack();
        f.setVisible(true);
    }
}
import javax.swing.*;
导入java.awt.*;
导入java.util.Random;
公共类ImageScrollTest扩展JPanel实现可滚动{
专用静态最终整数N=8;
专用静态最终int W=120;
专用静态最终int H=100;
私有最终FlowLayout=新FlowLayout();
私有final int hGap=layout.getHgap();
private final int vGap=layout.getVgap();
私有最终尺寸;
//在可滚动的FlowLayout中显示n个图像中的n个
公共图像滚动测试(int n){
设置布局(布局);
对于(int i=0;i
当您希望滚动条显示时,应在滚动窗格中指定(可能在水平方向和垂直方向):

还有:
HORIZONTAL\u SCROLLBAR\u总是
HORIZONTAL\u SCROLLBAR\u从不
,如果您需要的话


编辑:有关更多信息以及我的确切答案:

您更新的屏幕截图表明您可能正在寻找。

“我目前拥有的是:“不可编译的代码片段”。为了更快地获得更好的帮助,请发布一个。“然而,与WPF相比,Java在必要时不会显示和隐藏滚动条”Java必须被破坏,使用WPF进行此操作。您可能正在寻找。这似乎解决了我遇到的问题。我唯一不明白的是为什么FlowLayout默认不这么做?我必须同意@camickr,
FlowLayout
是一种奇怪的动物!特别是“当组件包装到新行时,首选的大小不会改变,因此您永远不会在额外的行上看到组件。”我已经尝试过这一点。出于某些原因,Java没有在FlowLayoutWell中隐藏scroolbar,所有内容的宽度是否都大于窗口?发布一些代码,我们无法通过猜测帮助您更多…我得到的正是@Catalina IslandNope发布的内容,它不会一直显示滚动条。但我试图实现的是只在需要时显示滚动条。根据需要,我的意思是,如果包装面板可以包装项目,而不是显示滚动条,它应该这样做。好的,所以请发布一些代码,可能是JFrame创建,这样我们就可以看到问题所在…这是一个很好的例子+1。这正是我所拥有的。问题是,只要有一些可用空间,我希望“包装”面板包装项目,如果没有,则仅显示滚动条。不,您不必“考虑间隙”-这是layoutManager的工作。永远不要使用setXXSize。相反,让您的面板在各自的getXXSize方法中返回合理的计算大小提示setXXSize可能是正确的,但这不是讨论的重点。@Vitalij:现在我看到了您的更新,
WrapLayout
看起来是正确的答案。@kleopatra:您是对的;我对喜欢的尺码很懒。我分析了差距,以便在更新中实现
可滚动
。这是错的吗?不幸的是,对我来说,这看起来不是很GPL
myScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);