2012-02-02 18 views
8

Tôi đang cố gắng để đặt một JList bên trong một JScrollPane và có nó theo thứ tự abc danh sách các mục trong cột dọc như thế này:JList - sử dụng thanh cuộn dọc thay vì nằm ngang với hướng cuộn dọc?

A D G 
B E H 
C F 

Tuy nhiên khi JList chạy ra khỏi không gian để hiển thị thêm mục, tôi muốn giống như JScrollPane để cuộn chỉ theo hướng thẳng đứng.

Tính năng này hoạt động khi tôi sử dụng VERTICAL_WRAP. Tuy nhiên, nó có vẻ như khi tôi sử dụng bọc dọc tôi nhận được một thanh cuộn ngang và khi tôi sử dụng HORIZONTAL_WRAP Tôi nhận được thanh cuộn tôi muốn, nhưng các mục được đặt theo thứ tự mà tôi không thích. Tôi có thể ăn bánh của tôi không? Đây là một ví dụ đơn giản về những gì tôi đang cố gắng làm.

enter image description here

này là gần nhất tôi có thể nhận được, nhưng tôi muốn để có thể cuộn theo chiều dọc trong khi duy trì trật tự chữ cái đứng.

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

Một giải pháp tôi đã mặc dù là: Nếu kích thước tế bào được biết tôi có thể tạo ra một người biết lắng nghe thành phần, và lắng nghe cho một sự kiện thay đổi kích thước. Khi sự kiện đó được kích hoạt, tôi có thể tính toán số hàng mong muốn để ngăn cuộn ngang. Điều này chỉ có vẻ như một hack, và tôi không chắc làm thế nào nó có thể làm việc với các thành phần văn bản có kích thước biến.

+1

đẹp câu hỏi 1 – mKorbel

+0

Lý do bạn đang nhận được thanh cuộn ngang khi sử dụng ' VERTICAL_WRAP' là 'VERICAL_WRAP => Cho biết bố cục" kiểu báo "với các ô đang chạy theo chiều dọc rồi theo chiều ngang.' SO, nếu ô sẽ theo chiều dọc và do kích thước của bạn, đầu ra sẽ được gói từ dưới để nó bắt đầu điền theo chiều ngang.Therefor một thanh cuộn ngang. – RanRag

+0

Điều đó có ý nghĩa, nhưng hầu hết nỗ lực của tôi để thay đổi kích thước các thành phần bên trong đã không làm việc như tôi mong đợi. Làm thế nào tôi sẽ buộc điều này để hiển thị một thanh cuộn dọc, và không phải là một ngang? Có một thành phần cụ thể tôi cần phải thay đổi kích cỡ? – Lockyer

Trả lời

2

Tôi nghĩ giải pháp của bạn là tốt và không phải là hack chút nào. Bất kỳ tính năng tích hợp nào cũng phải làm về cơ bản giống như mọi thứ.

Đây là một sửa đổi đối với ví dụ của bạn thực hiện những gì bạn muốn.

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

Tôi đã hy vọng có một cái gì đó hiển nhiên tôi đã mất tích, nhưng có vẻ như đây có lẽ là giải pháp đơn giản nhất. – Lockyer

0

Đây có phải là những gì bạn đang làm không? (Có thể cần phải thay đổi kích thước ưa thích ...)

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

Không xin lỗi, tôi nên đã tuyên bố rõ ràng rằng tôi muốn các mục trong danh sách để điền vào không gian có sẵn. Vì vậy, khi bạn mở rộng cửa sổ theo chiều ngang, cột bổ sung sẽ được thêm khi có thể. – Lockyer

0

Brilliant Mã @Kevin K ... Tôi đề nghị một sự thay đổi nhỏ để tránh 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; 
    } 
+0

Điều này có vẻ như nó sẽ được nhiều hơn ở nhà trong một bình luận thay vì như một câu trả lời đứng miễn phí. – Lockyer