Eventos

Jsf proporciona un modelo de programación basado en eventos, similar a otros utilizados en clientes pesados como Swing. Se basa en la utilización de eventos y escuchadores (event/listener), de modo que un componente lanzará un evento, como por ejemplo cuando escribimos en un campo de texto y otro elemento escuchará al componente para realizar una determinada acción.

Anteriormente hablamos sobre dos tipos de componentes, los que inician una acción, como un botón, y los que contienen información, como un campo de texto. También vimos que el primer grupo de componentes implementaba “ActionSource2”, este interfaz utiliza un “action event” y su correspondiente “action listener” para disparar y procesar los eventos. El segundo grupo de componentes implementa “ValueHolder” o “EditableValueHolder” y utilizan “value change event” y “value change listener” para realizar alguna acción cuando el contenido cambia. Estos serían los eventos de aplicación.

Además de manejar los eventos en lo relativo a los componentes UI, Jsf proporciona eventos de fase (phase events) y escuchadores de fase (phase listeners) que se utilizan en el propio ciclo de vida de procesamiento de peticiones. Esto permite registrar y procesar acciones cuando se producen cambios de estado en el ciclo de vida de una petición. Los eventos de fase, se producen antes y después de cada fase del ciclo de vida de una petición Jsf.

En otra categoría estarían los eventos de sistema (system events), que son como los eventos de fase pero con una granularidad mayor, como por ejemplo “la aplicación se va a iniciar”. Una subcategoría de esto, serían los eventos de sistema que ocurren a nivel de componente, algo así como: “se va a validar este componente”.

Eventos de aplicación

Action Event

Anteriormente, cuando vimos la primera aplicación de ejemplo en la introducción a Jsf ya vimos como al pulsar el botón:

Donde el método de acción sería el siguiente:

Hay dos tipos de métodos de acción, “action method” o “action listener method”. El primero, es un método java que no recibe parámetros y devuelve un String que se recoge por el “NavigationHandler” para determinar el flujo de navegación, como en el ejemplo anterior.

El segundo “action listener method”, no devuelve nada y recibe un “ActionEvent”, por ejemplo:

Donde el método, debe tener la siguiente firma:

Estos dos métodos se comportan básicamente del mismo modo, los datos del formulario, son enviados, validados, y si son correctos, se ejecutan las acciones. Si lo que queremos es que se ejecuten las acciones sin que entre en la siguiente fase del ciclo de vida de la aplicación, de modo que no se validen los campos, etc. hay que añadir immediate=”true”, de este modo:

Hay que tener en cuenta, que si queremos leer valores de otros campos, como por ejemplo campos de texto, etc. no podemos garantizar que estamos recuperando el valor actual que contienen estos campos, a no ser que cada uno de ellos también tenga el atributo immediate=”true”.

Value Change Event

Value change event es el evento que se usa para indicar que el contenido de un component ha cambiado. Normalmente se trata de componentes que implementan “ValueHolder” or “EditableValueHolder” como por ejemplo los campos de texto. El uso típico que se da a este tipo de evento, puede ser, actualizar una lista de provincias, cuando se selecciona un país, o actualizar una serie de listas desplegables en función del valor seleccionado en un campo.

El modo de aprovechar este tipo de eventos, es similar al comentado anteriormente, por ejemplo:

Donde el método, tendría esta firma:

Como se puede ver, hemos configurado immediate=”true”, para que se invoque al método cada vez que cambie el valor.

Action y value change listeners personalizados

Podemos escribir nuestras propias clases action listener o value change listener personalizadas, implementando respectivamente ActionListener o ValueChangeListener. Veamos un ejemplo de cada uno de ellos:

Para usar estas clases, hay que anidar respectivamente una etiqueta f:actionlistener y una etiqueta f:valueChangelistener en el componente que corresponda, del siguiente modo:

En el campo de texto, se ha incluido una función javascript, de modo que cuando cambie el foco del componente, por ejemplo, pulsando el tabulador, se haga submit del formulario.

Todo junto

Vamos a ver un ejemplo completo. Definiremos un formulario con un campo de texto que reciba el código de producto, de modo que cuando cambie el foco, si el código empieza por “xxx”, se rellenen los campos “Producto” y “Modelo”. Además se añadirá un campo “Más” que en el caso de estar marcado, mostrará un área de texto. Para ello, definimos la siguiente vista “inicio.xhtml”:

Producto

Como se puede ver usamos immediate=”true”, en todos los campos, para saltarnos las validaciones, si las hubiera. Se envían los datos a través de un botón oculto utilizando la llamada javascript onchange=”document.getElementById(‘cargar’).click();”. Para mostrar y ocultar campos, se utiliza rendered=”#{bean.mostrarMasInfo}” donde “mostrarMasInfo” es un valor booleano. El managed-bean queda del siguiente modo:

Al ejecutar la aplicación se mostrará algo parecido a lo siguiente:

Aplicación de ejemplo

Aplicación de ejemplo

Cuando introducimos “xxx” y pulsamos el tabulador, o pinchamos en otros campos, se nos cargan los campos “Producto” y “Modelo”. Si marcamos “Más”, se nos muestra el área de texto “Detalles”.

Quizá esta no sea la manera más interesante de implementar este tipo de comportamiento. Lo más adecuado es utilizar Ajax, de modo que no haya que enviar la página completa para que sea reenviada al cliente con los campos rellenos.

PhaseListener

La mejor manera de ver como se ejecuta es implementar un escuchador de fase que se ejecute en todas las fases y saque por consola lo que está haciendo. Declaramos la clase en el faces-config.xml

Mi listener, implementará “PhaseListener”, los métodos a implementar reciben un objeto PhaseEvent, que podemos volcar en una consola con phaseEvent.getPhaseId().toString(). Al ejecutar la aplicación podremos observar como se va pasando por cada fase del ciclo de vida de una petición Jsf.

3 comentarios:

  1. Podrias colocar el codigo para descarga por favor

  2. Excelente tutorial, muchas gracias.

  3. Muchas gracias por tu post. Me ha facilitado la compresión del tema.

    Un saludo

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *