【问题标题】:JList - use a vertical scrollbar instead of horizontal with a vertical wrap orientation?JList - 使用垂直滚动条而不是垂直环绕方向的水平滚动条?
【发布时间】:2012-02-25 11:38:36
【问题描述】:

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

A D G
B E H
C F 

但是,当JList 用完空间来显示更多条目时,我希望JScrollPane仅在垂直方向滚动。 p>

这在我使用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);
    }
}

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

【问题讨论】:

  • 使用VERTICAL_WRAP 时获得水平滚动条的原因是`VERICAL_WRAP => 表示单元格垂直流动然后水平流动的“报纸风格”布局。所以,如果单元格将垂直流动并到期到您的尺寸,输出将从底部包裹,因此它将开始水平填充。因此有一个水平滚动条。
  • 这是有道理的,但我调整内部组件大小的大部分尝试都没有达到我的预期。我将如何强制它显示垂直滚动条,而不是水平滚动条?我需要调整特定组件的大小吗?
  • @Lockyer:您需要的确切输出是什么,因为您可以使用HORIZONTAL_WRAP 获得vertical scrollbar,正如您所提到的。您需要的顺序是什么。
  • 我希望列表中的元素按字母顺序在窗口中垂直向下移动,以便更容易在视觉上扫描。就像您在 Windows 中选择“列表”视图时资源管理器所做的那样。
  • 我要指出,资源管理器的列表视图使用水平滚动条,至少在 Windows XP 上是这样。

标签: java swing user-interface jscrollpane jlist


【解决方案1】:

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

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

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

【讨论】:

  • 我希望有一些明显的我遗漏的东西,但似乎这可能是最简单的解决方案。
【解决方案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());
        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);
    }
}

【讨论】:

  • 不抱歉,我应该明确声明我希望列表中的项目填满可用空间。因此,当您水平扩展窗口时,应尽可能多添加一列。
【解决方案3】:

Brilliant Code @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;
    }

【讨论】:

  • 这看起来更像是在评论中,而不是作为一个独立的答案。
猜你喜欢
  • 2012-11-14
  • 2014-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-17
  • 2013-11-05
相关资源
最近更新 更多