2012-02-02 117 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