2012-02-23 29 views
5

Estoy usando una JList para contener datos de chat para mi programa de chat.
Utiliza un renderizador de lista personalizado para representar un objeto JPanel personalizado como el tipo de elemento.
Este JPanel contiene dos JLabels (ancladas en la parte superior, para el nombre y la hora), y un JTextArea (anclado en la parte inferior, para el mensaje de chat).Revalidando JList - elementos personalizados

Parece que este:

a pic1 http://oi44.tinypic.com/20jiix5.jpg

Todo funciona muy bien, pero quiero añadir una característica ocultar/mostrar.
Usando un controlador PopupMenu previamente programado, aparece una ventana emergente cuando haces clic con el botón derecho en un elemento.

a pic2 http://oi42.tinypic.com/2m5exxt.jpg

Al hacer clic en Ocultar (o show, es un conmutador), entonces se debe reducir al mínimo el elemento como tal ...

a pic3 http://oi41.tinypic.com/kf3apx.jpg

El único problema es ... que doesn Actualice el tamaño de la celda JList ya que puede ver la gran región vacía donde solía estar el texto.
Sin embargo, cuando escribo otro mensaje ...

a pic4 http://oi40.tinypic.com/35jdoo7.jpg

El JList fija el tamaño de la celda de completar la operación 'ocultar'.
Mi pregunta es cómo obtener la JList para revalidar/repintar/etc. programáticamente.
Y no creas que no he probado todas las soluciones obvias ...

public void setHidden(boolean hidden) { 
    // this is in the custom JPanel class 
    System.out.println("Initial: " + this.getPreferredSize()); 

    // TextArea is the JTextArea which we set invisible when we want to hide it. 
    TextArea.setVisible(!hidden); // TextArea is a variable btw 
    this.invalidate(); 
    this.validate(); 
    this.repaint(); 

    System.out.println("After: " + this.getPreferredSize()); 
    container.revalidate(); 
} 

/* 
* This is what the above printlns show when you hide, then show the element. 
* 
* Initial: java.awt.Dimension[width=176,height=38] 
* After: java.awt.Dimension[width=176,height=20] 
* Initial: java.awt.Dimension[width=176,height=20] 
* After: java.awt.Dimension[width=176,height=38] 
*/ 

public void revalidate() { 
    // container.revalidate() ^^^ 
    // list is the list containing the chat elements 
    list.invalidate(); 
    list.validate(); 
    list.repaint(); 
} 

La clase JPanel personalizada utiliza un GroupLayout para hacer que los componentes.
¿Tienen algún conocimiento sobre cómo hacer que una JList revalide programáticamente el tamaño de sus celdas?
... además de los métodos que he publicado? :)

Solución:
Después de buscar método después de método y probar si se solucionarían mi problema, he encontrado que la ejecución de este código después de una operación de ocultar/mostrar haría que la altura de la celda (y anchura) y volver a calcular sin ningún 'parpadeo' visual no deseado de la JList.

list.setFixedCellHeight(0); 
list.setFixedCellWidth(0); 
list.setFixedCellHeight(-1); 
list.setFixedCellWidth(-1); 
+0

por favor, aprenda las convenciones de nomenclatura de Java y adhiérase a ellas – kleopatra

+0

Conozco la convención de nomenclatura de Java, solo me gusta tener mis variables de swing en mayúsculas. Pero tampoco siempre sigo eso ... –

Respuesta

2

Este es el trabajo de JTable con dos columnas (Chat y Boolean) en el TableModel y con visibles Chat Columna única, el truco es mediante el uso de aplicar RowFilter donde se establece como parámetro a la segunda columna sólo String "false" (Object en el JTable con Boolean es posible filtrante con valor rendimientos en el String "true"/"false")

+0

Su gramática hace que su respuesta sea poco comprensible. ¿Cómo arreglará esta JTable el cambio de tamaño de la celda? Y debe recordar que estoy usando un procesador de celdas personalizado para representar esta JList. No mostraría lo que hace sin él. –

+0

@Bradley Odell, por favor, lea el tutorial [JList] (http://docs.oracle.com/javase/tutorial/uiswing/components/list.html) sobre el modelo (hay datos almacenados) y View y su representación, no nunca don 't use invalidate() – mKorbel

3

sin ver ningún código, sólo puedo adivinar: la razón más probable es que usted está haciendo la piel bajo los pies de la l ist, es decir, sin que su modelo notifique a sus oyentes.El delegado ui de la lista almacena en caché el tamaño de la celda en el interior, que se borra al recibir ListEvents

+0

¿Crees que estoy haciendo clic derecho y ocultar el elemento con el cursor físicamente debajo de la JList? Todo lo que sucede cuando "oculto" el elemento es el JTextArea (que contiene el mensaje de chat) que se establece como invisible. Entonces, cuando se modifique la visibilidad, necesito JList para volver a calcular el tamaño de la celda para ese elemento. –

0

Este es un inconveniente muy peculiar de la clase JList. Me encontré con el problema mismo mientras limpiaba parte de mi código en áreas no relacionadas.

Por lo que vale la pena, eliminar el elemento del ListModel y luego agregarlo de nuevo producirá las dimensiones adecuadas para el componente representado asociado en el JList. Es una extraña manera de hacerlo, y parece que la lista se comportan de la misma manera que la solución aceptada (y preferido):

list.setFixedCellHeight(0); 
list.setFixedCellWidth(0); 
list.setFixedCellHeight(-1); 
list.setFixedCellWidth(-1); 

me encontré con este problema, ya que el código de mi proyecto fue escrito originalmente para invocar el método removeAllElements() del ListModel y luego agregar todos los elementos de nuevo uno por uno usando addElement(). Todo estaba funcionando bien hasta que decidí que debía volver a escribir el programa para que simplemente dejara el modelo solo cuando el usuario solicitara cambios en las dimensiones de los componentes mostrados en la Lista J. En otras palabras, no era necesario involucrar al modelo porque los elementos no se agregaban o eliminaban de la lista. Desafortunadamente, después de cambiar el tamaño preferido del renderizador, ninguna cantidad del método repaint() o revalidate() llama al JList, lo que haría que el diseño de sus elementos fuera correcto. En mi caso, solo el cambio de tamaño del componente principal (un JFrame) produjo el comportamiento deseado.

Cuestiones relacionadas