FaceletsEnNetBeans

Facelets en NetBeans

[[{TableOfContentsTitle=TablaDeContenidos} | {TableOfContents title='Tabla de contenidos'}]] Definitivamente en nuestras aplicaciones web necesitamos que use la misma plantilla a lo largo de todas las páginas. Usar un <jsp:include /> resulta prometedor, pero si se necesita cambiar la plantilla, debemos recorrer todas las páginas y cambiar el contenido de <jsp:include />.

Para ello es adecuado utilizar un sistema de plantillas que sea flexible. Así al modificar una plantilla los cambios se verán reflejados en todo lugar donde se utilizó dicha plantilla.

Existe un framework llamado "Facelets" que permite crear plantillas con ayuda de JSF. Los archivos finales serán xhtml (ya no jsp) por lo que lo vuelve aún más flexible. Si queremos que un componente html utilice un componente especial de JSF, usamos unos atributos adicionales (como jsfc) para poder extender la funcionalidad de nuestro xhtml.

A continuación veremos un ejemplo de cómo se crea un proyecto con Facelets en NetBeans.

Software para elaborar este tutorial

  • JDK 5 o JavaSE 6 (En este tutorial se usó Java6)
  • NetBeans 6.5 (Este tutorial se usó NetBeans 6.5.1)
  • Glassfish v2 (En este tutorial se usó Glassfish v2.1)
  • Instalado el plugin Facelets en NetBeans. Si no se tiene instalado, seguir los siguientes pasos:

Instalando la compatibilidad de Facelets en NetBeans

Entramos a Tools > Plugins, activar Facelets Support

Image:facelets01_FaceletsEnNetBeans.jpg

y hacer clic en "Install"

Creando el proyecto web "AdivinaNumero"

Crearemos una aplicación web nueva llamada "AdivinaNumero". En los pasos de la creación de la aplicación, debemos seleccionar el Framework "Facelets" como se muestra en la siguiente imagen.

Image:facelets02_FaceletsEnNetBeans.jpg

Dejamos todas las opciones predeterminadas.

Notemos los archivos que NetBeans ha creado.

Image:facelets03_FaceletsEnNetBeans.jpg

Creando un ManagedBean - El corazón de la aplicación

Hacemos clic en File > New File (Ctrl + N) y seleccionamos de la categoría "JavaServer Faces", el tipo de archivo JSF Managed Bean

Image:facelets04_FaceletsEnNetBeans.jpg

El bean que estamos creando tendrá como nombre NumeroBean en el paquete facelets y tendrá como alcance (scope) "session"

Image:facelets05_FaceletsEnNetBeans.jpg

El bean creado lo editamos con el siguiente código

package facelets;

import java.util.Random;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.ValidatorException;

public class NumeroBean {

    protected final static Random RANDOM = new Random();
    protected int minimo;
    protected int maximo;
    protected int intento;
    protected int actual;

    public NumeroBean() {
        minimo = 1;
        maximo = 10;
    }

    public void validar(FacesContext context, UIComponent component, Object valor) throws ValidatorException {
        try {
            int param = Integer.parseInt(valor.toString());

            if (param > maximo || param < minimo) { //si está fuera del rango
                FacesMessage message = new FacesMessage(String.format("Intente escribir un número entre %1s y %2s", minimo, maximo));
                throw new ValidatorException(message);
            }
        } catch (NumberFormatException nfe) {
            FacesMessage message = new FacesMessage("Debe escribir un número");
            throw new ValidatorException(message);
        }
    }

    public synchronized int getActual() {
        if (actual == 0) {
            actual = RANDOM.nextInt(maximo - minimo);
            actual += minimo;
        }
        return actual;
    }

    public String getMessage() {
        if (intento == getActual()) {
            return "Excelente!, ese es el número";
        } else if (intento < getActual()) {
            return "Prueba con un número mayor";
        }
        return "Mal, intenta un número menor";
    }

    public int getIntento() {
        return intento;
    }

    public void setIntento(int intento) {
        this.intento = intento;
    }

    public int getMaximo() {
        return maximo;
    }

    public void setMaximo(int maximo) {
        this.maximo = maximo;
    }

    public int getMinimo() {
        return minimo;
    }

    public void setMinimo(int minimo) {
        this.minimo = minimo;
    }
}

Creando la página final que ve el usuario

Ahora, editaremos el código del archivo template-client.xhtml

<?xml version='1.0' encoding='UTF-8' ?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html">
    <body>

        This text above will not be displayed.

        <ui:composition template="/template.xhtml">

            This text will not be displayed.

            <ui:define name="title">
                Estoy pensando en un número del #{NumeroBean.minimo}
                al ${NumeroBean.maximo}. ¿Puedes adivinarlo?
            </ui:define>

            This text will also not be displayed.

            <ui:define name="body">
                <h:form id="form0">
                    <h:inputText id="numeroUsuario" value="#{NumeroBean.intento}" validator="#{NumeroBean.validar}" />
                    <br/>
                    <h:commandButton id="enviar" action="success" value="Enviar" />
                    <br/>
                    <h:message showSummary="true" showDetail="false" for="numeroUsuario" id="errors0" style="color: red; font-weight: bold;"/>
                </h:form>
            </ui:define>

            This text will not be displayed.

        </ui:composition>

        This text below will also not be displayed.

    </body>
</html>

Creando una nueva plantilla.

Para crear una nueva plantilla, entremos a File > New File (Ctrl+N). En la categoría JavaServer Faces seleccionamos el tipo archivo Facelets Template

Image:facelets06_FaceletsEnNetBeans.jpg

El nombre del archivo debe ser respuesta y el tipo de plantilla a mostrar es como se ve la siguiente imagen:

Image:facelets07_FaceletsEnNetBeans.jpg

A esta plantilla la modificamos con el siguiente contenido

<?xml version='1.0' encoding='UTF-8' ?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html">
    
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <link href="./css/default.css" rel="stylesheet" type="text/css" />
        <link href="./css/cssLayout.css" rel="stylesheet" type="text/css" />
        <title>Facelets Template</title>
    </head>
    
    <body>
        
        <ui:composition template="/template.xhtml">
            <ui:define name="title">
            #{NumeroBean.mensaje}
            </ui:define>
            <ui:define name="body">
                <form jsfc="h:form">
                    <input jsfc="h:commandButton" type="submit" id="atras" value="Atrás" action="success"/>                    
                </form>
            </ui:define>
        </ui:composition>
        
    </body>
    
</html>

Aplicar navegación de entre las páginas

Abrimos el archivo faces-config.xml. Seleccionamos en el botón superior "XML". Esto nos mostrará la estructura XML del archivo de configuración de JSF.

Ahora hacemos clic derecho en cualquier parte del código XML y seleccionamos "JavaServer Faces > Add navigation case..."

Image:facelets08_FaceletsEnNetBeans.jpg

Y seleccionamos los archivos involucrados. Es decir el archivo de salida (From view:/template-client.xhtml), la acción que va a pasar (success) y el archivo que tomará el control después de esa acción (To view:/respuesta.xhtml).

Image:facelets09_FaceletsEnNetBeans.jpg

Hagamos lo mismo pero desde /respuesta.xhtml hacia /template-client.xhtml con el mismo nombre de acción "success"

Ejecutando la aplicación

Ahora, ejecutemos el proyecto y veamos los resultados.

Recursos

Este proyecto se encuentra disponible en http://diesil-java.googlecode.com/files/AdivinaNumero.tar.gz

Not logged in. Log in, Register

By use of this website, you agree to the NetBeans Policies and Terms of Use. © 2012, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo