domingo, 5 de junio de 2011

Uso de CellFactory en Java FX 2

Tras las primeras horas bicheando JavaFX 2, aquí un post en el que explico cómo definir la forma en que se presentan los elementos de un lista.

Lo que tenemos es un objeto de tipo ListView, que se muestra por pantalla como una lista de elementos. Lo primero que debemos tener en cuenta, es que la forma más correcta de manejar su contenido es tener una ObservableList, que será sobre la que hagamos los cambios (adición, eliminación y actualización de elementos). Si fijamos esta lista observable como contenido de la ListView, ésta será notificada cada vez que se produzca un cambio en la colección, y tendremos la vista de nuestra aplicación siempre actualizada.



Pero lo que necesitamos en este caso es manejar una lista de elementos más complejos. Por ejemplo, supongamos que tenemos la clase Persona:


Sin problema podríamos crear una lista para presentar una serie de personas con el siguiente código.


Pero al ejecutar este código, lo que veríamos en la lista sería el valor obtenido al llamar al método toString de la clase Persona. Si no lo hemos sobrescrito, se mostraría la referencia al objeto. Un primer paso para refinar este comportamiento se reduciría a crear un método toString que devolviese el nombre y apellidos de la persona, y así podríamos ver esos valores en la lista.

Pero supongamos que queremos ir más allá, y no sólo presentar el nombre completo de la persona, sino también utilizar un color distinto en función de su edad, mostrando en rojo a los adultos, y en azul a los que todavía no lo son. Pues para eso podemos utilizar el método setCellFactory de la clase ListView.


Como podemos ver, la entrada al método es un objeto que implemente la interfaz Callback, con el que básicamente le decimos a la lista cómo debe crear sus celdas. La interfaz define un único método, call, que devolverá, en nuestro caso, una celda que contiene una persona (ListCell). 



Como podemos ver en el código anterior, el método call define en primer lugar un elemento Text, y después una ListCell, que es la celda que vamos a devolver. En este caso creamos una celda de Persona, y construimos el objeto sobrescribiendo el método updateItem, en el que configuramos el elemento Text como queremos, y lo asignamos como nodo de la celda. De esta forma, cuando veamos la lista por pantalla, lo que se presentará para cada elemento será el Text, con la configuración dada en función de los datos del objeto Persona correspondiente.

No sé si la explicación ha quedado clara, pero al ejecutarlo se verá que la idea es muy sencilla. Además, a partir de aquí surgen muchas posibilidades, ya que podemos representar elementos complejos dentro de una lista contando con todas las posibilidades de JavaFX.

2 comentarios:

  1. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  2. The code line setNode(text) do not compile anymore with the new builds of javaFX 2.0 .
    Any idea How to fix it ?

    ResponderEliminar

Cualquier aportación será bienvenida