2012-02-02 123 views
8

我试图把一个JList一个JScrollPane内,并将它按字母顺序列出垂直列中的条目是这样的:JList - 使用垂直滚动条而不是水平垂直折叠方向?

A D G 
B E H 
C F 

然而,当JList用完的空间来显示更多的条目,我像JScrollPane滚动只有在垂直方向。

这个工程,当我用VERTICAL_WRAP。但是,它似乎是当我使用垂直包装我得到一个水平滚动条,当我使用HORIZONTAL_WRAP我得到我想要的滚动条,但项目被放置在一个我不喜欢的顺序。我可以吃我的蛋糕,也可以吃吗?这是我想要做的一个简单的例子。

enter image description here

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

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

一个解决方案我已经,虽然为: 如果单元格大小已知我可以创建一个组件侦听器,并监听resize事件。当事件被触发时,我可以计算所需的行数,以防止水平滚动。这看起来像一个黑客,我不知道它如何可以处理可变大小的文本组件。

+1

有趣的问题+1 – mKorbel 2012-02-02 19:41:56

+0

的原因,你正在使用的时候'越来越水平滚动条“VERTICAL_WRAP”是'VERICAL_WRAP =>表示单元垂直然后水平流动的“报纸样式”布局。“因此,如果单元格将垂直流动,并且由于尺寸的原因,输出将从底部缠绕,因此它将开始水平填充。因此一个水平滚动条。 – RanRag 2012-02-02 20:09:01

+0

这是有道理的,但我大部分尝试调整内部组件的尝试都没有达到我预期的效果。我将如何强制显示垂直滚动条,而不是水平滚动条?是否有我需要调整大小的特定组件? – Lockyer 2012-02-02 20:23:46

回答

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

我一直希望有一些明显的缺失,但看起来这可能是最简单的解决方案。 – Lockyer 2012-02-05 21:48:04

0

这是你要去的吗? (可能需要更改首选大小...)

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

没有抱歉,我应该明确说明我希望列表中的项目填充可用空间。所以当你水平地扩展窗口时,应该尽可能地添加一个额外的列。 – Lockyer 2012-02-03 13:38:30

0

艳代码@Kevinķ......我建议一个小的修改,以避免ArithmeticException(除数为零)

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

这似乎是在家里的评论,而不是一个自由的答案。 – Lockyer 2012-11-29 17:22:57