Skip to main content

Libro JEE7 Capítulo 4. DataTable

Libro JEE7 Capítulo 4. DataTable

  • Para el manejo de tablas usaremos el componente <p:datatable>
  • Utilizaremos el CDI Beans EstatusDataController.java , que crearemos para el manejo de la lista de estatus que serán desplegados mediante el componente datatable.
  • Usaremos Método @PostConstructor
  • FILTRAR Y ORDENAR REGISTROS
  • DATATABLE CON FORMULARIO DE INSERCIÓN
  • Datatable con Selección, Edición y Eliminación de Registros


Para el manejo de tablas usaremos el componente <p:datatable>

Utilizaremos el CDI Beans EstatusDataController.java , que crearemos para el manejo de la lista de estatus que serán desplegados mediante el componente datatable.


Usaremos Método @PostConstructor

Se utiliza para invocar métodos al inicio, lo podemos usar para invocar mediante parámetros de un CDI Beans o de Session.

Pasos:
  1. Creamos un List<Estatus>
List<Estatus> estatusList;

  1. en el constructor inicializamos el estatusList.

public EstatusDataController() {
        estatusList = new ArrayList<>();
   }

  1. Ajustar método  getEstatusList()

Cambiamos el método getEstatusList()
por
public List<Estatus> getEstatusList() {
       return estatusFacade.getEstatusList();
   }
public List<Estatus> getEstatusList() {
       return estatusList;
   }

  1. crear los métodos set para estatusList, podemos utilizar el asistente clic derecho Insert code -->Getter and Setter… seleccionar estatusList

   public void setEstatusList(List<Estatus> estatusList) {
       this.estatusList = estatusList;
   }

Creamos el método  init con la anotación @PostConstruct, que sera invocado la primera vez que se carga el CDIBeans.Se usara otro metodo iniciar(), para el caso que deba ser invocado nuevamente.
@PostConstruct
       public void init(){
           iniciar();
       }
corregimos los import

Crear el método iniciar() para cargar registros.
public void iniciar(){
 estatusList = estatusFacade.getEstatusList();
}

Crear otro método iniciar con parámetro String ,este recibirá un parámetro para establecer el filtro de las entidades a mostrar en el datatable.
public void iniciar(String value){
   estatusList = estatusFacade.findByEsinicial(value);
}



Editar el método delete() y agregar la invocación al método iniciar(); de manera que carge el list actualizado.
 public String delete() {
       try {
           estatusFacade.remove(selected);
  iniciar();
           JSFUtil.addSuccessMessage(rf.getMensajeArb("info.delete"));
       } catch (Exception e) {
           JSFUtil.addErrorMessage(e.getLocalizedMessage());
       }
       return null;
   }


Si deseamos filtrar los registros iniciales


para obtener los filtrados por el atributo esinicial=”no”
En el método init() de  r, invocamos el método iniciar( con el parámetro no), para que devuelva los registros que cumplan esa condición.
 @PostConstruct
   public void init(){
       //iniciar();
       iniciar("no");       
   }
Solo se muestran los registros con esincial = “no”

Otra forma seria para invocar el método antes de cargar la página, en el código xhtml , en la sección metadata, indicamos el parámetro, y el viewAction.
<f:metadata>
<f:viewParam name="id" value="#{estatusDataController.estatus.idestatus}"/>
<f:viewAction action="#{estatusDataController.iniciar}"/>
</f:metadata>


FILTRAR Y ORDENAR REGISTROS


Agregamos un list del Entity Estatus
private List<Estatus> filtered;

y creamos los métodos set/get

public List<Estatus> getFiltered() {
       return filtered;
   }

   public void setFiltered(List<Estatus> filtered) {
       this.filtered = filtered;
   }
   En el componente dataTable agregar filteredValue="#{estatusDataController.filtered}"
<p:dataTable id="datatable" paginator="true" rows="7" value="#{estatusDataController.estatusList}"
                                    var="item"
                                     rowKey="#{item.idestatus}"
                                    selectionMode="single"
                                    selection="#{estatusDataController.selected}"
                                    filteredValue="#{estatusDataController.filtered}"
                                    >


En las columnas colocamos para filtrar por cada atributo filterBy="#{item.idestatus}"  y para ordenar sortBy="#{item.idestatus}"

       <p:column style="width:5%" filterBy="#{item.idestatus}" sortBy="#{item.idestatus}">
                    <f:facet name="header">
                            <h:outputText value="#{msg.idestatus}"/>
                     </f:facet>
                     <h:outputText value="#{item.idestatus}"/>
        </p:column>




en el browser, se muestra el componente para filtrar y ordenar


Agregaremos un dialogo con la propiedad es visible=”true”
<p:dialog visible="true" header="#{app['form.estatuslist']}" closable="false"
showEffect="clip" hideEffect="fade" widgetVar="estatuslistDialog">




DATATABLE CON FORMULARIO DE INSERCIÓN

PrimeFaces ofrece el componente <p:datatable> que permite generar una tabla en la página, con opciones como búsquedas, filtros, selección de filas.
Usaremos Named Queries, para obtener la lista de Entitys que cumplan los criterios deseados, de manera que podamos realizar operaciones de edición o eliminación sobre los mismos.

Si observamos en el entity “Estatus”, podemos ver las definiciones y Bean Validation como mostramos a continuación.




Formulario de estatusinsert .xthml
Ubicarse en el formulario estatusinsert.xhtml antes de  </h:form> y

dar clic derecho y seleccionar insert code

seleccionar  JSF Data Table From Entity
En el cuadro de diálogo que se presenta seleccionamos  Estatus como Entity y como  ManagedBean Property estatusDataController estatusList







El ide genera el siguiente código
<h:form>
                           <h1><h:outputText value="List"/></h1>
                           <h:dataTable value="#{estatusDataController.estatusList}" var="item">
                               <h:column>
                                   <f:facet name="header">
                                       <h:outputText value="Idestatus"/>
                                   </f:facet>
                                   <h:outputText value="#{item.idestatus}"/>
                               </h:column>
                               <h:column>
                                   <f:facet name="header">
                                       <h:outputText value="Estatus"/>
                                   </f:facet>
                                   <h:outputText value="#{item.estatus}"/>
                               </h:column>
                               <h:column>
                                   <f:facet name="header">
                                       <h:outputText value="Esinicial"/>
                                   </f:facet>
                                   <h:outputText value="#{item.esinicial}"/>
                               </h:column>
                           </h:dataTable>
                       </h:form>

Quitamos el componente <h:form> y </h:form> del  datatable de manera que únicamente exista el form principal.  Como se muestra a continuación en el  browser, tendremos los registros de estatus

Cambiaremos las etiquetas  <h:datatable> por <p:datatable> y <h:column> por <p:column> para usar los componentes primefaces y se usarán las etiquetas de los archivos de propiedades en los header de cada columna.



Esto permitirá que al cambiar el idioma el encabezado de cada columna cambie automáticamente.


<f:facet name="header">
     <h:outputText value="Idestatus"/>
</f:facet>
por
<f:facet name="header">
         <h:outputText value="#{msg.idestatus}"/>
</f:facet>

Colocamos el id=”datatable”,  paginación de la tabla y el número de filas
<p:dataTable id="datatable" paginator="true" rows="7" value="#{estatusDataController.estatusList}" var="item">







Despues de los cambios quedaria de la siguiente manera.


Para actualizar el datatable al agregar un registro, en el commandButton que utilizamos para guardar , agregamos al update el componente datatable, de esta manera se mostrará en el datatable los cambios sin renderizar el formulario completo.
        <p:commandButton value="#{app['boton.save']}" update="panel,growl,datatable" action="#{estatusDataController.save()}"/>






Al crear un nuevo estatus este automáticamente actualiza la tabla






Removemos el código que utilizamos del datatable del formulario estatusinsert.xhtml, ya que crearemos una página xhtml que se encargara de mostrar , editar y eliminar los registros.
Y eliminamos del <p:commandButton en el método update la actualización datatable.












Datatable con Selección, Edición y Eliminación de Registros

Aquí mostraremos como crear una página que permite mostrar los registros, realizar búsquedas e invocar un diálogo para realizar la edición de los registros.

Creamos una página nueva llamada estatuslist.xhtml en el directorio /page/estatus
Ahora creamos un Facelets Template Client
  • Desde menú File, seleccione New
  • en Categories, seleccione Java Server Faces
  • en File Types, seleccione Facelets Template Client
  • En File Name: estatuslist
  • Folder colocamos /page/estatus/
  • Template seleccionamos template.xhtml


Se genera el código de la página y  colocamos en comentario top,bottom, left <!--  - ->  para que este tome el que este utilice el que esta en el template, y en center escribimos

Editamos estatuslist.xhtml , nos ubicamos en la sección center y

dar clic derecho y seleccionar insert code , seleccionar  JSF Data Table From Entity

Seleccionar Entity Estatus y el CDI Property estatusDataController propiedad estatusList

Colocar el id para el form

<h:form id="form">

En el código generado, nos ubicamos en <h:datatable> y <h:column> y los reemplazamos por <p:datatable> y <p:column> para utilizar los componentes primefaces.
Seleccionar p=”http://primefaces.org/ui” library declaration

Modificamos  el componente dataTable original, indicando el número de filas(rows),  value indicamos el list de objetos, var define la variable para indicar los elementos, selectionMode define el modo de selección y selection asocia al entity la fila seleccionada.

 <p:dataTable id="datatable" paginator="true"
                                    rows="7" value="#{estatusDataController.estatusList}" var="item"
                                    rowKey="#{item.idestatus}"
                                    selectionMode="single"
                                    selection="#{estatusDataController.selected}"
                                    >                       

Ejecutamos el proyecto , podemos ver los registros en el datatable





Agregamos  el evento ajax  oncomplete()  para mostrar un diálogo con la fila seleccionada , y actualizaremos mediante  update el growl y el panel que contendrá el entity seleccionado de la fila.
Para mostrar el dialogo usamos   oncomplete="PF('editwidgetVar').show()"/>.
Si deseamos ocultarlo usamos     oncomplete="PF('editwidgetVar').hide()"/>

Codigo del datatable
<h1><h:outputText value="#{app['form.estatuslist']}" /></h1>
                       <p:dataTable id="datatable" paginator="true"
                                    rows="7" value="#{estatusDataController.estatusList}" var="item"
                                    rowKey="#{item.idestatus}"
                                    selectionMode="single"
                                    selection="#{estatusDataController.selected}"
                                    >
                            <p:ajax event="rowSelect"   
                                   oncomplete="PF('editwidgetVar').show();"
                                    update=":form:growl,:form:displayEdit" />
                         


Nos ubicamos debajo de    </p:dataTable>, colocamos el componente dialog y un panelGrid. La propiedad widgetVar se usará para asignar un nombre al componente que será localizado mediante PrimefacesFramework PF().

 <p:dialog id="editDialog"  header="#{app['dialog.edit']}"  widgetVar="editwidgetVar"
                  resizable="false"  height="235" width="550" showEffect="clip" hideEffect="fold">

            <h:panelGrid id="displayEdit" columns="2" title="#{app['dialog.edit']}">
            </h:panelGrid>
 </p:dialog>

Ubicarse dentro del panelgrid <h:panelGrid id="displayEdit"  y dar clic derecho Insert Code→ seleccionar JSF Form From Entity

Ahora seleccionar el Entity Estatus y el Managed Bean Property selecionar selected

se genera el código, y debemos eliminar las etiquetas <h:form> y </h:form>  ya que tenemos un formulario principal.

Eliminar <h1><h:outputText value="Create/Edit"/></h1>
Y colocamos las etiquetas de los properties, el title y requiredMessage para los componentes utilizados.

Cambiamos el  <h:inputText id="esinicial" … />, por el selectOneMenu similar al que usamos en el formulario insert.

     <p:selectOneMenu  id="esinicial" value="#{estatusDataController.selected.esinicial}"  required="true" requiredMessage="#{msg.esinicial} #{app['info.notnull']}">
                                       <f:selectItem itemLabel="#{app['boton.yes']}" itemValue="si" />  
                                       <f:selectItem itemLabel="#{app['boton.no']}" itemValue="no" />  
                                   </p:selectOneMenu>


Creamos la sección<f:facet name="footer"> del panelGrid y colocamos los botones para editar, eliminar,cerrar. El botón eliminar mostrará un diálogo solicitando la confirmación de si eliminamos o no el registro.
 <f:facet name="footer">
                                       <p:commandButton id="editButton" value="#{app['boton.update']}"
                                                        update=":form:growl,:form:datatable,:form:displayEdit"
                                                        actionListener="#{estatusDataController.edit()}"
                                                        oncomplete="PF('editwidgetVar').hide()"/>
                                       <p:commandButton id="deleteButton" value="#{app['boton.delete']}" title="#{app['boton.delete']}"  onclick="PF('confirmationwidgetVar').show();" type="button" icon="ui-icon-trash" />
                                       <p:commandButton id="declineButton" value="#{app['boton.cerrar']}" onclick="PF('editwidgetVar').hide();" type="button" />
                                   </f:facet>


Agregar antes del </h:form> el growl y el componente para mensajes
 <p:growl id="growl"/>
<p:messages autoUpdate="true"/>




En el browser al dar clic en la fila se muestra el registro con las opciones de editar/eliminar
Al presionar el boton eliminar se muestra el diálogo para confirmar


Para ajustar el tamaño de las columnas podemos hacerlo de dos maneras
<p:column style="width:20%">
o
<p:column style="width:5%; text-align:center;"> si lo deseamos centrado.
































Código completo estatuslist.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://xmlns.jcp.org/jsf/facelets"
     xmlns:h="http://xmlns.jcp.org/jsf/html"
     xmlns:f="http://xmlns.jcp.org/jsf/core"
     xmlns:p="http://primefaces.org/ui">

   <body>

       <ui:composition template="./../../template.xhtml">
           <!--
                       <ui:define name="top">
                           top
                       </ui:define>
           
                       <ui:define name="bottom">
                           bottom
                       </ui:define>
           
                       <ui:define name="left">
                           left
                       </ui:define>
           -->
           <ui:define name="center">
               <f:view>
                   <h:form id="form" >
                       <p:dialog visible="true" header="#{app['form.estatuslist']}" closable="false"
                                 showEffect="clip" hideEffect="fade" widgetVar="estatuslistDialog">

                           <h1><h:outputText value="List"/></h1>
                           <p:dataTable id="datatable" paginator="true"
                                        rows="7" value="#{estatusDataController.estatusList}" var="item"
                                        rowKey="#{item.idestatus}"
                                        selectionMode="single"
                                        selection="#{estatusDataController.selected}"
                                        filteredValue="#{estatusDataController.filtered}"
                                        >
                               <p:ajax event="rowSelect"
                                       oncomplete="PF('editwidgetVar').show();"
                                       update=":form:growl,:form:displayEdit"/>
                               <p:column style="width:20%" filterBy="#{item.idestatus}" sortBy="#{item.idestatus}">
                                   <f:facet name="header">
                                       <h:outputText value="#{msg.idestatus}"/>
                                   </f:facet>
                                   <h:outputText value="#{item.idestatus}"/>
                               </p:column>
                               <p:column filterBy="#{item.estatus}" sortBy="#{item.estatus}">
                                   <f:facet name="header">
                                       <h:outputText value="#{msg.estatus}"/>
                                   </f:facet>
                                   <h:outputText value="#{item.estatus}"/>
                               </p:column>
                               <p:column filterBy="#{item.esinicial}" sortBy="#{item.esinicial}">
                                   <f:facet name="header">
                                       <h:outputText value="#{msg.esinicial}"/>
                                   </f:facet>
                                   <h:outputText value="#{item.esinicial}"/>
                               </p:column>
                              
                           </p:dataTable>
                       </p:dialog>

                       <p:dialog id="editDialog"  header="#{app['dialog.edit']}" widgetVar="editwidgetVar"
                                 resizable="false" height="235"  width="550" showEffect="clip" hideEffect="fold">
                           <h:panelGrid id="displayEdit" columns="2" title="#{app['dialog.edit']}">

                               <h1><h:outputText value="Create/Edit"/></h1>
                               <h:panelGrid columns="2">
                                   <h:outputLabel value="Idestatus:" for="idestatus" />
                                   <h:inputText id="idestatus" value="#{estatusDataController.selected.idestatus}" title="Idestatus" required="true" requiredMessage="The Idestatus field is required."/>
                                   <h:outputLabel value="Estatus:" for="estatus" />
                                   <h:inputText id="estatus" value="#{estatusDataController.selected.estatus}" title="Estatus" required="true" requiredMessage="The Estatus field is required."/>
                                   <h:outputLabel value="Esinicial:" for="esinicial" />
                                   <p:selectOneMenu  id="esinicial"
                                                     value="#{estatusDataController.selected.esinicial}"  required="true"
                                                     requiredMessage="#{msg.esinicial} #{app['info.notnull']}">
                                       <f:selectItem itemLabel="#{app['boton.yes']}" itemValue="si" />
                                       <f:selectItem itemLabel="#{app['boton.no']}" itemValue="no" />
                                   </p:selectOneMenu>
                                   <f:facet name="footer">
                                       <p:commandButton id="editButton" value="#{app['boton.update']}"
                                                        update=":form:growl,:form:datatable,:form:displayEdit"
                                                        actionListener="#{estatusDataController.edit()}"
                                                        oncomplete="PF('editwidgetVar').hide()"/>
                                       <p:commandButton id="deleteButton" value="#{app['boton.delete']}"
                                                        title="#{app['boton.delete']}"  onclick="PF('confirmationwidgetVar').show();" type="button"
                                                        icon="ui­icon­trash" />
                                       <p:commandButton id="declineButton" value="#{app['boton.cerrar']}"
                                                        onclick="PF('editwidgetVar').hide();" type="button" />
                                   </f:facet>

                               </h:panelGrid>



                           </h:panelGrid>
                       </p:dialog>
                       <p:dialog id="confirmDialog" modal="false"  header="#{app['boton.delete']}"
                                 widgetVar="confirmationwidgetVar">
                           <p:commandButton id="removeButton" value="#{app['boton.yes']}"
                                            update=":form:displayEdit, :form:growl, :form:datatable"
                                            oncomplete="PF('confirmationwidgetVar').hide();,
                                            PF('editwidgetVar').hide();"
                                            actionListener="#{estatusDataController.delete()}" />
                           <p:commandButton id="cancelButton" value="#{app['boton.no']}"
                                            onclick="PF('confirmationwidgetVar').hide()" type="button" />
                       </p:dialog>
                       <p:growl id="growl"/>
                       <p:messages autoUpdate="true"/>
                   </h:form>
                   


               </f:view>

           </ui:define>

       </ui:composition>

   </body>
</html>







































Crear un CDI Beans para gestionar las list de entity para mostrar en las páginas
  • Desde menú File, seleccione New
  • en Categories, seleccione Java Server Faces
  • en File Types, seleccione JSF ManagedBeans
  • Class Name: EstatusDataController
  • Package com.avbravo.scrumweb.controller
  • Scope: View





Cambiar
Reemplazar
@ManagedBeans
@Named
import javax.faces.bean.ManagedBean;
import javax.inject.Named;
import javax.faces.bean.ViewScoped;
import javax.faces.view.ViewScoped;



Implementamos serializable,
inyectamos mediante @Inject EstatusFacade, ResourceFiles.

Agregamos un objeto de tipo estatus que se utilizará para hacer referencia al entity seleccionado del datatable.
Estatus selected = new Estatus();
generamos los métodos get/set, para ello hacemos  clic derecho Insert Code  y seleccionar Getter and Setter…



Seleccionar selected: Estatus, tal como aparece en la  imagen



el IDE genera los métodos

   public Estatus getSelected() {
       return selected;
   }

   public void setSelected(Estatus selected) {
       this.selected = selected;
   }


Además se creará el método edit() para actualizar registros y delete() para eliminarlo.

Crear método getEstatusList() para que devuelva un list de estatus
public List<Estatus> getEstatusList() {
       return estatusFacade.getEstatusList();
   }













Código de EstatusDataController.java
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.avbravo.scrumweb.controller;

import com.avbravo.scrumweb.Estatus;
import com.avbravo.scrumweb.ejb.EstatusFacade;
import com.avbravo.scrumweb.generales.JSFUtil;
import com.avbravo.scrumweb.generales.ResourcesFiles;
import java.io.Serializable;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Inject;
import javax.inject.Named;

/**
*
* @author avbravo
*/
@Named
@ViewScoped
public class EstatusDataController implements Serializable {

   private static final long serialVersionUID = 1L;
   @Inject
   EstatusFacade estatusFacade;
   @Inject
   ResourcesFiles rf;

   Estatus selected = new Estatus();

   List<Estatus> filtered;
   List<Estatus> estatusList;

   public List<Estatus> getFiltered() {
       return filtered;
   }

   public void setFiltered(List<Estatus> filtered) {
       this.filtered = filtered;
   }

   public Estatus getSelected() {
       return selected;
   }

   public void setSelected(Estatus selected) {
       this.selected = selected;
   }

   /**
    * Creates a new instance of EstatusDataController
    */
   public EstatusDataController() {
   }

   public void setEstatusList(List<Estatus> estatusList) {
       this.estatusList = estatusList;
   }

   public List<Estatus> getEstatusList() {
//    return estatusFacade.getEstatusList();
       return estatusList;
   }

   @PostConstruct
   public void init() {
       iniciar();
   }

   public void iniciar() {
       estatusList = estatusFacade.getEstatusList();
   }

   public void iniciar(String value) {
       estatusList = estatusFacade.findByEsinicial(value);
   }

   public String edit() {
       try {
           estatusFacade.edit(selected);
           JSFUtil.addSuccessMessage(rf.getMensajeArb("info.update"));
       } catch (Exception e) {
           JSFUtil.addErrorMessage(e.getLocalizedMessage());
       }
       return null;
   }

   public String delete() {
       try {
           estatusFacade.remove(selected);
           JSFUtil.addSuccessMessage(rf.getMensajeArb("info.delete"));
           iniciar();

       } catch (Exception e) {
           JSFUtil.addErrorMessage(e.getLocalizedMessage());
       }
       return null;
   }

}


Comments

Popular posts from this blog

Cambiando el estado de un checkbox

Cambiando el Estado de un CheckBox Algunas veces deseamos controlar el estado de un checkbox o cambiarlo segùn determinadas condiciones. Pasos: 1. Creamos un proyecto Web. 2. En el diseñador agregamos un checkbox y dos botones. * Dar click derecho en el checkbox y luego seleccionar Add Binding Attribute, para agregar los atributos al checkbox, de manera que los podamos usar en nuestro código. Generando automáticamente private Checkbox checkbox1 = new Checkbox(); public Checkbox getCheckbox1() { return checkbox1; } public void setCheckbox1(Checkbox c) { this.checkbox1 = c; } 3.Damos click derecho en el botón Habilitar, y seleccionamos Edit Action Event Handler. A continuación, agregamos el código: this.checkbox1.setSelected(true);, el método setSelected con valor true, marca el checkbox como seleccionado, y un valor de false, quita la marca. public String button1_action() { // TODO: Process the action. Return value is a navigation //

Corregir el error el archivo de manifiesto en proyectos maven

Corregir el error en el archivo de manifiesto en proyectos maven Si creamos un proyecto maven con NetBeans e intentamos ejecutarlo encontraríamos el siguiente error Agregamos el plugin   <artifactId>maven-jar-plugin</artifactId>  <plugin>                 <groupId>org.apache.maven.plugins</groupId>                 <artifactId>maven-jar-plugin</artifactId>                 <version>2.4</version>                 <configuration>                     <archive>                         <manifest>                             <mainClass>org.javscaz.maven1.App</mainClass>                         </manifest>                                           </archive>                 </configuration>             </plugin> Luego al construir el proyecto con dependencias, podemos ejecutar el .jar

Tutorial básico de aplicaciones Web con NetBeans parte 1

NetBeans ofrece un excelente soporte para el desarrollo de aplicaciones Web, en esta ocasión lo haremos utilizando el Framework Java Server Faces 2.0. En el Menu Seleccionamos Nuevo->Proyecto y luego en Categorias Java Web y en tipo de Proyectos Web  Application indicamos el nombre del proyecto Seleccinamos el servidor Web, usamos GlassFish ya que este soporta EJB3.0 y JSF 2.0 Framework Java Server Faces El IDE genera el esquelto del proyecto Web Pages   almacenamos las paginas .html, xhtml, jsf, los archivos de recursos, los scripts .js, imagenes Source Packages    Son las clases Java  Test Packages    Son las clases que usamos para los Test Libraries     Tenemos las bibliotecas de Java y GlassFish necesarias para ejecutar la aplicación Web. Test Libraries     Están las bibliotecas usadas para los test  Configuration Files    Archivos de configuración de la aplicación. Ejecutamos la aplicación  Esperamos que se inicie GlassFish y se cargue la aplicación Este se