Posts Tagged ‘ADF’

Primera página con ADF

Domingo, Febrero 1st, 2009

Vamos a realizar una pagina con dos inputText y hacer una pantalla de logueo. Si se hace correcta ir a una segunda página y si no es válida sacar un mensaje por el FacesContext.

(más…)

Componente ProcessTrain

Domingo, Febrero 1st, 2009

Este tutorial esta pensado para usuarios que tengan cierto conocimiento sobre el funcionamiento del framework ADF. Pues en este se usan terminos que no han sido explicados previamente y pueden resultar complejos para usuarios novatos.  

El componente processTrain es un componente ADF del tipo menú. Consiste en crear varias páginas JSF que están enlazadas entre sí. Este componente actualmente está en discusión entre los creadores de ADF, pues su lógica se realiza en el fichero de configuración faces-config.

(más…)

Navegación con popup

Domingo, Febrero 1st, 2009

La creación de popups varía según la implementación de JSF que utilicemos para cada proyecto. Cada implementación nos da la opción de crear popups modales o no modales. Hoy vamos a hablar sobre los popups en ADF, los cuales son modales.

(más…)

Refrescar la página

Domingo, Febrero 1st, 2009
Hay veces que se nos puede dar el caso, que tenemos que realizar una página donde se van a registrar ciertos tipos de datos, en formularios diferentes, y queremos que una vez el usuario a rellenado todos los campos y los ha validado e insertado en la base de datos, mediante la pulsación de un botón, se de la posibilidad de limpiar y refrescar todos los campos de todos los formularios, para que pueda seguir registrando más datos sin necesidad de salir de la página y volver a entrar en ella.

Existe un objeto en ADF de tipo botón llamado Reset pero para este caso no nos serviría pues tendríamos que asociar uno por cada formulario que tengamos. La solución a nuestro problema sería crear un metodo que refresque el objeto ViewRoot. Se haría del siguiente modo:

    public void recargarPagina(FacesContext contexto) {
        String currentView = contexto.getViewRoot().getViewId();
        ViewHandler vh = contexto.getApplication().
            getViewHandler();

        UIViewRoot x = vh.createView(contexto, currentView);
        x.setViewId(currentView);
        contexto.setViewRoot(x);
    }

Si nos fijamos, este metodo recoge la vista actual de la página (viewId) y lo que hace básicamente es crearla de nuevo y crear un nuevo viewRoot. Una vez que hemos creado el nuevo viewRoot se lo asociamos al contexto y el entenderá que tiene que refrescar la página completamente.

Subida de ficheros

Domingo, Febrero 1st, 2009
ADF, igual que otros muchos frameworks, trae su propio sistema de gestión para procesar la subida de ficheros. En este tutorial vamos a aprender como hacerlo.

Lo primero que necesitamos es configurar en el fichero web.xml ciertos parametros necesarios para gestionar la subida del fichero, vamos a darle valor a las propiedades que se van a encargar de gestionar donde se almacenarán los ficheros temporales, y cual va a ser el tamaño máximo permitido para los ficheros y para el buffer de memoria:

    <context-param>
        <!– Memoria maxima para cada peticion (en bytes) –>
        <param-name>
            oracle.adf.view.faces.UPLOAD_MAX_MEMORY
        </param-name>
        <param-value>992000000</param-value>
    </context-param>
    <context-param>
        <!– Tamano maximo en disco por peticion (en bytes) –>
        <param-name>
            oracle.adf.view.faces.UPLOAD_MAX_DISK_SPACE
        </param-name>
        <param-value>992000000</param-value>
    </context-param>
    <context-param>
        <!– Directorio de los ficheros temporales –>
        <param-name>
            oracle.adf.view.faces.UPLOAD_TEMP_DIR
        </param-name>
        <param-value>/tmp/ADFUploads/</param-value>
    </context-param>

Una vez configurado el fichero web.xml, podríamos comenzar a generar nuestra página. Para poder realizar la subida de ficheros, el componente que vamos a necesitar es <af:inputFile>. Nuestra página además llevará un botón que llevará asociado el evento ActionEvent para procesar la subida de ficheros cuando se pulse el mismo.

    <af:messages />
    <af:inputFile label="Seleccione el archivo"
        value="#{backing_registro.file}" />
    <af:commandButton text="Enviar"
        actionListener="#{backing_registro.procesarUpload}" />

Un dato a tener muy en cuenta, ya que a veces se nos puede olvidar, es que a la etiqueta que define el form, ya sea <h:form> o <afh:form>, debe llevar seteada una propiedad para indicarle que lo que se va a gestionar es una subida de ficheros. Veamos que valor hay que dar dependiendo del tipo de form que hayamos establecido:

    <af:form usesUpload="true">

    <h:form enctype="multipart/form-data">

Solo nos quedaría realizar el código del backing bean, como indicamos antes, el metodo llevará como parametro un ActionEvent para capturar el evento lanzado por el actionListener. En el método lo que vamos a realizar es una comprobación previa que el fichero no nos llega nulo, y si el fichero llega correctamente mostraremos un mensaje por pantalla:

    private UploadedFile file;
   
    public void procesarUpload(ActionEvent evento) {
        UploadedFile file = getFile();
      
        if (file != null)
        {

            FacesContext context =
                FacesContext.getCurrentInstance();
            FacesMessage message = new FacesMessage(
                "Subida del fichero " + file.getFilename() +
                " satisfactoria (" + file.getLength() +
                " bytes)");
            context.addMessage(
                evento.getComponent().
                    getClientId(context),message);

            // Aqui procesariamos el fichero
            // para guardarlo donde queramos
       
        }
       
    }
   
    public UploadedFile getFile() {
        return file;
    }

    public void setFile(UploadedFile file) {
        this.file = file;
    }

Aún no habríamos guardado el fichero en nuestro servidor, ya es cuestión del programador realizarlo de una manera u otra, y para ello ya no es necesario ningún framework, con las librerías de Java debería bastar. De todos modos, si alguien tuviera dudas de como realizarlo, hacédnoslo saber y ampliaríamos el tutorial.

Si hemos realizado todo correctamente, la página nos quedaría del siguiente modo:

subidaFicheros
Pulsa la imagen para verla en más detalle.

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.