2012-02-02 15 views
8

Sto cercando di mettere un JList all'interno di un JScrollPane e farlo in ordine alfabetico elencare le voci in colonne verticali come questo:JList: utilizzare una barra di scorrimento verticale anziché orizzontale con un orientamento verticale dell'involucro?

A D G 
B E H 
C F 

Tuttavia quando i JList si esaurisce lo spazio per visualizzare più voci, mi piacerebbe come lo JScrollPane per scorrere solo nella direzione verticale.

Questo funziona quando utilizzo VERTICAL_WRAP. Tuttavia, sembra che quando utilizzo l'involucro verticale ottengo una barra di scorrimento orizzontale e quando utilizzo lo HORIZONTAL_WRAP ottengo la barra di scorrimento che desidero, ma gli elementi vengono inseriti in un ordine che non mi piace. Posso avere la mia torta e mangiarla anch'io? Ecco un semplice esempio di ciò che sto cercando di fare.

enter image description here

Questo è il più vicino ho potuto ottenere, ma mi piacerebbe essere in grado di scorrere in senso verticale, pur mantenendo l'ordinamento alfabetico verticale.

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

Una soluzione che ho però di Is: Se le dimensioni della cella è noto posso creare un ascoltatore componente, e ascoltare per un evento di ridimensionamento. Quando viene attivato quell'evento, posso calcolare il numero di righe desiderato per evitare lo scorrimento orizzontale. Sembra solo un trucco, e non sono sicuro di come potrebbe funzionare con componenti di testo di dimensioni variabili.

+1

bella domanda +1 – mKorbel

+0

La ragione si stanno ottenendo barra di scorrimento orizzontale quando si utilizza ' VERTICAL_WRAP' è 'VERICAL_WRAP => Indica il layout di" stile giornale "con le celle che scorrono verticalmente e poi orizzontalmente." Quindi, se la cella fluirà verticalmente ea causa delle dimensioni l'output verrà avvolto dal fondo in modo che inizi a riempirsi orizzontalmente. una barra di scorrimento orizzontale. – RanRag

+0

Questo ha senso, ma la maggior parte dei miei tentativi di ridimensionare i componenti interni non ha funzionato come mi sarei aspettato. Come potrei forzare questo per mostrare una barra di scorrimento verticale e non orizzontale? C'è un componente specifico che devo ridimensionare? – Lockyer

risposta

2

Penso che la soluzione sia giusta, e non un trucco. Qualsiasi funzione integrata dovrebbe comunque fare la stessa cosa.

Ecco una modifica al tuo esempio che fa ciò che desideri.

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

Speravo che ci fosse qualcosa di ovvio che mi mancava, ma sembra che questa sia probabilmente la soluzione più semplice. – Lockyer

0

È questo che stai andando? (Potrebbe essere necessario modificare la dimensione preferita ...)

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

No, scusa, avrei dovuto dichiarare esplicitamente che voglio che gli elementi nella lista riempiano lo spazio disponibile. Quindi, quando si espande la finestra orizzontalmente, dovrebbe essere aggiunta una colonna aggiuntiva quando possibile. – Lockyer

0

brillante Codice @ Kevin K ... Suggerisco una piccola modifica per evitare ArithmeticException (divisione per lo 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

Sembra che sarebbe più a suo agio in un commento invece che come una risposta libera. – Lockyer

Problemi correlati