Thursday, November 27, 2014

Libro JEE7 Capítulo 3. Archivos de propiedades y temas

Capítulo 3. Archivos de propiedades y temas

  • Internacionalización y Localización de Aplicaciones
  • Creación de los archivos properties
  • Creación de las etiquetas para los campos de las Entity
  • Listado de propiedades en application.properties
  • Ahora crearemos el CDI Beans ResourcesFiles, para manejar los archivos properties.
  • Editar template.xhtml
  • Editamos menu.xhtml
  • Editar EstatusController.java
  • CREAR UN SelectOneMenu
  • TEMAS DE PRIMEFACES



Internacionalización y Localización de Aplicaciones


En este capítulo se mostrará como crear aplicaciones con soporte para múltiples idiomas.


Esté será el estándar que se usarán para las propiedades de la aplicación

messages.properties --> contendrá las etiquetas y nombre de tablas
application.properties --> mensajes del sistema, botones , mensajes de error.

Formato
sistema
application.
botones
boton.
idioma
language.
elementos de menu
menu.
elementos menuitem
menuitem.
formularios
form.
form.entidad, form.entidadnew, form.entidadedit, form.entidadlist, form.entidadsearch, form.entidadprint
mensajes de error
error.
mensajes warning
warning.
warning.ATRIBUTOcomplemento
warning.idexist
existe un registro con ese id
mensajes de información
info.
dialogos
dialog.



Para agregar el soporte para múltiples idiomas en nuestra aplicacion web, debemos seguir los siguientes pasos

Creación de los archivos properties

En Other Sources hacemos clic derecho sobre  src/main/resources  y seleccionamos New→ Java Package


Seguidamente, indicamos el nombre del paquete: com.avbravo.scrumweb.properties

Ahora, seguimos:

  1. Desde menú File, seleccionamos New
  2. en Categories, escogemos Other
  3. y en File Types, seleccionamos Properties File

Seguimos indicando el nombre: messages


Ahora le damos  clic derecho y seleccionamos Add→ Locale para crear compatibilidad con otros idiomas:


Indicamos la compatibilidad para el idioma inglés colocando en Language Code: en


Repetimos el procedimiento y agregamos soporte para el idioma español colocando en Language Code: es

Con esto se generarán los archivos messages_en.properties, y  messages_es.properties



Creación de las etiquetas para los campos de las Entity


Abrimos  el Entity Estatus
y observamos los atributos, que son los que usaremos para agregar al archivo de propiedades.

  • idestatus
  • estatus
  • esinicial



Agregaremos propiedades con el mismo nombre de cada atributo en el archivo messages.properties. Para ello, seleccionaremos el archivo messages.properties dar con el clic derecho y seleccionamos Open , luego hacemos clic en New Property
Indicamos los valores para los campos key y value correspondientes a los atributos del Entity




De esta manera agregamos todas las propiedades del Entity  para los idiomas que establecimos(predeterminado, inglés, español)




Creamos un archivo properties para el manejo de los mensajes, etiquetas, botones de la aplicacion, lo llamaremos application.properties y agregamos el soporte para el idioma español e inglés.




Listado de propiedades en application.properties

application.title=Scrum Web
application.shorttitle=Scrum Web
boton.all=Todos
boton.cerrar=Cerrar
boton.changetheme=Cambiar
boton.new=Nuevo
boton.save=Guardar
boton.delete=Eliminar
boton.update=Actualizar
boton.ayuda=Ayuda
boton.filter=Filtrar
boton.search=Buscar
boton.home=Inicio
boton.query=Consultar
boton.clear=Limpiar
boton.yes=Si
boton.no=No
boton.list=Listar
boton.print=Imprimir
boton.login=Login
boton.logout=Salir
boton.menu=Menu
boton.return=Regresar
dialog.edit=Editar
dialog.search=Busqueda
dialog.delete=Eliminar
error.title=Error
form.estatus=Estatus

form.estatusnew=Crear Estatus
form.estatusedit=Editar Estatus
form.estatuslist=Listar  Estatus
form.estatussearch=Buscar Estatus
form.estatusprint= Imprimir Estatus
label.similar=Similar
info.message=Mensaje
info.save=Guardado exitosamente
info.theme=Tema
info.required=es requerido
info.update=Editado exitosamente
info.delete=Eliminado
info.notnull=No nulo
info.sinrolasignado=No tiene rol asignado
info.title=Informacion
language.spanish=Espanol
language.english=Ingles
language.language=Idiomas
login.username=Username
login.password=Password
login.passwordnotvalid=Password no es correcto
login.usernamenotvalid=Nombre de usuario no valido
login.inactive=Usuario inactivo
login.logout=Salir
login.accesodenegado=Acceso Denegado
login.accesodenegadoDetalle=No cuenta con los privilegios para accesar esta pagina
menu.edit=Editar
menu.options=Opciones
menu.search=Buscar
menu.insert=Insertar
menu.list=Listar
menu.estatus=Estatus
menu.records=Registros
menu.themes=Temas
warning.title=Advertencia
warning.idnotexist=No existe un registro con ese id
warning.idexist=Existe registro con ese id


Nota:
Recuerde colocar el valor de las etiquetas en inglés y otros idiomas que desee agregar.











Ahora crearemos el CDI Beans ResourcesFiles, para manejar los archivos properties.


Crear el CDI llamado ResourcesFiles.java en el paquete generales
  • Desde menú File, seleccione New
  • Categories, seleccione Java Server Faces
  • File Types, seleccione JSF ManagedBeans
  • Class Name: ResourcesFiles
  • Package: com.avbravo.scrumweb.generales
  • Scope: Session




Nota:
Recuerde eliminar  import javax.faces.bean.ManagedBean; ,
import javax.faces.bean.SessionScoped; y @ManagedBean



Codigo completo ResourcesFiles.java
Definiremos dos atributos ResourceBundle mrb para el manejo de message.properties y arb para el manejo de application.properties, en el método  asignar() establecemos el idioma que el usuario seleccione. Locale usamos para obtener el objeto Locale correspondiente al idioma. Creamos losmétodoss set/get para arb, mrb.

import java.io.Serializable;
import java.util.Locale;
import java.util.ResourceBundle;
import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.faces.context.FacesContext;
import javax.inject.Named;

/**
*
* @author avbravo
*/
@Named
@SessionScoped
public class ResourcesFiles  implements Serializable{
private static final long serialVersionUID = 1L;
   Locale currentLocale;
   ResourceBundle mrb; //for messages
   ResourceBundle arb; //for application
   

   public  ResourcesFiles() {
   }

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

   public void saveLocale() {
        currentLocale = FacesContext.getCurrentInstance().getViewRoot().getLocale();
       mrb = ResourceBundle.getBundle("com.avbravo.scrumweb.properties.messages", currentLocale);
         arb = ResourceBundle.getBundle("com.avbravo.scrumweb.properties.application", currentLocale);

   }
   public Locale getCurrentLocale() {
       return currentLocale;
   }

   public void setCurrentLocale(Locale currentLocale) {
       this.currentLocale = currentLocale;
   }

   public ResourceBundle getMrb() {
       return mrb;
   }

   public void setMrb(ResourceBundle mrb) {
       this.mrb = mrb;
   }

   public ResourceBundle getArb() {
       return arb;
   }

   public void setArb(ResourceBundle arb) {
       this.arb = arb;
   }

/*
    *Devuelve el mensaje Mrb
    */

   public String getMensajeMrb(String mensaje) {
       return mrb.getString(mensaje);
   }
   /*
    *Devuelve el mensaje Arb
    */

   public String getMensajeArb(String mensaje) {
       return arb.getString(mensaje);
   }

}


























Crear el CDI Idiomas.java ,obtenemos el objeto locale y se define los métodos para cambiar el idioma a español inglés y se llama al método saveLocale() para guardar el idioma y establecerlo para la sesión del usuario.
  • Desde menú File, seleccione New
  • Categories, seleccione Java Server Faces
  • File Types, seleccione JSF ManagedBeans
  • Class Name: Idiomas
  • Package: com.avbravo.scrumweb.generales
  • Scope: Session



Codigo completo Idiomas.java

import java.io.Serializable;
import java.util.Locale;
import javax.enterprise.context.SessionScoped;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;

/**
*
* @author avbravo
*/
@Named
@SessionScoped
public class Idiomas implements Serializable {

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

  
   private String locale = Locale.getDefault().getDisplayLanguage();

   public void setLocale(String locale) {
       this.locale = locale;
   }

   public synchronized String getLocale() {
       return locale;
   }
   public synchronized String changeLanguage() {
       return "changed";
   }
public Idiomas() {
   }

   public String englishAction() {
       FacesContext context = FacesContext.getCurrentInstance();
       context.getViewRoot().setLocale(Locale.ENGLISH);
       this.locale = "en";
       rf.saveLocale();
       return null;
   }

   public String spanishAction() {
       FacesContext context = FacesContext.getCurrentInstance();
       context.getViewRoot().setLocale(new Locale("es"));
       this.locale = "es";
       rf.saveLocale();
       return null;
   }
}





















Editar template.xhtml

colocamos dentro de las etiquetas <h:head>,   el <f:view locale="#{idiomas.locale}"> indicaremos el CDI Beans que contiene el locale.
y para indicar el archivo de propiedades mediante    <f:loadBundle> y el valor de var como variable de referencia.
 <h:head>
             <f:facet name="first">
               <meta content='text/html; charset=UTF-8' http-equiv="Content-Type"/>

Agregamos
  <f:view locale="#{idiomas.locale}"></f:view>
     <f:loadBundle basename="com.avbravo.scrumweb.properties.messages" var="msg" />
    <f:loadBundle basename="com.avbravo.scrumweb.properties.application" var="app" />

con esto podemos utilizar msg para referirnos a los archivos message y app para application.



Ahora usaremos los valores establecidos en los archivos de propiedades dentro de template.xhtml, haremos referencia mediante "#{app['application.title']}"
   <title><h:outputText value="Scrum web"/></title>
por
<title><h:outputText value="#{app['application.title']}"/></title>

en donde app hace referencia a la variable para application.properties, y usamos ['aplication.title'] ya que la propiedad esta compuesta de application.title


y cambiar en bottom para agregar       <h:outputText value="#{app['application.foot']}"/>

<p:layoutUnit position="south" size="50" closable="true" collapsible="true">
               <ui:insert name="bottom">
                   Footer
              </ui:insert>
           </p:layoutUnit>

por
<p:layoutUnit position="south" size="50" closable="true" collapsible="true">
               <ui:insert name="bottom">
                                   <h:outputText value="#{app['application.footer']}"/>
               </ui:insert>
           </p:layoutUnit>


































Editamos menu.xhtml

Cambiamos las etiquetas de los menús
 <p:submenu label="#{app['menu.records']}" icon="ui-icon-check">  
             <p:column>                              
      <p:submenu label="#{app['menu.estatus']}">  
              <p:menuitem value="#{app['menu.insert']}" url="/faces/page/estatus/estatusinsert.xhtml" />  
              <p:menuitem value="#{app['menu.list']}"  url="/faces/page/estatus/estatuslist.xhtml"/>  
      </p:submenu>  


y agregamos las etiquetas para los idiomas

 <p:submenu label="#{app['menu.options']}" icon="ui-icon-check">  
         <p:column>  
              <p:submenu label="#{app['language.language']}"  >
    <p:menuitem action="#{idiomas.englishAction}" value="#{app['language.english']}" immediate = "true" ajax = "false" icon="ui-icon-flag"/>
   <p:menuitem action="#{idiomas.spanishAction}" value="#{app['language.spanish']}" immediate = "true" ajax = "false" icon="ui-icon-flag" />  
                           </p:submenu>
      </p:column>  
  </p:submenu>  


codigo de menu.xhtml

<h:form id="menuForm" >
           <p:megaMenu>
               <p:submenu label="#{app['menu.records']}" icon="ui-icon-check">  
                   <p:column>                              
                       <p:submenu label="#{app['menu.estatus']}">  
                           <p:menuitem value="#{app['menu.insert']}" url="/faces/page/estatus/estatusinsert.xhtml" />  
                           <p:menuitem value="#{app['menu.list']}"  url="/faces/page/estatus/estatuslist.xhtml"/>  
                       </p:submenu>  
                   </p:column>  
               </p:submenu>
               <p:submenu label="#{app['menu.options']}" icon="ui-icon-check">  
                   <p:column>  
                       <p:submenu label="#{app['language.language']}"  >
                           <p:menuitem action="#{idiomas.englishAction}" value="#{app['language.english']}" immediate = "true" ajax = "false" icon="ui-icon-flag"/>
                           <p:menuitem action="#{idiomas.spanishAction}" value="#{app['language.spanish']}" immediate = "true" ajax = "false" icon="ui-icon-flag" />  
                       </p:submenu>
                   </p:column>  
               </p:submenu>  

           </p:megaMenu>
       </h:form>







Si observamos el browser



Dar clic en ingles y cambia el idioma





Editamos estatusinsert.xhtml para agregar las etiquetas de los archivos de propiedades usar app.  para archivos application.properties y msg para messages.properties .
Usamos  msg.idestatus  para las etiquetas y el nombre del formulario
Cambiar
<h1><h:outputText value="Create/Edit"/></h1>
por
<h1><h:outputText value="#{app['form.estatusnew']}"/> </h1>

Cambiar
   value="Idestatus:" for="idestatus" />
por
<h:outputLabel value="#{msg.idestatus}" for="idestatus" />
Esto lo hacemos para cada atributo del CDI Beans que se encuentra en el JSF

Importante, crear las propiedades para title y para requiredMessage
En los inputText cambiamos title y requiredMessage agregamos la etiqueta con el atributo #{app['info.required']}" para enviar el mensaje que es requerido.
<h:inputText id="idestatus" value="#{estatusController.estatus.idestatus}" title="#{msg.idestatus}" required="true" requiredMessage="#{msg.idestatus} #{app['info.required']}"/>

Cambiamos todas las etiquetas.


Cambiar el botón save
<p:commandButton value="#{app['boton.save']}" update="panel,growl" action="#{estatusController.save()}"/>



Código que implementa las etiquetas

 <h1><h:outputText value="#{app['form.estatusnew']}"/></h1>
                       <h:panelGrid id="panel" columns="2">
                           <h:outputLabel value="#{msg.idestatus}" for="idestatus" />
                           <h:inputText id="idestatus" value="#{estatusController.estatus.idestatus}" title="#{msg.idestatus}" required="true" requiredMessage="#{msg.idestatus} #{app['info.required']}"/>
                           <h:outputLabel value="#{msg.estatus}" for="estatus" />
                           <h:inputText id="estatus" value="#{estatusController.estatus.estatus}" title="#{msg.estatus}" required="true" requiredMessage="#{msg.estatus} #{app['info.required']}"/>
                          <h:outputLabel value="#{msg.esinicial}" for="esinicial" />
                         <h:inputText id="esinicial" value="#{estatusController.estatus.esinicial}" title="#{msg.esinicial}" required="true" requiredMessage="#{msg.esinicial} #{app['info.required']}"/>

       <f:facet name="footer">
   <p:commandButton value="#{app['boton.save']}" update="panel,growl"  action="#{estatusController.save()}"/>
   </f:facet>

                       </h:panelGrid>




Formulario con idioma español
seleccionar el idioma inglés para cambiar los valores de los atributos
Mensajes de campos requeridos en español


Mensajes de campos requeridos en inglés




title, se mostrará una ayuda al colocar el cursor sobre el componente.











Editar EstatusController.java

Cambiaremos los mensajes en el CDI para utilizar los de los archivos messages.properties y application.properties, y en los métodos.
Inyectar ResourcesFiles

 @Inject
ResourcesFiles rf;

usamos rf.getMensajeArb(etiqueta)para obtener las etiquetas del archivo application.properties.
usamos rf.getMensajeMrb(etiqueta)para obtener las etiquetas del archivo messages.properties.

Modificar el codigo del método save(), para utilizar las etiquetas de los archivos properties.

@Named
@SessionScoped
public class EstatusController implements Serializable {
   @Inject
   EstatusFacade estatusFacade;
   Estatus estatus = new Estatus();
   @Inject
   ResourcesFiles rf;
   private List<Estatus> items;
   // Add business logic below. (Right-click in editor and choose
   // "Insert Code > Add Business Method")
   public Estatus getEstatus() {
       return estatus;
   }

   public void setEstatus(Estatus estatus) {
       this.estatus = estatus;
   }

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

   public String save() {
       try {
           if (estatusFacade.find(estatus.getIdestatus()) != null) {
 JSFUtil.warningDialog(rf.getMensajeArb("info.message"), rf.getMensajeArb("warning.idexist"));
               return null;
           }
           estatusFacade.create(estatus);
            JSFUtil.addSuccessMessage(rf.getMensajeArb("info.save"));
           estatus = new Estatus();
       } catch (Exception e) {
           JSFUtil.addErrorMessage(e.getLocalizedMessage());
       }
       return null;
   }

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

public String delete() {
       try {
           estatusFacade.remove(estatus);
           JSFUtil.addSuccessMessage(rf.getMensajeArb("info.delete"));
            encontrado = false;
           estatus = new Estatus();

       } catch (Exception e) {
           JSFUtil.addErrorMessage(e.getLocalizedMessage());
       }
       return null;
   }
public List<Estatus> getItems() {
       if (items == null) {
           items = estatusFacade.findAll();
       }
       return items;
   }


Muestra el mensaje en Espanol

o en inglés dependiendo del idioma seleccionado




CREAR UN SelectOneMenu

Ahora crearemos un selectOneMenu para desplegar las opciones para el atributo esinicial, con los valores de si/no.
Utilizamos el componente <p:selectOneMenu/> de primefaces, el valor para value se indicará el atributo del Entity

<p:selectOneMenu  id="esinicial" value="#{estatusController.estatus.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>

Genera el selectOneMenu con los valores en diversos idiomas.
en Español


Cambiamos el idioma a ingles.

















TEMAS DE PRIMEFACES

Primefaces ofrece una serie de temas que podemos implementar en nuestra aplicación web y cambiar su aspecto de manera sencilla.
Primero crearemos un CDI de tipo @SessionScoped para que contenga durante la sesión  del usuario el tema seleccionado, modificaremos el archivo web.xml para establecer el soporte para el tema y se mostrará una lista de temas para seleccionarlo.
  • Desde menú File, seleccione New
  • en Categories, seleccione Java Server Faces
  • en File Types, seleccione JSF ManagedBeans
  • Class Name: ManagementThemes
  • Package com.avbravo.scrumweb.generales
  • Scope: Session



import java.io.Serializable;
import java.util.Map;
import java.util.TreeMap;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;

/**
*
* @author avbravo
*/
@Named
@SessionScoped
public class ManagementThemes implements Serializable {

   private static final long serialVersionUID = 1L;
   private String tema = "home";
   private String temaPredeterminado = "home";

   private Map<String, String> themes;

   public Map<String, String> getThemes() {
       themes = new TreeMap<String, String>();
       themes.put("afterdark", "afterdark");
       themes.put("afternoon", "afternoon");
       themes.put("afterwork", "afterwork");
       themes.put("aristo", "aristo");
       themes.put("black-tie", "black-tie");
       themes.put("blitzer", "blitzer");
       themes.put("bluesky", "bluesky");
       themes.put("casablanca", "casablanca");
       themes.put("cupertino", "cupertino");
       themes.put("cruze", "cruze");
       themes.put("dark-hive", "dark-hive");
       themes.put("dot-luv", "dot-luv");
       themes.put("eggplant", "eggplant");
       themes.put("excite-bike", "excite-bike");
       themes.put("flick", "flick");
       themes.put("glass-x", "glass-x");
       themes.put("home", "home");
       themes.put("hot-sneaks", "hot-sneaks");
       themes.put("humanity", "humanity");
       themes.put("le-frog", "le-frog");
       themes.put("midnight", "midnight");
       themes.put("mint-choc", "mint-choc");
       themes.put("none", "none");
       themes.put("overcast", "overcast");
       themes.put("pepper-grinder", "pepper-grinder");
       themes.put("redmond", "redmond");
       themes.put("rocket", "rocket");
       themes.put("sam", "sam");
       themes.put("smoothness", "smoothness");
       themes.put("south-street", "south-street");
       themes.put("start", "start");
       themes.put("sunny", "sunny");
       themes.put("swanky-purse", "swanky-purse");
       themes.put("trontastic", "trontastic");
       themes.put("ui-darkness", "ui-darkness");
       themes.put("ui-lightness", "ui-lightness");
       themes.put("vader", "vader");
       return themes;
   }

   public String getTemaPredeterminado() {
       return temaPredeterminado;
   }

   public void setTemaPredeterminado(String temaPredeterminado) {
       this.temaPredeterminado = temaPredeterminado;
   }

   public void setThemes(Map<String, String> themes) {
       this.themes = themes;
   }

   public String getTema() {
       return tema;
   }

   public void setTema(String tema) {
       this.tema = tema;
   }
  
 public String cambiar(){
       return null;
   }
}


Editar el archivo web.xml ubicado en la carpeta WEB-INF

Agregar en <context-param> referencia al CDI ManagementThemes
   <context-param>
<param-name>primefaces.THEME</param-name>
<param-value>#{managementThemes.tema}</param-value>
</context-param>



Editar menu.xhtml
Agregar dentro del <p:column> en el submenú option
<p:submenu label="#{app['menu.themes']}">
                               <p:menuitem icon="ui-icon-star" onclick="PF('dlgTheme').show();"
                                           value="#{app['info.theme']}" immediate = "true" />
  </p:submenu>

y colocamos el menuitem para salir
<p:menuitem value="#{app['login.logout']}"  title="#{app['login.logout']}"  icon="ui-icon-power"/>

y agregamos el <p:dialog> debajo del  </p:megaMenu>

               <p:dialog header="#{app['info.theme']}" widgetVar="dlgTheme"
                         showEffect="bounce" hideEffect="explode" width="400"
                         height="200">
                   <h:panelGrid columns="2">
                       <h:panelGroup>
                           <p:outputLabel value="#{app['info.theme']}"/>
                           <p:selectOneMenu value="#{managementThemes.tema}" immediate
                                            = "true" editable="true">
                               <f:selectItems value="#{managementThemes.themes}" />
                           </p:selectOneMenu>
                           <p:commandButton value="#{app['boton.changetheme']}"
                                            action="#{managementThemes.cambiar}" ajax="false"/>
                       </h:panelGroup>
                   </h:panelGrid>
               </p:dialog>















Codigo de menu.xhtml

<h:form id="menuForm" >
               <p:megaMenu rendered="#{loginBean.logeado}">
                   <p:submenu label="#{app['menu.records']}" rendered="#{menuBeans.barraRegistros}" icon="ui­icon­check">
                       <p:column>
                           <p:submenu label="#{app['menu.estatus']}" rendered="#{menuBeans.estatusMenu}">
                               <p:menuitem value="#{app['menu.insert']}" rendered="#{menuBeans.estatusCrear}"  url="/faces/page/estatus/estatusinsert.xhtml" />
                               <p:menuitem value="#{app['menu.list']}"   rendered="#{menuBeans.estatusListar}" url="/faces/page/estatus/estatuslist.xhtml"/>
                           </p:submenu>
                       </p:column>
                   </p:submenu>
                   <p:submenu label="#{app['menu.options']}">
                       <p:column>
                           <p:submenu label="#{app['menu.themes']}">
                               <p:menuitem icon="ui-icon-star" onclick="PF('dlgTheme').show();"
                                           value="#{app['info.theme']}" immediate = "true" />
                           </p:submenu>

                           <p:submenu label="#{app['language.language']}">
                               <p:menuitem action="#{idiomas.englishAction}" value="#{app['language.english']}"
                                           immediate = "true" ajax = "false" icon="ui-icon-flag"/>
                               <p:menuitem action="#{idiomas.spanishAction}" value="#{app['language.spanish']}"
                                           immediate = "true" ajax = "false" icon="ui-icon-flag" />


                           </p:submenu>
                       </p:column>
                   </p:submenu>
<p:menuitem value="#{app['login.logout']}"  title="#{app['login.logout']}"  icon="ui-icon-power"/>
   
               </p:megaMenu>
               <p:dialog header="#{app['info.theme']}" widgetVar="dlgTheme"
                         showEffect="bounce" hideEffect="explode" width="400"
                         height="200">
                   <h:panelGrid columns="2">
                       <h:panelGroup>
                           <p:outputLabel value="#{app['info.theme']}"/>
                           <p:selectOneMenu value="#{managementThemes.tema}" immediate
                                            = "true" editable="true">
                               <f:selectItems value="#{managementThemes.themes}" />
                           </p:selectOneMenu>
                           <p:commandButton value="#{app['boton.changetheme']}"
                                            action="#{managementThemes.cambiar}" ajax="false"/>
                       </h:panelGroup>
                   </h:panelGrid>
               </p:dialog>
           </h:form>


Tenemos un ejemplo cambiando el tema a hot-sneaks
se muestra la aplicación con el tema aplicado







primefaces ofrece el componente  <p:themeSwitcher> que realiza la misma función.
                           <h:outputText value="#{app['info.theme']}" />   
                                       <p:themeSwitcher style="width:165px" id="defaultSwitcher">  
                                           <f:selectItem itemLabel="Choose Theme" itemValue="" />  
                                           <f:selectItems value="#{managementThemes.themes}" />  
                                       </p:themeSwitcher>