• Nenhum resultado encontrado

Projetos do MyFaces 1/12

N/A
N/A
Protected

Academic year: 2021

Share "Projetos do MyFaces 1/12"

Copied!
12
0
0

Texto

(1)

JSF com MyFaces e Tomahawk

Aprenda a utilizar os recursos do MyFaces

F

RANCISCO

 C

ALAÇA

 X

AVIER

Uma das implementações do JavaServer Faces mais utilizada atualmente é o MyFaces, um projeto 

da   Apache   Software   Foundation   que   vem   crescendo   rapidamente   e   hoje   vai   muito   além   da 

especificação JSF. Além do MyFaces Core, que é a implementação do JSF em si, há vários 

subprojetos, que fornecem componentes adicionais, trazendo suporte a Ajax, vinculação com dados, 

entre outras funcionalidades importantes no desenvolvimento web. 

Neste   artigo   apresentaremos  o  Apache   MyFaces,  e   criaremos   um  exemplo  que  faz   uso  dos 

componentes JSF fornecidos pelo mais popular dos seus subprojetos, o Tomahawk.

Projetos do MyFaces

Muitas das funcionalidades que diferenciam o MyFaces estão nos seus subprojetos.

Tomahawk – Principal e mais utilizado subprojeto do MyFaces. Possui uma grande quantidade 

de componentes visuais como editores html, menus, tabelas com ordenação etc. Já há versões 

estáveis disponíveis para uso em produção. 

ADF Faces / Trinidad  – O ADF Faces é a implementação JSF  e conjunto de componentes 

desenvolvido originalmente pela Oracle e doado para o Projeto MyFaces. Possui suporte a Ajax 

e futuramente será chamado Trinidad.

Tobago – Além de ser um conjunto de componentes JSF que funcionam sobre a implementação 

do MyFaces, o principal objetivo do Tobago é tornar o desenvolvimento de aplicações web mais 

ágil.   O   Tobago   fornece   um   gerenciador   de   layouts   que   organiza   automaticamente   os 

componentes na página, não sendo necessário o uso de tabelas para esse objetivo.

Sandbox – O projeto Sandbox consiste em componentes de teste do MyFaces, ainda em fase de 

desenvolvimento e que futuramente podem fazer parte do Tomahawk. Alguns componentes 

possuem suporte ao Ajax. Considerado instável pela Apache Software Foundation por se tratar 

de componentes de testes. 

A aplicação de exemplo

Para ilustrar o uso do MyFaces, construiremos uma agenda de contatos, conforme ilustrado na 

Figura 1. O exemplo utiliza vários componentes padrão do JSF (fornecidos pelo MyFaces Core) e 

também vários outros do Tomahawk. 

Observe que na inclusão de novos contatos,  é usado um componente de calendário para informar a 

data de aniversário, conforme mostra a  Figura 2. Note que usamos também um componente de 

menu. Com o Tomahawk, é possível construir  menus com submenus de forma rápida. Outra 

funcionalidade interessante é a ordenação de colunas. Através de cliques nos títulos das colunas da 

(2)

tabela de contatos é possível ordená­las conforme desejado. E à medida que um contato marcado 

como favorito é adicionado, este aparece no menu Favoritos.

Figura 1. A aplicação de exemplo em ação

Para mantermos o foco na programação JSF, não será feito acesso a banco de dados; todas as 

informações dos contatos permanecerão na memória. Na  Listagem 1  está o código da entidade 

Contato

. Na  Listagem 2, temos o código da classe  ContatoDao  que é responsável pela 

inclusão e consulta de contatos. Observe que temos nessa classe o atributo List contatos que é 

static

, para que todos os objetos criados a partir desta classe utilizem esta mesma lista (estamos 

aplicando o pattern Singleton). O método  consultarFavoritos()  retorna todos os contatos 

que possuem a propriedade  favoritos=true. O método  consultarAniversariantes()

retorna os contatos que fazem aniversário no dia e mês fornecidos como parâmetros. 

(3)

Figura 2. Inclusão de contatos

Adicionando suporte ao MyFaces Tomahawk

Para   que   o   MyFaces   Tomahawk   funcione   adequadamente,   é   necessário   utilizar   uma 

implementação   JSF.   Em   nossos   exemplos   estaremos   utilizando   o   MyFaces   como 

implementação JSF. Nada impede ao leitor de utilizar os componentes do Tomahawk junto 

com a implementação de referência da Sun para o JSF. Até o momento de escrita deste 

artigo a versão do Tomahawk que fornece suporte a outras implementações era a 1.1.3. O 

leitor pode acompanhar isto no site myfaces.apache.org.

Deve­se

 

também

 

incluir

 

o

 

filtro 

org.apache.myfaces.component.html.util.ExtensionsFilter

 no web.xml: 

   <filter>       <filter­name>extensionsFilter</filter­name>       <filter­class>          org.apache.myfaces.component.html.util.ExtensionsFilter       </filter­class>    </filter>    <filter­mapping>       <filter­name>extensionsFilter</filter­name>       <url­pattern>*.faces</url­pattern>    </filter­mapping>    <filter­mapping>       <filter­name>extensionsFilter</filter­name>       <url­pattern>/faces/*</url­pattern>    </filter­mapping>

O arquivo completo do web.xml pode ser verificado na Listagem 3. 

Para a utilização dos componentes do tomahawk é necessário também o uso da taglib:

<%@ taglib uri="http://myfaces.apache.org/tomahawk" prefix="t"%>

(4)

Componentes web do exemplo

Descreveremos agora os componentes utilizados em nossa aplicação. Veja também o  quadro 

“Mais componentes do Tomahawk”.

 

Menu

Para menus, utilizamos a tag  <t:jscookMenu>  com o atributo  layout="hbr". Isso faz 

com que o menu seja renderizado horizontalmente (para um menu vertical utiliza­se  “vbr”). 

Usamos também  theme="ThemeOffice"  para que o menu pareça como os do Microsoft 

Office.   Os   temas   disponíveis   são  ThemeIE,  ThemeMiniBlack,  ThemeOffice  e 

ThemePanel

.

Para criar um menu deve­se utilizar a tag <t:navigationMenuItem>, definindo o nome do 

menu no atributo  itemLabel.  Veja um exemplo na  Listagem 4,  os menus estão em negrito. 

Observe que os sub­menus são construídos aninhando as tags <t:navigationMenuItem>. 

O resultado deste menu está Figura 3:

Figura 3. Exemplo de um menu gerado pelo Tomahawk.

Calendário

O   calendário   usado   no   exemplo   é   criado   com   a   tag  <t:inputCalendar>.   Fizemos 

renderAsPopup="true"

  para   que   apareça   um   botão   que,   ao   ser   clicado,   mostra   o 

calendário,   e  renderPopupButtonAsImage="true"  para   que   esse   “botão   pop­up” 

possua uma imagem indicativa do que será mostrado. A aplicação desta tag pode ser vista na 

Listagem 5 com destaque em negrito para a utilização desta tag.

Tabela ordenada

O Tomahawk possui uma versão da tag  <h:dataTable>  do JSF:  <t:dataTable>  que 

possui  mais   funcionalidades  que  a   tag  da   implementação  de   referencia  do  JSF.  Dentre   estas 

funcionalidades podemos citar: ordenação automática de colunas, suporte a eventos java script para 

as linhas, exibição de tabelas em modo news paper (como um jornal) dentre outras. Em nosso 

exemplo,  para   que   seja   ativada   a   ordenação   automática,   foi   necessário   utilizar   o   atributo 

sortable="true"

.   Também   é   feita   a   substituição   das   tag’s  <h:column>  por 

<t:column>

. O uso dessas tag’s é demonstrado na Listagem 6.

O restante do projeto

O   restante   dos   arquivos   do   nosso   projeto   de   exemplo   é  o   Managed   Bean,   denominado 

(5)

Listagem 8. A classe GerenciadorContato possui apenas uma novidade em relação ao JSF 

padrão: a utilização da classe NavigationMenuItem, no método getFavoritos(), para 

inclusão dinâmica de contatos no menu Favoritos. 

Conclusões

Como vimos neste e em vários outros artigos da Java Magazine, o uso de JavaServer Faces torna o 

desenvolvimento web mais fácil e as aplicações mais ricas e interativas (por exemplo, veja a 

segunda   parte   da   série   “Aplicação   Completa   Java   EE”,   na   Edição   45).   A   utilização   de 

implementações como o Apache MyFaces, aliada ao uso de projetos como o Tomahawk ou o 

Trinidad, completa esta facilidade. Estes projetos trazem para a programação JSF recursos que antes 

só eram possíveis no mundo das aplicações desktop. O Tomahawk, conforme vimos no exemplo, 

possui componentes sofisticados que aumentam a qualidade e a navegabilidade das aplicações web. 

Mais componentes do Tomahawk

Aqui exploramos alguns componentes e funcionalidades adicionais do Tomahawk.

Validação

Existem   vários   validadores   no   Tomahawk.   O   validador   de   endereços   de   e­mail 

(<t:validateEmail>) verifica se um texto informado é um e­mail válido ou não (a 

validade é apenas sintática). Não sendo válido, é enviada como mensagem de erro a 

string definida no atributo  detailMessage. Veja um exemplo, onde   o campo a ser 

validado é um <h:inputText>: 

<h:inputText>

<t:validateEmail detailMessage="Não é um email válido."/>

</h:inputText>

O validar de números de cartão de crédito verifica se a quantidade e a estrutura dos 

números informados para o cartão de credito é válida ou não. Veja um exemplo de uso: 

<h:inputText>

<t:validateCreditCard detailMessage='

#{"{0} Não é um cartão de crédito válido."}'/>

</h:inputText>

Não existindo um validador apropriado, é possível utilizar expressões regulares para 

definir a regra de validação desejada. Por exemplo: 

<h:inputText>

<t:validateRegExpr pattern='\d{5}'

detailMessage='#{"{0} Campo inválido." }'/>

</h:inputText>

(6)

Painel com abas

Os painéis com abas são úteis em formulários web com muitos campos de entrada de 

dados, conforme pode ser visto na Figura Q1.

Figura Q1. Exemplo de painel com abas

Para   a   definição   de   um   painel   com   abas   são   necessárias   duas   tags: 

<t:panelTabbedPane>

 para a criação da região onde serão renderizadas as abas e 

<t:panelTab label="Nome da aba">

 para a aba. Por exemplo: 

<t:panelTabbedPane>

<t:panelTab label="Tab 1">

<! – conteúdo da aba Tab1 -->

</t:panelTab >

<t:panelTab label="Tab 2">

<! – conteúdo da aba Tab1 -->

</t:panelTab >

</t:panelTabbedPane>

Árvore

O Tomahawk possui também o recurso de árvore de dados ou data tree view, conforme 

ilustra   a

 Figura Q2

 que   foi   extraída   do   site   de   exemplos: 

irian.at/myfaces/tree2HideRoot.jsf.

(7)

A   tag   <t:tree2  clientSideToggle="false"   value="#{managedBean.treeData}"> 

renderiza uma árvore e a Listagem 9 mostra o código do método getTreeData(), também 

extraído do site de exemplos. Este código é responsável por montar a estrutura de dados 

da árvore. Observe o uso da classe  TreeNodeBase. Esta classe possui um construtor 

que   recebe   três   parâmetros:   um   identificador   para   o   nodo,   o   nome   do   nodo   e   um 

booleano que indentifica se o nodo será renderizado como uma folha (true) ou como uma 

pasta (false).Note que estando o atributo  clienteSideToggle  da tag  <t:tree2>  ajustado 

como false a cada clique em um nó da arvore será feita uma nova requisição para busca 

dos dados pois os dados continuarão no servidor. Estando este atributo ajustado como 

true

 toda a árvore é trazida para o cliente e a cada clique em um nó não será feita uma 

requisição, pois os dados já estão no cliente (note que isto não é AJAX. Apesar do AJAX 

não realizar requisições, neste caso os dados são trazidos para o browser e implica a não 

necessidade   de  consultas  ao   servidor).  O  site  wiki.apache.org/myfaces/Tree2  fornece 

mais informações sobre as opções possíveis para árvores. 

Html Editor

Um dos componentes mais interessantes e sofisticados do Tomahawk é o editor de 

HTML ilustrado na Figura Q3.

Figura Q3. Exemplo do componente HtmlEditor

O   editor   possui   recursos   dignos   de   qualquer   editor   de   texto   básico   como   negrito, 

sublinhado,   cores   de   fontes   etc.   O   seu   uso   é   bem   simples.   Basta   utilizar   a   tag 

<t:inputHtml> e será renderizado o editor de textos.

Outros componentes

Você pode obter mais informações sobre outros componentes do Tomahawk no site 

irian.at/myfaces/home.jsf. Trata­se de um site que hospeda os exemplos compilados do 

Tomahawk e do SandBox. Estes exemplos podem ser baixados, com o código fonte, a 

partir do site people.apache.org/builds/myfaces/nightly.

(8)

Listagem 1. Classe Contato package br.com.jm.agenda; import java.util.Date; public class Contato implements Comparable<Contato> {    private int codigo;    private String nome;    private String telefone;    private Date aniversario;    private boolean favorito;   //... getters e setters omitidos ... }

Listagem 2. Classe ContatoDao

package br.com.jm.agenda; import java.util.*; public class ContatoDao {    private static List<Contato> contatos = new ArrayList<Contato>();    public void incluir(Contato contato) {       contatos.add(contato);    }    public List<Contato> consultar() {       return contatos;    }    public List<Contato> consultarFavoritos() {       List<Contato> resultado = new ArrayList<Contato>();       for (Contato contato : contatos) {          if (contato.isFavorito()) {       resultado.add(contato);          }       }       return resultado;    }    public List<Contato> consultarAniversanriantes(Date data) {       Calendar cal = Calendar.getInstance();       cal.setTime(data);       int dia = cal.get(Calendar.DAY_OF_MONTH);       int mes = cal.get(Calendar.MONTH);       List<Contato> resultado = new ArrayList<Contato>();       for (Contato cont : contatos) {          Calendar calAniversario = Calendar.getInstance();          calAniversario.setTime(cont.getAniversario());          int diaAniversario = calAniversario.get(Calendar.DAY_OF_MONTH);

(9)

         int mesAniversario = calAniversario.get(Calendar.MONTH);          if (diaAniversario == dia && mesAniversario == mes) {       resultado.add(cont);          }       }       return resultado;    } }

Listagem 3 web.xml completo

<web­app id="WebApp_ID">    <display­name>agenda</display­name>    <filter>       <filter­name>extensionsFilter</filter­name>       <filter­class>          org.apache.myfaces.component.html.util.ExtensionsFilter       </filter­class>    </filter>    <filter­mapping>       <filter­name>extensionsFilter</filter­name>       <url­pattern>*.faces</url­pattern>    </filter­mapping>    <filter­mapping>       <filter­name>extensionsFilter</filter­name>       <url­pattern>/faces/*</url­pattern>    </filter­mapping>    <servlet>       <servlet­name>Faces Servlet</servlet­name>       <servlet­class>javax.faces.webapp.FacesServlet</servlet­class>       <load­on­startup>1</load­on­startup>    </servlet>    <servlet­mapping>       <servlet­name>Faces Servlet</servlet­name>       <url­pattern>*.faces</url­pattern>    </servlet­mapping> </web­app> Listagem 4 menu.jsp <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%> <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%> <%@ taglib uri="http://myfaces.apache.org/tomahawk" prefix="t"%> <h:outputText styleClass="tituloAplicacao" value="Agenda de Contatos" /> <h:panelGrid width="500px" style="background­color: #cfc">       <t:j s c o o k M e n u   layou t = " h b r "   them e = " T h e m e O f f i c e " >       <t:n a v i g a t i o n M e n u I t e m   item L a b e l = " C a d a s t r o " >       <t:n a v i g a t i o n M e n u I t e m   item L a b e l = " I n c l u i r   Conta t o "       acti o n = " i n c l u i r "   />       <t:n a v i g a t i o n M e n u I t e m   item L a b e l = " C o n s u l t a r " >       <t:n a v i g a t i o n M e n u I t e m   item L a b e l = " C o n s u l t a r   Todo s "        action="consultar" actionListener=       "#{gerenciadorContato.consultar}" />       <t:navigationMenuItem        itemLabel="Consultar Aniversariantes de Hoje"        action="consultar" actionListener=       "#{gerenciadorContato.consultarAniversariantes}" />          </t:navigationMenuItem>       </t:navigationMenuItem>       <t:navigationMenuItem itemLabel="Favoritos">          <t:navigationMenuItems value="#{gerenciadorContato.favoritos}" />       </t:navigationMenuItem>    </t:jscookMenu>

(10)

</h:panelGrid> <f:verbatim>    <br />

<br />

<br /> </f:verbatim> Listagem 5. incluir.jsp <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%> <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%> <%@ taglib uri="http://myfaces.apache.org/tomahawk" prefix="t"%> <html> <head> <link href="estilo.css" type="text/css" rel="stylesheet" /> <title></title> </head> <body bgcolor="#ffffff"> <f:view>    <h:form>       <%@ include file="menu.jsp"%>       <h:outputText styleClass="titulo" value="Inclusão de Contatos:" />       <h:panelGrid columns="2">          <h:outputText value="Nome:" />          <h:inputText value="#{gerenciadorContato.contato.nome}" />          <h:outputText value="Telefone:" />          <h:inputText value="#{gerenciadorContato.contato.telefone}" />          <h:outputText value="Favorito:" />          <h:selectBooleanCheckbox       value="#{gerenciadorContato.contato.favorito}" />          <h:outputText value="Aniversario:" />       <t:i n p u t C a l e n d a r   rende r A s P o p u p = " t r u e "       rend e r P o p u p B u t t o n A s I m a g e = " t r u e "       valu e = " # { g e r e n c i a d o r C o n t a t o . c o n t a t o . a n i v e r s a r i o } "   />          <h:commandButton actionListener="#{gerenciadorContato.incluir}"       value="Incluir" />       </h:panelGrid>    </h:form> </f:view> </body> </html> Listagem 6. consultar.jsp <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%> <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%> <%@ taglib uri="http://myfaces.apache.org/tomahawk" prefix="t"%> <html> <head> <link href="estilo.css" type="text/css" rel="stylesheet" /> <title></title> </head> <body bgcolor="#ffffff"> <f:view>    <h:form>       <%@ include file="menu.jsp"%>       <h:outputText styleClass="titulo" value="#{gerenciadorContato.tituloTela}" />       <t:dataTable cellspacing="0" headerClass="tituloTabela"          rowClasses="linha1, linha2"          columnClasses="colE, colC, colC, colC" width="500px"          sortable="true" value="#{gerenciadorContato.contatos}"          var="contato">          <t:column>       <f:facet name="header">        <h:outputText value="Nome" />       </f:facet>       <h:outputText value="#{contato.nome}" />          </t:column>          <t:column>

(11)

      <f:facet name="header">        <h:outputText value="Telefone" />       </f:facet>       <h:outputText value="#{contato.telefone}" />          </t:column>          <t:column>       <f:facet name="header">        <h:outputText value="Favoritos" />       </f:facet>       <h:outputText rendered="#{contato.favorito}" value="sim" />       <h:outputText rendered="#{!contato.favorito}" value="não" />          </t:column>          <t:column>       <f:facet name="header">        <h:outputText value="Aniversário" />       </f:facet>       <h:outputText value="#{contato.aniversario}">        <f:convertDateTime pattern="dd/MM/yyyy" />       </h:outputText>          </t:column>       </t:dataTable>    </h:form> </f:view> </body> </html>

Listagem 7. Classe GerenciadorContato

package br.com.jm.agenda; import java.util.*; import javax.faces.event.ActionEvent; import javax.faces.model.*; import org.apache.myfaces.custom.navmenu.NavigationMenuItem; public class GerenciadorContato {    private Contato contato = new Contato();    private DataModel contatos;    private String tituloTela;    public List getFavoritos() {       List resultado = new ArrayList();       ContatoDao cDao = new ContatoDao();       List<Contato> favoritos = cDao.consultarFavoritos();       for (Contato cont : favoritos) {          StringBuilder label = new StringBuilder(cont.getNome());          label.append(": ");          label.append(cont.getTelefone());          resultado.add(new NavigationMenuItem(label.toString(), ""));       }       return resultado;    }        public void consultarAniversariantes(ActionEvent e){       tituloTela = "Aniversariantes de Hoje";       ContatoDao cDao = new ContatoDao();       contatos = new ListDataModel(cDao.consultarAniversanriantes(new Date()));    }    public void consultar(ActionEvent e){       tituloTela = "Contatos da Agenda";       ContatoDao cDao = new ContatoDao();       contatos = new ListDataModel(cDao.consultar());    }    public void incluir(ActionEvent e) {       ContatoDao cDao = new ContatoDao();       cDao.incluir(contato);       contato = new Contato();    }

(12)

  //... getters e setters omitidos } Listagem 8 faces-config.xml <faces­config>    <managed­bean>       <managed­bean­name>gerenciadorContato</managed­bean­name>       <managed­bean­class>          br.com.jm.agenda.GerenciadorContato       </managed­bean­class>       <managed­bean­scope>session</managed­bean­scope>    </managed­bean>    <navigation­rule>       <from­view­id>*</from­view­id>       <navigation­case>          <from­outcome>incluir</from­outcome>          <to­view­id>/incluir.jsp</to­view­id>       </navigation­case>       <navigation­case>          <from­outcome>consultar</from­outcome>          <to­view­id>/consultar.jsp</to­view­id>       </navigation­case>    </navigation­rule> </faces­config>

Listagem 9 exemplo do código Java necessário para montar uma tree

public TreeNode getTreeData() {     TreeNode treeData = new TreeNodeBase();     //adicionado a pasta Frank Foo     TreeNodeBase personNode = new TreeNodeBase("", "Frank Foo", false);     personNode.getChildren().add(new TreeNodeBase("", "Requires Foo", false));     TreeNodeBase folderNode = new TreeNodeBase("", "Requires Foo Reviewer", false);     personNode.getChildren().add(folderNode);     personNode.getChildren().add(new TreeNodeBase("", "Requires Foo Recommendation", false));     folderNode = new TreeNodeBase("", "Requires Foo Approval", false);     personNode.getChildren().add(folderNode);     folderNode = new TreeNodeBase("", "Requires Bar Processing", false);     personNode.getChildren().add(folderNode);     folderNode = new TreeNodeBase("", "Requires Bar Approval", false);     personNode.getChildren().add(folderNode);     treeData.getChildren().add(personNode);     //adicionado a pasta Betty Bar     personNode = new TreeNodeBase("", "Betty Bar", false);     return treeData; }    

Links

myfaces.apache.org

Página oficial do projeto MyFaces

irian.at/myfaces.jsf

Exemplos implementados de componentes do MyFaces

Referências

Documentos relacionados

Manual de Instalação do Citsmart 30 de 56 &lt;/xa-pool&gt; &lt;security&gt; &lt;user-name&gt;${user.name}&lt;/user-name&gt; &lt;password&gt;${user.password}&lt;/password&gt;

 Projeto: Nanoemulsões à base de óleo de copaíba (Copaifera multijuga Hayne): Desenvolvimento tecnológico, estudo de permeação cutânea, avaliação da atividade

Especialmente no primeiro ano de curso, segundo Tinto (2007), é necessária a integração e envolvimento do acadêmico, e essas intervenções visam duas adaptações: no

O armazenamento da embalagem vazia, até sua devolução pelo usuário deve ser efetuado em local coberto, ventilado, ao abrigo de chuva e com piso impermeável, no

1) O atendimento de nossos clientes é realizado por empregados da XP Investimentos CCTVM S/A (“XP Investimentos ou XP”) ou por agentes autônomos de investimento que

• O módulo principal.v serve para correr todos os módulos acima descritos aquando da simulação em Veriwell, iniciando as variáveis enable, reset e tecla; de seguida evoca os

Em termos da orgânica do novo Instituto, optou-se por uma estrutura simples que, garantindo a desejada coordenação das actividades, remete para as delegações a criar uma ampla

O presente documento pretende registar a análise efectuada pela equipa gestora do Portal CampingCar Portugal (Portal Português de Autocaravanismo) ao estudo de