JList - 使用垂直滚动条而不是水平滚动条并具有垂直换行方向?

发布于 2025-01-02 02:46:24 字数 1397 浏览 0 评论 0原文

我试图将 JList 放置在 JScrollPane 内部,并让它按字母顺序列出垂直列中的条目,如下所示:

A D G
B E H
C F 

但是,当 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);
    }
}

我想到的一种解决方案是: 如果单元格大小已知,我可以创建一个组件侦听器,并侦听调整大小事件。当该事件被触发时,我可以计算所需的行数以防止水平滚动。这看起来像是一个黑客,我不确定它如何与可变大小的文本组件一起工作。

I'm trying to place a JList inside of a JScrollPane and have it alphabetically list the entries in vertical columns like this:

A D G
B E H
C F 

However when the JList runs out of space to display more entries, I'd like the JScrollPane to scroll only in the vertical direction.

This works when I use VERTICAL_WRAP. However, it seems like when I use vertical wrap I get a horizontal scrollbar and when I use HORIZONTAL_WRAP I get the scrollbar I want, but the items get placed in an order that I don't like. Can I have my cake and eat it too? Here's a simple example of what I'm trying to do.

enter image description here

This is the closest I could get, but I'd like to be able to scroll vertically while maintaining the vertical alphabetical ordering.

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);
    }
}

One solution I've though of is:
If the cell size is known I can create a component listener, and listen for a resize event. When that event is triggered I can calculate the desired row count in order to prevent horizontal scrolling. This just seems like a hack, and I'm not sure how it could work with variable sized text components.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

何以畏孤独 2025-01-09 02:46:24

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

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

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;
    }
}

I think your solution is just fine, and not a hack at all. Any built-in feature would have to do basically the same thing anyways.

Here's a modification to your example that does what you want.

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;
    }
}
落在眉间の轻吻 2025-01-09 02:46:24

这就是你想要的吗? (可能需要更改首选尺寸......)

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());
        final JScrollPane scrollPane = new JScrollPane(list);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
       scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        contentPane.add(scrollPane);
        frame.setPreferredSize(new Dimension(200,200));
        frame.pack();
        frame.setVisible(true);
    }
}

Is this what you're going for? (Might need to change the preferred size...)

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());
        final JScrollPane scrollPane = new JScrollPane(list);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
       scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        contentPane.add(scrollPane);
        frame.setPreferredSize(new Dimension(200,200));
        frame.pack();
        frame.setVisible(true);
    }
}
厌倦 2025-01-09 02:46:24

出色的代码@Kevin K...我建议进行一些小修改以避免ArithmeticException(除以零)

private int computeVisibleColumnCount(JList list) 
    {
        int cellWidth = list.getCellBounds(0, 0).width;
        int width = list.getVisibleRect().width;
        return width == 0 ? 1 : width / cellWidth;
    }

Brilliant Code @Kevin K... I suggest a small modification to avoid ArithmeticException (Divide by zero)

private int computeVisibleColumnCount(JList list) 
    {
        int cellWidth = list.getCellBounds(0, 0).width;
        int width = list.getVisibleRect().width;
        return width == 0 ? 1 : width / cellWidth;
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文