JList - 使用垂直滚动条而不是水平垂直包裹方向?

Loc*_*yer 8 java user-interface swing jscrollpane jlist

我正在尝试放置一个JList内部JScrollPane并按字母顺序列出垂直列中的条目,如下所示:

A D G
B E H
C F 
Run Code Online (Sandbox Code Playgroud)

但是当JList空间用完以显示更多条目时,我希望在垂直方向JScrollPane上滚动.

这在我使用时有效VERTICAL_WRAP.然而,似乎当我使用垂直包装时,我得到一个水平滚动条,当我使用时,HORIZONTAL_WRAP我得到我想要的滚动条,但是项目按照我不喜欢的顺序放置.我可以吃蛋糕吗?这是我正在尝试做的一个简单的例子.

在此输入图像描述

这是我能得到的最接近的,但我希望能够在保持垂直字母顺序的同时垂直滚动.

public class ScrollListExample {
    static List<String> stringList = new ArrayList<String>();
    static {
        for (int i = 0; i < 500; i++) {
            stringList.add("test" + i);
        }
    }

    public static void main(final String[] args) {
        final JFrame frame = new JFrame();
        final Container contentPane = frame.getContentPane();
        final JList list = new JList(stringList.toArray());
        list.setLayoutOrientation(JList.VERTICAL_WRAP);
        list.setVisibleRowCount(0);
        final JScrollPane scrollPane = new JScrollPane(list);
        contentPane.add(scrollPane);
        frame.setPreferredSize(new Dimension(800, 400));
        frame.pack();
        frame.setVisible(true);
    }
}
Run Code Online (Sandbox Code Playgroud)

我遇到的一个解决方案是:如果单元格大小已知,我可以创建一个组件监听器,并监听resize事件.当触发该事件时,我可以计算所需的行数以防止水平滚动.这看起来像是一个黑客,我不知道它如何适用于可变大小的文本组件.

Kev*_*n K 2

我认为你的解决方案很好,根本不是黑客。无论如何,任何内置功能都必须做基本相同的事情。

这是对您的示例的修改,可以满足您的要求。

public class ScrollListExample {
    static List<String> stringList = new ArrayList<String>();
    static {
        for (int i = 0; i < 500; i++) {
            stringList.add("test" + i);
        }
    }

    public static void main(final String[] args) {
        final JFrame frame = new JFrame();
        final Container contentPane = frame.getContentPane();
        final JList list = new JList(stringList.toArray());
        list.setLayoutOrientation(JList.VERTICAL_WRAP);
        final JScrollPane scrollPane = new JScrollPane(list);
        contentPane.add(scrollPane);
        frame.setPreferredSize(new Dimension(800, 400));
        frame.pack();

        list.addComponentListener(new ComponentAdapter() {
            @Override
            public void componentResized(ComponentEvent e) {
                fixRowCountForVisibleColumns(list);
            }
        });

        fixRowCountForVisibleColumns(list);
        frame.setVisible(true);
    }

    private static void fixRowCountForVisibleColumns(JList list) {
        int nCols = computeVisibleColumnCount(list);
        int nItems = list.getModel().getSize();

        // Compute the number of rows that will result in the desired number of
        // columns
        int nRows = nItems / nCols;
        if (nItems % nCols > 0) nRows++;
        list.setVisibleRowCount(nRows);
    }

    private static int computeVisibleColumnCount(JList list) {
        // It's assumed here that all cells have the same width. This method
        // could be modified if this assumption is false. If there was cell
        // padding, it would have to be accounted for here as well.
        int cellWidth = list.getCellBounds(0, 0).width;
        int width = list.getVisibleRect().width;
        return width / cellWidth;
    }
}
Run Code Online (Sandbox Code Playgroud)