Crear componentes en ejecución

A veces, puede darse el caso, que queremos crear componentes diferentes según el estado de la página o según alguna acción que se ha ejecutado en la misma. Una solución para mostrar el componente deseado sería crear un switcher e ir rotando la visibilidad del componente deseado en cada momento, pero esto muchas veces puede ser una técnica bastante limitada y a veces “engorrosa” de escribir el fichero jspx de nuestra página.

Una posibilidad bastante útil es la de crear el componente en tiempo de ejecución, así ahorraríamos codigo extra en el fichero jspx y además nos da mucho más control de lo que queremos mostrar en la página. Con esto quitaríamos un peso innecesario a la carga inicial de la página, pues sólo cargaremos los componentes cuando los necesitemos.

La manera de crear un componente sería así:

    FacesContext.getCurrentInstance().getApplication().
       createComponent(COMPONENTE.COMPONENT_TYPE);

Esta llamada nos daría como resultado un Object que debemos castear al componente deseado:

   CoreInputText input = (CoreInputText)FacesContext.
        getCurrentInstance().getApplication().
        createComponent(CoreInputText.COMPONENT_TYPE);

Una vez que tenemos creado el componente, ya sólo nos quedaría darle los valores típicos de modo semejante a como lo hacemos en el jspx:

   input.setId("id1");
    input.setLabel("Etiqueta");

Del mismo modo que podemos crear componentes, podemos crear también validadores o converters en tiempo de ejecución, lo único que cambiaría es que en vez pasar como parametro la constante COMPONENT_TYPE pasaríamos otra constante llamada COMPONENT_FAMILY:

FacesContext.getCurrentInstance().getApplication().
       createComponent(Validator.COMPONENT_FAMILY);

Habrá veces que además de crear el componente, querramos asociarle acciones al mismo, y nos haga falta asociarle a un action un MethodBinding, la manera de crearlo no es muy complicada simplemente tenemos que saber cual es el nombre asociado al backing_bean y que valores va a recibir como parámetro el método al que lo vamos a asociar. La forma de realizarlo es usando el siguiente método:

FacesContext.getCurrentInstance().getApplication().
       createMethodBinding(String, Class[]);

Donde la cadena que recibe corresponde a la etiqueta EL que referencia al método que queremos llamar, es decir, “#{nombre_backing_bean.metodo}”, y como segundo parámetro recibe un array de las clases que va a recibir como parametros, como por ejemplo:

Class[] array = new Class[1];
    array[0] = ValueChangeEvent.class;

Este MethodBinding que recibiremos lo tenemos que asociar al componente, mediante su correspondiente setter.

Cuando creamos componentes, aunque no es requerido, siempre es conveniente setearle un id, hay un método que se puede acceder a él a través del FacesContext, que nos generá un id único para ese componente en la página, pero en páginas donde usemos a la misma vez varios objetos UIViewRoot este método puede causarnos muchos problemas, más que ayudarnos. Esto ocurre porque ese método simplemente recorre la lista de componentes existentes para ese objeto viewRoot y le asigna un valor correlativo al último encontrado. Por tanto, lo mejor siempre será asignarle el id de una manera segura y única para todos los casos que se puedan dar en la página. El método es el siguiente:

    FacesContext.getCurrentInstance().getViewRoot().
       createUniqueId();

Una vez que ya sabemos como crear componentes, validadores, etc sólo nos queda mostrarlos en algún lugar de la página, pues los tenemos creados, pero no posicionados. La manera de insertarlo en algún lugar de la página es muy sencilla, sería accediendo al metodo getChildren() de algún componente que permita insertarle hijos, y añadir nuestro componente. La forma de hacerlo es siempre la misma:

getPanel().getChildren().add(input);

Tags:

Comments are closed.