2012-02-02 10 views
8

estoy tratando de colocar una JList en el interior de un JScrollPane y han alfabéticamente una lista de las entradas en las columnas verticales como esto:ListaJ: ¿utiliza una barra de desplazamiento vertical en lugar de horizontal con una orientación de ajuste vertical?

A D G 
B E H 
C F 

Sin embargo, cuando los JList se queda sin espacio para mostrar más entradas, que había como el JScrollPane para desplazarse solo en dirección vertical.

Esto funciona cuando uso VERTICAL_WRAP. Sin embargo, parece que cuando uso envoltura vertical obtengo una barra de desplazamiento horizontal y cuando uso HORIZONTAL_WRAP obtengo la barra de desplazamiento que quiero, pero los artículos se colocan en un orden que no me gusta. ¿Puedo tomar mi torta y comerla también? Aquí hay un ejemplo simple de lo que intento hacer.

enter image description here

Esto es lo más cerca que pude conseguir, pero me gustaría ser capaz de desplazarse verticalmente, manteniendo el orden alfabético vertical.

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 solución que he pesar de decir: Si se conoce el tamaño de la celda puedo crear un oyente componente, y escuchar para un evento de cambio de tamaño. Cuando se desencadena ese evento, puedo calcular el recuento de filas deseado para evitar el desplazamiento horizontal. Esto parece un truco, y no estoy seguro de cómo podría funcionar con componentes de texto de tamaño variable.

+1

buena pregunta 1 – mKorbel

+0

La razón por la que está recibiendo barra de desplazamiento horizontal cuando el uso de ' VERTICAL_WRAP' es 'VERICAL_WRAP => Indica el diseño de" estilo de periódico "con las celdas fluyendo verticalmente y luego horizontalmente. ASÍ, si la celda fluirá verticalmente y debido a su dimensión, la salida quedará envuelta desde abajo para que comience a llenarse horizontalmente. una barra de desplazamiento horizontal. – RanRag

+0

Eso tiene sentido, pero la mayoría de mis intentos de cambiar el tamaño de los componentes internos no han funcionado como yo esperaba. ¿Cómo forzaría esto a mostrar una barra de desplazamiento vertical, y no horizontal? ¿Hay algún componente específico que necesite cambiar el tamaño? – Lockyer

Respuesta

2

Creo que su solución está muy bien, y no un corte en absoluto. Cualquier característica incorporada tendría que hacer básicamente lo mismo de todos modos.

Aquí hay una modificación de su ejemplo que hace lo que quiere.

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

Esperaba que hubiera algo obvio que me faltaba, pero parece que esta es probablemente la solución más simple. – Lockyer

0

¿Es esto lo que estás buscando? (Puede que tenga que cambiar el tamaño preferido ...)

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

Lo siento, debería haber declarado explícitamente que quiero que los elementos de la lista llenen el espacio disponible. Entonces, cuando expanda la ventana horizontalmente, se debe agregar una columna adicional cuando sea posible. – Lockyer

0

brillante Código @ Kevin K ... me sugieren una pequeña modificación para evitar ArithmeticException (división por cero)

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

Esto parece que sería más cómodo en un comentario en lugar de una respuesta independiente. – Lockyer

Cuestiones relacionadas