Escolar Documentos
Profissional Documentos
Cultura Documentos
JSF com MyFaces e Tomahawk
Aprenda a utilizar os recursos do MyFaces
FRANCISCO CALAÇA XAVIER
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/12
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/12
Figura 2. Inclusão de contatos
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/12
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 popup”
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
GerenciadorContato que se encontra na Listagem 7 e o facesconfig.xml que se encontra na
5/12
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.
Validação
Existem vários validadores no Tomahawk. O validador de endereços de email
(<t:validateEmail>) verifica se um texto informado é um email 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>
<h:inputText>
<t:validateRegExpr pattern='\d{5}'
detailMessage='#{"{0} Campo inválido." }'/>
</h:inputText>
6/12
Figura Q1. Exemplo de painel com abas
<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.
Figura Q2. Exemplo de uma árvore de dados extraído do site
7/12
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. Tratase 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/12
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 ...
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/12
int mesAniversario = calAniversario.get(Calendar.MONTH);
if (diaAniversario == dia && mesAniversario == mes) {
resultado.add(cont);
}
}
return resultado;
}
}
<filter>
<filtername>extensionsFilter</filtername>
<filterclass>
org.apache.myfaces.component.html.util.ExtensionsFilter
</filterclass>
</filter>
<filtermapping>
<filtername>extensionsFilter</filtername>
<urlpattern>*.faces</urlpattern>
</filtermapping>
<filtermapping>
<filtername>extensionsFilter</filtername>
<urlpattern>/faces/*</urlpattern>
</filtermapping>
<servlet>
<servletname>Faces Servlet</servletname>
<servletclass>javax.faces.webapp.FacesServlet</servletclass>
<loadonstartup>1</loadonstartup>
</servlet>
<servletmapping>
<servletname>Faces Servlet</servletname>
<urlpattern>*.faces</urlpattern>
</servletmapping>
</webapp>
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="backgroundcolor: #cfc">
<t:jscoo kM en u layout=" hb r" theme="T he me Of fi ce " >
<t:navig at io nM en uI t em itemLabel =" Ca da st r o" >
<t:navig at io nM en uI t em itemLabel =" In cl ui r Contato"
action=" in cl ui r" />
<t:navig at io nM en uI t em itemLabel =" Co ns ul t ar " >
<t:navig at io nM en uI t em itemLabel =" Co ns ul t ar Todos"
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/12
</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:input Ca le nd ar renderAs Po pu p= "t r ue "
renderPo pu pB ut to nA s Im a ge = "t r ue "
value="# {g er en ci ad o rC o nt a to . co n ta t o. a ni v er s ar 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/12
<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>
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/12
//... getters e setters omitidos
}
Listagem 8 faces-config.xml
<facesconfig>
<managedbean>
<managedbeanname>gerenciadorContato</managedbeanname>
<managedbeanclass>
br.com.jm.agenda.GerenciadorContato
</managedbeanclass>
<managedbeanscope>session</managedbeanscope>
</managedbean>
<navigationrule>
<fromviewid>*</fromviewid>
<navigationcase>
<fromoutcome>incluir</fromoutcome>
<toviewid>/incluir.jsp</toviewid>
</navigationcase>
<navigationcase>
<fromoutcome>consultar</fromoutcome>
<toviewid>/consultar.jsp</toviewid>
</navigationcase>
</navigationrule>
</facesconfig>
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