El componente Grid de Apache Tapestry

Publicado por pico.dev el .
blog-stack java planeta-codigo tapestry programacion
Comentarios

En la mayoría de aplicaciones no solo es habitual sino algo muy usado el mostrar listados de elementos de forma tabular con paginación y columnas ordenables. En estos listados el complejo componente internamente Grid de Apache Tapestry pero a la vez muy sencillo de usar puede marcar una diferencia significativa en el número de líneas de código necesarias a escribir, la flexibilidad, funcionalidad ofrecida, la productividad al hacer la implementación o modificarla comparándolo con lo necesario en otros frameworks web en los que no hay nada comparable de serie.

Apache Tapstry

Apache Tapestry es uno de los muchos frameworks disponibles en Java para el desarrollo de aplicaciones y páginas web. A diferencia de la mayoría se basa en componentes y proporciona una larga lista de ellos listos para usar de serie, pero también se pueden crear componentes nuevos basados en los propios de Tapestry o los que desarrollemos nosotros muy fácilmente. Los componentes son piezas reusables de código que se pueden reutilizar bien directamente o para formar nuevos componentes y es uno de los motivos por los que en Tapestry se consigue una alta productividad además de otros beneficios como la encapsulación.

Uno de los componentes más complejos pero al mismo tiempo muy simple de usar ofrecidos por el framework es el componente Grid. El componente Grid muestra en una tabla un listado de datos ofreciendo las funcionalidades de paginación, ordenación, personalización de columnas, filtrado de columnas, personalización en caso de estar vacío y algunas cosas más. Lo único que debemos tener en cuenta para aprovechar al máximo el componente Grid son los parámetros que declara en su documentación su funcionamiento interno nos es irrelevante, será de los componentes más complejos y no por ello no es más difícil de utilizar basta decir que solo tiene un parámetro requerido y que es lo único imprescindible que es la lista de datos a mostrar.

Aunque el componente tiene un buen número de parámetros para personalizar según queramos su comportamiento basta que hagamos uso únicamente del parámetro source que es la fuente de datos del Grid, puede ser un objeto de tipo Collection o un GridDataSource que proporciona métodos para hacer la paginación y ordenación eficientemente recuperando de la base de datos o fuente de datos únicamente los registros a mostrar realizando paginación.

Componente Grid de Tapestry
  • source

Con los parámetros include y exclude podemos determinar que propiedades de los objetos o beans de la fuente de datos se incluyen en el Grid, con el parámetro add podemos añadir nuevas columnas y personalizarlas con los datos que necesitemos como sería el caso de añadir una columna con un Checkbox por fila para realizar una selección múltiple o de una columna con botones para realizar acciones. Para ambas cosas en el cuerpo del componente_Grid_definimos subcomponentes con la siguiente nomenclatura <p:[nombreColumna]Cell>, en en ejemplo usando <p:nombreCell> y <p:actionCell>. Las celdas de las columnas por defecto hacen un toString() de la propiedad del bean de la fila a mostrar, si queremos cambiar este comportamiento como en la columna nombre definimos la etiqueta <p:nombreCell> y dentro incluimos el contenido que deseemos que puede contener otros componentes en este caso el nombre con un enlace.

  • include
  • exclude
  • add
  • <p:[nombreColumna]Cell>

Con el parámetro rowsPerPage podemos cambiar el número de filas por página del Grid, en el ejemplo son 2 pero puede ser la cifra que deseemos y tampoco tiene por que ser una constante, el número de filas a mostrar puede provenir de una expresión y cambiar según alguna lógica. Los parámetros columnIndex, rowIndex y row nos proporcionan información del índice de la columna actual, índice de la fila actual y el objeto actual de la fila respectivamente que podemos usar al personalizar las celdas del Grid. Son parámetros de salida que el Grid se encarga de proporcionarnos según procesa las filas y celdas, en base a ellos podremos implementar alguna funcionalidad.

  • rowsPerPage
  • columnIndex
  • rowIndex
  • row

Los parámetros informales (denominados así para aquellos que le pasamos al Grid que no están declarados explícitamente en su interfaz o contrato y que no proporcionan alguna funcionalidad) son incluidos en la etiqueta table del HTML que genera el Grid. Igualmente el parámetro informal class se incluye tal cual se indica en el atributo en class de la tabla para personalizar los estilos y usando el parámetro rowClass se incluye en cada fila en su etiqueta tr de HTML. Además de estas clases que podemos el componente añade algunas clases más a ciertas filas: t-first para la primera fila, t-last para la última, t-sort-column-ascending y t-sort-column-descending para las columnas que estén ordenadas ascendentemente y descendentemente de forma que con CSS tengamos la posibilidad de cambiar sus estilos.

  • class
  • rowClass

Con el parámetro empty definimos un componente Block que se usará cuando el Grid no tenga filas que mostrar, lo que es útil para mostrar un mensaje indicando que la tabla no tiene filas como cuando no hay elementos.

Mensaje de un Grid sin elementos
  • empty

Con pagerPosition indicaremos si queremos la barra de paginación situada encima de la tabla, abajo, en ambas posiciones o no queremos.

  • pagerPosition

Por si fuera poco con el parámetro inPlace podemos hacer que la paginación y ordenación funcione usando AJAX de modo que no se recargue toda la página en cada pulsación de un enlace. No será necesario que añadamos nada de JavaScript, el componente se encargará de hacer la petición AJAX y con el resultado que sea devuelto actualizar la tabla.

  • inPlace

Finalmente, comentaré el parámetro encoder con el que podemos hacer que el componente Grid funcione cuando se usa dentro de un componente Form. La clase ValueEncoder transforma un objeto a un String que lo identifique en el cliente y a partir del identificador del cliente los transforme al objeto cuando se envíe de nuevo al servidor. Podemos indicar el ValueEncoder en cada Grid o definirlo como una configuración del contenedor IoC.

Hay algún parámetro más como sortModel y paginationModel para mantener la información de ordenación y paginación pero los anteriores son los que más habitualmente usaremos y probablemente con source, include, exclude y add tengamos suficiente para muchos casos.

Es sorprendentemente lo sencillo que es usar el componente Grid para toda la funcionalidad que proporciona. En ciertos casos este componente por si solo puede reducir drásticamente la cantidad de código necesario a escribir en las plantillas que producen HTML y aumentar notablemente la productividad al crear o modificar páginas con listados de elementos. En el artículo Mantenimiento CRUD en Apache Tapestry comento como conseguir un CRUD completo usando el componente Grid entre otras cosas.

Portada libro: PlugIn Tapestry

Libro PlugIn Tapestry

Si te interesa Apache Tapestry descarga gratis el libro de más de 300 páginas que he escrito sobre este framework en el formato que prefieras, PlugIn Tapestry: Desarrollo de aplicaciones y páginas web con Apache Tapestry, y el código de ejemplo asociado. En el libro comento detalladamente muchos aspectos que son necesarios en una aplicación web como persistencia, pruebas unitarias y de integración, inicio rápido, seguridad, formularios, internacionalización (i18n) y localización (l10n), AJAX, ... y como abordarlos usando Apache Tapestry.


Yo apoyo al software libre