Posts Tagged ‘Java ServerFaces’

Messages in the FacesContext

Domingo, Febrero 1st, 2009
Although to insert messages of error or information in the FacesContext, can be for many something quite simple, but it can be good explaining it for those people who are beginning in JSF. In the following tutorial we are going to learn to create them and show it in our pages with ADF.

In order to insert error messages simply we must call to the static object FacesContext and accede to the present context of the page:

FacesContext facesContext = FacesContext.getCurrentInstance();


Once we have gathered the object, we must call to one of its methods that are addMessage (…), of intuitive way, thanks to javaDoc we are going to insert the values to him to the parameters that need to us:

facesContext.addMessage
    ("cadena", new FacesMessage
        (FacesMessage.SEVERITY_ERROR, "cadena", "cadena"));

If we paid attention, the FacesMessage object is the one that will generate the type to us of message which we are going to show, that can be or of error, information, warning, etc.

Now we are going to remember, that component of ADF shows the information to us generated by the FacesContext:
<af:messages>


Adding this component, when the requests arrive at Phase 6 of the life cycle, the value of the component with the messages will be setted automatically that has contained in the FacesContext.

In addition to inserting messages, the FacesContext object has other functionalities, that already we will be seeing in tutorial futures.

Navigation with popup

Domingo, Febrero 1st, 2009
The creation of popups varies according to the JSF implementation that we use for each project. Each implementation gives to us the option to create popups modals or non modals. Today we are going to speak on popups in ADF, which are modals.

In order to create popup in ADF, we must define a rule of specific navigation, which will open the new window in form of popup, for it, in the file faces-config.xml we must write the following thing:

    <navigation-rule>
        <from-view-id>/ejemplo1.jspx</from-view-id>
        <navigation-case>
              <from-outcome>dialog:abrirPopup</from-outcome>
              <to-view-id>/ejemplo2.jsxp</to-view-id>
        </navigation-case>
    </navigation-rule>

Like any other rule of navigation, when executing a method and giving back a string like “dialog: abrirPopup” will redirect us to this page, but this time like a popup.

The case can be given that we want to pass values to the new page which we are opening, because equally that would happen if not outside popup, we would have to call to the static class AdfFacesContext and to do the following thing in our method associated to action:

    AdfFacesContext().getCurrentInstance().getProcessScope().put ( " key " , " objeto " );

If we want to get from the backing_bean these values would be made in the same way, but instead of set the values we would gather them:

    AdfFacesContext().getCurrentInstance().getProcessScope().get( " key " );

The only thing that we would have left to do would be to associate a property to him to the button that is going to open popup:

    useWindow = true;

This way we would have created simple popup in our page. Average ones exist other to be able to pass values to him to popup, and would be associating an event to him of type launchEvent to the button, and the only thing that would be to do is to capture the component and to pass the values to him of way to similiar to since we have explained previously. The problem to this is that sometimes, we want that according to that type of condition is made in the method associated to the event makes a navigation or another one, or that does not open any popup.

It can happen that we have in the event a condition that according to the size of a list, is sent to popup certain values to him, our intention would be that if that list is empty not sends popup but that is sent a message to the FacesContext. The parameters would be associated acceding to launchEvent, gathering the component and executing the method getDialogParameters().put (…);

To the same time, this being associated action to the button that sends popup, that would be executed before the previous event, therefore, is already settling down the string that is due to return to send popup (dialog: …).

If case gave us that not we must to send popup, we commanded message of error to FacesContext, would appear painted in screen, but since the navigation rule has been defined before the event is executed, is also opened to us popup.

The solution to the problem would be to eliminate that launchEvent and to execute the logic in action, and the values of popup of passing them through AdfFacesContext as we explain at the beginning of the tutorial.

Create components in runtime

Domingo, Febrero 1st, 2009
Sometimes, the case, that can occur we want to create different components according to the state from the page or some action that has been executed in the same one. A solution to show the wished component would be to create a switcher component and be rotating the visibility of the component wished at every moment, but this can be a technique limited enough and “sometimes troublesome” to write the file jspx of our page.

A quite useful possibility is the one to create the component in run time, thus we would save extra code in the file jspx and in addition it gives control much more us of which we want to show in the page. With this we would clear an unnecessary weight to the initial charge of the page, because we will only load the components when we need them.

The way to create a component would be thus:

    FacesContext.getCurrentInstance().getApplication().
       createComponent(COMPONENTE.COMPONENT_TYPE);
This call would give like result a Object that we must cast to the wished component:

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

Once we have created the component, only we would already have left to give him the typical values of similar way to since we do it in jspx:
    input.setId("id1");
    input.setLabel("Etiqueta");

In the same way that we can create components, we can also create validators or converters in run time, the only thing that it would change is that in time to give as parameter constant COMPONENT_TYPE we would pass another constant called COMPONENT_FAMILY:

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


There will be times that besides to create the component, we want to associate actions to him to he himself, and lack makes associate to action a MethodBinding to him, the way to create it is not very complicated, simply we must know as it is the name associated to backing_bean and that values is going to receive like parameter the method to which we are going it to associate. The method to make is using it the following method:
    FacesContext.getCurrentInstance().getApplication().
       createMethodBinding(String, Class[]);

Where string that receives corresponds to label EL that reference to method that we want to call, that is to say, “# {nombre_backing_bean.metodo}”, and as second parameter receives an Array of the classes that is going to receive like parameters, like for example:

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

This MethodBinding that we will receive we have it to associate to the component, by means of its corresponding one setter.

When we created components, although it is not required, always is advisable to set an id, there are a method which it is possible to be acceded to him through FacesContext, that will generá to us you go only for that component in the page, but in pages where we use to the same time several east UIViewRoot objects method can cause many problems to us, more than to help us. This happens because that method simply crosses the list of existing components for that object viewRoot and it assigns a found value to him corelative to the last one. Therefore, the best thing always will be to assign to him you go of a safe and unique way for all the cases that can be given in the page. The method is the following one:

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

Once we already know like creating components, validators, etc only we have left to show them in some place of the page, because we have them created, but not positioned. The way to insert it in some place of the page is very simple, it would be acceding to the method getChildren () of some component that allows to insert children to him, and to add our component. The form to do it is always the same one:

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

CoreTable (1)

Domingo, Febrero 1st, 2009
Vamos a dedicar este tutorial al uso del componente Table del framework ADF. Se encuentra en la librería:

	oracle.adf.view.faces.component.core.data.CoreTable 

El componente Table se usa para mostrar datos de manera ordenada. Este componente permite la selección de datos única y multiple, ordenación de campos por las columnas, así como más funcionalidades que iremos viendo a lo largo del manual.

Los valores que acepta este componente son CollectionModel, aunque nosotros podemos darle como valor un List o un SortableModel y él mismo se encargará de convertirlo en el tipo CollectionModel.

Para renderizar correctamente este componente, debemos asociarle unos hijos, que serán de tipo Column. Cada Column representará una columna de la tabla.

Podemos ver como deberíamos anotar una tabla en el fichero JSF en el siguiente ejemplo:

    <af:table …>
        <af:column …/>
        <af:column …/>
    </af:table>

A cada columna, podemos darle como valores de los hijos, cualquier componente que queramos que sea mostrado. Normalmente este componente será un OutputText que mostrará la información necesaria en cada momento:

    <af:table …>
       <af:column …>
          <af:outputText …/>
       </af:column>
    </af:table>

Las tablas tienen asociados una serie de facet en los cuales podemos colocar distintos componentes para darle un aspecto y funcionalidades distintos a las tablas según lo que añadamos. Vamos a ver uno a uno cuales son estos facets:

  • Actions : En este facet podemos añadir botones que aparecerán en la cabecera de la tabla y que son usados normalmente para realizar operaciones con los datos de las filas que tengamos seleccionadas.
  • DetailStamp : Se nos habilitará una columna extra donde aparecera un desplegable que controlará que aparezcan o desaparezcan los componentes asociados a dicho facet.
  • Footer : Los componentes añadidos a este facet se mostrarán en el pie de la tabla.
  • Header : Los componentes añadidos a este facet se mostrarán en la cabecera de la tabla.
  • Selection : A este facet le podemos añadir dos tipos de componentes, TableSelectOne o TableSelectMany que habilitan una columna extra donde dependiendo de cual componente hayamos añadido la tabla podrá ser de selección única o simple.

Un ejemplo completo de tabla sería el siguiente:

    <af:table emptyText="No items were found" banding="row"
        bandingInterval="1" binding="#{backing_untitled1.table1}"
        id="table1" rows="3" var="row"
        value="#{backing_untitled1.listaManuales}">
       
        <af:column sortable="false" headerText="Titulo"
            binding="#{backing_untitled1.column1}" id="column1">
            <af:outputText value="#{row.titulo}"
                binding="#{backing_untitled1.outputText1}"
                id="outputText1"/>
        </af:column>
       
        <af:column sortable="false" headerText="Autor"
            binding="#{backing_untitled1.column2}" id="column2">
            <af:outputText value="#{row.autor}"
                binding="#{backing_untitled1.outputText2}"
                id="outputText2"/>
        </af:column>
       
        <af:column sortable="false" headerText="Formato"
            binding="#{backing_untitled1.column3}" id="column3">
            <af:outputText value="#{row.formato}"
                binding="#{backing_untitled1.outputText3}"
                id="outputText3"/>
        </af:column>

       
        <f:facet name="detailStamp">
            <af:commandButton text="commandButton 1"
                binding="#{backing_untitled1.commandButton1}"
                id="commandButton1" blocking="true"/>
        </f:facet>
           
        <f:facet name="selection">
            <af:tableSelectMany text="Select items and …"
                binding="#{backing_untitled1.tableSelectMany1}"
                id="tableSelectMany1" required="false"/>
        </f:facet>
      
        <f:facet name="actions">
            <af:commandButton text="commandButton 2"
                binding="#{backing_untitled1.commandButton2}"
                id="commandButton2"/>
        </f:facet>
       
        <f:facet name="header">
            <af:outputText value="Cabecera"
                binding="#{backing_untitled1.outputText4}"
                id="outputText4"/>
        </f:facet>

        <f:facet name="footer">
            <af:outputText value="Pie de tabla"
                binding="#{backing_untitled1.outputText5}"
                id="outputText5"/>
        </f:facet>
    </af:table>

Vamos a conocer ahora más propiedades que tienen asociadas los componentes Table:

  • Banding : Indica si queremos que haya una separación de color entre las diferentes filas o columnas. Los valores aceptados son : none, column o row.
  • BandingInterval : El intervalo con el que se mostrará la separación de color explicada anteriormente.
  • EmptyText : Texto que aparecerá cuando la tabla no contenga ningun resultado.
  • Rows : El número de filas que apareceran en la tabla. Si hubiera más resultados que filas definidas, la tabla paginará automaticamente los resultados según el valor que le hayamos seteado. Si le damos el valor 0 se mostrarán todos los resultados sin ningún tipo de paginación.
  • Sortable : Indica si la columna es ordenable o no.
  • SortProperty : Acepta como parámetro el valor de un String o una expresión EL, que corresponderá a la propiedad por la que queremos que se organice la tabla (Ej. Ascendente, Descendente, etc).
  • Var : nombre con el que vamos a referenciar los valores de la tabla cuando le demos valor a las propiedades en los elementos Column. Es decir, si a la propiedad le hemos dado el valor "row" cuando vayamos a acceder a un valor de la tabla desde un Column se haría del siguiente modo:

            <af:outputText value="#{row.formato}" />

Como hemos comentado antes, las tablas aceptan varios tipos de valores, los cuales se encargará de convertir a CollectionModel, para nuestro ejemplo vamos a crear una lista de objetos del tipo List y se la asociaremos a la tabla para que sean mostrados por pantalla:

    public List<Manuales> getListaManuales(){
       
        List<Manuales> listaManuales = new ArrayList<Manuales>();
       
        Manuales manual = new Manuales();
       
        manual.setTitulo("Tablas");
        manual.setFormato("HTML");
        manual.setAutor("nuevascreaciones");
       
        listaManuales.add(manual);
       
        manual = new Manuales();
               
        manual.setTitulo("JSF");
        manual.setFormato("Word");
        manual.setAutor("nuevascreaciones");
               
        listaManuales.add(manual);
               
        manual = new Manuales();
               
        manual.setTitulo("ADF");
        manual.setFormato("PDF");
        manual.setAutor("nuevascreaciones");
               
        listaManuales.add(manual);
       
        return listaManuales;

    }

Este resultado es el que le asociamos a la propiedad value de la tabla:

    <af:table emptyText="No items were found" banding="row"
        bandingInterval="1" binding="#{backing_untitled1.table1}"
        id="table1" rows="3" var="row"
        value="#{backing_untitled1.listaManuales}">

Ahora sólo bastaría crear 3 columnas en nuestra tabla, que se encarguen de mostrarnos los valores de la lista. Como vimos antes, primero debemos setear un valor a la propiedad var y desde los outputText que están asociados como hijos en los column acceder a las propiedades de la lista:

    <af:column sortable="false" headerText="Formato"
        binding="#{backing_untitled1.column3}" id="column3">
        <af:outputText value="#{row.formato}"
            binding="#{backing_untitled1.outputText3}"
            id="outputText3"/>
    </af:column>

Si ejecutásemos ahora nuestra página, nos debería de aparecer algo parecido a lo siguiente:

CoreTable
Los componentes Table llevan también asociadas unas propiedades para capturar los eventos referentes a las filas de la table. Estos son el SelectionListener, Disclosure Listener, etc. Con ellos, podemos acceder a las filas y realizar su tratamiento de manera individual. Esto se realiza de igual manera que con cualquier otro componente. Debemos asociar al Listener el evento que tenemos en el BackingBean que reciba como parámetro el correspondiente Event.

Existen métodos del componente para acceder al elemento seleccionado, como es el getSelectedRowData() que nos devuelve la fila marcada. Éste y otros métodos serán estudiados con más detalles en futuros manuales.

Ejemplo Interceptor JSF

Domingo, Febrero 1st, 2009
Vamos a crear un caso práctico, donde vamos a poder ver en que fases del ciclo de vida de las peticiones JSF, van interactuando nuestros métodos. 

Tenemos que crear un interceptor, que se va a encargar de capturar el inicio o el fin de cada fase. Para nuestro ejemplo, lo que vamos a hacer, es que antes de que se inicien o finalicen las fases, se mostrará por la consola, un mensaje de información.

Este interceptor, entre otras muchas utilidades, puede sernos útil a la hora de comprobar por qué no se están renderizando ciertos componentes o como afecta la propiedad immediate a nuestra ventana.

InterceptorFases.java

public class InterceptorFases extends SeamPhaseListener{

    private static final long serialVersionUID = 1L;

    public void beforePhase(PhaseEvent event){

        System.out.println(

            “————-ANTES DE LA FASE “+

            event.getPhaseId()+”———–”);

    }

    public void afterPhase(PhaseEvent event){

        System.out.println(

        “————-DESPUES DE LA FASE “+

        event.getPhaseId()+”———–”);

    }

   

}

A continuación debemos configurar el interceptor para que escuche los eventos lanzados por el PhaseEvent. Esto debemos definirlo en el fichero de configuración faces-config.xml. Tenemos que añadir un listener adicional, que será nuestro interceptor:

<lifecycle>

    <phase-listener>

        rutaDelPaquete.InterceptorFases

    </phase-listener>

</lifecycle>

Una vez hecho esto, si arrancamos nuestra aplicación, en cada fase del ciclo de vida entrará en acción el interceptor que hemos creado. Accediendo al objeto event, podréis acceder también al FacesContext, por tanto, aparte de esta utilidad, se le pueden dar otras muchas, dependiendo de lo que queráis en cada caso.

Interceptor example JSF

Domingo, Febrero 1st, 2009

We are going to create a practical case, where we will see in that phases of the JSF lyfe cycle, are interacting our methods.

We must create an interceptor, that is going away to order to capture the beginning or the end of each phase. For our example, it is that before the phases begin or finalize, will be showned by the console (an information message).

This interceptor, among other many utilities, can be to us useful at the time of verifying so that certain components are not being render or as immediate property affects to our window. 

InterceptorFases.java

public class InterceptorFases extends SeamPhaseListener{

    private static final long serialVersionUID = 1L;

    public void beforePhase(PhaseEvent event){

        System.out.println(

            “————-BEFORE PHASE “+

            event.getPhaseId()+”———–”);

    }

    public void afterPhase(PhaseEvent event){

        System.out.println(

        “————-AFTER PHASE “+

        event.getPhaseId()+”———–”);

    }

   

}

 

Next we must configure the interceptor so that it listens to the events sent by the PhaseEvent. This we must define it in the configuration file faces-config.xml. We must add to listener additional, that will be our interceptor: 

<lifecycle>

    <phase-listener>

        package.InterceptorFases

    </phase-listener>

</lifecycle>

Once fact this, if we start our application, in each phase of the life cycle will be actioned the interceptor that we have created.

Acceding to the object event, you will be able to also accede to the FacesContext, therefore, aside from this utility, many can be given him other, depending on which you want in each case.