0% acharam este documento útil (0 voto)
528 visualizações76 páginas

PDF Java Magazine Ediao 038 DL - PDF

1) O documento apresenta vários artigos sobre tecnologias Java, incluindo AJAX, relatórios, interfaces gráficas e frameworks. 2) Há um tutorial completo sobre como criar relatórios e gráficos no Eclipse usando a ferramenta Eclipse BIRT. 3) Também é apresentado um artigo mostrando como criar totalizações, agrupamentos e gráficos com as ferramentas JasperReports e iReport.

Enviado por

Ricardo Grião
Direitos autorais
© © All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
0% acharam este documento útil (0 voto)
528 visualizações76 páginas

PDF Java Magazine Ediao 038 DL - PDF

1) O documento apresenta vários artigos sobre tecnologias Java, incluindo AJAX, relatórios, interfaces gráficas e frameworks. 2) Há um tutorial completo sobre como criar relatórios e gráficos no Eclipse usando a ferramenta Eclipse BIRT. 3) Também é apresentado um artigo mostrando como criar totalizações, agrupamentos e gráficos com as ferramentas JasperReports e iReport.

Enviado por

Ricardo Grião
Direitos autorais
© © All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
Você está na página 1/ 76

 Relatórios • Eclipse • Interfaces gráficas • JGoodies • Struts • AJAX

AJAX fácil com GWT


A Revista da Comunidade Java Brasileira Usando o Google Web Toolkit para
a criação produtiva de aplicações AJAX

Google Search API


Fazendo pesquisas no Google
Fazendo
a partir de suas aplicações Java

Edição 38 - Ano V - R$ 9,90


Conversores
Conversores no Struts
S truts
Estenda o framework para garantir
a conversão e a formatação de dados

Datas com Swing


Usando componentes para
GUIs com Qualidade manipulação de datas e calendários
Boas práticas para a criação de interfaces em aplicações desktop
gráficas e uma introdução ao JGoodies

Eclipse Callisto
Conheça o novo projeto do Eclipse.org
que simplifica a vida do desenvolvedor

Relatórios
&
Gráficos
Usando o Eclipse BIRT para
criar relatórios completos
Agrupamentos,
totalizações e gráficos com
no Eclipse, passo a passo  JasperReports e iReport

 jm38.indb 1 17/7/2006 14:07:33


 jm38.indb 2 17/7/2006 14:07:45
 jm38.indb 2 17/7/2006 14:07:45
Conteúdo
EXPLORANDO O CD
PRODUTOS ORACLE
Passos para instalação do JDeveloper
10g, Oracle Containers for J2EE e
Oracle Database Express Edition,
incluídos no CD-ROM.

10

    s
    e CAFEÍNA
      õ
    ç
LEONARDO  GALVÃO
Aprendendo programação OO com Greenfoot; Shale
08
    e
e Tapestry top-level; novos Groovy, Geronimo e WTK

      S

BUSCAS COM A GOOGLE SEARCH API


JULIO  FAERMAN
Como usar a API do Google para realizar pesquisas na web, fazer 60
correções ortográficas e obter páginas do cache

    e
      l
    g AJAX FÁCIL COM GOOGLE WEB TOOLKIT
    o
    o 64
DOUGLAS JOSÉ RODRIGUES
Conheça as tecnologias e ferramentas do Google que tornam

      G extremamente produtivo o desenvolvimento de aplicações AJAX

RELATÓRIOS E GRÁFICOS NO ECLIPSE


OSVALDO PINALI  DOEDERLEIN
Usando o Eclipse BIRT para criar relatórios completos e gráficos
22
comerciais dentro do IDE mais popular do mercado

MAIS RELATÓRIOS PASSO A PASSO
    a ANA ABRANTES E YARA SENGER 36
    p
Definindo agrupamentos, calculando totais em vários níveis
e criando gráficos de resumo – com JasperReports e iReport
    a
      C

DATAS NO DESKTOP
FERNANDO LOZANO
Manipulação de datas em aplicações Swing usando componentes de
12
    p calendário do projeto NachoCalendar, e conceitos sobre JavaBeans e MVC

    o
     t
      k
    s
GUI S COM QUALIDADE, PARTE  1
    e 44
HUGO  VIDAL  TEIXEIRA
Técnicas e boas práticas para o projeto de interfaces gráficas e

      D implementação com a API JGoodies Forms

CONVERSÃO E FORMATAÇÃO NO STRUTS


      b ARI DIAS NETO 68
    e
Estendendo o framework para definir conversores personalizados e
garantir a formatação de números e datas

      W

    e
    s PROJETO CALLISTO
    p
      i 56
      l
FERNANDO LOZANO

    c
Detalhes sobre o novo projeto da Fundação Eclipse, que simplifica a
instalação de dez plug-ins fundamentais do Eclipse.org

      E
 jm38.indb 3 17/7/2006 14:09:05
Direção
Ano V • Edição 38 • 2006 • ISSN 1676-8361

Diretor Editorial Leonardo Galvão


Diretor de Marketing Gladstone Matos
Diretor Comercial Casseano Filho
Edição
Esp
Publisher e Editor-Chefe
Leonardo Galvão ( [email protected] )
Editores-Adjuntos
Fernando Lozano ( [email protected] )
Osvaldo Doederlein ( [email protected] )
Colaboraram nesta edição
Ana Abrantes, Ari Dias Neto, Douglas José Rodrigues,

A
Fernando Lozano, Hugo Vidal Teixeira, Julio Faerman, té poucos anos atrás, o suporte a relatórios em Java se encontrava muito aquém
Leonardo Galvão, Osvaldo Doederlein, Yara Senger do oferecido em outras plataformas. Mas a tecnologia evoluiu muito, e hoje
Arte nos deparamos com a situação oposta: há diversas opções de qualidade e até
Diretor de Arte Tarcísio Bannwart ( [email protected] ) mesmo dificuldade para escolher a melhor alternativa para cada caso. Esta edição traz
Diagramação Jaime Peters Junior, Lais Pancote e Tersis Zonato dois artigos com enfoque na criação de relatórios. Um tutorial completo com diversos
exemplos apresenta e explora o Eclipse BIRT, um conjunto de ferramentas que est ende
Ilustrações Felipe Machado e Francisco Peixoto
o IDE Eclipse oferecendo uma solução integrada para a criação de gráficos e relatórios.
Produção O segundo artigo destacado volta-se ao par de ferramentas iReport/JavaReports,
Gerência de Marketing Kaline Dolabella mostrando como criar totalizações, agrupamentos e gráficos. O texto demonstra
Distribuição recursos mais avançados dessas ferramentas, tratando de necessidades comuns em
Fernando Chinaglia Distribuidora S.A. relatórios não-triviais.
Rua Teodoro da Silva, 907, Grajaú - RJ Freqüentemente dizemos aqui que a tecnologia Java está ganhando força no segmento
CEP 20563-900, (21) 3879-7766 - (21) 2577-6362 de aplicações desktop. Esse movimento continua firme, com várias lacunas sendo pre-
Atendimento ao leitor enchidas por ferramentas e APIs que não param de melhorar. São exemplos disso os
A DevMedia possui uma Central de Atendimento on-line, onde você pode projetos do JGoodies: há desde look-and-feels bem projetados até soluções completas
tirar suas dúvidas sobre serviços, enviar críticas e sugestões e falar com um de binding, além de um popular gerenciador de layouts incluído na API JGoodies
de nossos atendentes.Através da nossa central também é possível alterar Forms. Esta API é o assunto de um artigo sobre criação de GUIs, que também trata de
dados cadastrais, consultar o status de assinaturas e conferir a data de envio técnicas fundamentais para o projeto de interfaces gráficas, passando gradualmente
de suas revistas.Acesse www.devmedia.com.br/central, ou se preferir da teoria à prática.
entre em contato conosco através do telefone 21 2283-9012.
Ainda no desktop, você verá como incrementar suas aplicações Swing com os com-
Edições anteriores ponentes NachoCalendar, que simplificam a entrada de datas, são muito configuráveis
Adquira as edições anteriores da revista Java Magazine ou de qualquer outra e podem dar um toque especial e profissional às suas aplicações desktop. O artigo
publicação do Grupo DevMedia de forma prática e segura, em apresenta detalhes sobre os componentes, e como fazer a instalação no Eclipse e no
www.devmedia.com.br/anteriores. NetBeans. Discute também questões importantes no desenvolvimento para o ambiente
Publicidade desktop, como características dos JavaBeans e o modelo MVC no Swing.
 [email protected] , 21 2213-0940
Na edição anterior, o artigo “10 Mais do Eclipse 3.2” colocou na primeira posição o
Projeto Callisto, uma importante iniciativa que resolve problemas comuns de instalação
Anúncios – Anunciando nas publicações e nos sites do Grupo DevMedia,
você divulga sua marca ou produto para mais de 100 mil desenvolvedores e versionamento no Eclipse. Nesta edição são mostrados mais deta lhes sobre o projeto,
de todo o Brasil, em mais de 200 cidades.Solicite nossos Media Kits, com incluindo o processo de instalação e possíveis problemas e soluções.
detalhes sobre preços e formatos de anúncios. Temos ainda um artigo que explica como estender o Struts, criando e registrando
Reprints Editoriais – Se foi publicado na Java Magazine um artigo que conversores para processar a entrada de dados e garanti r uma formatação apropriada.
possa alavancar as suas vendas, multiplique essa oportunidade! Solicite a Além de conhecer o uso de converters no framework, você aprende técnicas que per-
reimpressão da matéria junto com a capa da edição em que saiu, e distribua mitem mudar o funcionamento interno do Struts e resolver problemas sutis.
esse reprint personalizado entre seus clientes. As tecnologias do Google aparecem aqui em dose dupla, com artigos sobre o Google
Encarte de CDs – Faça como nossos maiores anunciantes.Encarte um CD Web Toolkit e a Google Search API. Lançado durante o JavaOne 2006, o GWT torna
com uma amostra de seus produtos na Java Magazine e atinja um público
possível a criação de aplicações AJAX rapidamente usando código Java. Já a API de
segmentado e formador de opinião.
pesquisas do Google permite integrar o maior mecanismo de busca mundial às suas
Realização
aplicações.
Apoio

Boa leitura!
Leonardo Galvão

Parceiros

 jm38.indb 4 17/7/2006 14:10:00


 aço do Leitor
Iniciando com Java

G
ostaria de orientações sobre como iniciar com com ferramentas e servidores. hoje e mos-
 Java, sem que o conhecimento de conceitos Há uma variedade imensa de IDEs disponíveis. tra como
fundamentais possa passar despercebido e Entre os open source, destacam-se o Eclipse criar uma
me faltar no futuro. Por onde devo começar?  (eclipse.org) e o NetBeans ( netbeans.org). Entre os aplicação
William de Jesus Rende comerciais, há vários populares, como o JDeveloper com o NetBeans, do início ao fim. Temos ainda
da Oracle ( oracle.com/technology/products/jdev ; artigos identificados como “Primeiros Passos” em
A tecnologia Java tem várias “sub-áreas”, com cada gratuito para uso comercial e incluído no CD desta várias edições, e textos sobre várias tecnologias
uma formando um universo de conhecimentos edição), o JBuilder da Borland (borland.com/jbuilder ; importantes do Java, como Swing, JSP, Servlets
bastante independente. O caminho do aprendi- também com versão gratuita, mas com restrições), e JDBC.
zado vai depender muito, portanto, da área em o Rational Application Developer da IBM ( ibm. Quanto a livros, a série “Head First Java” da O’Reilly,
que você pretende se especializar. Porém, alguns com/software/awdtools/developer/application ), e o  já traduzida para português (com título "Use a Ca-
conhecimentos e ferramentas serão essenciais em IntelliJ IDEA ( jetbrains.com/idea). A maioria dos IDEs beça"), é excelente para o aprendizado da lingua-
todos os casos.  já vem com tudo que é necessário para desenvol- gem. Comece com “Use a Cabeça! Java” (Alta Books),
Comece fazendo o download do JDK (Java SE De- ver com Java, mas vale a pena ter o JDK à parte, por que cobre toda a sintaxe do Java e suas principais
velopment Kit) em java.sun.com/javase/downloads. exemplo, para executar e testar outras aplicações APIs, de forma clara, prática e inovadora.
A versão estável mais atual é a 5.0. Somente com Java (além disso, alguns IDEs, como o NetBeans, Depois de conhecer a sintaxe da linguagem e
o JDK, você já poderá criar aplicações que usam exigem que um JDK esteja instalado). as APIs fundamentais, abre-se muito o leque de
centenas de recursos, desde a leitura e escrita de Com o JDK e um IDE, você está pronto para de- opções de aprendizado. Você poderia, por exem-
arquivos, a operações avançadas de rede, passan- senvolver praticamente qualquer tipo de aplicação plo, decidir se especializar em programação web.
do pelo acesso a bancos de dados relacionais e a Java. O próximo passo é conhecer a linguagem e Neste caso, vale a pena conhecer Struts, JSP, JSF,
criação de interfaces gráficas completas. suas APIs. Há vários sites dedicados a desenvolve- Servlets e AJAX. Já se seu foco é no Java corpo-
Você pode passar muito tempo apenas usando o dores Java na web, inclusive em português, como rativo (enterprise), será importante conhecer EJB,
JDK, mas terá mais facilidade de evoluir no apren-  portaljava.com.br e devmedia.com.br/javamagazi- JMS, JNDI e outras tecnologias do Java Enterprise
dizado se tiver instalado também um IDE – um ne. Em inglês, alguns portais se destacam, como Edition. Em ambos os casos, valerá a pena dominar
ambiente integrado de desenvolvimento.Todo IDE  java.net , onjava.com ,  java.com e  javaranch.com. ferramentas muito usadas, como Ant e Hibernate.
Java inclui pelo menos um editor de código e um Outra fonte rica de informações são as listas de Se você pretende desenvolver para celulares,
depurador visual (para execução passo a passo de discussão do grupo de usuários SouJava (cadastre- vai precisar conhecer o MIDP e suas muitas APIs,
programas, inspeção de variáveis e objetos etc.); se em soujava.org.br ). como GCF, LCDUI e MMAPI, e instalar emuladores
a maioria vem também com um editor visual de Na Java Magazine, já publicamos dezenas de para os dispositivos alvo. Neste ponto, como se
interfaces e vários recursos auxiliares que facilitam artigos voltados ao desenvolvedor iniciante. A série vê, a decisão por qual caminho seguir dependerá
o desenvolvimento, como funcionalidades para “Aplicação Java Completa” nas Edições 25, 26 e 27, muito mais de suas necessidades, e talvez do que
manipulação de bancos de dados e integração por exemplo, é citada e usada pelos leitores até o mercado pede em sua região.

Edição 38 • Java Magazine 5

 jm38.indb 5 17/7/2006 14:10:09


Espaço do Leitor

 JDBC mesmo. Somente os subtipos concretos como lam conexões ao banco de dados e já incluem
Quero parabenizar toda a equipe de Java Ma- ClienteSimples  e ClienteEspecial  seriam instanciáveis o suporte a pools.
gazine pelo excelente trabalho de conteúdo e de no segundo exemplo. Mas note que isso não im- Somente se não quiser ou não puder usar
visual da revista. Os artigos sobre JDBC nas edições pede que a invocação cliente.venda() funcione. um servidor Java EE, você precisará se preo-
25 e 26 (“Persistência Turbinada”) são excelentes, e Osvaldo Doederlein cupar com pools de conexões (e com outros
ajudaram a esclarecer muitas questões. pools, como os de threads). Se for esse o caso,
Carlos Eduardo Privati dê uma olhada no Jakarta Commons DBCP
Pools ( jakar ta.ap ache.o rg/comm ons/d bcp ). O DBCP
Em aplicações que processam várias requisições é construído sobre outro projeto do Jakarta, o
Correção na Edição 36 ao mesmo tempo e exigem múltiplas conexões Commons Pool, que permite construir tipos de
 Ao me deparar com um trecho de código na pá- com o banco de dados, fica clara a necessidade pools adicionais.
gina 22 da Ediçao 36 (artigo “Qualidade Ap licada”), de um pool de conexões. Existem várias APIs que
no código referente à escolha de polimorfismo ao  prometem resolver o problema, mas para quem é
 switch , há uma linha desta forma: iniciante na tecnologia fica difícil avaliar o melhor
caminho. Vocês podem dar algumas sugestões? 
public class Cliente { public abstract void venda() ; } Carlos Eduardo Privati

Essa classe não deveria ser abstrata, e por conse- A princípio, você não precisaria se preocupar Participe!
qüência ela não poderia ser instanciada?  com isso, pois hoje em dia a grande maioria da s
aplicações Java que acessam SGBDs diretamen- Envie sua dúvida, comentário, correção
Fábio José Fernandes te, se forem construídas segundo um paradigma ou sugestão, com nome completo,
multicamadas, utilizam servidores Java EE para o cidade e estado, para:
Realmente, houve um erro neste trecho de back-end (servidor). Em qualquer servidor Java
[email protected]
código: Cliente deveria ser abstract . Já a primeira EE, desde um produto open source e limitado
versão da classe Cliente mostrada no artigo, à web como o Tomcat até um servidor Java EE Cartas publicadas podem ser editadas
com um atributo int tipo, é concreta. Quanto a completo como o JBoss ou Weblogic,você pode por motivos de clareza ou extensão.
não permitir instanciação, era essa a intenção utilizar o recurso de DataSources, que encapsu-

6  Java Magazine • Edição 38

 jm38.indb 6 17/7/2006 14:10:22


Edição 38 • Java Magazine 7

 jm38.indb 7 17/7/2006 14:10:27


Cafeín
News & Bits
de discussão, espaço de repositório e Project Graphics (JSR-226), Payment API (JSR-229),
Management Committee (PMC). Desenvol- Advanced Multimedia Supplements (JSR-
vido pelo mesmo criador do Struts, Craig 234) e Mobile Internationalization API (JSR-
McLanahan, o Shale é um framework focado 238). O novo W TK inclui ainda a SNAP Mobile
na tecnologia JavaServer Faces (JSF) e está API, da Nokia, que suporta a criação de jogos
Shale é top-level
chegando a seu primeiro release estável. multiusuário em rede. O WTK 2.5 exige um
O framework web Shale foi aprovado como
shale.apache.org. JDK 1.5 ou superior.
um projeto “top-level” da Apache Software
Foundation. Com isso torna-se autônomo
na ASF, em vez de um subprojeto do Apache Magnolia 3 Graduação do Tapestry
Struts. Terá, assim, seu próprio website, listas Um dos mais populares e maduros sistemas O Tapestry se graduou para um projeto
de gerenciamento de conteúdo corporativos “top-level” da Apache. Antes subprojeto do
(ECM), o Magnolia chega à versão 3.0 com projeto Jakarta, este framework web agora

Geronimo 1.1 muitos novos recursos. O Magnolia está


entre os primeiros a suportar a especificação
tem site próprio e passa a se chamar Apache
Tapestry.

A versão 1.1 do servidor Java EE da


Apache traz melhorias de perfor-
mance e muitas correções de bugs.
JSR-170, Java Content Repository, e inclui por
padrão o Apache Jackrabbit (uma implemen-
tação open source desta JSR). Também são
O Tapestry é voltado à criação de apli-
cações web dinâmicas em Java. Divide
as aplicações em conjuntos de páginas,
Uma novidade de destaque é o suporte suportadas implementações comerciais do sendo cada uma construída a partir de
a plug-ins: agora aplicações Geronimo, repositório de conteúdo. componentes. Essa estrutura permite que
recursos do servidor e produtos inte- Criado por uma empresa suíça, a Obinary, o framework cuide de tarefas comuns
grados podem ser distribuídos como o projeto fornece uma interface adminis- como a construção de URLs, validação de
plug-ins, que são fáceis de instalar, trativa baseada na web, uma API extensa e entradas do usuários, armazenamento de
automaticamente fazem o download bem documentada e taglibs para a criação estado e localização/internacionalização.
de dependências e não exigem a reini- de templates. No Tapestry o desenvolvedor cria templates
cialização do servidor. A versão 1.1 inclui Entre as novidades principais estão recursos em HTML puro e os combina com código
ainda recursos e visualizações adicio- para versionamento, suporte a Portlets (JSR- Java, e opcionalmente descritores XML. As
nais no console administrativo, como 168), autenticação integrada ( single sign-on) aplicações lidam com objetos, métodos e
gráficos de utilização de memória e um e uma interface gráfica renovada. O produto propriedades, e não com URLs e requisi-
wizard para a configuração remota do tem três edições, sendo a Community Edition ções/respostas HTTP (que são abstraídos
servidor http. Outra novidade é a dis- open source. As edições Enterprise e Business do desenvolvedor). A distribuição do pro-
tribuição “leve” do servidor, chamada Process completam as opções, oferecendo  jeto inclui mais de 50 componentes, que
Little-G, que inclui um subconjunto das suporte profissional e funcionalidades vão de simples objetos para saída de dados,
funcionalidades do Geronimo. O Little- adicionais. Há localizações para 15 idiomas. até componentes complexos como grades
G vem com um gerenciador de transa- www.magnolia.info. e árvores de navegação.
ções, um container web (que pode ser Atualmente na versão 4.02, o Tapestry já
Tomcat ou Jetty) e outros elementos do está com a versão 4.1 adiantada. Este novo
Geronimo, mas não é um servidor Java Novo WTK release incluirá o dojo, um framework para
EE completo. Será útil para usuários que Foi lançado o beta do Sun Wireless Toolkit desenvolvimento com AJAX, que é a base de
não precisam de todas as facilidades do 2.5 para CLDC, o popular kit de ferramen- boa parte das funcionalidades adicionais. En-
Java EE e desejam consumo menor de tas para desenvolvimento de aplicações tre os destaques está o novo supor te a JSON
memória e processamento. geronimo. Java Micro Edition. Várias novas APIs estão (JavaScript Object Notation), widgets, novas
apache.org. implementadas, entre elas Mobile Service anotações e validações no lado do cliente.
Architecture (JSR-248), Scalable 2D Vector tapestry.apache.org.

8  Java Magazine • Edição 38

 jm38.indb 8 17/7/2006 14:10:34


a LEONARDO GALVÃO

coração da implementação, o chamado basicamente correções de bugs (incluindo


Groovy JSR-6
Meta-Object Protocol, o que atrasou um algumas submetidas pela Oracle), além do
Está disponível a última versão do Groovy pouco o lançamento do primeiro RC. Em novo suporte a stored procedures e um
antes do lançamento da primeira versão compensação, as alterações estão per- esquema mais simples de carregamento
Release Candidate (RC). Segundo o líder mitindo aumentar a performance para de classes, bem como algumas outras
do projeto, Guillaume Laforge, estão sen- níveis próximos do desempenho do Java. funcionalidades ainda não documentadas.
do realizadas mudanças significativas no As mudanças visíveis na versão JSR-6 são groovy.codehaus.org .

Aprendendo OO com Greenfoot um método sobre o mundo que afeta todos


os atores; e invocar métodos de atores, por
exemplo fazendo-os se mover ou realizar

O
BlueJ, IDE voltado ao aprendizado cas de imagens. Por ser baseado no BlueJ, o outras operações mais complexas.
de orientação a objetos e Java, tem Greenfoot já vem com editor de código Java, O Greenfoot está em desenvolvimento há
um novo derivado – o Greenfoot depurador e inspetor de objetos, incluindo mais de dois anos, tendo inclusive sido apre-
– que cria um ambiente gráfico bidimen- recursos que permitem atuar sobre o mo- sentado em congressos, mas só recentemen-
sional altamente flexível para estimular o delo de objetos criado (os atores e mundos te teve liberada sua primeira versão pública.
aprendizado de técnicas OO. O novo am- são objetos Java comuns com métodos, Como o BlueJ, o Greenfoot é gratuito, mas
biente, assim como o BlueJ, é direcionado atributos e construtores). Pode-se, por não open source. O site do projeto oferece
a estudantes que estão iniciando a progra- exemplo, criar um novo ator escolhendo um downloads e a documentação da API, além
mação, mas se diferencia por privilegiar um de seus construtores em um menu; executar de um bom tutorial. greenfoot.org .
público mais jovem, do nível colegial.
Com visual bem cuidado, o Greenfoot
se baseia em dois conceitos funda-
mentais: “mundos” e “atores” que são
representados por imagens e têm seus
comportamentos programados por
código Java. Como mostram os vários
exemplos incluídos na distribuição, atores
podem ser praticamente qualquer coisa,
desde pequenos mamíferos australianos
até foguetes, formigas e rochas. Podem
também ser programados para interagir
com o mundo e com outros atores, permi-
tindo a criação de simulações sofisticadas
e até jogos.
Através de uma API simples, mas já
bastante extensa, o usuário pode definir
novos atores e mundos, e programar
rapidamente operações comuns em
simulações, como deslocamento na tela,
verificação de colisões, animações e tro- Greenfoot: Criação de simulações e jogos para aprender Java e orientação a objetos

Edição 38 •  Java Magazine 9

 jm38.indb 9 17/7/2006 14:10:36


   o
    D
.

    d
    C O
CD encartado nesta edição in-
clui três produtos completos da
Oracle, que são especialmente
descompactar, será pedida a senha for-
necida no passo anterior. Isso conclui a
instalação. Para inicializar o JDeveloper

   n   o
úteis para o desenvolvedor Java: o IDE (no Windows), simplesmente execute
 Java Oracle JDeveloper, uma ferramenta  jdeveloper.exe.
de desenvolvimento completa para a cria- Ao executar o JDeveloper pela primeira

   a
ção de aplicações Java de diversos tipos; o vez, será mostrada uma caixa de diálogo
Oracle Containers for J2EE (ou OC4J), um perguntando se você deseja migrar de uma

   r
runtime J2EE que é o coração do Oracle versão anterior do IDE. Responda “No”, e
Application Server 10g; e o Oracle Databa- o IDE será aberto. É então mostrada outra
se 10g Express Edition, uma versão “light” caixa de diálogo exclusiva para a primeira

   o
do SGBD da Oracle. execução (veja a Figura 2); nela você define

    l
as extensões de arquivos que serão associa-
Início da instalação das ao JDeveloper. Vale a pena selecionar
O CD inclui um arquivo Autorun.inf, pelo menos a segunda opção: .jpr.
que, em alguns sistemas, fará com que a A clássica janela de dicas é a próxima a

   p
página inicial seja carregada automatica- ser exibida. Depois de fechá-la, você estará
mente (veja a Figura 1). Caso não seja, abra com o IDE disponível para criar aplicações
a página index.htm na raiz do CD.  Java de diversos tipos. Veja o JDeveloper

   x
Para iniciar a instalação, clique no botão em ação na Figura 3.
“Install Now!”. Será mostrada uma lista
de restrições; marque todas as checkboxes, OC4J

    E
leia a licença a seguir e, se decidir aceitá-la, A instalação do OC4J é igualmente sim-
clique em “I Accept”. Na próxima pági na, ples. Descompacte o arquivo oc4j1013.zip,
será mostrada uma senha para instalação, localizado no diretório oc4j  do CD, para
que será sempre “10gJ2EE” (para os três uma pasta adequada do disco (exemplo:
produtos). Ao final da página, você verá c:\Java\oc4j). Para que seja possível usar os
instruções para instalação, que detalha- scripts de execução do OC4J, sua variável
mos a seguir. de ambiente JAVA_HOME deve estar defi-
nida, apontando para o diretório principal
 JDeveloper 10g
Para instalar o IDE, expanda
o arquivo  jde v1013 .zip, locali-
zado na pasta  jdev do CD, para
um diretório apropriado (por
exemplo c:\Java\jdev ). Ao

Figura 1. Página inicial do CD-ROM.

Figura 2. Associação de extensões ao IDE JDeveloper.

10  Java Magazine • Edição 38

 jm38.indb 10 17/7/2006 14:10:42


de um JDK 1.4.2 ou 5.0. Também é preciso definir a
variável ORACLE_HOME para o diretório onde o
OC4J foi descompactado.
Para executar o servidor, em um prompt de coman-
dos entre no subdiretório bin e execute o comando
oc4j –start. Depois de algum processamento, será soli-
citada uma senha de administrador. Forneça a senha
(note que ao digitar não serão mostrados caracteres,
nem mesmo asteriscos), e depois de mais alguns
passos o OC4J já estará em execução, pronto para a
instalação de aplicações J2EE.
Para testar a instalação, abra seu navegador web e
entre na URL http://localhost:8888/em. Isso carrega o
site de administração do servidor. Na tela de login,
forneça a senha de administração criada anteriormen-
te. O site de administração (veja a Figura 4) permite
Figura 3. O JDeveloper 10g é especialmente forte no desenvolvimento de aplicações com acesso a instalar e desinstalar aplicações Java EE, verificar o
banco de dados. O exemplo mostra o uso dos componentes ADF i ncluídos com o IDE. desempenho e investigar web services disponíveis,
entre outras operações.

Oracle Express
O Oracle Database 10g Express Edition inclui um
instalador convencional (para Windows). Descompac-
te o arquivo OracleXE.zip para algum local do disco
e execute OracleXE.exe. Siga os primeiros passos do
wizard, defina uma senha para contas de sistema e
prossiga com a instalação.
Para testar a instalação, selecione a opção “Ir Para a
Home Page de Banco de Dados” no grupo de progra-
mas criado para o programa (ou visite diretamente a
URL http://127.0.0.1:8080/apex ). Forneça o logi n “sys-
tem” e a senha definida na in stalação. A página inicial
de administração será exibida (veja a Figura 5).

Se a página de administração não for carregada, poderá ter


havido problemas durante a instalação, causados por progra-
mas como o Google Desktop ou sistemas de antivírus. Desative
Figura 4. Acompanhando o desempenho do OC4J no site de administração do produto.
esses programas e refaça a instalação. Se mesmo assim a página
não carregar,um bom site para analisar outros erros possíveis é
orablogs.com/sergio/archives/001759.html.

A partir do site de administração do Oracle XE, você


pode criar e manipular bases de dados, visualizar es-
tatísticas de execução, e criar aplicações para cadastro
de dados, e realizar muitas outras tarefas.

Figura 5. Administração do Oracle XE: da navegação de dados à criação de apli cações.

Edição 38 •38 Java
Edição •  Java
Magazine 11 11
Magazine

 jm38.indb 11 17/7/2006 14:10:43


 Java Livre

Datas no Desktop
Usando Componentes Swing para Manipular

O Swing é uma biblioteca de componentes


visuais muito rica e poderosa, permitindo
criar uma grande quantidade de aplicações
com qualidade profissional, usando apenas os com-
ponentes padrões inclusos no Java SE. Mas sempre
oferecida pelo Swing (o componente
 JFormattedTextField ).

O termo tecnicamente correto para qualificar


componentes como um “date picker” em uma apli-
haverá situações em que o desenvolvedor po- cação seria JavaBean, mas este termo ganhou usos
derá se beneficiar de algum componente comuns fora do seu sentido original, por isso pre-
adicional. ferimos o termo “componente”. Para mais detalhes
Um caso comum é o de um “date sobre esta questão, veja o quadro “Componentes,
picker”, um componente que per-  JavaBeans e POJOs” 
mite selecionar uma data num
calendário. A maioria dos usu- Existem vários componentes proprie-
ários prefere este tipo de tários e livres para a seleção de datas,
interface em vez da caixa de mas decidimos focar este artigo no
texto formatada NachoCalendar  (nachocalendar.sf.net) para
fornecer ao leitor um modelo de
como incluir componentes
Swing externos em
suas aplicações.
Veja também o
quadro “Outras bi-
 bliotecas Java para
calendários”.
Enquanto este
artigo apresenta
detalhes específicos
da instalação e uso do
NachoCalendar, os qua-
dros que demonstram a
integração deste componen-
te com os IDEs NetBeans e
Eclipse serão úteis também para
o desenvolvedor interessado em
outros componentes para aplicações
Swing.

Sobre o NachoCalendar
O NachoCalendar é um projeto open
source criado em meados de 2004 no
SourceForge. Como tem licença LGPL,
pode ser incluído também em aplicações
distribuídas sob licenças de software
proprietário, sem que isto exija a permis-
são dos desenvolvedores e sem obrigar a

12  Java Magazine • Edição 38

 jm38.indb 12 17/7/2006 14:10:51


Saiba como usar o
NachoCalendar em aplicações
Swing, como integrá-lo ao
NetBeans e Eclipse, e conheça
conceitos gerais sobre
componentes visuais em Java
Datas e Calendários
FERNANDO LOZANO

mendada para os usuários do NachoCalendar e  java -jar %N ACHO%\l ib\nach ocalendar- 0.23-demo.jar
abertura do código da aplicação que faz
componentes similares.
uso do componente. Usuários Linux devem executar o co-
São fornecidos três componentes prin- mando:
cipais, todos no pacote net.sf.nachocalendar. Instalação do NachoCalendar  java -jar $NACHO /lib/ nachocalend ar-0.23-demo.jar
components : Para obter o NachoCalendar, visite
• DateField  – Permite tanto a digitação nachocalendar.sf.net, siga o link “Downloads” Os quadros  “NachoCalendar no Net-
de datas quanto a seleção em uma jane- e baixe o arquivo nachocalendar-0.23. Beans 5” e “NachoCalendar no Eclipse
la pop-up, com estilo semelhante a um zip. Então descompacte o ZIP em uma VE” apresentam instruções específicas de
combobox. pasta qualquer. Será criado o diretório instalação e uso para esses IDEs.
• DatePanel – É basicamente o pop-up uti- nachocalendar-0.23  que contém, entre Agora veremos um exemplo de uso do
lizado pelo DateField, mas fornecido como outros, o arquivo manual-0.23.pdf , um NachoCalendar em aplicações Swing, para
uma subclasse de  JPanel. Por isso pode ser “QuickStart” para a utilização do com- depois estudarmos em mais detalhes a
posicionado livremente dentro de uma ponente. A documentação JavaDoc pode arquitetura do NachoCalendar e exemplos
 janela para formar telas de entrada de ser encontrada no subdiretório doc. Em adicionais de aplicações.
dados customizadas (como numa agenda lib  está o arquivo nachocalendar-0.23.jar,
de compromissos). que deve ser adicionado ao classpath de Exemplo de seleção de datas
• CalendarPanel – Outra subclasse de  JPanel, compilação e de execução de qualquer A Listagem 1   apresenta um exemplo
que exibe múltiplos DatePanel s simultanea- aplicação que utilize os componentes do  básico de uso do componente DateField do
mente, formando uma visão de calendário NachoCalendar. NachoCalendar, e demonstra quase tudo
que exibe diversos meses, com navegação Para executar o programa de demons- o que é necessário saber sobre ele para
e layout customizáveis. tração do projeto, execute a seguinte lin ha utilizá-lo em uma aplicação real.
de comando, onde %NACHO% deve ser O exemplo modifica a instância de
A Figura 1 apresenta a aplicação de de- substituído pelo diretório contendo o JAR  java.text.DateFormat do componente por meio
monstração inclusa com o NachoCalendar. do NachoCalendar: do método setDateFormat() . A razão disso é
Observe que o componente já está “locali-
zado” para o português brasileiro, usando
recursos presentes no Java SE, por meio de
 java.text.DateFormat  e classes relacionadas.
Os três componentes compartilham
muitos recursos, de modo que a maior
parte do que se aprende sobre o mais
simples é válida também para os mais
complexos. Assim o artigo inicia apre-
sentando exemplos de uso do DateField, e
depois passa para o DatePanel. Para evitar
que o artigo fique muito longo, entretan-
to, não serão apresentados exemplos do
CalendarPanel . No entanto, a parte principal
da sua utilização será exatamente igual
à do DatePanel.

 A Edição 22 apresenta, na seção “Primeiros


Passos”, um artigo que detalha todas as APIs de Figura 1. Aplicação de demonstração do NachoCalendar: observe no DatePanel  que a data atual pode ser indicada por uma
manipulação de datas do Java SE. Leitura reco- elipse vermelha (os retângulos vermelhos indicam os componentes em si).

Edição 38 •  Java Magazine 13

 jm38.indb 13 17/7/2006 14:10:52


 Java Livre • Datas no Desktop

que a configuração padrão do componente


Outros componentes Java exibe anos com apenas dois dígitos (por
exemplo, “17/05/06”), enquanto que o
relacionados com calendários formato padrão MEDIUM de DateFormat utiliza
quatro dígitos.
A qui apresentamos uma breve relação de outros componentes e bibl iotecas livres para Java,
que podem substituir ou complementar o NachoCalendar, agrupados em categorias de
acordo com suas finalidades.
O exemplo também ilustra como ini-
cializar e como recuperar a data editada
pelo componente. Os métodos getValue()
Note que são todos projetos hospedados no SourceForge, mesmo que alguns tenham seus pró-
e setValue()  são declarados para receber e
prios domínios DNS independentes e em alguns casos sites independentes do SourceForge.
retornar um  java.lang.Object em vez de um
 java.util.Date ou  java.util.Cale ndar. O motivo
Componentes Swing para edição de datas e visualização de calendários
disto é tornar o componente um substituto
• microba.sf.net
direto para o  JFormattedTextField, que define
• web.ukonline.co.uk/mseries
• opensource.theotherbell.com/php/datepicker.php os métodos get/setValue()  da mesma forma.
Apesar de a assinatura dos métodos indicar
Componentes web para edição de datas e visualização de calendários um Object, passar qualquer coisa diferente
• calendartag.sf.net de um  java.util.Date irá gerar uma exceção.
•  jcal.sf.net Para compilar e executar o exemplo,
• sf.net/projects/palooka antes acrescente o JAR com os com-
ponentes ao classpath do sistema,
Interação com serviços de calendário, PIMs e Groupware por exemplo:
• k5n.us/javacaltools.php
• moonbird.sf.net setCLASSPATH=%CLASSPATH%;%NACHO%\l ib\nachocalendar-0.23.jar
•  jpim.sf.net
• web.mac.com/sebsto/iWeb/projects/JSCalendarSync.html (Usuários Linux devem usar o comando
•  jical.sf.net export em vez do comando set.) O resultado
• icalgrabber.sf.net da execução do programa pode ser visto
na Figura 2.
APIs alternativas para manipulação de datas e horas
•  joda-time.sf.net Arquitetura do NachoCalendar
• recurrance.sf.net O manual do NachoCalendar parece in-

Arquitetura MVC no Swing

N o Swing, todos os componentes visuais


seguem a arquitetura MVC, pela qual
classes diferentes desempenham o papel de
por ele para formar a arquitetura MVC.
Em componentes simples como  JButton e
 JLabel, o desenvolvedor não tem necessidade
desenvolvedores, todo componente Swing
instancia um Model e um UI Delegate padrão.
É por isso que a maioria das aplicações instan-
Modelo, Visualização e Controlador ( Model , de interagir com o Model, mas esta interação se cia (por exemplo) apenas um  JButton , e tudo
View , Controller ). Isto não significa que uma torna necessária em componentes mais com- funciona corretamente.
aplicação Swing tenha necessariamente que plexos como JList ou
seguir a arquitetura MVC, nem que o uso do  JTree.
Swing torne uma aplicação automaticamente Já a interação com Model
  Component UI Delegate
(Controller) (View)
aderente à arquitetura MVC. Veja a série “Uma a View (chamada
aplicação completa com o NetBeans”, publica- pelo Swing de UI
da nas Edições 25, 26 e 27 para mais detalhes Delegate ) em geral
sobre como construir uma aplicação Swing na é necessária apenas  javax.swing  javax.swing.plaf 

arquitetura MVC. para desenvolvedo-


Dentro do Swing, a classe com a qual nor- res de novos look- ButtonModel JButton ButtonUI
malmente o desenvolvedor interage (e que and-feels, como o
para ele parece ser o próprio componente) é TinyLAF ( muntjak.
na verdade o controlador na arquitetura MVC. de/hans/java/ 
A Figura Q1 ilustra o relacionamento entre o tinylaf ). Para tornar Figura Q1. Uso da arquitetura MVC na arquitetura do próprio Swing, exemplificada pelo
componente e as classes auxiliares utilizadas mais fácil a vida dos componente JButton

14  Java Magazine • Edição 38

 jm38.indb 14 17/7/2006 14:10:54


Usando o NachoCalendar no NetBeans

A Figura Q2   mostra uma versão do


primeiro exemplo deste artigo sendo
construída visualmente no editor Matisse
do NetBeans 5.x. Observe que ele é exibido
na área de desenho com seu aspecto real, e
que suas propriedades aparecem na janela
de propriedades. Porém não será possível
expandir a seta para ver o calendário em
tempo desenvolvimento (assim como não
seria possível expandir um  JComboBox ).
Acrescentar este componente no NetBeans
é fácil:
1.   Execute o commando Tools|Palette
Manager>Swing/AWT Components.
2. Clique em Add from JAR.
3 .   Localize e selecione o arquivo
nachocalendar-0.23.jar .
4. Clique em Next   para ver a lista de com-
ponentes disponíveis ( available components),
que lista todas as classes JavaBean encontra- Figura Q2. DateField  do NachoCalendar no editor visual do NetBeans 5
das no JAR selecionado.
5.  Selecione (usando Ctrl+Shift+clique) Note, entretanto, que
apenas os componentes “CalendarPanel”, este código será utilizado
“DateField” e “DatePanel”. (As demais clas- exatamente da maneira
ses listadas, embora pareçam para o IDE que foi digitado, podendo
JavaBeans independentes, são na verdade gerar erros de compila-
classes auxiliares para os três componentes ção na classe por falta de
citados.) imports e por outros moti-
6. Clique em Next   para ver as categorias vos. Havendo algum erro,
do Palette. ele deverá ser corrigido
7. Escolha a categoria “Beans” e clique em dentro da própria janela
Finish. de propriedades, pois o
trecho de código corres-
Será possível ver imediatamente os novos pondente não será editá-
componentes na categoria Beans do Palette. vel pelo editor de código
Todos terão, no entanto, um ícone contendo Java do NetBeans. Figura Q3. Editando a propriedade dateFormat  de um DateField 
um ponto de interrogação. O motivo é que Por outro lado, o des-
o NachoCalendar não inclui classes BeanInfo taque de sintaxe e o auto-completamento oportunidade. Um primeiro passo seria acres-
para seus componentes. Estas classes seriam de código estarão disponíveis no editor de centar as classes BeanInfo ao NachoCalendar,
responsáveis por fornecer o ícone para uma propriedades da mesma forma como no de modo a incluir ícones personalizados no
ferramenta visual, além de editores customi- editor de código. Palette do NetBeans (ou de qualquer outro IDE
zados para propriedades, como dateFormat ou No momento que um dos componentes  Java com suporte à edição visual Swing). Só isto
selectionMode, que fogem aos tipos usuais. do NachoCalendar for inserido em qualquer  já seria um acréscimo apreciado pelos usuários
O NetBeans contorna a falta de um custo- classe visual, o JAR correspondente será do projeto. Podem também ser criados editores
mizador para propriedades ao permitir que o acrescentado automaticamente às proprie- especializados para  selectio nMode  e outras pro-
valor inicial de uma propriedade seja def inido dades do projeto.  priedade s q ue exigem a digitaç ão de código
por um trecho de código Java. Basta clicar no NetBeans. Por fim, bastaria empacotar tudo
no botão de reticências ao lado do valor da em um plug-in do NetBeans (.nbm) que na sua
propriedade, e o resultado será semelhante  Se o leitor está interessado em participar instalação já acrescente automaticamente os
à Figura Q3. de um projeto de software livre, eis uma ótima componentes no Palette.

Edição 38 •  Java Magazine 15

 jm38.indb 15 17/7/2006 14:10:55


 Java Livre • Datas no Desktop

Usando o NachoCalendar no Eclipse VE

A Figura Q4  apresenta o primeiro exemplo


deste artigo sendo construído visualmente
com o Visual Editor (VE) da Fundação Eclipse,
de data, conforme o código a seguir:

private DateField getDateField() {


}
return dateField;

if (dateField == null) { Esta mudança será reconhecida pelo VE e incor-


mostrando que o desenvolvedor não precisa dateField = new DateField();
se limitar aos componentes fornecidos com o   dateField.setShowToday(false); porada à área de desenho em poucos se gundos.
Palette padrão do VE. dateField.setDateFormat( O VE é um editor poderoso e flexível, embora
  DateFormat.getDateInstance( ainda não seja tão intuitivo nem eficiente quanto
O VE não fornece uma maneira direta de se
  DateFormat.MEDIUM));
acrescentar componentes ao Palette; isto é possí- o Matisse do NetBeans.
}
vel apenas por meio de plug-ins que estendem o
próprio VE. Em compensação, é fornecido o ícone
“Choose Bean” ( ), que exibe uma pequena
variação de um diálogo bastante conhecido dos
usuários do Eclipse (veja a Figura Q5). Nele, digi-
ta-se o início do nome de uma classe ou interface
e são exibidas todas as correspondências visíveis
para o projeto corrente.
Esta variação do diálogo permite limitar as
correspondências a apenas os JavaBeans que es-
tendem alguma classe ou interface definida pelo
Swing, o que permite encontrar rapidamente o
componente desejado.
Para que isto funcione, o JAR do NachoCalendar
deve ser adicionado manualmente às proprieda-
des do projeto, como qualquer biblioteca Java.
Usuários experientes do Eclipse irão preferir
cadastrar o NachoCalendar como uma “User
Library” nas propriedades do IDE ( Figura Q6),
o que torna mais simples, depois, acrescentar a
biblioteca a cada projeto que venha a utilizá-la.
O VE não fornece nenhum mecanismo que fa-
cilite a edição de propriedades como selectMode  e
dateFormat dos componentes do NachoCalendar. Figura Q4. DateField do NachoCalendar no editor visual do Eclipse 3.1.x/3.2
Em compensação, ele não restringe a edição de
nenhum bloco de código gerado pelo editor. En-
tão é possível, por exemplo, editar manualmente
o método getDateField()  para modificar o formato

Figura Q5.Localizando o componente DateField  do


NachoCalendar no Eclipse VE Figura Q6. Localizando o JavaBean DateField  do NachoCalendar no Eclipse VE

16  Java Magazine • Edição 38

 jm38.indb 16 17/7/2006 14:10:57


dicar que o componente foge a especifica- uma classe de Model, que o desenvolvedor do NachoCalendar é demonstrada pelas
ção JavaBeans, ao indicar o uso de cla sses pode estender para fornecer funcionalida- extensões já i nclusas no download padrão,
de fábrica para a criação dos componentes, des adicionais. por exemplo:
por exemplo: O efeito imediato da obediência do Na- • Uso integrado a um  JTable:
choCalendar à arquitetura do Swing é a net.sf.nachocalendar.table.DateFieldTableEditor .
DateField datefield = CalendarFactory.createDateField(); compatibilidade com vários look-and-feels • Exibição de feriados dentro dos calendá-
As classes de fábrica são úteis para re- (LAFs) alternativos. rios: net.sf.nachocalendar.holidays.HolidayModel
duzir a quantidade de código necessária e HolidayRenderer  dentro do mesmo pacote.
para a configuração dos componentes,   Muitos componentes Swing de terceiros não • Suporte à exibição diferenciada de
em especial quando são utilizadas as têm aspecto visual “correto” a não ser que sejam dias alocados para tarefas (pense em uma
extensões de feriados e de tarefas, que utilizados com o LAF padrão Metal ou o LAF nativo aplicação de gerenciamento de projetos
fazem parte do download padrão do do Windows. Felizmente este não é o caso com o
NachoCalendar. O fato é, no entanto, que NachoCalendar.
todos os componentes do NachoCalendar
são verdadeiros JavaBeans, perfeitamente Nos componentes DatePanel e CalendarPanel,
aderentes à especificação, e podem ser é possível fazer seleções múltiplas de
utilizados sem se recorrer aos métodos datas, inclusive de faixas descontínuas.
de fábrica, como foi mostrado no primeiro Também é possível modificar a relação de
exemplo deste artigo. “dias úteis”, para todos os componentes, e
Além disso, o NachoCalendar é cons- também alterar o formato de datas utili-
truído segundo boas práticas do Swing, zado no DateField.
mantendo-se a separação de papéis. Se
você não está habituado ao design de  O cuidado na elaboração do NachoCalendar foi tan-
componentes desse toolkit, veja o quadro to que os componentes padrão são capazes até mesmo Figura 2. Execução do exemplo EscolheData.java, após o
“A arquitetura MVC no Swing”. Os com- de incluir as fases da Lua nas visões de calendário. clique sobre o botão de seta.
ponentes do NachoCalendar delegam
sua renderização para um UI Delegate e o A flexibilidade
gerenciamento das suas informações para dos componentes

Listagem 1.  EscolheData.java – exemplo básico de uso do DateField  do NachoCalendar

import java.util.Date;
import java.text.DateFormat;
import java.awt.BorderLayout;
import javax.swing.*;
import net.sf.nachocalendar.components.*;

public class EscolheData extends JFrame {


private DateField dateField;

public EscolheData() throws Exception {


setTitle(“Exemplo do NachoCalendar”);
  setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

// será um formato DD/MM/AAAA para o Brasil


DateFormat df = DateFormat.getDateInstance(
  DateFormat.DEFAULT);
Date dia = df.parse(“17/05/2006”);

  getContentPane().add(BorderLayout.NORTH,
new JLabel(“Esc olha uma data:”));
dateField = new DateField();
  dateField.setDateFormat(df);
  dateField.setValue(dia);
  //dateField.setPrintMoon(true);

getContentPane().add(BorderLayout.CENTER, dateField);
  pack();
}

public static void main(String[] args) throws Exception {


JFrame frame = new EscolheData();
  frame.setVisible(true);
}
}

Edição 38 •  Java Magazine 17

 jm38.indb 17 17/7/2006 14:10:59


 Java Livre • Datas no Desktop

ou em um PIM – Personal Information mesmo tempo, sua API básica é bastante


 Manager – como os fornecidos em PDAs simples, como veremos em mais detalhes
e aplicativos de Groupware). E exi- nos exemplos.
 bição de tooltips com a descrição
das tarefas associadas ao dia sob o Eventos de edição e mudança de data
cursor (TaskDataModel e TaskRenderer, Toda a navegação pelo calendário, por
no pacote  net.sf.nachocalendar.task) exemplo mudar de ano ou de mês, gera
eventos específicos (veja as interfaces em
Como se vê, estamos lidando net.sf.nachocalendar.event ). É fornecida uma
com um componente bastante API genérica para configuração dos com-
poderoso, capaz de fazer quase ponentes, cujo uso é demonstrado pelas
tudo o que se espera de um extensões padrão de feriados e tarefas,
componente deste tipo, mesmo  já citadas.
nas aplicações mais sofisticadas. Ao Na maioria das vezes, o único listener
que interessa registrar em um DateField é
um  javax.swi ng.ChangeLi stener. Este listener
Listagem 2.  EventosData.java – demonstra como responder ao evento de mudança da data armazenada no componente
permite agir no momento em que ocorre
//...imports omitidos uma mudança de data, seja por digitação
public class EventosData extends JFrame {
direta ou pela escolha no pop-up de ca-
private DateField dateField; lendário. Seu uso poderia ser validar dois
DateField s de modo que um deles aceite
public EventosData() throws Exception {
setTitle(“Exemplo do NachoCalendar”); apenas datas que sejam posteriores à for-
  setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); necida no outro.
getContentPane().add(BorderLayout.NORTH, A Listagem 2 demonstra como capturar
new JLabel(“Escolha uma data:”));
dateField = new DateField();
  dateField.setDateFormat(DateFormat.getDateInstance(DateFormat.MEDIUM));
  dateField.getDateFormat().setLenient(false);
dateField.addChangeListener(dataAlterada);

getContentPane().add(BorderLayout.CENTER, dateField);
  pack();
}

private ChangeListener dataAlterada = new ChangeListener() {


public void stateChanged(ChangeEvent e) {
  JOptionPane.showMessageDialog(EventosData.this,
“A data escolhida foi: “ + dateField.getValue(),
“Data alterada”, JOptionPane.INFORMATION_MESSAGE);
}
};

//...método main omitido


}
Figura 3. Execução do exemplo ExibeCalendario.java
após um pequeno aumento no tamanho da janela.
Listagem 3.  ExibeCalendario.java – mostra um calendário para o mês corrente

//...imports omitidos

public class ExibeCalendario extends JFrame {


private DatePanel datePanel;

public ExibeCalendario() throws Exception {


setTitle(“Exemplo do NachoCalendar”);
  setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

getContentPane().add(BorderLayout.NORTH,
new JLabel(“Calendário Swing”));
datePanel = new DatePanel();

getContentPane().add(BorderLayout.CENTER, datePanel);
  pack();
}

//...método main omitido


} Figura 4. ExibeCalendario.java após a adição de um
DayRenderer  customizado.

18  Java Magazine • Edição 38

 jm38.indb 18 17/7/2006 14:11:02


os eventos de mudança de data por meio
do ChangeListener . Listagem 4. ExibeCalendario.java – adição de um DayRenderer  customizado para exibir “linhas de grade”no calendário
Note que este exemplo é quase igual ao //...imports omitidos
apresentado no início deste artigo. A novi-
public class ExibeCalendario extends JFrame {
dade é o tratamento do evento, e também private DatePanel datePanel;
ter deixado o DateField com o valor inicial
public ExibeCalendario() throws Exception {
padrão, que é a data corrente. Experimente setTitle(“Exemplo do NachoCalendar”);
ainda alterar o argumento da chamada   setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

a setLenient(), fornecendo datas do tipo DefaultDayRenderer dayRenderer = new DefaultDayRenderer();


dayRenderer.setBorder(new MatteBorder(new Insets(1, 1, 1, 1),
“30/13/2006”. Color.LIGHT_GRAY));

getContentPane().add(BorderLayout.NORTH,
Exemplo de exibição de calendário new JLabel(“Calendário Swing”));
A Listagem 3 apresenta um exemplo de datePanel = new DatePanel();
datePanel.setRenderer(dayRenderer);
uso do DatePanel, que simplesmente exibe
um calendário para o mês corrente. getContentPane().add(BorderLayout.CENTER, datePanel);
  pack();
Observe que a janela pode ser redimen- }
sionada, e que o calendário será redimen-
//...método main omitido
sionado proporcionalmente (mas note }
que o tamanho de fonte utilizado não irá
Listagem 5.  EscolheVariasDatas.java – como lidar com seleções múltiplas em um DatePanel 
aumentar para compensar o aumento da
área do calendário). A Figura 3 ilustra a //...imports omitidos
aparência deste exemplo, após um peque- public class EscolheVariasDatas extends JFrame {
no aumento da janela. private DatePanel datePanel;
Caso a aparência padrão do calendário public EscolheVariasDatas() throws Exception {
não lhe agrade, o DatePanel fornece uma //...inicialização do JFrame e do DatePanel omitida
forma poderosa de customização que é datePanel.addChangeListener(dataAlterada);
 bem coerente com outros componentes
getContentPane().add(BorderLayout.CENTER, datePanel);
Swing sofisticados, por exemplo o  JTable.   pack();
Em vez de definir muitas propriedades que }
alteram o aspecto visual do componente, é private ChangeListener dataAlterada = new ChangeListener() {
definida uma interface de renderer (renderi- public void stateChanged(ChangeEvent e) {
Object[] datas = datePanel.getValues();
zador) para cada parte. Por exemplo, existe DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM);
String listaDatas = “”;
o net.sf.nachocalendar.components.DayRenderer, for (Object d : datas)
que é o responsável pela exibição de cada listaDatas += df.format(d) + “\n”;
célula de mês no calendário. JOptionPane.showMessageDialog(EscolheVariasDatas.this,
São fornecidas pelo NachoCalendar “As datas escolhidas foram:\n” + listaDatas,
“Datas alteradas”, JOptionPane.INFORMATION_MESSAGE);
várias implementações de DayRenderer, em }
especial o DefaultDayRenderer, que é uma };
subclasse do  JLabel  do Swing. É possível //...método main omitido
mudar a aparência do renderizador da }
mesma forma que se faz com um  JLabel
padrão, por exemplo adicionar uma bor-
da. A Listagem 4 ilustra como fazer esta and-feels personalizados, um renderizador deve valos de datas utilizando Shift+clique ou
customização simples, que tem o efeito de evitar fixar cores como foi feito no exemplo. Em então várias datas não-contíguas utilizan-
inserir “linhas de grade” no calendário. O vez disso, deve usar preferencialmente alguma cor do Ctrl+clique, da mesma forma que se
resultado pode ser visto na Figura 4. dependente do ambiente do usuário, por exemplo faz com  JList e  JTables. Na verdade, a con-
O mesmo modelo da Listagem 4  pode uma das definidas na classe  java.a wt.SystemColor . figuração padrão de um DatePanel permite
ser utilizado para mudar a fonte e as co- No exemplo, em vez de Color.LIGHT_GRAY   poderia seleções múltiplas desse tipo.
res de texto e de fu ndo, bem como outros ser utilizado SystemColor.control . Para se restringir a seleção a uma
atributos da exibição do calendário. Caso única data, ou a uma única faixa de
se deseje modificar os cabeçalhos com os datas contíguas, deve ser chamado
dias da semana, deve ser fornecido um Seleção de múltiplas datas o método setSelectionMode()  do objeto
HeaderRenderer, que é similar ao DayRenderer. Com um DateField, não se pode selecionar DateField . Este método pode receber uma
múltiplas datas no calendário. Mas com de três constantes definidas na interface
Para manter a compatibilidade com look- um DatePanel, é possível selecionar inter- net.sf.nachocalendar.model.DateSelectionModel ,

Edição 38 •  Java Magazine 19

 jm38.indb 19 17/7/2006 14:11:03


 Java Livre • Datas no Desktop

cujos significados são auto-explicativos: Caso seja configurada uma das duas clique) caso seja utilizado Shift+clique
• MULTIPLE_INTERVAL_SELECTION formas de seleção múltipla, o conjunto de ou Ctrl+clique.
• SINGLE_INTERVAL_SELECTION datas selecionadas pode ser obtido cha-
• SINGLE_SELECTION mando o método getValues(), que retorna
um array de Object. Exibição de feriados
1
 Um decorator  é uma classe que imita a interface de ou-
tra classe, por meio de especialização ou implementan-
A Listagem 5   demonstra como lidar Encerrando os exemplos de uso do Na-
do a mesma interface, e tem por objetivo substituir esta com seleções múltiplas de datas; é uma choCalendar, será visto como acrescentar
classe apenas acrescentando alguma funcionalidade. pequena modificação do exemplo na feriados ao DatePanel. O processo envolve
Este design pattern é muito usado em aplicações gráficas
para acrescentar algum elemento decorativo por cima de
Listagem 4. Note que o ChangeListener  será duas etapas:
outro elemento. Daí o nome. chamado várias vezes (uma para cada 1. Fornecer um decorator1 para o DayRenderer,

Componentes, JavaBeans e POJOs

F
reqüentemente os termos “componente” própria definição de JavaBeans. ou estender a classe BeanInfo  do componente
e “JavaBean” são usados como sinônimos O recurso de introspecção é uma característica original. O IDE também pode fornecer classes
pelos desenvolvedores Java. Além disso, única aos JavaBeans, quando comparado com BeanInfo para JavaBeans que não incluem seus
os termos “POJO” e “JavaBean” também cos- os componentes fornecidos por ambientes próprios BeanInfos.
tumam ser utilizados como equivalentes. Mas, RAD não-Java. Nestes ambientes, limitações da Um JavaBean que fornece seu próprio BeanInfo
se um “POJO” ( Plain Old Java Object ) é nada linguagem e da plataforma exigem a construção não é obrigado a s eguir as convenções definidas
mais do que um objeto/classe Java comum, explícita e trabalhosa de tabelas de proprieda- para o uso da introspecção, permitindo por
sem restrições adicionais, então o que seria um des e eventos, de modo que a construção de exemplo construir componentes que devam ser
componente? um componente é um processo bem diferente instanciados por métodos de fábrica.
Há muitas definições de “componente” no do processo de construção de uma classe O BeanInfo  é a única maneira de se fornecer
meio de TI, portanto em vez de discutir livre- “comum”. alguns recursos específicos para o uso em IDEs
mente o conceito, vamos ver o que diz a espe- Mas em Java a maior parte das classes cons- visuais, como um ícone para ser exibido na pa-
cificação JavaBeans 1.01, na seção 2.1: truídas seguindo apenas as “melhores práticas” leta de componentes. É uma pena, no entanto,
de desenvolvimento OO se tornam automatica- que tantos desenvolvedores de componentes
“A Java Bean is a reusable software component mente JavaBeans. Assim o conceito de JavaBean sigam o caminho mais fácil e deixem que o IDE
that can be manipulated visually  como componente construído para uso num IDE use apenas a introspecção para configurar o
in a builder tool.”  visual acaba sendo esquecido por muitos. O fato suporte aos seus JavaBeans.
de a maioria dos desenvolvedores estar traba- O uso de um BeanInfo não acrescenta esforço
Ou seja, de acordo com a especificação, um lhando na construção de aplicações focadas em significativo ao desenvolvimento do componen-
JavaBean existe para ser manipulado por um ferramentas como Ant e Maven, em vez de vol- te, pois a maioria dos métodos desta interface
IDE visual. Um JavaBean seria portanto aná- tadas a recursos particulares de IDEs, também podem retornar null (nestes casos, o IDE deve
logo aos componentes fornecidos por IDEs ajuda a se perder o conceito de JavaBeans como recorrer ao uso da introspecção para obter as
RAD (Rapid Application Development) como componentes para IDEs visuais. informações não fornecidas pelo BeanInfo).
Delphi ou VB. Hoje em dia, é comum que vários frameworks, A especificação de JavaBeans define ainda
Para que seja viável a manipulação de como Hibernate, Struts e Spring usem o termo muitos outros recursos que podem ser utilizados
JavaBeans por uma ferramenta, a especificação “JavaBean” para indicar uma classe qualquer (um por JavaBeans, como as bound properties (pro-
define conceitos como propriedades e eventos, POJO) que obedeça a estas convenções. priedades que geram eventos sempre que seus
além de duas maneiras pelas quais um IDE pode valores forem modificados). E APIs complemen-
relacionar propriedades, eventos e métodos BeanInfo tares definem recursos como serialização de Ja-
fornecidos pelo componente: A outra forma de se relacionar atributos, vaBeans em formato XML, ou comportamentos
1. Usando introspecção propriedades e eventos fornecidos por um alternativos de um JavaBean, quando executado
2. Usando um BeanInfo. JavaBean é fornecendo uma classe que imple- dentro de um ambiente de desenvolvimento,
menta a interface java.beans .BeanInf o. Esta classe em vez de numa aplicação final.
Convenções e introspecção deve ser nomeada acrescentando-se o sufixo No final das contas, o uso do termo “JavaBean”
O uso da introspecção em JavaBeans é ba- “BeanInfo” ao nome do JavaBean, e pode estar como sinônimo de “POJO” já pegou e não vai de-
seado na obediência a algumas convenções, tanto no mesmo pacote do JavaBean descrito saparecer tão cedo na comunidade Java. Mas a
como o uso de um construtor sem argumentos por ela quando num pacote em separado, con- verdade é que um JavaBean pode ser muito mais
e de métodos de acesso getXxx()/setXxx()  para figurado pelo IDE. do que uma classe comum, por isso neste artigo
propriedades. Estas convenções básicas se Então o IDE pode oferecer suporte especializa- preferiu-se usar o termo “componente” para se
tornaram bastante populares, ao ponto de se do para um dado componente, fornecendo uma referir a JavaBeans criados para complementar
confundir a obediência a elas como sendo a classe BeanInfo customizada, que pode substituir aplicações visuais em Swing.

20  Java Magazine • Edição 38

 jm38.indb 20 17/7/2006 14:11:04


que cuida de modificar a cor do texto A Listagem 6 apresenta o código que modi-
de um dia que corresponda a um feria- fica o exemplo ExibeCalendario para configurar
do e de acrescentar um tooltip com o o DatePanel  com o renderizador decorado e
nome do feriado. Este decorator é uma o modelo customizado, e acrescentar dois
instância de net.sf.nachocalendar.holidays. feriados: Independência do Brasil e Natal.
HolidayDecorator; A Figura 5  apresenta o resultado da
2.  Utilizar um HoliDayModel (definido no execução deste último exemplo, ilustran-
mesmo pacote do decorator) em lugar do do um dos feriados definidos. Em uma
DayModel padrão. aplicação real, seria interessante obter os
feriados de algum arquivo externo, e tam-
 Note que o NachoCalendar é inconsistente na no-  bém fornecer um novo HoliDayModel  capaz
meação das classes e interfaces do subpacote  holidays , de calcular as datas de feriados flutuantes,
ora usando Holiday  , ora usando HoliDay . como o Carnaval.
 nachocalendar.sf.net 
Site oficial do NachoCalendar.
Conclusões
Demonstramos os cenários de uso eclipse.org/vep
mais freqüentes dos componentes do Página oficial do VE (Visual Editor), plug-in que
NachoCalendar, que podem fornecer às permite programação visual Swing e SWT no IDE
suas aplicações Swing com manipula- Eclipse.
ção de datas aquele “toque profissional”
 java.sun.com/docs/books/tutorial/uiswing
que faltava.
Trilha de construção de interfaces Swing do Java
Vimos ainda algumas boas práticas de
Tutorial da Sun.
projeto e de uso de componentes Swing
customizados, que podem ser resumidos  java.sun.com/products/jfc/tsc/articles/ 
por “imite o design dos componentes architecture
Swing padrões”. Além disso, mostra- Documento da Sun que descreve a arquitetura do
Figura 5. Execução do exemplo ExibeFeriados.java, após a
mos como adicionar componentes adi- Swing e seu uso da arquitetura MVC.
seleção do mês de setembro. (O cursor do mouse, que não cionais aos IDEs livres mais populares,  java.sun.com/developer/onlineTraining/ 
aparece na captura, está sobre o número “7”.) o NetBeans e o Eclipse. Beans
Tutoriais sobre componentes JavaBeans; leitura
Listagem 6.  ExibeFeriados.java – exibe um calendário com diferenciação gráfica para os feriados
obrigatória para construtores e usuários de
componentes de extensão Swing.
//...imports omitidos
 java.sun.com/products/javabeans/ 
public class ExibeFeriados extends JFrame {
private DatePanel datePanel; docs/spec.html 
Especificação JavaBeans.
public ExibeFeriados() throws Exception {
//...configuração do JFrame e do DatePanel omitidas
 netbeans.org
HoliDayModel model = new HoliDayModel(); Site oficial do NetBeans, com recursos
HoliDay feriado;
DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM); sofisticados para programação visual.
feriado = new DefaultHoliDay();
  feriado.setName(“Natal”);  javamagazine.com.br/downloads/jm38/ 
  feriado.setDate(df.parse(“25/12/2006”));  jm-datasdesktop.zip
  feriado.setRecurrent(true);
  model.addHoliDay(feriado);

feriado = new DefaultHoliDay(); Fernando Lozano


  feriado.setName(“Independência”); ([email protected],
  feriado.setDate(df.parse(“07/09/2006”));
  feriado.setRecurrent(true); www.lozano.eti.br ) trabalha há
  model.addHoliDay(feriado); mais de 10 anos com desenvol-
datePanel.setModel(model);
vimento de sistemas de informações
datePanel.setRenderer(new HolidayDecorator(dayRenderer)); e integração de redes, sendo um dos
getContentPane().add(BorderLayout.CENTER, datePanel);
pioneiros do uso do Software Livre no Brasil. Dentro
  pack(); da comunidade, atua como Conselheiro do L PI Brasil,
} Webmaster da FSF e Community Manager do Java.net.
//...método main omitido Atualmente é consultor associado à Neki Technologies
} (www.neki.com.br ).

Edição 38 •  Java Magazine 21

 jm38.indb 21 17/7/2006 14:11:13


Byte Code

Relatórios e Gráficos
Usando o Business Intelligence and Reporting

22  Java Magazine • Edição 38

 jm38.indb 22 17/7/2006 14:11:22


Crie passo a passo relatórios

com Eclipse e gráficos de vários tipos, de


exemplos simples utilizando
wizards a soluções sofisticadas
baseadas em scripts
Tools – BIRT
OSVALDO PINALI DOEDERLEIN

A geração de relatórios é uma neces-


sidade comum a muitas aplicações,
especialmente as que fazem acesso
a bases de dados corporativas. De fato, o vo-
lume de dados acumulados pelas empresas
de relatórios com um tutorial prático, e
examinando os recursos e características
desta ferramenta.

Embora o BIRT e este artigo sejam calcados no


rador de relatórios; utiliza definições
produzidas pelo ERD ou WRD.
• ECE (Eclipse Charting Engine) – Gera-
dor de gráficos; também utiliza definições
produzidas pelo ERD ou WRD.
só faz crescer a cada ano, seja devido à infor- Eclipse, usuários de outros IDEs também podem
matização crescente de atividades, seja por usar o BIRT, graças ao RCP Report Designer (veja Instalando
força de legislações ou práticas comerciais a seção “Instalando”). Existem quatro maneiras de instalar o
que exigem o controle e a armazenagem de BIRT de forma a acompanhar este artigo
cada vez mais informações (ex.: contratos O Projeto BIRT (utilizaremos o BIRT 2.1, que é baseado no
de qualidade de serviço). O projeto BIRT tem o objetivo de cons- Eclipse 3.2):
Isso se traduz numa demanda cada vez truir ferramentas de Business Intelligence 1. Instalação tradicional do Eclipse.
maior por funcionalidades de geração e relatórios, usando o modelo open source Começando com o Eclipse 3.2 (Platform
de relatórios, tarefa que não costuma ser e as tecnologias da Fundação Eclipse. É + JDT, ou SDK), instale os plug-ins EMF
das favoritas de muitos desenvolvedores. interessante destacar algumas conseqüên- 2.2 e GEF 3.2 (também exigidos por vários
Certamente por este motivo, o mercado de cias menos evidentes desta definição: outros plug-ins, como o WTP). Basta então
ferramentas de software há muito tempo • O BIRT não é simplesmente um "plug-in  baixar o pacote birt-report-framework-2.1.zip
oferece produtos de geração (semi-)auto- para o IDE Eclipse". Pode-se utilizá-lo e descompactá-lo sobre sua instalação do
mática de relatórios, desde produtos amar- sem nenhum IDE, inclusive para a edição Eclipse.
rados a SGBDs como o Oracle Reports De- visual de relatórios. 2. Callisto.  Com o Eclipse 3.2 instalado,
veloper, a softwares independentes como • O BIRT se integra à arquitetura de vá em  Help|Soft ware Updates>Find and
Crystal Reports. E mais recentemente, ferramentas do Eclipse, o que significa Install>Search for new features to install, es-
opções open source como o JasperReports que haverá outros plug-ins para Eclipse a colha “Callisto Discovery site” e selecione
e iReport para Java. se beneficiar do BIRT, como já é o caso do um mirror. Dentro da árvore de opções
O BIRT (Business Intelligence and TPTP 4.2 (Eclipse Test and Tools Platform). “Callisto Discovery Site”, abra o ramo
Reporting Tools), projeto da Fundação O quadro “O BIRT, outros geradores de “Charting and Reporting” e selecione
Eclipse, é uma nova opção na categoria relatórios e open source” discute o status a opção “Eclipse BIRT Report Designer
“independente, open source e para Java”. do BIRT como projeto do Eclipse.org, e o Framework 2.1.x”. Depois clique no botão
Mas não é apenas mais um gerador de compara com outros projetos competido- Select Required para selecionar as depen-
relatórios. O BIRT promete revolucionar o res no mundo open source. dências necessárias para a operação do
cenário dos relatórios para Java, especial- BIRT, e clique em Next. Aceite a licença
mente devido à sua forte integração com o Componentes do BIRT  para os componentes a serem instalados;
IDE Eclipse, o que traz vantagens de pro- Como toda ferramenta de business clique em Next e depois em Finish.
dutividade claramente além do possível intelligence, o BIRT traz sua própria sopa 3. Opção “all-in-one”. Na página
para outros competidores (mesmo os que de letrinhas, com muitos novos acrôni- de download do BIRT, baixe o pacote
possuem plug-ins para IDEs). mos para aprendermos. Os componen- birt-report-designer-all-in-one-2_1.zip, que
Apesar de relativamente novo, o BIRT tes de runtime e design do BIRT são os vem com tudo que você precisa, incluindo
tem evoluído a passos largos e já é uma seguintes: o próprio Eclipse (SDK), o EMF, o GEF e
tecnologia madura. Já encontramos o BIRT • ERD (Eclipse Report Designer) – Edi- o BIRT.
na sua versão 2.1, que acompanha o release tor visual de definições de relatórios. 4. RCP Report Designer. É a opção para
do Eclipse 3.2 e faz parte do Callisto 1.0 • WRD (Web Based Report Designer) quem quer usar o BIRT sem o Eclipse;
(distribuição integrada dos principais – Equivalente ao ERD, mas com interface
projetos do Eclipse.org). web (este componente ainda não está 1
 A versão embutida da base Classic Models usa o Apa-
Neste artigo, veremos como utilizar disponível). che Derby. Veja mais sobre es se SGBD em “Demonstrando
o BIRT, guiando o leitor na construção • ERE (Eclipse Report Engine) – Ge- o Apache D erby”, na Edição 29.

Edição 38 •  Java Magazine 23

 jm38.indb 23 17/7/2006 14:11:28


Byte Code • Relatórios e Gráficos com Eclipse

ideal para usuários de outros IDEs. Baixe  pulação de dados para o Derby e para o MySQL 2 , e fizer isso, ainda poderá digitar as legendas
o arquivo birt-rcp-report-designer-2_1_0.zip um arquivo .mdb para o Microsoft Access. Uma vez nos cabeçalhos dos relatórios, mas este
(ou mais recente), que contém um editor criadas as tabelas, crie a data source com a opção trabalho teria que ser feito repetida mente
visual de relatórios auto-contido. “JDBC Data Source”. O diálogo de criação de data para cada novo relatório que utilize o
sources possu i um bot ão “Manage Drivers”, que Data Set.
O projeto  permite cadastrar odriver JDBC para seu SGBD pre-
Feita a instalação, execute o comando ferido (o driver para o Derby em modo embutido já O relatório
File|New>Project, e você verá que foi cria- vem registrado.) Tendo o driver configurado, basta Como o layout básico do relatório está
do um novo grupo de projetos para BIRT. entrar com os dados de URL, login e senha. pronto (usamos um template que já inclui
Escolha a opção Report Project e forneça um um grid de quatro colunas), só falta asso-
nome para o projeto. Isso cria um projeto Na mesma view, em Data Sets, precisamos ciar nosso Data Set ao layout. Observe que
“puro” de relatório, o que num primeiro criar agora um “conjunto de dados” (Data cada coluna do Grid (na aba Layout) possui
momento simplificará o acompanhamento Set), que corresponde a um resultset ou as linhas ( rows) Header (cabeçalho), Detail
desse tutorial. Depois veremos como com- cursor. Crie o Data Set com o nome “car- (dados) e Footer (rodapé). Selecione, no
 binar o relatório a um projeto Java. ros” e tipo “SQL Select Query”. Será apre- Data Set, a coluna de resultado Fabricante,
Após a criação do projeto, o BIRT apre- sentado o diálogo de construção visual de e arraste-a até a linha Detail na primeira
senta a perspectiva Report Design, tam- consultas do BIRT ( Figura 1). coluna (aparece um diálogo Select Data
 bém conhecida como ERD (Eclipse Re- A database Classic Models modela uma Binding; você pode aceitar as opções de-
port Designer). No novo projeto, use loja de automóveis. Vamos criar um rela- fault e fechá-lo). Faça o mesmo para as
New>Report  para criar um relatório. For- tório simples, mostrando nome, fabricante, outras três colunas de resultado.
neça o nome carros.rptdesign e na opção de descrição e preço de todos os automóveis Um último retoque é alterar o formato dos
templates escolha Simple Listing. cadastrados, ordenados por fabricante e cabeçalhos, para que estes se diferenciem
Depois de finalizar o wizard, você verá depois por nome. Os nomes da tabela e das dos dados. Selecione com Shift+clique
o ERD lotado de ferramentas atraentes colunas podem ser copiados para a con- cada célula de cabeçalho, e no Property
– editor visual de relatórios, paleta de sulta com um duplo clique (ou arrastando Editor mude o Background Color. Mas, como
elementos, editor de propriedades etc. para a janela que contém o código SQL); queremos usar o mesmo estilo para todas
Mas um relatório, antes de tudo, precisa pode-se também digitar os comandos SQL as células do cabeçalho, há uma forma
de dados de entrada, portanto o próximo diretamente. Assegure que a consulta seja mais fácil: passe o cursor do mouse sobre
passo será disponibilizar esses dados. algo como: o Grid para mostrar o manipulador Table
(sob o canto inferior esquerdo do Grid);
Os dados select PRODUCTNAME, PRODUCTVENDOR, clique nele, revelando os manipuladores
PRODUCTDESCRIPTION, BUYPRICE
Entre na view Data Explorer, clique com from PRODUCTS de linhas e colunas; depois clique no da
o botão direito sobre o nó Data Sources e order by PRODUCTVENDOR, PRODUCTNAME primeira linha (a do cabeçalho). Use en-
selecione New Data Source. Depois escolha tão o Property Editor, customizando a cor
Classic Models Inc. Sample Database. Dê um Após a criação inicial do Data Set, o diá- de toda a linha selecionada. O resultado
nome à data source, ex.: “carrosDS”. Este logo Edit Data Set permite customizar deta- deverá ser parecido com a Figura 2.
 banco de dados de teste é embutido no lhes como parâmetros, colunas calculadas, Para testar o relatório, clique na aba
BIRT1; por isso não é exigida nenhuma cache e filtros, e também se ter um pre- Preview. Você verá o relatório funcionan-
outra configuração. view dos dados
selecionados, de
Num projeto real, você usaria um banco de forma a verificar
dados externo. Se quiser já praticar este cenário que a query está
mais realista, baixe o pacote birt-database-2.1.zip , correta.
que contém os scripts para criação e população Uma última
do mesmo banco de dados “Classic Models”. Este etapa essencial é
 pacote contém scripts de criação de tabelas e po- ir na aba Output
Columns   (ainda
no diálogo Edit
2
 Para outros SGBDs, é fácil criar as tabelas a partir dos Data Set) e pre-
scripts create_classicmodels.sql  de uma destas versões. Já encher, para cada
a população de dados iniciais está disponível em vários
arquivos-texto (formato CSV), que podem ser importados
coluna do resul-
com facilidade em muitos SGBDs, por exemplo com o tado, o seu Dis-
Oracle SQL*Loader.  pl ay Na me   (ex.:
3
 Para quem já usou o JasperReports, o arquivo .rptde-
BUYPRICE   = “Pre-
sign é o equivalente aos arquivos .jrxml , exceto que não
existe uma etapa de pré-compilação para .class. ço”). Se você não Figura 1. Definindo um data set a partir de uma query SQL.

24  Java Magazine • Edição 38

 jm38.indb 24 17/7/2006 14:11:29


do, como na Figura 3. Este preview é uma
 janela embutida do navegador web default
do Eclipse: assim, o que estamos vendo é
um relatório HTML. Note que a primeira
visualização do preview pode demorar
alguns segundos para aparecer, pois o
ERE (Eclipse Report Engine) precisa a ntes
ser carregado.
A primeira versão do nosso relatório está
pronta. Dito isto, o que foi que construí-
mos? O projeto possui apenas o arquivo
carros.rptdesign, que é um documento
XML (editável diretamente na aba XML Figura 2. Layout já associado às colunas de resultado do data set.
Source). Este documento descreve todos
os aspectos do relatório: layout, fontes
de dados, associações entre os dados e o
layout, formatação e outros itens ainda não
vistos. O documento pode ser utilizado
como entrada para o Report Engine, que
gera relatórios em aplicações web (HTML),
desktop (Swing, SWT), e outros formatos
como PDF3.
O arquivo .rptdesign isolado só funciona
porque a aba Preview do Report Designer
invoca o Report Engine. Uma aplicação
real precisaria de um pouco de código para Figura 3. Primeiro relatório no BIRT.
invocar o engine, e apresentar o resultado
ao usuário. Mas antes de fazer isso, vamos Na segunda aba, Select Data, você deverá  botão Text Format; no diálogo que se abre,
dar mais um passo fácil. associar colunas do Data Set às séries de selecione Label / Font > ‘...’ (outro botão, que
dados que formam o gráfico. Comece mar- abre o diálogo Edit Font); finalmente, neste
No download deste artigo, o arquivo correspon- cando a opção Select Data Set / Use Data Set, novo diálogo, altere o valor Rotation para
dente a esta etapa é o carros1.rptdesign. escolhendo o Data Set “carrosDS” no com- 90º. Isto fará as legendas do eixo X serem
 bobox. A tabela Preview exibirá os dados exibidas no sentido vertical, o que será
Gráficos obtidos do Data Set. Selecione com o botão importante para acomodar um número
Diz-se que uma imagem vale por mil direito o cabeçalho da coluna Fabricante, e grande de itens.
palavras, mas no caso de relatórios, “por no menu que aparecerá ative a opção Use De volta ao designer, ajuste o tamanho e
mil números” seria mais apropriado. as Category (X) Axis. Em seguida faça o a posição do gráfico no relatório, e então
Gráficos de relatórios (ou charts) permitem mesmo para a coluna Preço, com a opção acione novamente a aba Preview. Você
visualizar massas de dados grandes ou Plot as Value (Y) Series. Veja o final desta verá algo... feio, com rótulos numéricos
complexas, de forma rápida e intuitiva. etapa na Figura 4. embaralhados (dígitos demais) e uma
Com o BIRT, também podemos criar estes Na última aba, Format Chart, você pode legenda vazia. Se não queremos perder
gráficos sem nenhuma programação. escolher muitas opções de formatação do nossos clientes, temos que embelezar um
Na view Palette, selecione o componente Data Set e de elementos como eixos, legen- pouco mais.
Chart e clique no relatório, no espaço vazio das, fundo etc. Vamos fazer somente as Para as legendas, de volta ao Edit Chart
logo abaixo ou acima do Grid (coloquei configurações essenciais para este gráfico.  / Format Chart / Series, preencha o campo
acima). Um diálogo New Chart permitirá Em Series / Category (X) Series > Grouping,
customizar uma série de opções, das quais marque Enabled, e selecione Interval = 0.
exploraremos uma seleção. Isto fará o gráfico ter uma única coluna 4
 O Mozilla Firefox possui suporte nativo a SVG, mas o
Na primeira aba, Select Chart Type, a op- para cada fabricante (ao invés de várias, MSIE exige um plug-in da Adobe.
5
 Em estatística, percentil é uma medida de posição de
ção mais importante é Output Format. São uma por registro do mesmo fabricante). um valor relativamente aos demais valores do conjunto.
suportados gráficos bitmap (JPG, PNG e Mude também a opção  Aggregate Expres - Por exemplo, se um modelo X tem preço 72, e 90% dos
BMP) ou vetoriais (SVG). O SVG é teorica- sion para Average. modelos têm preço na faixa 0-72, então o percentil do
preço de X é 90, ou seja, está na faixa de preço de 90%
mente a opção ideal, mas o suporte a esse Em Chart Area / Chart Title, forneça o dos modelos. Há nomes para percentis comuns, como
formato ainda está longe de ser universal 4). título “Preços Médios por Fabricante”. “primeiro quartil” ou Q1 (= percentil 25), e “Mediana” (=
Por segurança, escolha JPG ou PNG. Em Chart Area / Axis / X-Axis, clique no percentil 50).

Edição 38 •  Java Magazine 25

 jm38.indb 25 17/7/2006 14:11:31


Byte Code • Relatórios e Gráficos com Eclipse

claro, ainda poderíamos retocar legendas,


proporções, cores, fontes, e outros aspectos
visuais buscando tornar o gráfico (e o rela-
tório) mais compreensível ou bonito.
Até este ponto, não escrevemos uma só
linha de código Java. O BIRT faz o serviço
de forma totalmente visual e interativa,
sendo que as configurações que mostra-
mos (e outras que ainda teremos espaço
para apresentar neste artigo) são uma
fração do total disponível. O custo disso,
como o leitor certamente terá verificado a
essa altura, é que o designer de relatórios
do BIRT é bastante pesado. Mas se você
observar um OutOfMemoryError, não significa
que o BIRT seja assim tão exigente – veja
o quadro “Configurando a memória para
o BIRT”.

No download deste artigo, o arquivo correspon-


dente a esta etapa é o carros2.rptdesign.

Uma aplicação real


e completa (ou quase)
Antes de entrarmos em mais detalhes
sobre funcionalidades do BIRT, vejamos
como podemos usá-lo para criar aplicações
 Java reais. Nosso exemplo será uma aplica-
ção desktop (Swing) que invoca o Report
Figura 4. Configurando um gráfico do relatório. Engine e exibe o relatório produzido numa
caixa de diálogo; mas como veremos,
mesmo nome permi- o BIRT também pode ser utilizado por
tindo customizar as aplicações web.
legendas do eixo Y,
conforme a Figura 5. Instalando o Report Engine
Você verá uma lista Uma vez finalizada sua aplicação, ela
Values, já populada precisará do runtime do BIRT – o ERE,
com um item: “Value para relatórios completos, ou o ECE
Data” (pode haver (Eclipse Chart Engine), somente para
várias legendas para gráficos. O download destes runtimes,
cada item: o valor nu- birt-runtime-2.1.zip, possui assustadores
mérico, sua categoria, 86 Mb, mas inclui várias versões do ERE
nome, ou percentil 5). e ECE. O ECE isolado tem 3,7 Mb, na pasta
Clique no item Value /ChartEngine, e é a única opção de runtime
Data e então acione o que pode ser utilizada facilmente de ma-
pequeno botão 0.0#, neira semelhante à maioria das bibliotecas
Figura 5. Customizando as legendas do eixo Y.
que traz outro diálogo  Java; ou seja, basta colocar todos os seus
(ufa!) para editar a formatação desta legen-  JARs no classpath da sua aplicação.
Category (X) Series com “Fabricante”, e da. Basta selecionar Data Type = Number (o O ERE completo (incluindo o ECE) tem
Value (Y) Series com “Preço”. default), Standard, Fraction Digits = 2. Pron- 28 Mb, sendo fornecidas duas versões. A
Agora vamos ajustar a exibição dos to, agora nosso gráfico está razoavelmente primeira fica na pasta /ReportEngine. A
rótulos numéricos dos valores, que apa- apresentável, devendo se parecer com o estrutura de diretórios e arquivos do ERE é
recerão no tipo de cada barra. Isso está mostrado na Figura 6. semelhante à do Eclipse, com subdiretórios
mais escondido. Em Series / Value (Y) Series, Nossa segunda versão do relatório, des- como plugins, configuration, e até workspace.
clique em Labels, que abre um diálogo de sa vez com um gráfico, está completa. É Você pode remover o subdiretório samples,

26  Java Magazine • Edição 38

 jm38.indb 26 17/7/2006 14:11:32


mas não mais que isso (pelo menos, não sem Criando o projeto Java que tendem a ser iguais para todos os relatórios
ser um expert no BIRT). Não dá para apenas Crie um novo projeto Java vazio, e copie  produzidos por uma mesma aplicação.
“pescar” os JARs e colocá-los no classpath para seu source folder raiz o arquivo carros.
da sua aplicação, pois o ERE utiliza a infra- rptdesign que construímos na seção an- Utilizando parâmetros
estrutura de plug-ins da plataforma Eclipse, terior. Em seguida, crie a classe TesteBIRT, Nesta etapa, vamos modificar o re latório
e exige que a sua estrutura de diretórios e conforme a Listagem 1. Esta classe utiliza para utilizar parâmetros: além do Data Set,
arquivos seja mantida intacta. a API do Report Engine, que não é trivial, quase todos os relatórios reais precisam de
A segunda distribuição do ERE é o mas também não é algo assustador. argumentos que determinam opções como
birt.war, para implantação em servidores Observe que o exemplo gera um relatório filtros de dados.
 Java EE. Basta instalá-lo no seu servidor de em formato HTML; o Report Engine não Vamos criar um filtro para gerar relató-
forma normal. Também há uma aplicação possui uma opção para geração em forma- rios que consideram apenas produtos de
web, /WebViewerExample, que ilustra o uso to de imagem ( java.awt.Image , GIF ou seme- determinado tipo, como carros ou motos.
do ERE embutido numa aplicação web Java lhante). Somente os gráficos produzidos Na database, isso exige um filtro como
EE, como alternativa à birt.war. (Veremos pelo Chart Engine geram imagens. Assim, WHERE productLine = ‘Classic Cars’   para filtrar
como usar esta opção de deployment mais precisamos de um componente  JEditorPane apenas os carros; porém, o argumento do
adiante.) do Swing para exibir o relatório. Outra op- WHERE  deve ser um parâmetro dinâmico.
O tamanho dos runtimes do BIRT não é ção seria usar um PDFRenderContext, que gera Na view Data Explorer, em   Report
problema para implantação em servidores, o relatório em formato PDF, o que poderia Parameters, acione New Parameter e preen-
mas pode tornar inviável embuti-lo em ser exibido numa aplicação Java através cha os valores: Name = “productLine”, Data
aplicações desktop com download pela da biblioteca iText6, ou então apresentado type = “String” e Default value = “Classic
internet. lançando o visualizador de PDF instalado Cars”. Isso cria um parâmetro de entrada
Para nosso tutorial, inicialmente você no sistema (como o Acrobat). do relatório, cujo valor deve ser setado pela
precisará somente do ERE no subdiretório aplicação antes de invocar o relatório.
 /ReportEngine. O código da Listagem 1 funciona e ilustra o Agora, abra novamente o Edit Data Set.
assunto discutido, mas não é igual ao que você
Instalando a documentação faria (ou deveria fazer) numa aplicação real. O
A documentação do BIRT é impres- ideal seria encapsular partes repetitivas deste 6
  O runtime do iText pode ser baixado pelo site de
cindível para se utilizar sua API, mas código em métodos ut ilitários. Por exemplo, você update do Callisto. Mas e ste componente, assim como um
não está disponível num download  poderia ter um ServiceLocator com um métodoque arquivo prototype.js para funcionalidade AJAX, não são in-
cluídos nos runtimes do BIRT, talvez devido a restrições
isolado. Para obtê-la, primeiro baixe o inicializa o ReportEngine , e também métodos que de licença. Devem ser baixados à parte; veja instruções na
birt-report-framework-sdk-2.1.zip. Este pacote abrem o design e definem opções de renderização página de download do BIRT.
contém o mesmo framework que orien-
tamos a instalar no Eclipse, mas inclui
também a documentação, o código-fonte
e exemplos. A documentação estará nos
seguintes arquivos:
• plugins/org.eclipse.birt.doc_versão /doc.zip
• plugins/org.eclipse.birt.doc.isv_versão /doc.zip
• plugins/org.eclipse.birt.chart.doc.isv_versão / 
doc.zip

Ao extrair estes ZIPs, você poderá explo-


rar a abundante API pública dos engines
de relatórios, charts, de scripting e de ex-
tensão de IDE do BIRT. Observe, contudo,
que todas estas APIs estão documentadas
como provisórias, significando que po-
dem sofrer alterações incompatíveis em
releases futuros (ainda que, na prática,
isto seja raro).
Mas antes de enveredar por estes Java-
Docs, comece pela página eclipse.org/birt/ 
 phoenix/deploy/reportEngineAPI.php, que in-
clui diagramas que explicam a arquitetura
geral do runtime e das APIs do BIRT. Figura 6. Relatório com um gráfico (inserido acima do grid).

Edição 38 •  Java Magazine 27

 jm38.indb 27 17/7/2006 14:11:33


Byte Code • Relatórios e Gráficos com Eclipse

o relatório novamente, veremos que o


Listagem 1. Código Java para uma aplicação desktop mínima com o BIRT.
gráfico e o grid só exibem os modelos de
import java.io.File; automóveis. Não passamos nenhum valor
import java.io.IOException;
import java.util.HashMap; para o parâmetro productLine do relatório,
import javax.swing.JEditorPane; portanto foi usado o valor default “Classic
import javax.swing.JFrame;
import org.eclipse.birt.report.engine.api.*; Cars”. Na aba Preview, clique em Show Re-
 port Parameters para experimentar outros
public class TesteBIRT {
public static void main (String[] args) throws EngineException, IOException { valores, como “Planes”.
// Cria o engine (para simplificar, usamos path fixo do ERE) De volta à nossa aplicação, o cenário mais
EngineConfig config = new EngineConfig();
  config.setEngineHome(“D:/Java/BIRTRuntime/ReportEngine”); comum seria termos uma tela de seleção
ReportEngine engine = new ReportEngine(config); de parâmetros, por exemplo com um com-
// Carrega o arquivo de design  bobox “Tipo” preenchido dinamicamente
IReportRunnable design = engine.openReportDesign(“carros3.rptdesign”); com todos os valores distintos da coluna
// Cria tarefa de renderização, configurada para para HTML PRODUCTLINE. Por limites de espaço, não po-
IRunAndRenderTask task = engine.createRunAndRenderTask(design);
HTMLRenderContext renderCtx = new HTMLRenderContext();
demos construir uma aplicação realmente
  renderCtx.setImageDirectory(“image”); completa, com uma estrutura de nave-
HashMap ctxMap = new HashMap();
ctxMap.put(EngineConstants.APPCONTEXT_HTML_RENDER_CONTEXT, renderCtx); gação, menus e telas de parâmetros para
  task.setAppContext(ctxMap); relatórios. Mas veremos o essencial: como
HTMLRenderOption options = new HTMLRenderOption();
definir um valor para um parâmetro inte-
// Gera a saída num arquivo temporário rativamente. Basta alterar a classe TesteBIRT
File output = new File(System.getProperty(“java.io.tmpdir”), “birt.html”);
  options.setOutputFileName(output.getAbsolutePath()); para incluir o código em destaque:
  options.setOutputFormat(“html”);
  task.setRenderOption(options); ...
  task.run(); options.setOutputFormat(“html”);
  engine.destroy(); task.setParameterValue(“productLine”,
 JOption Pane.sh owInputD ialog ( null,
// Cria um componente Swing para exibir o HTML
JEditorPane htmlPane = new JEditorPane(“file:///” + output.getAbsolutePath()); “Tipo”, “Escolh a o tipo”,
  htmlPane.setEditable(false);  JOption Pane.OK_OPTION,
JFrame frame = new JFrame(); null, null, null));
  frame.add(htmlPane); task.setRenderOption(options);
frame.setBounds(0, 0, 640, 480); ...
  frame.setVisible(true);

// Exibe o consumo de memória do heap O novo código simula uma mini-tela de


  System.gc(); entrada de parâmetros, com uma caixa de
Runtime rt = Runtime.getRuntime();
System.out.println(rt.totalMemory() - rt.freeMemory()); diálogo que permite digitar o valor para o
} parâmetro. Executando a aplicação nova-
}
mente, digite o valor “Planes” para ver um
relatório dos modelos de aviões.
Agora, sim, temos um relatório seme-
Na aba Query, adicione à query a cláusula de relatório e de Data Set – são necessários lhante ao mínimo que se esperaria de uma
“WHERE productLine = ? ”. O ‘? ’ é o familiar in- porque um relatório pode ter vários Data aplicação real, com os dados de entrada
dicador de parâmetro da API JDBC. Na aba Sets; os parâmetros do relatório podem ser variando de acordo com alguma seleção
Parameters, crie um parâmetro com Name = usados em outros lugares além dos Data do usuário ou outra fonte.
“productLine”, Data type = “String” e Direc- Sets; e os parâmetros dos Data Sets podem
tion = “Input”. Queremos que o valor deste receber valores de outras origens além de  No download deste artigo, o arquivo correspon-
parâmetro da query seja preenchido com o parâmetros do relatório. Porém, o caso dente a esta etapa é o carros3.rptdesign.
valor passado para o parâmetro productLine mais simples e comum é o de relatórios
do relatório. São parâmetros diferentes, com um único Data Set e uma correspon- Uso em aplicações web
apesar do nome igual. Para associar um dência um-para-um entre os parâmetros. Ainda que o BIRT dê suporte a aplica-
ao outro, clique em Default Value (no botão Para alimentar o parâmetro do data ções desktop, seu maior brilho sem
“...”), o que abre o diálogo Expression Builder, set com o do relatório, clique em Report dúvida é no suporte a relatórios web.
mostrado na Figura 7. Parameters ; depois na categoria ---All---, Para integrar o Report Engine numa
O BIRT utiliza um sistema de “parâme- e finalmente no parâmetro {}productLine. aplicação web, você tem duas opções:
tros em cascata”, no qual os parâmetros Agora basta confirmar. O resultado é a instalar no container o birt.war, ou
de um Data Set podem ser associados a expressão params[“productLine”]   (que você integrar ao WAR da sua aplicação
valores disponíveis ou calculados num es- também poderia digitar à mão – o que será os arquivos do Report Engine.
copo mais externo, como os parâmetros do geralmente mais rápido após se familiari- A segunda opção é bem mais
relatório. Os dois conceitos – parâmetros zar com o BIRT). Pronto. Se executarmos complexa, mas pode-se come-

28  Java Magazine • Edição 38

 jm38.indb 28 17/7/2006 14:11:39


çar mais facilmente copiando o conteúdo Para mais detalhes sobre o uso do viewer, Set uma coluna calculada. Ou seja, uma
do WebViewerExample  (prática familiar à consulte: eclipse.org/birt/phoenix/deploy/  coluna cujo valor não é uma cópia direta
cópia do struts-blank por desenvolvedores viewerUsage.php. de uma coluna retornada pela query, mas
que usam o framework Struts). O uso do sim o resultado de uma expressão arbi-
birt.war é bem mais simples e permite o Scripting trária (possivelmente envolvendo dados
compartilhamento do engine por diversas Como vimos, podemos ir longe no BIRT só retornados pela query). Vamos demonstrar
aplicações. Por outro lado, aplicações mais com cliques do mouse. No outro extremo, é isso com uma coluna Avaliacao, cujo valor
sofisticadas, especialmente aquelas com possível utilizar suas APIs Java para custo- será “caro” ou “barato”, conforme o preço
relatórios contendo scripts complexos que mizar a construção e a geração de relatórios do modelo.
acessam classes Java da aplicação, irão pre- ou gráficos de uma forma mais dinâmica do No diálogo Edit Data Set, abra a aba Com-
ferir a implantação integrada, que facilita que seria possível somente com documentos  puted Columns. Na primeira linha em bran-
o acesso a estas classes. .rptdesign estáticos. Mas a virtude, já diziam co, digite Column name = “Avaliacao” e Data
Vimos que a API do BIRT pode ser con- os antigos, pode estar no meio, ou seja, entre Type = “string”. Na célula Expression, clique
figurada para gerar relatórios em formato quaisquer opções extremas. o botão “...” para abrir o diálogo Expression
HTML, bastando então determinar o nome O BIRT possui um abrangente suporte a Builder. Então, clique em Avaliable Data Sets
do arquivo e seu subdiretório de imagens, scripting, permitindo que muitos recursos  / carros / Preço  para selecionar a coluna
gerar o arquivo, e devolver ao cliente a avançados sejam implementados com de preço. Um duplo-clique irá inserir a
URL do arquivo gerado. Isso é possível, pequenos trechos de código embutido expressão row[“Preço”]  na área de edição
mas tem desvantagens sérias, como nos documentos .rptdesign. É suportada da expressão.
gerenciar estes arquivos: deve-se evitar  JavaScript, linguagem que será familiar O Expression Builder permite criar ex-
conflitos com outros arquivos de relatórios para muitos desenvolvedores de interfaces pressões complexas sem usar o teclado
produzidos por usuários concorrentes, e gráficas baseadas na web. Para mais – há botões para cada operador e listas de
os arquivos devem ser deletados após a detalhes sobre o suporte a scripting do seleção para as colunas (como a que usa-
visualização. Assim, em geral, esta opção BIRT, veja o quadro “Scripting no BIRT e mos), parâmetros, funções do JavaScript e
de geração de relatório em arquivo só é boa no Eclipse”. do BIRT, e também para operadores. Mas
para tarefas de geração em batch, ou para Com a aplicabilidade dos scripts é muito como somos programadores de verdade,
aplicações que já possuam mecanismos de ampla, vamos ilustrá-la com uma seleção vamos terminar de digitar esta expressão
produção e gerenciamento dinâmico de de exemplos. à mão:
conteúdo (como ferramentas CMS). Para
row[“Preço”] >= 50 ? “caro” : “barato”
a maioria das aplicações, recomenda-se Colunas calculadas
usar o servlet do Report Engine. Se você Nossa primeira tarefa é gerar no Data Esta expressão (que é um mini script
examinar a janela do Preview, descobrirá
que o relatório é gerado invocando-se uma
URL como:
http://127.0.0.1:52939/viewer/run?__report=E%3A%5
COsvaldo%5Ctestws%5CBIRTJava%5Ccarros4.rptdesign&
__format=html&__svg=false&__designer=true&_
_masterpage=true& __rtl=false&__maxrows=&1486415089

Aqui viewer  é o contexto de instalação


do Report Engine e run é o nome do ser-
vlet de geração de relatórios; o parâmetro
report contém o path completo do arquivo
de design do relatório, e os demais
parâmetros são as opções para o
relatório. Parâmetros iniciando por
dois sublinhados, como __svg, são
opções do viewer. Já os parâmetros
do relatório podem ser passados
de forma normal, por exemplo
“productLine=Planes”. Tudo que a
aplicação precisa fazer, após per-
mitir ao usuário selecionar valores
para os parâmetros de um relatório, é mon-
tar a URL exigida pelo viewer. Figura 7. Parâmetros em cascata no Expression Builder.

Edição 38 •  Java Magazine 29

 jm38.indb 29 17/7/2006 14:11:42


Byte Code • Relatórios e Gráficos com Eclipse

 JavaScript) será executada, para cada linha mos para colunas “reais”. De que outra é associada à expressão dataSetRow[“Preço”].
do Data Set, produzindo a coluna “Avalia- maneira poderíamos ter obtido o mesmo Clicando nesta ex pressão, veremos nova-
cao”. Se clicarmos na aba Preview Results, efeito? Se você voltar ao design do Grid (o mente (sem muita surpresa) o Expression
veremos a nova coluna preenchida com componente de relatório tabular) e der u m Builder.
valores, como na Figura 8. duplo-clique na célula de detalhe da colu- Agora, se você selecionar o gráfico e
Poderíamos, então, utilizar esta coluna na Preço, verá o diálogo Select Data Binding. acionar Select Data, examinando com no-
no relatório, da mesma forma como fize- Observe que, neste diálogo, a coluna Preço vos olhos esta aba do diálogo Edit Chart
(Figura 4), verá que existem scripts por
todo lado. Por exemplo, o campo Category
Scripting no BIRT e no Eclipse (X) Series tem o valor row[“Fabricante”] – um
script. O mesmo vale para as opções de
A versão atual do BIRT suporta JavaScript
(ECMAScript). Versões futuras deverão
suportar outras linguagens de scripting para
ambiente; ou seja, a plataforma Eclipse, os
plug-ins instalados e os recursos gerenciados
por estes plug-ins.
valor Y, agrupamento e colunas de dados
para o eixo X. Embora a prática mais co-
mum seja derivar todos estes dados de co-
a JVM (como Groovy, Jython etc.), possivel- O BIRT já faz isso para o ROM (Report
lunas do Data Set, pode-se, no lugar disso,
mente através da JSR-223. Object Model, isto é, a representação em
escrever código JavaScript arbitrário.
Há anos a comunidade Eclipse vem dis- memória do documento .rptdesign ), o que
Poderíamos ter criado no Grid a expres-
cutindo a implementação de facilidades permite ao script utilizar sintaxes especiais
são que transforma um preço na string
de scripting para o Eclipse como um todo, como row[nome] e params[nome ] para acessar
“caro” / “barato”. Mas se definirmos esta
para automatizar qualquer operação do IDE elementos do ROM. E vai mais além: é pos-
expressão no próprio Data Set, o valor
e de todos os seus plug-ins. A falta dessas sível escrever scripts com expressões como
resultante pode ser reusado em vários
facilidades é uma das principais lacunas do sum(row.BUYPRICE) , onde sum é uma função
lugares; por exemplo, podemos querer
Eclipse, para usuários avançados que gostam agregada semelhante à do SQL. Ela retorna
exibir esta informação tanto no Grid
de automatizar seu trabalho com scripts. Essa a soma dos valores da coluna BUYPRICE  para
quanto no gráfico. Calculá-la uma vez só,
deficiência já vem sendo investigada por todas as linhas (rows) do Data Set. Esta
no Data Set, economiza tanto o esforço
projetos na incubadora da Fundação Eclipse sintaxe não é suportada por JavaScript, mas
de edição do relatório, quanto tempo de
(como o EclipseMonkey), além de projetos como linguagens de scripting são por natu-
processamento.
externos (como o EclipseShell). Sem falar reza fáceis de manipular, o BIRT pode criar
Uma terceira alternativa para gerar va-
em ferramentas que incluem suporte ad-hoc extensões desse tipo com facilidade 8.
lores calculados seria fazer o cálculo na
para scripting, como o próprio BIRT. O BIRT também permite invocar classes
própria query do Data Set; por exemplo:
A Fundação parece ter demorado para levar Java a partir do relatório. Não abordamos
o assunto a sério, devido à grande ênfase essa funcionalidade neste artigo, mas é uma SELECT PRODUCTNAME, PRODUCTVENDOR,
do Eclipse no desenvolvimento de plug-ins. opção bem mais complexa. O código Java PRODUCTDESCRIPTION, BUYPRICE,
Mas mesmo uma ferramenta poderosa como não tem os benefícios do Report Object ( CASE WHEN BUYPRICE >= 50 THEN ‘caro’
ELSE ‘barato’ END) AS AVALIACAO
o PDE não supera a facilidade de escrever Model ou de extensões de sintaxe, sendo FROM PRODUCTS
scripts, que permitem inclusive cenários de obrigado a utilizar APIs do BIRT, ex.: task. ORDER BY PRODUCTVENDOR, PRODUCTNAME
“programação zero” (macros gerados pela getParameterValue(“productLine”) . Estas APIs prio-
Este tipo de programação é comum
captura de ações do usuário no IDE). Mas rizam flexibilidade e desempenho sobre a fa-
quando são usados geradores de relatórios
agora os scripts estão na moda, ganhando su- cilidade de uso, e na versão 2.1 ainda não são
sem capacidade de scripting. Porém apre-
porte até da plataf orma Java SE (ver JSR-223, APIs estáveis (com garantia contra mudanças
senta alguns problemas. A sintaxe “CASE”
 já incluída no Mustang, e a JSR-292). O Eclipse incompatíveis em releases futuros).
usada no exemplo é uma extensão SQL de
precisa de um suporte robusto e unificado a Em geral, você só utilizar á Java no lugar de
um SGBD específico, e mesmo essa sintaxe
scripting, compartilhado por todas as ferra- JavaScript se tiver necessidades especia is de
não permitiria implementar cálculos mais
mentas que possam se beneficiar de scripts, integração, como reusar métodos de al guma
complexos (por exemplo, qualquer cálculo
e suportando várias linguagens. O assunto biblioteca Java. Ou de desempenho, como
exigindo um loop). A solução poderia ser o
foi discutido num painel da EclipseCon 2006, calcular um Data Set muito complexo (o
uso de procedimentos armazenados (que
e provavelmente será materializado numa que pode ser feito em JavaScript, mas com
o BIRT também pode invocar para gerar
solução definitiva no Eclipse 3.3. menos desempenho, por ser uma linguagem
um Data Set), mas esta prática também
O suporte a scripting não requer somente interpretada).
tem seus inconvenientes, como baixa por-
fazer a interface entre Java e o runtime de
tabilidade. Além disso, transferir colunas
alguma linguagem de scripting – problema
que a JSR-223 já padroniza e resolve. Boa 8
 Ou seja, os scripts do BIRT não são realmente Ja-
parte do esforço é a definição de um Object vaScript puro, e sim uma extensão. Mas o BIRT faz um
pré-processamento que trata estas extensões e gera
7
 Este artigo de Joel Spolsky diz tudo sobre a questão
Model (OM) que represente, de uma forma código JavaScript comum, compatíveis com runtimes “aparência versus funcionalidade”:
simples, os dados e funcionalidades do de JavaScript padrão, como o Mozilla Rhino.  joelonsoftware.com/articles/fog0000000356.html 

30  Java Magazine • Edição 38

 jm38.indb 30 17/7/2006 14:11:44


calculadas no SGBD consome banda de
rede desnecessariamente. É muito mais
eficiente fazer uma query que retorna so-
mente os dados brutos, e gerar os valores
calculados localmente.

Customizações de layout 
Vamos a uma outra necessidade im-
portante de relatórios “caprichados”:
modificar dinamicamente a apresentação
dos dados, para destacar informações
importantes. Nunca esqueça que você é
pago (principalmente) para fazer suas
aplicações parecerem boas!7
Digamos que você queira que as linhas Figura 8. Data set com uma coluna calculada por scri pt.
do Grid que exibem os modelos mais ba-
ratos sejam exibidas em negrito. Para fazer
isso, selecione o manipulador da linha,
e vá na aba Property Editor / Highlights,
que permite definir regras de destaque.
Clique em  Add, trazendo o diálogo New
 Highlight; no primeiro campo, If following
condition is true, clique o botão “...”. Lá está
mais uma vez o Expression builder. Crie
a expressão row[“Preço”]. De volta ao New
 Highlight, no segundo combobox (para a
seleção de operador) escolha Less than;
e no terceiro campo, que também aceita
uma expressão, digite 50. Agora, no grupo
Then apply following formatting, clique no
segundo botão “B” (bold); veja a Figura 9.
Pronto, basta confirmar e testar novamente
o relatório.
O Report Engine procura oferecer uma
GUI que permita fazer tudo com o mouse,
selecionando opções predefinidas mes-
mo na edição de scripts. Usuários mais
experientes, que conheçam JavaScript e já
tenham aprendido palavras-chave como
row e params, poderão ignorar esta interface
gráfica e digitar as expressões diretamen- Figura 9. Editando uma regra de destaque.
te. No caso do highlight, acho mais fácil
digitar um único script no primeiro campo
– row[“BUYPRICE”] < 50 – e deixar os outros
como “Equals to” e “true”.

No download deste artigo, o arquivo correspon-


dente a esta etapa é o carros4.rptdesign.

Data sources de script 


Você já deve ter observado que o BIRT
só gera relatórios a partir de algum Data
Source; não existe uma opção de passar
ao gerador uma coleção de objetos Java,
como os datasets do JasperReports e do Figura 10. Definição de colunas para o data set de scripted data source.

Edição 38 •  Java Magazine 31

 jm38.indb 31 17/7/2006 14:11:45


Byte Code • Relatórios e Gráficos com Eclipse

 JFreeChart. Mas o princípio do BIRT é ex- opção de scripting. no caso de JDBC: não há query, somente
plorar a generalidade do conceito de Data Crie um novo Data Source, com o tipo colunas calculadas (na aba Output Colu-
Source, que não precisa necessariamente Scripted Data Source e nome “scriptDS”. Na mns). Crie duas novas colunas, angulo e seno,
ser uma fonte de dados relacional. aba Script do editor, você verá que o BIRT ambas com o tipo Float. Veja a Figura 10.
Ao criar um Data Source, você deve ter permite definir cinco métodos: open, close, Observe que o diálogo não permite a
observado que existem opções de flat beforeOpen, beforeClose, afterOpen e afterClose. entrada de expressões para calcular o valor
files (arquivos CSV – texto com campos Pode ser preciso redefinir estes métodos, destas colunas, o que pode parecer estra-
separados por vírgula), e XML (que usam por exemplo, para abrir e depois fechar nho. Mas faz sentido, pois nosso Data Set
expressões XPath para extrair um Data Set uma conexão com um sistema externo. não possui colunas de dados “primárias”
tabular de um documento XML qualquer). Neste exemplo, não precisaremos disso. a partir das quais as colunas calculadas
Estas opções são muito interessantes para Crie um Data Set chamado “senoidal” possam ser derivadas (no caso de Data Sets
a integração entre aplicações através de para este Data Source. Você verá que o  JDBC, estas colunas seriam as do resultset
arquivos. Mas ainda mais poderosa é a diálogo Edit Data Set é mais simples que da query ou stored procedures. O Scripted
Data Source exige o uso de scripts para
tudo, inclusive para determinar quantas
linhas existem, portanto, sua configuração
é um pouco diferente.
Na view Data Explorer, deixe o Data Set
senoidal selecionado; agora, na view do
.rptdesign (área central), clique na aba
Script. Você verá um combobox no topo,
listando todos os métodos disponíveis
para o script do Data Set. Entre com o
seguinte código.
Para o método open:
x = 0.0;

E para o método fetch:


if (x < 8) {
row[“angulo”] = x;
row[“seno”] = Math.sin(x);
x = x + 0.01;
 return true;
}
else return false;

Figura 11. Data Set totalmente baseado em scripting, com o código que gera cada nova linha. Para compreender a programação de um
Data Set baseado em script, basta pensar
que ele funciona como um  java.util.Iterator.
O método open  inicializa o Data Set, e o
método fetch  retorna true  se existir mais
uma linha, ou false se não houver mais
linhas. Além disso, o fetch deve também
setar os valores de todas as colunas para
a próxima linha (se houver).
No nosso exemplo, queremos calcular
os senos de todos os ângulos entre 0 e 8
radianos (i.e., de 0 e 1.440 graus, ou 4 voltas
na circunferência trigonométrica), com
incrementos de um centésimo de radiano
(3,6 graus). (Utilizamos valores fixos para
o ângulo inicial, final e incremento, mas
poderíamos facilmente ter criado parâme-
tros do Data Set para estes valores.)
Para fazer isso, usamos uma variável de
Figura 12. Chart gerado a partir do data set  senoidal , calculado por um script. estado do Data Set, a variável x, iniciali-

32  Java Magazine • Edição 38

 jm38.indb 32 17/7/2006 14:11:48


zada no open. O valor desta variável será fabricante, seria ótimo poder clicar na Escolha Type = “Mouse Click” e Action =
preservado entre as invocações de método: coluna correspondente a um fabricante e “URL Redirect”. Clique no botão Edit Base
funciona como um atributo, não como uma imediatamente visualizar um outro rela- URL, que abre o diálogo Hyperlink Options
variável local. O método fetch atualiza este tório de preços por fabricante. Este tipo de (Figura 13). Existem vários tipos de links.
x até chegar ao valor máximo, e se ainda funcionalidade é excelente para o usuário Você poderia, por exemplo, querer que
não tiver chegado, calcula as colunas angulo final, pois evita a necessidade de voltar um clique na coluna de um Vendedor di-
e seno para a linha sendo retornada. Veja a um menu de relatórios, escolher outra recionasse o usuário à página de cadastro
na Figura 11 o Report Designer durante a opção e preencher muitos critérios de filtro daquele fabricante; bastaria então entrar
edição de scripts. Na Figura 12 é mostra- iguais aos do relatório anterior. Já para com sua URI (que pode ser gerada dina-
do um relatório que podemos construir o programador, implementar recursos micamente). Mas no nosso caso, queremos
facilmente (exercício para o leitor!) utili- como este costuma ser bastante
zando este Data Set. trabalhoso, especialmente em in-
Finalizamos observando que, embora terfaces web, devido à dificuldade
este exemplo seja um caso extremo – o de programar qualquer tipo de in-
script gera o Data Set de forma comple- teratividade envolvendo gráficos
tamente sintética, sem ler nenhuma fonte – o que exige a geração dinâmica
de dados externa – é mais comum que de image maps. Felizmente, o BIRT
este recurso seja utilizado para ler dados torna funcionalidades como essas
de fontes que não sejam suportadas dire- relativamente simples.
tamente pelos Data Sets comuns do BIRT. Vamos ao nosso exemplo. No
Por exemplo, se os seus dados exigem fazer carros.rptdesign, volte à aba Layout,
uma consulta a um EJB, ou uma query do clique duas vezes no gráfico, mude
Hibernate – ou quem sabe invocar DAOs para a aba Format Chart e selecione
 Java que montam queries JDBC – pode-se Series / Value (Y) Series. Clique no
usar scripts para acessar tais dados.  botão Interactivity, que abre um
dialogo de mesmo nome. Observe
No download deste artigo, o arquivo correspon- (nos combos Type e  Action) que o
dente a esta etapa é o senoide.rptdesign. BIRT suporta vários tipos de even-
tos de mouse, foco, teclado etc.,
Interatividade e ações drill-through e diversos tipos de ações, como
Relatórios complexos devem não só exi- exibir uma tooltip, ocultar/exibir,
 bir dados, mas também permitir ao usuá- destacar, ou invocar um script (que
rio navegar por esses dados. Por exemplo, pode fazer praticamente qualquer
ao visualizar o relatório de preços por coisa). Figura 13. Editando opções de drill-through.

Configurando a memória para o BIRT

O Report Designer é um ambiente pesado,


e após um OutOfMemoryError, você pode
querer aumentar o limite de tamanho do heap da
para o Eclipse 3.2 com o BIRT (e outros plug-ins
pesados, como o WTP e AJDT).
O problema é contornado com outra opção do
solução é sempre a mesma: o NetBeans 5, por
exemplo, aciona automaticamente a opção
-XX:MaxPermSize=160m .
JVM que executa o Eclipse. Isso pode ser feito adi- HotSpot: -XX:MaxPermSize=128m, que configura Resta perguntar: por que o Eclipse + BIRT utilizam
cionando ao atalho ou script que inicia o Eclipse o limite máximo da PermGen. Nem é necessá- tanta memória para código? A funcionalidade do
(ou ao eclipse.ini ) as opções “-vmargs –mxXXXm” rio usar o -Xmx. Outra solução é utilizar JVMs BIRT é impressionante, mas creio que a resposta
onde  XXX é o número de Mb. No entanto, esta alternativas, como as da IBM e da BEA, que não é, em boa parte, a arquitetura nada leve utilizada
configuração pode não funcionar, mesmo com apresentam esta limitação. pela solução como um todo. Quando você f az um
um tamanho de heap enorme. Quando você ler este artigo, atualizações do preview do relatório, o BIRT carrega (na mesma
O problema não é do Eclipse (embora haja BIRT, Eclipse SDK e JDK p odem ter contornado o JVM do Eclipse) não só todo o código do Report
vários bugs do Eclipse.org discutindo o assunto), problema de forma transparente (na dúvida, adi- Engine, mas também o de suas dependências,
e sim da JVM da Sun. É que o HotSpot possui uma cione esta opção somente se observar erros “java. incluindo o Mozilla Rhino, o Apache Axis, o Apache
região especial de memória, a “geração perma- lang.OutOfMemoryError: PermGen space”). Tomcat (usado só para servir o relatório HTML para
nente” (PermGen), onde são alocadas classes e Este problema não é exclusividade do Eclipse o preview!), e se estiver sendo usado o Data Source
strings internalizadas, mas o tamanho máximo ou do BIRT; tem atingido outras aplicações de teste “Classic Cars”, até o servidor Apache De rby
default desta região de memória é insuficiente Java peso-pesadas em número de classes. A embutido.

Edição 38 •  Java Magazine 33

 jm38.indb 33 17/7/2006 14:11:49


Byte Code • Relatórios e Gráficos com Eclipse

BIRT, outros geradores de relatórios, e open source

E xistem diversos geradores de relató-


rios puro-Java. As opções open source
mais tradicionais são o JasperReports
tem uma linha de produtos co merciais de
BI. Já a Infologic produz o JasperAssistant,
editor de JasperReports integrado ao
opções previamente existentes?
Em parte isso parece ser um modus
operandi da Fundação Eclipse, que já
(gerador de relatórios) e iReport (editor Eclipse (que apesar do nome, não tem começa com o produto básico, o IDE,
visual de relatórios do JasperReports), relação com a JasperSoft; é um produto criado da mesma maneira pela IBM, sem
cobertos nesta e na edição anterior, comercial e de código fechado). A Pen- ligar para os projetos de IDE Java open
e o gerador de gráficos comerciais taho oferece seu BI Suite, produto que já source anteriores. A Fundação incorpo-
JFreeChart, tratado nas edições 24 e 25. suporta dois engines de relatórios: Jas- ra, talvez emblematicamente, uma nova
As perguntas que podem est ar na mente perReports e o BIRT. Mas recentemente, a modalidade de open source desenvolvido
de muitos leitores são: Qual é o melhor? Pentaho “adotou” os projetos do JFree.org primariamente por grandes empresas,
Vale a pena migrar para o BIRT? (JFreeChart e JFreeReport), que devem que procura combinar vantagens de mo-
Passados dois anos, JasperReports, tornar-se preferenciais. delos extremos9. E é difícil não perceber
iReport e JFreeChart continuam disponí- Também não podemos desprezar a as vantagens: nunca ouvimos falar que
veis, melhorando continuamente, e agora vantagem do BIRT como solução de BI uma funcionalidade de um projeto do
também contam com suporte comercial. oficial da Fundação Eclipse. O BIRT faz Eclipse.org não é implementada por “falta
Este é um mercado que está se expandin- parte da distribuição integrada Callisto. de recursos”, ou que a nova versão terá
do, tornando-se muito mais competitivo, É suportado por outros pesos-pesados seu release de produção “quando estiver
e sofrendo uma forte “comoditização” como a IBM (que, imagino, deve estar pronta”. Não é só o Eclipse. Este novo mo -
das funcionalidades básicas. As seguintes ansiosa para excluir de seus IDEs comer- vimento “open source corporativo” inclui
tendências recentes são críticas para esta ciais o Crystal Reports, e parar de pagar outros projetos – qualquer um onde 90 %
competição: licenças à Business Objects). No seu dos desenvolvedores sejam pagos pela
• Integração com IDEs. Com o sucesso primeiro ano de vida pós-1.0, o BIRT já mesma empresa, o que inclui vários pro-
de “plataformas de IDE” como o Ecli pse e se tornou um dos sucessos da Fundação  jetos open source famosos (IDEs , sistemas
o NetBeans, ferramentas visuais e integra- Eclipse, e é cada vez mais um diferencial operacionais, servidores Java EE etc.) .
das não são mais um l uxo – são essenciais. competitivo. Nenhum outro IDE gratui- Recomeçar do zero às vezes é bom ou
A vantagem de produtividade de um to / open source para Java inclui capa- mesmo necessário. A arquitetura do BIRT
ambiente não só visual, mas totalmente cidade nem remotamente semelhante. me parece superior à do JasperReports e
integrado ao IDE, é evidente. Por outro lado, antes de migrar cega- do JFreeChart (embora esta impressão
•  Suporte a recursos de B.I. (Business mente de uma tecnologia que você já possa ser viciada pela documentação do
Intelligence). Isso significa capacidades conhece para outra que ainda não domi- BIRT, que é formal, vasta , de alta qualidade
de análise e apresentação de dados mais na, avalie bem a novidade, considerando e gratuita). E sendo um projeto integrado
avançadas; recursos “enterprise” como suas necessidades particulares. Uma à plataforma Eclipse, o BIRT é obrigado a
relatórios agendados, segurança, alta vantagem do JFreeChart, por exemplo, é fazer uso intenso de vários componentes
escalabilidade (clustering e caching), a riqueza de recursos e grande flexibilida- desta plataforma, incluindo a SWT, JDT,
OLAP, suporte total à plataforma JEE (ex. : de de extensão, que permite customizar EMF e GEF, portanto, seria dif ícil reutilizar
EJB e JCA) etc. gráficos praticamente sem limites – ainda muito código de projetos anteriores.
que a um custo de escrever muito código Um fato interessante é que o BIRT
Os recursos mais high-end nestes Java. pretende estabelecer um padrão com
grupos podem não estar presentes em seu ROM (Report Object Model), que,
produtos open source ou gratuitos, BIRT e open source lembrando, é o modelo dos s eus arquivos
mas todos os competidores adotaram a O projeto BIRT já foi criticado pela forma .rptdesign e dos objetos do relatório visí-
mesma estratégia, oferecendo produtos como entrou no mundo open source. O veis por scripts e APIs (algo semelhante
comerciais mais avançados e/ou serviços projeto foi uma iniciativa da Actuate, em- ao DOM para documentos HTML). Talvez
e suporte. presa do ramo de BI que ainda não tinha esta iniciativa não tenha sucesso – os
A Actuate, empresa que criou e é a presença especificamente no segmento competidores ainda não estão correndo
principal contribuinte do BIRT, oferece o de ferramentas Java, e viu a oportunida- para implementar compatibilidade com
Actuate BIRT. O produto é o mesmo; so- de de ganhar este mercado “doando” ao o ROM. Mas é importante devido ao es-
mente os serviços e suporte comerci al se Eclipse.org todo o desenvolvimento do forço por trás do design e documentação
diferenciam. A JasperSoft, empresa estru- BIRT. Mas por que a Actuate tinha que desse modelo, e também porque facilita
turada para desenvolvimento e suporte criar geradores de relatórios e de gráfi- a integração do BIRT com outros projetos
comercial do JasperReports e iReport, cos completamente novos, com tantas do Eclise.org e plug-ins de terceiros. Tra-

34  Java Magazine • Edição 38

 jm38.indb 34 17/7/2006 14:11:51


invocar outro relatório; então, escolha o como List, Image e Dynamic Text;
tipo Drill-through, que é como é conheci- • Páginas-mestre;
da esta ação de navegar entre relatórios • Libraries, que permitem reutilizar
duzindo: o BIRT não é só um gerador distintos, mas relacionados. definições comuns (como datasets e
de relatórios, é uma plataforma. E na O diálogo exibido permitirá selecionar páginas-mestre) entre vários relatórios
medida em que esta plataforma atrair o relatório de destino, bem como várias semelhantes;
o interesse de muitos desenvolvedores opções para invocá-lo (como seus parâme-
de soluções complementares, isso tros). Selecione o parâmetro productVendor Também não tivemos espaço para falar
pode transformar o BIRT (ou pelo me- (a coluna Parameters  já disponibiliza os em desempenho, mas o BIRT possui uma
nos seu ROM) num padrão de fato. parâmetros exigidos pelo .rptdesign de característica muito importante que é seu
Não vejo as práticas de desenvol- destino). Em Values, digite a expressão cache de relatórios, que faz com que invo-
vimento do BIRT como nada de ex- row[“Fabricante”] , para passar para este cações freqüentes aos mesmos relatórios,
cepcional. O projeto JasperReports parâmetro o valor da coluna Fabricante no com mesmos parâmetros, não exijam a
também é mantido por uma empresa contexto de ocorrência do evento – ou seja, repetição de todo o processamento de ge-
com interesses comerciais, que aliás o fabricante associado à barra clicada. ração do relatório (especialmente a query
oferece produtos proprietários mais Clique no botão Ok e, de volta ao diálogo ao SGBD). Esta funcionalidade muito
avançados. Quanto à duplicação de Interactivity, clique em  Add para inserir a importante faz falta em alguns geradores
funcionalidades, os autores do JFree- nova ação na lista à esquerda. de relatórios, obrigando desenvolvedores
Chart também criaram o JFreeReport,  Está feito. É só testar (omitimos somente de aplicação a implementar mecanismos
um engine de relatórios simples, con- as instruções para criar o relatório por de cache ad-hoc, tarefa que é bastante
correndo com o JasperReports. Não se fabricante; mas este é parecido com o rela- complexa e arriscada.
trata necessariamente de falta de cola- tório por tipo de produto, variando apenas Os recursos que pudemos explorar neste
boração: muitas vezes os líderes destes as colunas filtradas e selecionadas). artigo já cobrem a funcionalidade de rela-
projetos podem ter motivos técnicos O suporte a scripts e eventos do BIRT tórios exigida por muitas aplicações, e mais
para criar um projeto novo, como também pode ser utilizado para imple- importante que isso, devem ilustrar bem o
preferir uma arquitetura diferente, ou mentar ações de drill-down (gerar o mesmo ciclo de trabalho com o BIRT, e seus pontos
desejar uma solução mais simples e relatório com dados mais filtrados), para fortes (como a facilidade de desenvolvimen-
leve (ou mais completa e ambiciosa). validar parâmetros, e outras operações. to) e fracos (como o tamanho do runtime).
Ou ainda, ter em vista a evolução para Tenha em mente este conjunto total de
um modelo de open source com explo- No download deste artigo, os arquivos correspon- funcionalidades para comparar o BIRT a
ração comercial, o que é um objetivo dentes a esta etapa são carros5.rptdesign (relatório outras opções. O BIRT certamente será uma
perfeitamente legítimo. base) e carros5porFabricante.rptdesign (relatório excelente alternativa para muitas aplicações,
Em qualquer caso, a proliferação filho).TTR e considerando sua facilidade de uso, é baixo
de projetos open source na mesma o investimento de tempo para aprender o
categoria não é necessariamente um Conclusões restante de suas funcionalidades.
mal, pois também há vantagens na Este artigo pretendeu dar uma introdu-
diversidade e na competição. O Jasper- ção abrangente ao BIRT, mas o enorme eclipse.org
Reports e JFreeChart avançaram muito volume de recursos deste gerador de re- Projeto Eclipse.
em comparação com a última vez que latórios só nos permitiu abordar os itens
mais essenciais ou interessantes. Ficou eclipse.org/birt/phoenix/ref 
os utilizei seriamente (há cerca de dois
faltando falar de muitos outros itens, que Referência do BIRT
anos). Ambos atingiram as versões
“1.0”, com promessa de estabilidade enumeramos aqui para completar uma  jasperreports.sf.net 
de API, após anos de atualizações 0.x visão geral das capacidades do BIRT: JasperReports, gerador de relatórios open source
com quebras arbitrárias e freqüentes • Relatórios tabulares (em grids) mais
de APIs. E o JasperReports e iReport complexos, com agrupamentos, cabeçalhos  javamagazine.com.br/downloads/jm38/ 
ganharam integração com a JFree- e rodapés;  jm-birt.zip
Chart. Enfim, se a ameaça do BIRT tiver • Localização/Internacionalização;
servido para agilizar estas melhorias, • Refinamentos de layout: suporte a CSS, Osvaldo Pinali Doederlein
os desenvolvedores que continuarem quebra de página, índices, bookmarks etc.; ([email protected]) é Mestre
preferindo estas outras opções só têm • Recursos de filtro e ordenação (ge- em Engenharia de Software
a agradecer. ralmente desnecessários para Data Sets Orientado a Objetos, membro
 JDBC que podem usar WHERE e ORDER, mas individual do Java Community Process
9
  Ver www.catb.org/esr/writings/cathedral- necessários para outros Data Sets); (tendo participado do Expert Group da JSR-170:
bazaar/ 
• Mapas (tabelas "de/para"); Tiger/J2SE 5.0), e trabalha na Visionnaire Informática
como arquiteto e desenvolvedor.
• Outros componentes importantes,

Edição 38 •  Java Magazine 35

 jm38.indb 35 17/7/2006 14:11:53


Mais relatórios Pas
Totalizações e gráficos com iReport e Jaspe

N o artigo “Relatórios na Web Passo


a Passo”, publicado na edição
anterior, apresentamos o Jasper-
Reports e o iReport e mostramos como
criar um relatório mestre-detalhe com-
 bém mostraremos como criar e configurar
gráficos no relatório

Sobre o projeto de exemplo


O projeto utilizado neste artigo permite a
relatório são obtidos a partir de um banco
MySQL, e o modelo de dados é mostrado
na Figura 1.
A Figura 2 representa o resultado final
desse relatório e o quadro “Como criar o
pleto, que lista detalhes dos pedidos de execução de um relatório a partir de uma relatório inicial” resume os passos para a
clientes. Neste artigo, vamos incrementar aplicação web. Ele é baseado em quatro criação. O projeto inicial completo, com
esse relatório inicial definindo grupos e entidades principais: pedidos, itens de todas as classes necessárias, os templates
acrescentando diversas totalizações. Tam- pedido, clientes e produtos. Os dados do de relatorio.jrxml e o script para criação do
 banco de dados, está disponível no site
da Java Magazine. Os leitores que não
acompanharam o artigo na edição ante-
rior poderão obter esse exemplo pronto,
e partir dele para realizar as mudanças
detalhadas aqui. Será disponibilizado no
download tanto o projeto inicial, como
o projeto final, resultado das alterações
feitas neste artigo.

Agrupando pedidos por cliente


Repare na Figura 2 que, quando um
cliente tem diversos pedidos, os dados
do cliente (no caso, o nome) aparecem
repetidos para cada pedido. Vamos
melhorar o relatório, agrupando todos
os pedidos de um cliente e imprimin-
do somente uma vez os seus dados.
Precisamos definir um  grupo  para
fazer quebra de pedidos por cliente.
Quando um grupo é criado no
 Jas perReport s, automaticamente
são criadas duas novas bandas: no-
megrupo Header e nomegrupoFooter
(por exemplo, clienteHeader e cliente-
Footer). Colocamos nestas bandas as
informações associadas ao grupo,
que neste caso são o nome e o valor
total do cliente; já os dados de cada
item do grupo permanecem na
 banda detail (são eles os pedidos e
os itens de pedido do cliente).
Também é preciso defi-
nir uma expressão de agru-
pamento, que é utilizada pelo
 JasperReports para fazer a quebra do gru-

36  Java Magazine • Edição 38

 jm38.indb 36 17/7/2006 14:11:58


Aprenda a definir

so a Passo agrupamentos
agrupament os e calcular
totais em vários níveis,
num relatório mestre-
detalhe, e como criar
gráficos de resumo
r Reports
ANA ABRANTES E YARA SENGER

po. Usamos o nome do cliente. Para que 2.  Clique no ícone de grupos


os grupos sejam apresentados da maneira na barra de ferramentas, e
esperada, é preciso que a fonte de dados depois em New. Na janela que
também esteja ordenada corretamente,
correta mente, ou aparece, configure o grupo
seja, a consulta SQL deve ter a cláusula conforme a Figura 3 e clique
“order by” (ou se for usado
u sado um datasource em OK .
de JavaBeans, deve-se passar uma coleção 3 .   Mova o textfield que
com os objetos já ordenados de forma mostra o nome do cliente da
compatível com os grupos desejados, neste  ba nd a detail   para a banda
caso o nome do cliente). clienteHeader, que acabou de ser
Pode haver vários grupos “aninhados”; criada. Na aba Text Field  das
por exemplo um grupo Região, que englo- propriedades do textfield, altere
 ba todos os clientes de umau ma determinada a Textfield expression para:
região; dentro deste um grupo Estado, e Figura 1. Modelo de dados do projeto de exemplo.
assim por diante. Quando o grupo mais “Cliente:“+$F{nomeCliente}
“externo”” for reinicializado,
“externo reinicia lizado, todos os gru- 5. Como iremos agrupar os pedidos por
pos contidos nele também o serão.
se rão. 4.   Nabanda detail, apague o elemento cliente, a fonte de dados deve ter os dados
Os passos para a criação do grupo são static text com a descrição “Cliente”. Este ordenados por algum campo do cliente
os seguintes: texto não será mais necessário, pois o que o diferencie; no nosso caso a consulta
1. No iReport, abra o arquivo do relatório, nome do cliente só aparece uma vez para SQL deve ter a cláusula
cl áusula “order by c.nome”.
RelatorioPedidos.jrxml. cada grupo. Desta forma, à medida que o JasperReports

Como criar o relatório inicial

S iga estes passos para criar os relatórios que


utilizaremos e que foram criados conforme
o último artigo.
7.  Insira os elementos textfield (com os
campos do datasource), static text, imagem e
subreport até que o relatório fique com a apa-
torioItens ;
11.. O relatório não deve ter margens, e so-
11
mente as bandas columnHeader  e  e detail  serão
  serão
1. Crie um banco de dados de nome “ecom- rência da primeira imagem da Figura 2; usadas; as demais devem ser desativadas
merce” no MySQL conforme o diagrama na 8.   Crie os parâmetros subReport   do tipo zerando sua band height;
Figura 1; net.sf.jasperreports.engine.JasperReport   para 12. Configure a consulta deste relatóri o com
2. Abra o iReport; serem passados o arquivo do sub-relatório e a seguinte string SQL:
3. Crie um novo relatório chamado “Relato-  pageRoot  do
 do tipo java.lang.String  para o caminho
rioPedidos”; do projeto quer será usado na localização de SELECT it.quantidade, pro.nome as nomeProduto, pro.preco
4. Defina a conexão de dados a ser usada; imagens e outros recursos; FROM pedidos_itens it
JOIN pedidos ped ON ped.numero = it.numero_pedido
5.  Configure a consulta do relatório com a 9.  Nas propriedades do elemento subre- JOIN produtos pro ON pro.id = it.id_produto
seguinte string SQL:  po rt , em Connection/Datas
Connection/Datasource ource expres- WHERE it.numero_pedido do = $P{numeroPedido}
sion, coloque Use connection expression , em
SELECT p.data, p.numero, c.nome as nomeCliente Subreport expression coloque $P{subReport} 10. Insira os elementos textfield e static text
FROM pedidos p
JOIN clientes c ON p.id_cliente = c.id e Subreport Expression Class  igual a até que o relatório fique com a aparência da
ORDER BY p.numero net.sf.jasperreports.engine.JasperReport; em Su- segunda imagem da Figura 2;
breport parameters  adicione um parâmetro 11.. Crie o parâmetro numeroPedido  do tipo
11
6. Somente as bandas  pageHeade r , detail  e de nome numeroPedido  com Default value  java.lang. Integer ;
 pageFooter  serão
 serão usadas; as demais devem ser expression  igual a $F{numeroPedido}; 12. Ao executar, o relatório ficará como mos-
desativadas zerando-se sua band height ; 10. Crie um novo relatório chamado Rela- trado ao final da Figura 2.

Edição 38 •  Java Magazine


Magazine 37

 jm38.indb 37 17/7/2006 14:11:59


Mais relatórios Passo a Passo

Total por pedido do na variável total, após listar todos os


Queremos agora exibir o itens:
valor total de cada pedido, ou 1. Vá em Editar|Propriedades do Relatório
seja, a soma dos valores de e altere a altura para 60 pixels.
todos os seus itens. Como os 2 .   É necessário ativar a banda
dados do pedido estão no sub- columnFooter: selecione Visualizar|Bandas
relatório RelatorioItens.jrxml, do Relatório e altere na banda columnFooter
RelatorioPedidos.jrxml vamos declarar uma variável a sua band height para 20; clique no botão
e exibí-la neste relatório.  Apply.
1 .   Abra o RelatorioItens. 3. Adicione um textfield à banda
RelatorioItens.jrxml  jrxml , columnFooter e altere o campo Evaluation
2 .   Clique em Visualizar time para Report, indicando que o valor
|Variáveis, e depois no botão do textfield deve ser avaliado ao término
Novo. da execução do relatório (no caso, o
3.  Configure uma nova sub-relatório que contém todos
variável fazendo seu os itens do pedido). Para que
atributo name  igual a a variável total seja apresen-
total e Calculation Type tada com formato de moeda,
= Sum. Mude o tipo da vamos utilizar o formatador
variável (campo Variable obtido através do método
class Type) para  jav a.l ang. getCurrencyInstance() da classe
Double. Indique também que  java .tex t.Nu mbe rFor mat , com a
a variável deve ser reinicia- seguinte expressão no campo
lizada sempre que o relatório Textfield expression:
for executado, configurando
“Total do Pedido: “ + java.text.NumberFormat.
java.text.NumberFormat.
ResetType para Report.   getCurrencyInstance().format($V{total}.doubleValue())
4.  Ainda falta especificar
como a variável total   será  O identificador
iden tificador do pacote, “java.text”,
“java.text”, poderia ser
calculada, ou seja, definir omitido nesta expressão; o JasperReports é capaz
a soma dos valores de cada de encontrar sozinho a classe no Java SE.
item do pedido. Para isso,
utilizamos o campo Variable Veja na Figura 6 como ficam o layout
l ayout e o
expression da variável, forne- resultado da execução.
cendo uma expressão (que
deve necessariamente ser do Total por cliente
tipo Double, devido à configu- Nosso próximo objetivo é apresentar o
Figura 2 . Relatório e sub-relatório iniciais (como criados na edição anterior), e ração feita no passo anterior).
resultado da execução do relatório Como o campo quantidade é
do tipo  java.la ng.Integ er e  preco  é do tipo
percorre a fonte de dados, poderá iden-  java.lang .Double , precisamos converter es-
tificar quais são itens que pertencem ao ses campos para o tipo primitivo double,
mesmo grupo: uma mudança no valor de realizar a multiplicação e armazenar o
nomeCliente indicará o início de um novo resultado em um objeto  java.lang.Double , ou
agrupamento. Vá em Data|Consultas do seja, a expressão ficará assim:
Relatório|Report Query e altere a consulta
SQL acrescentando o nome do cliente na new Double ($F{quantidade}.doubleValue()
  *$F{preco}.doubleValue())
cláusula order by:
5. A variável deve ser inicializada com
SELECT p.data, p.numero, c.nome as nomeCliente
FROM pedidos p 0; por isto definimos o campo Initial Value
JOIN clientes c ON p.id_cliente = c.id Expression como new Double(0).
ORDER BY c.nome, p.numero 6. Clique em OK para finalizar. Veja os
resultados na Figura 5.
Veja na Figura 4 como ficam o layout e o Figura 3. Tela
Tela de configuração do grupo de quebra de
resultado da execução do relatório. Feito isso, vamos mostrar o valor obti- pedidos por cliente.

Magazine • Edição 38
38  Java Magazine

 jm38.indb 38 17/7/2006 14:12:01


Como o valor total de cada pedido “Total do Cliente: “
está sendo calculado no sub-relatório + java.text.Num
java.text.NumberFormat.getCurr
berFormat.getCurrencyInstance(
encyInstance(
new Locale(“pt”,”br”)).format(
RelatorioItens.jrxml, através de sua variável   $V{totalCliente}.doubleValue())
total, vamos usar este valor para incre-
mentar a variável totalCliente no relatório Veja como ficam o layout do relatório e o
principal, RelatorioPedidos.jrxml, enquanto resultado da execução na Figura 9.
RelatorioPedidos.jrxml estiver sendo processado o mesmo clien-
te (na geração do relatório). Para fazer Total geral
esta ligação entre as variáveis, criamos O próximo passo é apresentar o valor
um parâmetro de retorno no elemento total dos pedidos de todo o relatório. No-
subreport no RelatorioPedidos.jrxml, do vamente usaremos a variável com o valor
seguinte modo: total de cada pedido (no sub-relatório) e
1.   No relatório RelatorioPedidos.jrxml, teremos de criar uma variável
vari ável no relatório
abra a janela de propriedades do elemento RelatorioPedidos.jrxml  para armazenar o
subreport, que está na banda detail; clique total geral, da mesma forma que foi feito
na aba Subreport (Other) e dentro dela com a variável de total por cliente.
c liente.
Figura 4. Relatório depois de da criação do grupo cliente. mude para a aba Subreport return values. Execute os seguintes passos em
2.  Clique no botão  Add e digite o nome RelatorioPedidos.jrxml:
da variável do sub-relatório ( Subreport 1.  Crie uma variável com campo name
variable) que contém o valor que queremos igual a totalGeral.
somar, neste caso a variável total. 2.  Configure o tipo da variável ( Variable
3. Indique o nome da variável que deve Class type) para java.lang.Doub
 java.lang.Double.
le.
estar definida no relatório principal onde 3. Defina Calculation type = System.
a totalização será armazenada (Local desti- 4. A variável deve ser reinicializada sem-
nation variable), ou seja, totalCliente. pre que o relatório é executado; então altere
4.  Indique também que o cálculo repre- o campo Reset type para Report.
senta uma soma: Calculation type igual a Veja o resultado na Figura 10.
Sum.
Esta configuração está representada na A seguir, é preciso configurar em
Figura 8. RelatorioPedidos.jrxml mais um parâmetro
Figura 5.Tela de configuração da variável que totaliza o de retorno no elemento subreport, para
valor de um pedido. Falta apenas exibir a variável total- que o valor da variável total do sub-rela-
Cliente  no final do
valor total dos pedidos de cada cliente. grupo cliente, ou seja,
Primeiro será necessário criar uma va- na banda clienteFooter
riável totalCliente  no relatório principal, (criada automatica-
RelatorioPedidos.jrxml. Siga estes passos: mente ao criar o gru-
1. Crie uma variável
vari ável com campo name = po cliente): RelatorioItens.jrxml
totalCliente. 1 .   Adicione um
2.  Configure o tipo da variável ( Variable textfield à banda
Class type) para java.lan
 java.lang.Double(pois o total
g.Double clienteFooter. Altere
dos pedidos é desse tipo). seu Evaluation time
3. Faça Calculation type = System: não que- para  gr ou
oupp   e faça
remos que o JasperReports faça nenhum Evaluation Group =
tipo de cálculo, mas sim que receba o valor cliente, indicando
retornado pelo sub-relatório (explicaremos que o textfield deve
isso a seguir). ser avaliado ao final
4.  É necessário também fazer que a vari- desse grupo.
ável seja reinicializada a cada grupo, pois 2.   Configure a Tex-
queremos o total por cliente. Neste caso o tfield expression de
campo Reset type deve ser igual a  group e forma que o valor
Reset group = cliente (que é o nome do grupo seja apresentado
definido anteriormente). Veja como fica o como moeda, da se-
relatório na Figura 7. guinte forma: Figura 6. Relatório com total por pedido.

Edição 38 •  Java Magazine


Magazine 39

 jm38.indb 39 17/7/2006 14:12:02


Mais relatórios Passo a Passo

tório também seja passado para a variável final da geração do relatório. SELECT c.nome as nomeCliente,
totalGeral  do relatório principal. Faça o 2.   Configure a Textfield expression de SUM(it.quantidade * pro.preco) as totalCliente
seguinte: modo que o valor seja apresentado como FROM pedidos_itens it
JOIN pedidos ped ON ped.numero = it.numero_pedido
1. No relatório principal RelatorioPedidos. moeda, novamente utilizando o formata- JOIN produtos pro ON pro.id = it.id_produto
 jrxml, abra a janela de propriedades do ele- dor de moedas, da seguinte maneira: JOIN clientes c ON ped.id_cliente = c.id
mento subreport; clique na aba Subreport GROUP BY c.nome
(Other) e dentro dela selecione a aba Subre- “Total Geral: “ + java.text.NumberFormat.getCurrencyInstance(
new Locale(“pt”,”br”)).format($V{totalGeral}.doubleValue())
 port return values. Depois clique em OK   para salvar as
2.  Clique no botão  Add e digite o nome Veja na Figura 12 como ficam o layout e alterações. Ao ser definida a consulta, os
da variável do sub-relatório ( Subreport o resultado da execução. campos retornados serão automaticamente
variable) que contém o valor a ser somado: declarados no subdataset.
total. Gráfico de vendas por cliente
3. Indique o nome da variável que deve O JasperReports tem suporte a gráficos, O elemento de gráfico
estar definida no relatório principal onde através de um elemento de relatório que  Já podemos incluir o gráfico no rela-
a totalização será armazenada ( Local usa a biblioteca JFreeChart ( jf ree.org / tório:
destination variable), ou seja, a variável  jfreechart). Este elemento também está dis- 1.  Vá em Visualizar|Bandas do Relatório,
totalGeral. ponível na barra de ferramentas
4.  Indique também que o cálculo repre- do iReport, e permite a configu-
senta uma soma, fazendo Calculation type ração de um subconjunto das
= Sum. propriedades visuais suportadas
Veja essas configurações na Figura 11. pelo JFreeChart.
Como exemplo, vamos acres-
Resta apenas exibir a variável totalGeral centar um gráfico de barras que
no final do relatório: mostra o valor total consumido
1.   Coloque na banda summary um por cada cliente em todos os
textfield com Evaluation time = Report; isso pedidos realizados por esse RelatorioPedidos.jrxml
faz com que o textfield seja avaliado ao cliente no final do relatório
RelatorioPedidos.jrxml, na banda
summary.

 Subdataset 
Precisamos que os valores se-
 jam agrupados pelo cliente, ou
seja, é necessário criar uma con-
sulta SQL diferente da definida
no relatório principal. Por isso
iremos usar um subdataset.
Um subdataset é um elemento
do JasperReports usado para
fornecer uma fonte de dados Figura 9. Relatório com total por cliente.
secundária para um gráfico.
Subdatasets têm seus próprios parâmetros,
Figura 7.Tela de configuração da variável que totaliza o variáveis e fields, e podem ter também
valor de pedidos por cliente. uma consulta SQL executada (ou um
outro datasource, que neste caso viria de
um dos campos do datasource principal).
O conceito é muito parecido com o de um
subreport, e é possível ter vários subdata-
sets num mesmo relatório.
Para criar o subdataset:
1. Vá até Editar|Subdatasets e clique em New.
2.  Clique em Create. Isso habilita os de-
mais botões da janela.
3. Clique em Query, e insira a seguinte
Figura 8. Configuração de parâmetro de retorno do subreport. consulta SQL: Figura 10. Tela de configuração da variável de total geral.

40  Java Magazine • Edição 38

 jm38.indb 40 17/7/2006 14:12:03


aumente a altura da banda summary para
385 e clique em Apply.
2.  Vá em Editar|Propriedades do Relatório
e, na aba  More, selecione Sumário a cada
nova página (que deveria ter sido traduzi-
do como “Sumário numa nova página”).
3.  Em seguida, adicione um elemento de
gráfico , escolha o gráfico de barras, e
ajuste suas dimensões para que ocupe a
maior parte possível da banda. Veja na
Figura 11.Configuração de parâmetro de retorno do subreport. Figura 14 como ficará o layout.
Agora vamos configurar o gráfico:
1.   Clique com o botão direito sobre o
gráfico e selecione Chart properties.
2.  Altere o campo Chart title expression
para “Valores por Cliente”; este valor será
Figura 15.Tela de configuração das propriedades de um gráfico.
exibido no título do gráfico.
3.   Faça  Orientation =  Horizontal, o que
RelatorioPedidos.jrxml vai ajudar na leitura dos nomes dos
clientes.
4.   Faça  Category axis label expression =
“cliente”; esta é a descrição que apare-
cerá no eixo em que ficam os nomes dos
clientes.
5.  Altere Value axis label expression para
“valores”, que é a descrição a ser mostrada
no eixo dos valores.
6.  Selecione Show labels, para que apa-
Figura 12. Relatório com total geral. reçam os valores correspondentes a cada Figura 16.Configuração da fonte de dados do subdataset
do gráfico.
uma das barras.
Veja na Figura 15   as configurações
realizadas.

Após configurar visualmente o gráfi-


co, temos que indicar os dados a serem
exibidos. Esses dados estão definidos no
subdataset criado anteriormente. É im-
portante observar que ao utilizar um sub-
dataset, somente os campos, parâmetros e
Figura 13. Tela de criação e edição de um subdataset. variáveis definidos no subdataset estarão
disponíveis para o gráfico. Porém, os cam-
pos, parâmetros e variáveis do relatório
principal não estarão di sponíveis.
Vamos então vincular o gráfico ao sub-
dataset seguindo os seguintes passos:
1.  Clique na aba Chart data desta mesma
 janela de propriedades do gráf ico para
configurar a fonte de dados do gráf ico.
2.  Na caixa Dataset run da aba Dataset,
selecione o subdataset que criamos no
combobox Subdataset.
3.   Clique na aba Connection/Datasource
ex p  e selecione Use connection expres-
sion . Isso faz com que o iReport uti- Figura 17.Configuração dos campos do subdataset usados
Figura 14. Layout do relatório com o gráfico já in serido. lize a mesma conexão do relatório, pelo gráfico.

Edição 38 •  Java Magazine 41

 jm38.indb 41 17/7/2006 14:12:04


Mais relatórios Passo a Passo

declarando automaticamente a expressão Como executar o relatório


$P{REPORT_CONNECTION} . Veja a
Figura 16.

Por fim, selecione a aba Details e depois


D entro do diretório do projeto, temos os
seguintes subdiretórios:
• reports para os arquivos .jrxml ;
comando no Windows ou terminal no Linux, vá
até o diretório do projeto e digite: ant compile.
Depois devemos compilar a classe do servlet,
clique no botão  Add , para incluir uma • src para as classes Java; que fará a execução do relatório. Na mesma
Category series: • web para os arquivos JSP;  janela de prompt, digite ant javac .
1. Faça Series expression igual a “valores” • web/WEB-INF para o web.xml ; Para finalizar, geramos o arquivo
(o nome da série). • web/WEB-INF/lib para os arquivos JAR ecommerce.war. Vá ao prompt de comando e
2 .   Altere   Category expression  para necessários. digite: ant war.
$F{nomeCliente}; esta é a expressão que será Em seguida, copie o WAR para a pasta weba-
avaliada para obter os nomes mostrados no Vamos usar o Ant para efetuar algumas  pps do Tomcat.
eixo de categorias. operações; para isso criamos um arquivo Feito isso, inicie o Tomcat, abra o seu
3 .   Mude   V a l u e e x p r e s s i o n   para build.xml  que está no diretório raiz do projeto navegador web e digite a seguinte URL:
$F{totalCliente}, que é a expressão a ser inicial (incluído nos downloads deste artigo). http://localhost:8080/ecommerce .
avaliada para obter os valores exibidos no Primeiro precisamos compilar os dois templa- Clique no link que aparece na tela, e o rela-
eixo de valores. Veja a Figura 17. tes de relatório. Abra uma janela de prompt de tório será gerado.

Veja como fica o gráfico após a execução do


relatório na Figura 18. Com isso, chegamos do textfield que utiliza uma variável (e,
ao final deste tutorial. O relatório e o gráfico se for o caso, também o grupo) é essen-  jasperreports.sf.net 
 já podem ser compilados e executados con- cial para se obter o resultado desejado. O Site da biblioteca JasperReports, onde se
forme instruções do quadro “Como executar uso de variáveis é de extrema utilidade pode encontrar downloads do software,
o relatório”. e dificilmente teremos relatórios mais documentação,fóruns e mais.
elaborados sem a sua utilização.
 ireport.sf.net 
Conclusões Vimos ainda como criar um gráfico
Site da ferramenta iReport, também com
Neste tutorial mostramos como fazer simples, que também utiliza totais, e per-
downloads, novidades etc.
agrupamentos e totalizações e como criar cebemos que este é um recurso que ainda
gráficos, em um relatório mestre-detalhe. tem algumas limitações de configuração  jfree.org/jfreechart 
Vimos também como definir variáveis e a no JasperReports. Mas o JasperReports já JFreechart, biblioteca usada para a criação de
importância de indicar o tipo de cálculo está integrado o suficiente ao JFreeCha rt, gráficos no JasperReports/iReport
e de reinicialização adequados para cada a ponto de nos oferecer um resultado
tipo de variável. O momento de avaliação satisfatório com facilidade.  javamagazine.com.br/downloads/jm38/
 jm-maisrelatorios.zip

Ana Abrantes
([email protected]  )
é desenvolvedora Java na
Globalcode, co-autora do curso
de JasperReports/iReport e possui
algumas certificações em Java (SCJA, SCJP e SCWCD). É
formada pela FATEC-SP e atua na área de informática
há mais de 15 anos.

 Yara M. H. Senger
[email protected] ) é formada
em Ciências da Computação na USP
em São Carlos, especialista em desen-
volvimento web; possui as certificações
SCJA, SCJP e SCWCD. Atualmente é Instrutora e Diretora
Educacional da Globalcode, criadora e coordenadora
de diversos cursos das carreiras Academia do Java e
Academia do Web Developer.
Figura 18.Última página do relatório gerado, com gráfico inserido.

42  Java Magazine • Edição 38

 jm38.indb 42 17/7/2006 14:12:10


Edição 38 •  Java Magazine 43

 jm38.indb 43 17/7/2006 14:12:16


Interfaces Gráficas co
Parte 1: Conceitos e Técnicas Fundamentais, e a

O projeto de interfaces gráficas


eficazes exige mais do que co-
nhecimento sobre componentes
visuais ou outras questões relacionadas
à tecnologia. São detalhes mais humanos
sobre nossos olhos revelam detalhes que
complementam o significado das infor-
mações e auxiliam o usuário a entender
o conteúdo da imagem observada.
Este artigo apresenta a primeira parte
do a importância do projeto visual para
o desenvolvimento de GUIs (Graphic
User Interfaces; interfaces gráficas com
o usuário). Em seguida, abordaremos
erros comuns e técnicas de organização
que fazem a diferença, e que precisam de uma série voltada para a qualidade de interfaces. E veremos como utilizar
ser compreendidos antes mesmo de se das interfaces gráficas, apresentando a API JGoodies Forms para montar
digitar qualquer linha de código. Os técnicas fundamentais para um bom telas eficientes e com poucas linhas de
efeitos que cada elemento visual produz projeto visual. Começaremos analisan- código.

44  Java Magazine • Edição 38

 jm38.indb 44 17/7/2006 14:12:18


Saiba como projetar

m Qualidade interfaces gráficas


eficazes que facilitam a
vida dos usuários, e como
implementá-las utilizando a
API JGoodies Forms API Forms do JGoodies

HUGO VIDAL TEIXEIRA

Técnicas de
nosso estudo analisando alguns dos
principais erro s cometidos no projeto de
GUIs. Em seguida veremos técnicas de
organização de informações e de redução

projeto visual
de poluição gráfica, entre outras.

Erros comuns em interfaces gráficas


Uma técnica de aprendizado muito
eficiente é a analise de erros comuns

P or ser um conceito muito abstrato,


qualquer julgamento sobre a qua-
lidade de um software é difícil.
Embora existam normas e processos de
engenharia de software voltados para
apoio de designers e outros especial istas
em projeto visual. O resultado dessa de-
cisão freqüentemente são sistemas com
telas complexas e pouco intuitivas, que
às vezes confundem seus usuários por
cometidos no desenvolvimento de inter-
faces gráficas. Ilustraremos esta técnica
com um exemplo – veja a Figura 1 – que
resume alguns problemas que precisam
ser sempre evitados. Você dificilmente
esse propósito, a tendência de um usuá- refletirem diretamente as entidades de encontrará todos esses problemas juntos
rio é determinar a qua lidade de algo que negócio por trás do sistema (EJBs, tabelas na mesma tela de um sistema real, mas
não conhece baseando-se naquilo que etc.). Além disso, o desconheci mento de a freqüência com que cada um aparece
vê e sente. Assim, a interface gráfica de princípios de criação de interfaces ou a separadamente é bastante alta.
um sistema conta muito para uma boa simples vontade de embelezar muito a Vejamos os erros. Comece observando
impressão. tela podem resultar em interfaces pobres os componentes  JText Fiel d desalinhados
Vamos começar explorando algumas e excessivamente poluídas. na parte superior esquerda da tela. As
questões fundamentais que precisam A segunda questão que precisamos suas posições horizontais variam de
estar claras para qualquer equ ipe envol- destacar é a suposição incorreta de que acordo com o tamanho de cada  JLa bel .
vida na criação de GUIs. A importância o simples uso de componentes e APIs Esse problema de alinhar os  JLab el s, mas
dessas questões está relacionada ao papel (como os do Swing e do AWT) é suficien- não os componentes relacionados, torna
do projeto visual no desenvolvimento e o te para se alcan-
momento em que ele deve ser aplicado. çar os benefícios
Em primeiro lugar, o projeto visual n ão de uma boa apre-
é uma tarefa que pode ser deixada para sentação. A for-
depois. Este é um erro comum cometido ma com que essas
em muitos projetos e que ainda precisa peças são unidas
ser combatido. Para ser eficaz, o projeto é tão importan-
visual precisa estar bem integrado ao te quanto cada
ciclo de vida de desenvolvimento, per- peça individual.
mitindo que interfaces gráficas possam E é necessário ir
ser elaboradas e melhoradas conforme além; entender a
o entendimento do problema avança ao influência e efei-
longo do tempo. tos que diferen-
É comum vermos empresas que deixam tes composições
o projeto e a implementação de GUIs ape- causam numa
nas nas mãos de programadores sem ex- GUI.
periência na criação de interfaces, e sem Começaremos Figura 1. Tela de exemplo que ilustra um projeto visual com problemas.

Edição 38 •  Java Magazine 45

 jm38.indb 45 17/7/2006 14:12:20


Interfaces Gráficas com Qualidade

a leitura dos valores muito mais difícil sendo que um adicionou


do que poderia ser. o recurso e o outro, sem
Agora observe o grupo “Medidas” e notar a presença da borda,
repare como os  JTextF iel ds estão colados, deixou de segui r o mesmo
enquanto sobra muito espaço ao redor. estilo.
Observe ainda que a base dos textos Para terminar nossa aná-
dos  JLab el s não está alinhada com a base lise, note que o subgrupo
dos textos dos  JTextF iel ds, o que também “Comandos” não está ali-
atrapalha a leitura dos valores. nhado com o resto dos
Descendo mais o olho, percebemos componentes, e que não
que a parte inferior da tela está dentro ocupa toda a largura dis-
de uma borda interna e ainda contém ponível na tela, deixando
subgrupos com bordas e títulos. A borda de aproveitar um espaço
interna cria uma dimensão desnecessária valioso. Compare ainda Figura 2. Problemas de redimensionamento na tela de exemplo.
que polui mais do que real mente enfatiza o tamanho dos botões
aquela área. Já a borda dos subgrupos existentes, e verifique que não exi ste um “Editar” grande demais). Já o subgrupo
distrai os olhos e gera uma separação padrão consistente. “Comandos” permaneceu intacto e po-
visual pouco eficaz entre os elementos. deria ter aproveitado melhor o espaço,
A presença de bordas aninhadas normal- Cuidados com redimensionamento por conter um  JTe xt Ar ea . Além disso,
mente revela um projeto visual pobre. Algumas armadilhas ainda aguardam vários espaços vazios surgiram na tela,
Veremos como combater esse problema o desenvolvedor desatento. Um teste reduzindo o relacionamento visual entre
na seção “Redução de poluição grá fica”, que não podemos deixar de fazer no os componentes.
mais adiante. desenvolvimento de interfaces é obser-
Os problemas ainda não acabaram. var como a janela se comporta qua ndo é Técnicas de organização visual
Repare a repetição desnecessária da redimensionada. Agora que já vimos um pouco sobre
palavra “Controle” tanto no label da o que não   fazer em interfaces gráficas,
 JComb oBox  quanto no título do subgrupo. O teste de redimensionamento é importante podemos discutir alguns princípios ge-
Além disso, existem duas  JText Area s, uma em GUIs criadas com toolki ts como AWT, Swing rais para boa organização e estrutu ração
com borda 3D e outra não. É uma incon- e SWT, porque estes utilizam gerenciadores de visual. As técnicas que abordaremos
sistência comum normalmente causada layout que formatam e posicionam cada com- aqui estão divididas em três categorias:
(por exemplo) pelo fato de desenvolve-  ponen te, segui ndo r egras pr ópria s que não sã o Simetria e Balanceamento, Alinhamento
totalmente explicitadas pela GUI.
dores diferentes alterarem a mesma tela, e Relacionamentos Visuais, e Formatação
com Espaços Vazios.
A idéia, ao fazer o redimensionamen- É praticamente impossível conse-
to, é favorecer sempre aqueles compo- guir elaborar GUIs eficazes sem o uso
nentes que podem crescer sem deixar dessas técnicas. Para nossa sorte, são
a tela desproporcional, como  JTab le s, técnicas simples, e o domínio vem com
 JText Area s,  JTree s,  JLis ts etc. Caso uma ja- pouco tempo de prática. São princípios
nela não possua componentes deste tipo, que fazem parte de disciplinas como
podemos sempre pensar em proibir o design gráfico e ergonomia, além de
redimensionamento através do método serem apoiados pela área de psicologia
setResizable(false)  da classe cognitiva. Portanto, são muito valiosos
Frame. para causar uma boa impressão em
A F i g u r a 2   mostra qualquer trabalho, mesmo fora da área
esse problema com de software.
a janela do nosso
exemplo. Repare que  Simetria e b alanceamento
o subgrupo “Con- Simetria é uma propriedade que re-
trole” foi favorecido sulta da harmonia e equilíbrio de uma
sem necessidade (o estrutura. É muito importante por ser
que deixou o botão facilmente reconhecida e agradável aos

46  Java Magazine • Edição 38

 jm38.indb 46 17/7/2006 14:12:22


nossos olhos. Sempre que uma forma é tente igualar aspectos como quantidade tos visuais entre suas estrutura s sempre
repetida – seja por translação, rotação e espaço ocupado. que possível, e o alinhamento é u m passo
ou reflexão – cria-se uma nova imagem necessário a uma apresentação coerente.
simétrica que compartilha características  Alinhamento e relac ionamentos visuais Para estabelecer um bom alinhamento,
semelhantes. No mundo dos símbolos O alinhamento é o meio mais impor- considere as seguintes dicas:
visuais, as figuras mais memoráveis nor- tante de se estabelecer relacionamentos 1. Identifique as principais fronteiras
malmente são muito simétricas, como a entre elementos. Objetos alinhados da tela e procure um modo de organizar
estrela, a seta, a cruz e o yin-yang. criam uma forte atração entre si, mesmo seus elementos em alinhamento com
A simetria é u m fator importante quan- quando separados por longas distâncias. essas fronteiras.
do o objetivo do trabalho depende de Isso acontece porque nossos olhos têm 2. Procure por elementos e margens
 balanceame nto, ordem e simpl icidade. preferência natural por estruturas regu- (internas ou externas) que podem ser
Para elaborar um layout simétrico, algu- lares, onde regiões bem definidas podem alinhados pela alteração de seus tama-
mas dicas são importantes: ser facilmente identificadas. Por outro nhos ou posições.
1. Identificar os eixos pelos quais a simetria lado, elementos desalinhados produzem 3. Identifique elementos mais “soltos”
será estabelecida. Em interfaces gráficas, a tensão no observador, o que pode causar na tela e verifique se estão alinhados
simetria normalmente é vertical e hori- incômodo ou dúvida quanto às relações com alguma outra coisa, seja com uma
zontal. A simetria diagonal é mais rara, entre os elementos. margem principal, seja com algum outro
mas também é valida. Uma das vantagens em se alinhar ele- elemento associado a eles.
2.Posicionar a informação sobre o eixo mentos é a redução da complexidade d a 4. Se um elemento não está relacionado
de simetria através de um balanceamento tela, a qual se torna mais limpa e mais a nenhum outro na tela, tente posicio-
cuidadoso de cada lado. A informação não fácil de ser compreendida. Uma interface ná-lo de forma a balancear o espaço já
precisa formar um espel ho perfeito, mas eficaz precisa estabelecer relacionamen- ocupado.

Edição 38 •  Java Magazine 47

 jm38.indb 47 17/7/2006 14:12:26


Interfaces Gráficas com Qualidade

existirem fronteiras ção você sentiria? Se for “sentida” uma


 bem definidas). trepidação grande, sua tela provavelmen-
3. Identifique ele- te precisa ser revisada. Agora se forem
mentos que preci- percebidos apenas a lguns níveis, sua tela
sam de uma ênfa- provavelmente não e stá poluída.
se visual adicional É importante ressaltar que o objetivo
(como títulos). Au- dessa técnica é apenas identificar bordas
mente o espaçamento e linhas que o programador adicionou
entre esses elementos à interface sem necessidade. Como
e outros considerados primeiro exemplo, volte à Figura 1 e
críticos. veja como bordas inúteis se confundem
Formatação com espaços vazios com as bordas dos componentes. Temos
Quando projetamos telas para Embora o espaço va- outro exemplo ilustrado na Figura 3,
sistemas de informação, temos uma zio seja uma variável onde duas visões de um mesmo painel
tendência natural de tentar incluir poderosa em ter- são apresentadas. Repare que a substi-
o máximo de informações possíveis mos de percepção, tuição das bordas com título por  JLab el s
para o usuário. Essa busca por uti- ele é também o reduziu a poluição do painel e resultou
lizar cada pixel disponível resulta mais custoso, em uma tela mais simples e clara para
normalmente em telas saturadas e utilizando o o usuário.
com muita poluição visual. É daí que pouco espaço Lembre-se que as bordas naturais dos
vem a importância de se utilizar es- que dispomos componentes são as poucas que devem
paços vazios na organização da infor- para mostrar as predominar na tela, já que trazem infor-
mação, direcionando os olhos do usuário informações. As- mações úteis ao usuário. Portanto, não se
para certas regiões da tela e permitindo sim, a técnica deve ser usada sem incomode com elas.
que cada pedaço de informação seja exageros. Outra questão são os novos e modernos
corretamente destacado. look-and-feels que simulam interfaces
Espaços vazios na tela não significam Redução de poluição gráfica arredondadas e com componentes bri-
desperdício, mas sim um elemento po- Existem algumas técnicas de identifi- lhantes. Visuais como o da Figura 4, por
deroso para guiar a atenção do obser- cação e remoção de poluição visual que exemplo, produziriam uma sensação de
vador. Essa técnica é uma da s melhores precisam estar na ponta da língua de “ondulação” nas unhas que poderia atra-
soluções para evitar o uso de bordas e quem desenvolve interfaces gráficas. palhar essa técn ica. Nesses casos, não se
linhas que delimitam áreas da tela. As Uma delas, e na minha opinião, uma das preocupe com essas ondulações; preste
seguintes dicas ajudarão você a encon- mais divertidas, é a chamada técnica das atenção somente nas bordas e linhas que
trar os melhores lugares para aplicar unhas na tela. Como todos já percebemos, o programador possivelmente colocou
essa técnica: toolkits Java como Swing e AWT, e os de em excesso. Isso não consegue passar
1. Agrupe as informações em con- outras linguagens, desenham seus com- despercebido mesmo quando usamos
 ju nt os de ta ma n ho s gerenc iáve i s ponentes utilizando cores que simulam um look-and-feel bem projetado, como
(ex.: no máximo sete elementos) e um pseudo-3D dando a sensação de mostrado na Figura 4 : veja o excesso de
defina suas prioridades de acordo profundidade.  bordas causadas pelo ani nhamento de
com a importância da informação É exatamente essa sensação de 3D que componentes  JTabbe dPan e.
para o usuário. exploramos nessa técnica. Imagine que Na próxima seção, mostraremos como
2. Garanta uma separação entre os con- você fosse capaz de sentir os relevos 3D implementar interfaces gráficas lançan-
 juntos de informação através da adição e passasse suas unhas sobre a tela em um do mão dos princípios e técnicas apre-
de espaço vazio entre eles (mesmo se já movimento contínuo, qual grau de vibra- sentadas até aqui.

Figura 3. Excesso de bordas no painel à esquerda em contraste com a simplicidade do painel à direita.

48  Java Magazine • Edição 38

 jm38.indb 48 17/7/2006 14:12:30


Implementação
organiza e oferece uma maneira consistente de
trabalhar com diferentes tipos de elementos inter-
relacionados.

O FormLayout revela-se como uma solução

com JGoodies vantajosa por ser simples e intuitivo, e ade-


quado para a codificação direta sem o uso
de editores visuais de interfaces. Você verá
a partir de agora que o código exigido para
a montagem de uma tela normalmente é

U ma das soluções open source mais


interessantes para quem traba-
lha com Java no desktop é, sem
dúvida, o conjunto de APIs do JGoodies.
Consulte o quadro “O que é JGoodies?”,
para executar os exemplos.

Começando com o FormLayout 


A classe central da API Forms é FormLayout ,
um gerenciador de layout que divide a tela
 bem curto e de fácil leitura, o que aumenta
a produtividade do desenvolvedor.

Usando o FormLayout 
Para a criação de uma instância de
ao final desta seção, para conhecer melhor em linhas e colunas flexíveis. Assim como FormLayout , passamos no construtor duas
essa iniciativa. Veremos agora como utilizar a classe GridBagLayout do Java SE, o FormLayout strings que definem, respectivamente, as
a API JGoodies Forms para implementar alinha componentes às células da grade colunas e as linhas que formam a grade da
interfaces eficazes em Java. Nosso objetivo retangular que forma a tela, permitindo tela sendo projetada. O JGoodies Forms de-
principal será reconstruir a tela inicial que cada componente ocupe uma ou mais fine uma linguagem simples para montar
apresentada nas Figuras 1 e 2 (onde muitos células. essas strings e especificar cada linha e co-
erros foram encontrados) seguindo as técni- luna. Uma vantagem é que toda a estrutura
cas de projeto visual apresentadas.   Uma das mais importantes vantagens do do painel está centralizada nessas duas
FormLayout é o uso da grade para dividir o espaço strings, o que facilita a sua compreensão
Preparação da tela. De fato, essa é a principal técnica utilizada e rápida modificação. Em outros geren-
A obtenção e instalação da API Forms  pelos designers profissionais. Uma grade alinha, ciadores, a estrutura normalmente fica
são bastante simples: navegue até o site espalhada, exigi ndo que o desenvolvedor
do JGoodies ( jgoodies.com), vá até a seção leia partes extensas do código de GUI para
Downloads e clique em Libraries. Lá você entender a estrutura sendo definida.
terá acesso aos arquivos zipados de todas Nosso primeiro exemplo é o painel
as APIs, os quais contêm exemplos, docu- ilustrado na Figura 5. Para criá-lo utili-
mentação, código-fonte e o JAR que deve zando o FormLayout, esboçamos a tela em
ser incluído no classpath da sua aplicação papel e identificamos as linhas e colunas
que formam a sua estrutura. Observe a
Listagem 1. Método para criar o painel do exemplo da Figura 5 com o FormLayout. Figura 6 e veja como o painel foi proje-
private static Component montaPainelExemplo() {
tado. Repare que existem nove colunas.
FormLayout layout = new FormLayout( As colunas 1, 3, 7 e 9 determinam que a
“right:pref, 3dlu, pref, 3dlu, 15dlu, 10dlu, right:pref, 3dlu, pref”, // colunas
“pref, 3dlu, pref, 3dlu, pref”); // linhas largura seja a largura preferida dos com-
layout.setColumnGroups(new int[][] { {1, 7}, {3, 9} });
ponentes inseridos em seu interior (no
caso,  JLabels ou  JTextFields /  JComboBoxes).
JPanel panel = new JPanel(layout);
As colunas 1 e 7 exigem ainda que seus
CellConstraints cc = new CellConstraints();
panel.add(new JLabel(“Nome:”), cc.xy (1, 1));
componentes estejam alinhados à direita.
panel.add(new JTextField(), cc.xyw(3, 1, 7)); Note que a contagem das linhas e colunas
panel.add(new JLabel(“CPF:”), cc.xy (1, 3));
panel.add(new JTextField(10), cc.xy (3, 3)); começa em 1.
panel.add(new JLabel(“Categoria:”), cc.xy (1, 5)); As colunas 2, 4 e 8 formam um espa-
panel.add(new JComboBox(), cc.xy (3, 5));
panel.add(new JButton(“...”), cc.xy (5, 5)); çamento de proporção fixada em 3dlu
panel.add(new JLabel(“Telefone:”), cc.xy (7, 3));
panel.add(new JTextField(), cc.xy(9, 3));
(dialog units). Essa unidade estabelece um
panel.add(new JLabel(“Telefone(Fax):”), cc.xy (7, 5)); tamanho que é independente de pixels e
panel.add(new JTextField(), cc.xy(9, 5));
return panel; é calculado levando em conta o taman ho
} das fontes (definido pelo look-and-feel) e
a resolução da tela. Dessa forma, podemos

Edição 38 •  Java Magazine 49

 jm38.indb 49 17/7/2006 14:12:31


Interfaces Gráficas com Qualidade

mudar essas características, e as propor- instanciar nosso gerenciador de


ções serão sempre mantidas. layout:
Da mesma forma, a coluna 6, que divide FormLayout layout = new FormLayout(
a tela ao meio, possui a largura fixada em “right: pref, 3dlu, pref, 3dlu, 15dlu, 10dlu, right:
10dlu. Poderíamos ter inserido uma l inha pref, 3dlu, pref”, // colunas
“pref, 3dlu, pref, 3dlu, pref” ); // linhas
para separar os dois grupos inferiores,
mas lembre-se que usar espaços vazios é
sempre melhor. Por fim, a coluna 5 ficará Para manter uma boa sime-
com a largura fixa de 15dlu para o único tria no painel, podemos utilizar
 botão nela inserido. o recurso de agrupamento de
As linhas da grade seguem o mesmo estilo linhas e colunas, que garante Figura 4. Bordas aninhadas em um projeto com look-and-feel moderno.
das colunas. Assim, as linhas 1, 3 e 5 ficam tamanhos iguais para conjuntos
com a altura preferida dos componentes, definidos através dos métodos
enquanto as linhas 2 e 4 são fixadas em setColumnGroups() e setRowGroups() .
3dlu. Com essas informações, já podemos No nosso caso, é interessante
Figura 5. Exemplo simples de um painel para ilustrar o FormLayout .

Tipo de especificação Valores Exemplos

fill ou f : preencher com o conteúdo (default). “fill:30dlu” – coluna de 30dlus de largura, onde os componentes são
Alinhamento de left ou l : alinhado à esquerda. esticados para ocupar toda a largura.
Colunas center ou c : centralizado. “right:pref ” – coluna onde os componentes ficam alinhados à direita, e
Right ou r : alinhado à direita. sua largura é a largura preferida dos componentes.

center ou c : centralizado (default). “top:100px” – linha de 100 pixels de altura, onde todos os componen-
top ou t : alinhado ao topo. tes estão alinhados na parte de cima (topo).
Alinhamento de Linhas
bottom ou b : alinhado ao chão. “fill:3cm” – linha de 3 cm de altura, onde os componentes ocupam todo
fill ou f : preencher com o conteúdo. o espaço vertical.

Inteiro + Unidade
“10px ” – linha/coluna com 10 pixels de altura/largura.
Onde Unidade pode ser: px ( pixel ), pt ( point ) ou dlu
“36pt” – linha/coluna com 36 pontos de altura/largura (36 pontos = ½
(dialog unit ). (Obs.: 1 pt   = 1/72 polegada)
Tamanho Constante polegada).
– ou –
“0.33cm” – linha/coluna com 0.33 cm de altura/largura.
Double + Unidade
“0.15in” – linha/coluna com 0.15 polegadas de altura/largura.
Onde Unidade pode ser: in ( polegada ), mm ou cm .

min  ou m : tamanho mínimo.


Tamanho de “min ” – linha/coluna com a altura/largura mínima dos componentes.
pref  ou p : tamanho preferido.
Componente “pref ” – linha/coluna com a altura/largura preferida dos componentes.
default ou d : tamanho default.

min(constante ; componente ) : assume o tamanho menor “min(30dlu;p)” – linha/coluna cuja altura/largura assume o menor  valor
entre os valores. entre 30dlu e a altura/largura dos componentes.
Tamanho Limitado
max(constante ; componente ) : assume o tamanho maior “max(0.5cm;p)’ – linha/coluna cuja altura/largura assume o maior   valor
entre os valores. entre 0.5cm e a altura/largura dos componentes.

none : nenhum (default).


grow: cresce conforme o painel cresce.
“pref:grow” – linha/coluna que cresce na mesma proporção do cresci-
grow( double) ou g( double) : cresce seguindo a proporção
mento do painel.
Redimensionamento passada como parâmetro. Essa definição só faz sentido
“p:g(0.5) ” – linha/coluna que cresce com a metade da proporção do
quando existem mais linhas/colunas que crescem no mes-
crescimento do painel.
mo painel. Assim, podemos definir aquelas que crescem
mais do que as outras.

Tabela 1. Valores para especificação de uma lin ha ou coluna.

50  Java Magazine • Edição 38

 jm38.indb 50 17/7/2006 14:12:32


manter as colunas 1 e 7, assim como 3 e 9, com CellConstraints cc = new CellConstraints();
panel.add(new JLabel(“Nome:”), cc.xy (1, 1)); Especificação = [Alinhamento :] Tamanho [ : Redimensionamento]
a mesma largura (lembre-se que a simetria é
importante). Portanto, podemos definir: Além de xy(), existe o método xyw(), usado Os termos entre colchetes são opcionais,
layout.setColumnGroups(new int[][] { {1, 7}, {3, 9} });
para posicionar um componente que se es- e os valores que podem ser usados para
tende por várias colunas. Assim, podemos definir a estrutura da tela são detalhados
Agora só falta adicionar os componentes adicionar o primeiro JTextField do exemplo, e exemplificados na Tabela 1.
ao painel. Para isso, precisamos utili- da seguinte forma: Aqui estão mais exemplos de especifica-
zar uma classe chamada CellConstraints, ções de colunas:
para posicionar os componentes na // Adiciona o componente na coluna 3, linha 1, • "left:pref:grow” – coluna alinha-
// e ocupa a largura de 7 colunas
grade. Essa classe possui o método panel.add(new JTextField(), cc.xyw(3, 1, 7)); da à esquerda, cuja largura é a largura
xy(int coluna, int linha)  que posiciona um com- preferida dos componentes, e que cresce
ponente em uma determinada célula. O resto do código deste exemplo simples conforme o crescimento do painel.
Assim, para adicionar o primeiro  JLabel ao está na Listagem 1. Agora vamos estudar um • "r:min(20dlu;p)” – coluna alinhada
nosso exemplo, fazemos: pouco mais a linguagem de especificação de à direita, cuja largura é o menor valor
linhas e colunas do JGoodies, e refa- entre 20dlu e a largura preferida dos
zer o exemplo inicial do artigo. componentes.

Especificando Linhas e Colunas E aqui estão mais alguns exemplos


A especificação de uma linha para linhas:
ou coluna do FormLayout sempre • " b:pref:grow” – linha alinhada
segue este formato: à parte de baixo, cuja altura é a altura
Figura 6. Projeto das linhas e colunas do painel de exemplo.
preferida dos componentes, e que cresce
conforme o crescimento do painel.
• "c:d:g(0.8) ” – linha centralizada,
cuja altura é o tamanho default dos com-
ponentes, e que cresce a uma taxa de 80 %
do crescimento do painel.
• "fill:max(25mm;min)” – linha onde os
componentes preenchem todo o espaço verti-
cal, e sua largura vale o maior valor entre 25
mm e a altura mínima dos componentes.

Figura 7. Esboços de layouts para o exemplo. Reconstrução do exemplo inicial 


Agora que já vimos o básico sobre o
FormLayout, vamos reprojetar o exemplo
inicial usando esse gerenciador de layout,
e também demonstrar outros pequenos
detalhes ainda não mencionados sobre a
API JGoodies Forms.
O primeiro passo na reconstrução de
uma interface é identificar como os ele-
mentos serão posicionados. Para isso, é
recomendado que a equipe se afaste do
computador e trabalhe um pouco com
papel e caneta. Utilizar o computador para
essa tarefa frequentemente atrapalha mais
a criatividade do que realmente ajuda a
desenvolver um bom projeto visual.
O segundo passo é identificar e especi-
ficar as linhas e colunas da grade onde
serão inseridos os componentes, buscando
Figura 8. Planilha usada para identificar a nova estrutura do painel. alinhar e balancear a estrutura. Fazer

Edição 38 •  Java Magazine 51

 jm38.indb 51 17/7/2006 14:12:36


Interfaces Gráficas com Qualidade

isso para telas complexas com lápis e o arquivo da planilha como documenta- dies Forms chamada DefaultFormBuilder ,
papel tende a ser um pouco trabalhoso, ção para a equipe. A Figura 8 apresenta a que apresenta algumas funcionalidades
portanto você pode talvez preferir voltar planilha criada para o exemplo. vantajosas como, por exemplo, o suporte
ao computador neste ponto. Uma opção é A identificação das linhas e colunas a separadores com títulos, depuração e
utilizar uma planilha eletrônica e colorir  já é suficiente para iniciar a codificação internacionalização. A implementação com
as células onde ficam os componentes. da interface. Construiremos o painel essa classe não é muito diferente da vista
Essa estratégia tem a vantagem de deixar utilizando uma classe utilitária do JGoo- até aqui:

Listagem 2. Classe que recria o painel do exemplo inicial, agora utilizando a API Forms do JGoodies.

public class JanelaBomExemplo { builder.add(new JComboBox(new String[]


public static void main(String[] args) { {“Automático”}), cc.xyw(2, 11, 3));
try { builder.add(new JButton(“Editar...”), cc.xy(6, 11));
  UIManager.setLookAndFeel(
  PlasticXPLookAndFeel.class.getName()); builder.addSeparator(“Medidas”, cc.xyw(1, 13, 6));
} catch (Exception e) { ... } builder.add(new JLabel(“Altura:”), cc.xy(2, 15));
builder.add(new JTextField(6), cc.xy(4, 15));
JFrame frame = new JFrame(“Bom Exemplo”); builder.add(new JLabel(“m”), cc.xy(6, 15));
  frame.getContentPane().add(montaPainel()); builder.add(new JLabel(“Comprimento:”), cc.xy(2, 17));
  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); builder.add(new JTextField(6), cc.xy(4, 17));
  frame.setLocationRelativeTo(null); builder.add(new JLabel(“m”), cc.xy(6, 17));
  frame.pack(); builder.add(new JLabel(“Largura:”), cc.xy(2, 19));
  frame.setVisible(true); builder.add(new JTextField(6), cc.xy(4, 19));
} builder.add(new JLabel(“m”), cc.xy(6, 19));
builder.add(new JLabel(“Peso:”), cc.xy(2, 21));
private static Component montaPainel() { builder.add(new JTextField(6), cc.xy(4, 21));
FormLayout layout = new FormLayout( builder.add(new JLabel(“kg”), cc.xy(6, 21));
// colunas
“10dlu, right:p, 3dlu, p, 3dlu, min, 10dlu, p:grow”, builder.addSeparator(“Descrição”, cc.xy(8, 1));
// linhas builder.add(new JScrollPane(
“p, 3dlu, p, 3dlu, p, 3dlu, p, 7dlu, p, 3dlu, p, 7dlu, p, new JTextArea(2, 21)), cc.xywh(8, 3, 1, 7));
3dlu, p, 3dlu, p, 3dlu, p, 3dlu, p, 7dlu, p”);
builder.addSeparator(“Comandos”, cc.xy(8, 13));
CellConstraints cc = new CellConstraints(); builder.add(new JScrollPane(
new JTextArea(2, 21)), cc.xywh(8, 15, 1, 7));
DefaultFormBuilder builder = new DefaultFormBuilder(layout);
  builder.setDefaultDialogBorder(); builder.add(montaBarraBotao(), cc.xyw(1, 23, 8));

builder.addSeparator(“Valores”, cc.xyw(1, 1, 6)); return builder.getPanel();


builder.add(new JLabel(“Primeiro Valor:”), cc.xy(2, 3)); }
builder.add(new JTextField(15), cc.xyw(4, 3, 3));
builder.add(new JLabel(“Outro Valor:”), cc.xy(2, 5)); private static Component montaBarraBotao() {
builder.add(new JTextField(15), cc.xyw(4, 5, 3)); JButton btnOK = new JButton(“OK”);
builder.add(new JLabel(“Label Comprida:”), cc.xy(2, 7)); JButton btnCancelar = new JButton(“Cancelar”);
builder.add(new JTextField(15), cc.xyw(4, 7, 3)); return ButtonBarFactory.buildCenteredBar(btnOK, btnCancelar);
}
builder.addSeparator(“Controle”, cc.xyw(1, 9, 6)); }

Figura 9. Tela de exemplo reconstruída com a API Forms. Figura 10.Tela do exemplo, em modo de depuração, mostrando a definição da grade.

52  Java Magazine • Edição 38

 jm38.indb 52 17/7/2006 14:12:36


Conclusões
O que é JGoodies? Apresentamos nesse primeiro artigo um
conjunto básico de técnicas fundamentais
J Goodies é uma empresa alemã que
oferece, dentre outras coisas, um
conjunto de APIs open source voltadas
pelo W3C, porém utilizando Java para des-
crever as animações (ao invés de XML).
• Binding : Framework para conectar os
para o projeto visual de i nterfaces gráficas,
incluindo um exemplo prático com a API
para o desenvolvimento de interfaces componentes de interface com as classes Forms do JGoodies. É importante lembrar
gráficas desktop de alta qualidade. de modelo da aplicação. A idéia é reduzir que bons projetos visuais não vêm natu-
As APIs do JGoodies são baseadas em o código de apresentação e permiti r uma ralmente nem dependem de APIs gráficas,
Swing e são subdivididas em cinco melhor separação de camadas. como Swing ou SWT. Existe uma série de
projetos: • Validation : Suporte flexível para princípios que se deve aplicar corretamen-
• Forms : Suporte para a criação de validação de campos e formulários, que te para que o resultado seja satisfatório. A
formulários precisos e elegantes de forma permite diferentes tipos de técnicas e estrada que leva à alta qualidade de GUIs é
simples, rápida e consistente. indicações de erros. longa, mas com os princípios introduzidos
• Looks : Uma série de Look-and-Feels aqui já é possível iniciar essa jornada.
permitindo fornecer novos visuais às suas Cada API está disponível para downlo-
aplicações. ad no site do JGoodies na forma de um Designing Visual Interfaces:
• Animation: Classes para criar anima- arquivo zipado que contém o código- CommunicationOriented Techniques
ções com diferentes recursos e estilos. fonte, a documentação e arquivos JAR. Kevin Mullet & Darrell Sano, Prentice Hall PTR,
Essa API utiliza conceitos definidos pela Inicialmente essas APIs não eram open 1994
especificação SMIL (Synchronized Mul- source, mas agora estão disponíveis sob Um dos livros mais completos sobre projeto de
timedia Integration Language) definida a licença BSD. interfaces gráficas que explora diferentes técnicas e
examina tipos variados de problemas encontrados em
sistemas reais.
DefaultFormBuilder builder = mostra a Figura 10. Para ver as linhas
newDefaultFormBuilder(layout);
builder.setDefaultDialogBorder(); e colunas indicadas em vermelho du-  jgoodies.com
builder.addSeparator(“Valores”,cc.xyw(1,1, 6)); rante a execução do programa, basta Site do JGoodies com tutoriais, artigos,
builder.add(new JLabel(“Primeiro Valor:”), cc.xy(2, 3));
passar como segundo parâmetro do aplicações e APIs para download.
Repare na chamada ao método seu construtor uma instância da classe www.sum-it.nl/enguilin.html 
setDefaultDialogBorder(), que serve para FormDebugPanel: Links sobre projeto visual de interfaces gráficas.
criar uma borda vazia em torno do pai-
nel, evitando que este fique colado aos DefaultFormBuilder builder = www.rspa.com/spi/design-interface.html 
new DefaultFormBuilder(layout, new FormDebugPanel()); Site com informações sobre interfaces gráficas
limites da janela. Além disso, o método
mantido por Roger Pressman, famoso especialista
addSeparator()   cria um separador com Concluindo, observe o método
em Engenharia de Software.
um título, ajudando na identificação montaBarraBotao() ,
ainda na Listagem 2,
visual dos grupos, mas sem criar linhas que retorna um painel contendo os  javamagazine.com.br/downloads/jm38/
desnecessárias. dois botões, “OK” e “Cancelar”. Ele  jm-guisqualidade-p1.zip
O código completo desta implemen- utiliza o método buildCenteredBar() da
tação pode ser visto na Listagem 2. A classe ButtonBarFactory   que, além de Hugo Vidal Teixeira
([email protected] ) é Bacharel
tela recriada está ilustrada na Figura 9 e criar os botões com o mesmo tamanho, em Informática pela UFRJ,mestre
utiliza o Look and Feel Plastic XP da API os centraliza e mantém uma distância em Engenharia de Software pela
 JGoodies Looks (veja o quadro “O que é padronizada de separação. Por fim, esse COPPE/UFRJ e pesquisador da área de
 JGoodies?”). Um recurso interessante da painel é adicionado à última linha do componentes e GUI Design.Atualmente
classe DefaultFormBuilder é a possibilidade nosso layout, ocupando a largura de trabalha como consultor integrado à Sakonnet Technology,
de depurar os painéis criados, como todas as colunas. onde trabalha diretamente com Karsten Lentzsch (criador
do JGoodies) e empresas especializadas em GUI design,
como Ergosign(.de),Centigrade(.de) e OculusInfo(.com).

Edição 38 •  Java Magazine 53

 jm38.indb 53 17/7/2006 14:12:40


Complete
a sua     1
   o
   S  G
   E
   T  A
  O
  A
   D

    2
   o
   S  G
   E
  A
   D
   T  A
  O

    3
   o

coleção!
    ã     ã     ã
   ç    ç    ç
    i     i     i
    d     d     d
    E     E     E

- Ferramentas livres - Multimídia no celular - Dados em J2ME


- Introdução ao J2EE 1.4 - Automação com Ant - JavaServer Faces
- Introdução a J2ME - Robocode - Jogos wireless
- J2EE Fundamental - Tag Libraries JSP - Certificação J2EE
- Dados com JDBC - Processando XML em Java - Montando um ambiente Java

  A
   D
   T  A
  O
   S  G
   E     3
    0     1     2
    9     1     1     1     1
   o    o    o    o    o
    ã     ã     ã     ã     ã
   ç    ç    ç    ç    ç
    i     i     i     i     i
    d     d     d     d     d
    E     E     E     E     E

- Java no Governo - Códigos no Eclipse - Tutorial de NetBeans - Eclipse para Web - Relatórios Corporativos
- Apache FOP - New I/O Fundamental - API New I/O (java.nio) - Fome Zero com Java - Gráficos com Java 2D
- JSTL – Guia Completo - Game API - Cesta de compras com Struts - Tags Customizadas em JSP 2.0 - Java.net na Prática
- Cocoon Inicial - Criando Plug-ins para Eclipse - Testes de carga com JMeter - Tiger: A Evolução do Java - Raio-X do Tiger
- Pacotes WAR e JAR - Preferences API - Concorrência e a JVM - Dicas para Web - Paginação na Web

    


    

    


  

  
    

  
  






    


 
    9
    1
   o
    ã
   ç
    0
    2
   o
    ã
    1
    2
   o 
    ã 
   ç 
    2
    2
   o
    ã
   ç
    3
    2
   o
    ã
   ç
    i    ç     i          i     i
    d     i     d

 

     d     d
    E     d     E     E     E
    E

- JSTL aplicado no Tomcat 5 - Relatórios avançados - Criptografia aplicada - O Projeto Eclipse


- Threads no Java 5.0
- Modularizando páginas com Tiles - Mais design patterns - XML de alto desempenho - Segurança no JBoss
- Cadastros com Struts
- Componentes View do Struts - Gerenciamento com JMX - Segurança em apllicações web - JSF Avançado
- MVC na web
- O rugido do Java livre - Java Web Start - JSF Passo a Passo - Começando com Java
- Servlet API Avançada
- Padrões de projeto - Dúvidas de classpath - Datas e Horas em Java - Tira-dúvidas

    9     0     1     2     3


    2     3     3     3     3
   o    o    o    o    o
    ã     ã     ã     ã     ã
   ç    ç    ç    ç    ç
    i     i     i     i     i
    d     d     d     d     d
    E     E     E     E     E

- JavaMail - HSQLDB - SWT no Eclipse - NetBeans 5.0 - Hibernate em aplicações web


- Por Dentro do Apache Derby - Internacionalização de MIDlets - Eclipse Web Tools Project - Aprendendo Groovy - Java 6 (Mustang)
- Clusters com Tomcat e Apache - Performance na JVM - Validação avançada com Struts - Test-Driven Development - Programação em par
- Mais HttpClient - Caso de sucesso: Procon - Fronteiras do Java - Debate Internacional Sou+Java - Processos ágeis
- Examinando o Mustang - Benchmarks JME - CD do NetBeans - Java Business Integration (parte 1) - Java Business Integration (parte 2)

www.javamagazine.com.br devmedia.com
 jm38.indb i 54 i l i 17/7/2006 14:12:50
  A   A   A
   D    D    D
   T  A    T  A    T  A
  O   O   O
   S  G
   E    S  G
   E    S  G
   E
    4     5     6     7     8
   o    o    o    o    o
    ã     ã     ã     ã     ã
   ç    ç    ç    ç    ç
    i     i     i     i     i
    d     d     d     d     d
    E     E     E     E     E

- Eclipse inicial - JBoss Inicial - Introdução ao Tomcat - Bancos de dados livres - JavaOne 2003
- O mercado J2ME - Introdução ao JMX - Conectivade com MIDP - Testes unitários com JUnit - Conhecendo o CVS
- Segurança em aplicações web - Java no Lego Mindstorms - Struts, primeiros passos - JSTL- Guia Completo: tags Core - JSTL- Guia completo SQL e Format
- Interfaces ricas com Flash - Logging - Automação com XDoclet - Java na Droga Raia - Tomcat e o Servidor Apache
- Expressões regulares no J2SE 1.4 - Memória e desempenho - Jakarta Velocity - Validação na Web

  A
   D
   T  A
  O
   S  G
   E
    4     5     6     7     8
    1     1     1     1     1
   o    o    o    o    o
    ã     ã     ã     ã     ã
   ç    ç    ç    ç    ç
    i     i     i     i     i
    d     d     d     d     d
    E     E     E     E     E

- Genéricos no Tiger - SwingWT - JSP 2 e Servlets no Tomcat 5


- Formulários com Swing - Otimização de EJBs no JBoss
- JBuilder para web - Java 2D: Animação e impressão - Primeiros passos com wireless
- ANT - Automatizando Java - Processamento de imagens
- MIDP 2.0 - Anotações no Java 5 - Collections avançado
- JBoss e Entity Beans - Programação com regras
- JavaOne 2004 - Projeto Looking Glass - Conhecendo o JDeveloper 10g
- Extreme Programming - Jakarta Taglibs
- Segurança com JAAS - Java 2D: Animações e Impressão - Servlets: do básico ao avançado
- Metaprogramação e Reflection - Case J2ME

                     
           
        Java 5 Impressão  Java Content Repository Caches e JDBC NetBeans  JavaOne
• • • • •

      
  Imprimindo com Java
       
  ConheçaduasAPIsde impressãodo
 J2SEeobtenha controlefino
sobrelayoute formatação
 
  
   Gerência deConteúdo
   
Edição24-AnoIII-R$9,90
Detalhessobrea NovíssimaAPI
 JCRea CriaçãodeRepositórios
   deConteúdona Web
  
 
Uma Aplicação Java Tira-DúvidasEspecial
 CacheseDAOscom JDBC,Usando
  Completa com NetBeans
       Partefinal–AcessoaBanco
 JVMsAlternativas,Relatóriose
DriblandoRestrições
      deDadoseGerênciade
   daMáquina
PreferênciasdeUsuários


 Java:

  Futuro
Presente

    4
    5     6     7
&     8
    2
    2     2     2  JavaOne 2005     2
   o Grandesnovidadesem
    ã    o    o    o produtoseAPIs,planos e Migrando para o Java 5    o
   ç             ã     ã     ã comemoraçõesnoevento Conheça na prática eem detalhes     ã
    i            ç    ç    ç mundialda tecnologia Java como,porqueequando fazero    ç
    i     i     i     i
    d           upgradepara o J2SE 5.0
    E     d     d     d     d
    E     E     E     E

- Novo NetBeans - Aplicação Completa - Parte 1 - Aplicação Completa - Parte 2 - Aplicação Completa - Parte 3 - Hibernate Fundamental
- Máquinas virtuais alternativas - Desempenho com JDBC e DAOs - Mais Desempenho com JDBC - Migrando para o Java 5 - Apache Geronimo na Web
- Gráficos com JFreeChart - Portlets - Fundamentos - Portlets - Recursos Avançados - Impress ão com Java - Ajax: Interatividade Turbinada
- SuperWaba Inicial - JFreeChart Avançado - Jakarta Commons Inicial - Gerenciamento de Conteúdo - Tutorial de Genéricos
- Tag Files do JSP 2.0 - O Novo Extreme Programming - Números: Conceitos e Formatação - JavaOne 2005 - De Volta aos Patterns

    4
    3
    5
    3
    6
    3
    7
    3
Leia uma vez,
   o
    ã
   ç
    i
   o
    ã
   ç
    i
   o
    ã
   ç
    i
   o
    ã
   ç
    i
use em todos
    d
    E
    d
    E
    d
    E
    d
    E os lugares
- Para onde vai o Struts - Frameworks de Logging - Conhecendo o Ant - Criação de Plug-ins
- Teste com J2MEUnit - Otimização de Código - Acessando Código Nativo - Os 10 Mais do Eclipse 3.2
- Web Services - Ajuda com JavaHelp - Qualidade Aplicada - JavaOne 2006
- Scripting na JVM - Maven 2 Essencial - Migrando para o Maven 2 - Relatórios Passo a Passo
- Aspectos no Mundo Real - Java ME no Eclipse - Logging no Java SE - Testes com mock objects

.br/anteriores 21 2283 9012


 jm38.indb 55 17/7/2006 14:12:52
O Eclipse Callisto
A maneira fácil de instalar os principais plug

N o final de junho foi finalmente


liberado um dos lançamentos
mais aguardados do ano, o
Eclipse Call isto, que reúne 10 dos projetos
mais importantes da Fundação Eclipse:
• Eclipse Test and Performance Tools
Platform Project (TPTP)
• Eclipse Web Tools Platform Project
(WTP)
• Visual Editor (VE)
atualizações gerada por cada projeto indi-
vidual no passado – por exemplo, hoje sai
um novo Eclipse SDK, algumas semanas
depois um novo EMF, apenas depois disso
um novo WTP, e daí em diante.
• Business Intelligence and Reporting O propósito do Callisto é facilitar a vida
Tools (BIRT) O projeto Callisto, destacado no artigo de dois tipos de usuários, ao oferecer
• C/C++ IDE (CDT) sobre o Eclipse 3.2 na edição passada, foi uma plataforma unificada com releases
• Data Tools Platform (DTP) iniciado no começo de 2006 com o ambi- simultâneos de componentes-chave dos
• Eclipse Modeling Framework (EMF) cioso objetivo de liberar simultaneamente 10 projetos citados:
• Graphical Editi ng Framework (GEF) e as novas versões de vários dos principais • Desenvolvedores individuais que
Graphical Modeling Framework (GMF) projetos da Fundação Eclipse. Dessa for- usam o Eclipse como ambiente de desen-
• Eclipse Project: Eclipse Platform, ma, os novos recursos ficam disponíveis volvimento de aplicações;
 Java Development Tools (JDT) e Plug-in para uso imediato pelos interessados, em • Integradores que constroem produ-
Development Environment (PDE) vez de terem que esperar pela cascata de tos baseados nos projetos da Fundação
Eclipse

Como diz o próprio site do Callisto


(eclipse.org/callisto), os projetos não foram

56  Java Magazine • Edição 38

 jm38.indb 56 17/7/2006 14:13:07


Aprenda como instalar o
Callisto, que fornece um
conjunto integrado de plug-ins
Eclipse para desenvolvimento
Web, Visual, Relatórios e
Modelagem
-ins do Eclipse
FERNANDO LOZANO

detalhes de acompanhamento e gerencia-


mento dos projetos i ndividuais.

Instalação do Callisto
Curiosamente, o Callisto não fornece
uma página de downloads e nem um ins-
talador integrado, o que o torna bastante
diferente de “distribuições” do Eclipse
como o Yoxos ( yoxos.com ).
Para se obter o Callisto, é necessário
 baixar e instalar manualmente o Eclipse
Platform Runtime 3.2 (ou então o Ecl ipse
SDK 3.2) para a sua plataforma específica.
Depois deve-se abrir o Update Manager
da plataforma ( Hel p|Soft war e Upd ate s
>Find and Install), conforme mostra a
Figura 1. O próximo passo é escolher a
opção Search for new features to install, e na
página seguinte do assistente selecionar
Callisto Discovery Site.
Figura 1. Como chegar ao site de download do Calli sto.
Antes de receber a relação de features
que podem ser instaladas pelo Callisto,
de se deixar de acom- o usuário recebe a opção de selecionar
panhar cada projeto um espelho ( mirror) para o download
individualmente e uti- dos arquivos. Há uma grande quantidade
lizar apenas as últimas de espelhos ao redor do mundo (veja a
versões disponibili- Figura 2), mas nenhum ainda no Brasil.
zadas como parte do O site principal tende a estar saturado,
Callisto. especialmente logo após o anúncio de
O Callisto garante um novo release de algum componente
que cada projeto no popular como o JDT, portanto pode ser
seu conjunto de rele- interessante selecionar uma das demais
ases funcionará junto alternativas.
com os demais sem A próxima janela exibe a relação de
problemas, coisa que features disponibilizadas pelo Callis-
nem sempre acontece to, organizadas em categorias como
com as versões mais “Java Development” e “Charting and
recentes dos projetos Reporting”. A mesma feature pode ser
individuais; garante exibida em mais de uma categoria, de
Figura 2. Escolha de um dos espelhos. também que serão modo a facilitar a localização das features
sempre versões está- desejadas pelos usuários iniciantes em
unificados. Cada um permanece com seus veis. O projeto ainda traz uniformidade Eclipse.
próprios planos de desenvolvimento e no controle de versões, critérios para Caso uma feature tenha dependências
cronogramas de releases individuais. O qualificação de releases como estável ou contidas em outras features, será exibido
que o Callisto fornece é a possibilidade em desenvolvimento, e outros pequenos um marcador de erros semelhante ao

Edição 38 •  Java Magazine 57

 jm38.indb 57 17/7/2006 14:13:17


O Eclipse Callisto

usado pelo Eclipse para o usuário tem a oportunidade de selecio-


indicar problemas em nar um local alternativo para a instalação
código Java ( Figura 3). de cada feature. Instalar features em dire-
Apenas depois que todas tórios separados (em especial, diferentes
as dependências sejam sa- da própria Eclipse Platform) facilita a
tisfeitas será habilitado o posterior desinstalação ou desabilitação
 botão Finish. dessas features. Facilita ainda a sua cópia
A página seguinte ( Fi- para a máquina de outro desenvolvedor
gura 4 ) permite que se (que assim não precisa fazer o download
verifique a licença de direto da internet), ou mesmo o com-
uso de cada feature, mas partilhamento de features entre vários
as opções de “aceito” ou sistemas operacionais para quem tem
“não aceito” se aplicam a “dual boot”. Também pode ser um
todo o conjunto. Retorne “quebra-galho” interessante em caso de
com o botão Back   caso falta de espaço no disco de instalação
alguma das licenças não do Eclipse. Infelizmente o Eclipse não
lhe agrade. Por enquanto, suporta (via Update Manager) o compar-
todos os componentes tilhamento de features entre diversos
usam a mesma licen- usuários de um mesmo sistema Linux,
ça padrão da Fundação Mac OS ou outro sistema Unix-Like.
Eclipse, mas no futuro Mas a solução está a caminho, veja o
poderá haver compo- quadro  “Empacotando o Eclipse para
nentes utilizando outras Linux”.
licenças open source. Finalmente, clicar no botão Finish  faz
Antes de iniciar o com que cada feature seja baixada e
Figura 3. Seleção de features fornecidas pelo Callisto para download e instalação, download e instalação instalada. Como mostra a Figura 6. Se
mostrando que uma dependência ainda não foi satisfeita. das features selecionadas, for necessário, o Eclipse será automa-

Empacotando o Eclipse para Linux

U suários de Linux poderão achar o Update


Manager do Eclipse “primitivo”, por não ser
capaz de gerenciar automaticamente dependên-
mática dos plug-ins. Só para citar um exemplo,
o JDT não é gerado diretamente pelo PDE, mas
sim por uma ferramenta conhecida como Releng
talações independentes e paralelas do Eclipse,
caso haja outros usuários do IDE no mesmo
computador.
cias e indicar exatamente quais são as features (procure por org.eclipse.releng.tools-3.2.zip na O recém-criado Linux Distributions Project
que devem ser acrescentadas para resolvê-las. página de downloads do Eclipse). da Fundação Eclipse ( wiki.eclipse.org/index.
Afinal, usuários de Debian, Ubuntu e Kurumim Os empacotamentos customizados das distri-  php/ Linux_ Distribu tions_ Projec t ) visa resolver
fazem isto há anos usando o apt-get , e usuários buições resolvem alguns problemas de integra- estes problemas e além disso fornecer plug-ins
do Fedora e Yellow Dog contam com o yum ; isto ção do Eclipse com o ambiente Linux, como a específicos para o desenvolvedor Linux / Unix,
sem falar nas ofertas comerciais da Novell/SuSE criação de ícones no desktop ou a utilização do por exemplo editores de páginas de manual (man
e da Red Hat. IDE por vários usuários da mesma máquina (ex.:  pages), geradores de pacotes RPM e integração
Muitas distribuições do Linux já empacotam com clientes magros), mas nenhum deles hoje com o GNU Autotools (origem do popular script
o Eclipse como componentes padrão, às vezes consegue permitir a instalação de atualizações ou configure usado por quase todos os projetos de
utilizando um Java Livre como o GCJ (caso do novas features, pelo Update Manager e mantendo software livre escritos em C para Unix).
Fedora Core Linux, fedora.redhat.com) ou então a integração estreita com os gerenciadores de  Usuários de outros sistemas Unix-Like como o
com o pré-requisito da instalação manual do Java pacotes do Linux.
Solaris, FreeBSD e o Mac OS têm problemas seme-
da Sun (como no JPackage,  jpackage.org). Em resumo, a situação atual exige que o usuário
lhantes e serão também beneficiados pelo projeto.
A manutenção destes empacotamentos é tra- Linux escolha ter uma instalação do Eclipse bem
balhosa, pois o Linux espera que cada pacote seja integrada, e faça todas as atualizações e acrés- Os resultados deste projeto serão importantes
construído a partir dos fontes originais e de forma cimos por meio do gerenciador de pacotes da para todos os usuários do Eclipse, não apenas
automatizada (o conceito de “pristine sources” distribuição; ou então, que realize a instalação para os usuários Linux, pois a integração de um
originado pelo RPM). Mas não existe um processo manual em seu diretório pessoal, e f aça todas as melhor gerenciamento de dependências ao
padronizado para a obtenção destes fontes na atualizações e acréscimos por meio do Update Update Manager tornará o Eclipse e seus plug-ins
Fundação Eclipse, nem para a compilação auto- Manager. Dessa forma são geradas várias ins- mais fáceis de instalar em qualquer plataforma.

58  Java Magazine • Edição 38

 jm38.indb 58 17/7/2006 14:13:21


ticamente reiniciado Update Manager não serão úteis, exceto
ao final para ativar os para usuários já familiarizados com os
novos recursos. projetos em questão, pois irão relacionar
Ao fim do processo, o nomes de plug-ins que muitas vezes não
usuário poderá ver os fornecem qualquer “dica” de qual projeto
novos menus, perspec- ou feature é fornecido, como no exemplo
tivas e outros recursos da Figura 7, onde foi selecionado o VE
acrescentados ao IDE. + GMF, que cita o plug-in “org.eclipse.
draw2d”; ou a seleção do EMF, que pede
Dependências o plug-in “org.apache.batik”.
O Callisto ainda não
é o “Eclipse para Ini- Conclusões
ciantes”. Afinal, muitos Embora o Callisto ainda não forneça
não saberão distinguir a maneira “mais fácil” de se instalar o
“x86_64 GTK 2” de “x86 Eclipse, deixando de fora coisas como a
/Motif” na página de criação de um atalho na á rea de trabalho,
downloads da Fun- ele representa um grande avanço em
dação, ou então serão relação à busca e download manual de
induzidos a baixar o cada distribuição de cada plug-in forne-
“Eclipse SDK” e gastar cido pelos vários projetos da Fundação
dezenas de megabytes Eclipse.
de disco (além de mui- O objetivo de l iberar simultaneamente
to tempo de conexão novas versões finais de dez projetos
internet) com fontes e complexos foi bastante ambicioso, ainda
Figura 4. Aceitação dos termos de licença de todas as features. plug-ins que eles pro- mais considerando-se a quantidade de
vavelmente não irão pessoas e empresas envolvidas em cada
utilizar tão cedo. um desses projetos.
Além disso, algu- Apenas um projeto falhou com o ob-
mas dependências do  jetivo, o VE, que foi incluso no Callisto
Callisto parecem estar com a versão 1.2RC-2 (segundo Release
erradas, por exemplo é Candidate), que embora não seja uma
estranha a exigência de versão final (GA, General Availability) é
se incluir o PDE (desen- quase isso. Segundo qualquer c ritério de
volvimento de plug-ins) avaliação, entretanto, pode-se considerar
para instalar tanto o o Callisto como um gra nde sucesso.
VE (para desenvolver
visualmente aplicações eclipse.org/callisto
SWT ou Swing) quanto Página principal do Eclipse Callisto
o JST (que permite o
desenvolvimento de eclipse.org/downloads
aplicações Java EE). Página de downloads do Eclipse,para baixar
Em alguns casos, as o SDK ou plataforma e iniciar o processo
Figura 5. Seleção do diretório de instalação para cada feature. mensagens de erro do

Figura 7. Nem sempre o Update Manager será útil para quem não conhece os projetos que deseja
Figura 6. Baixando e instalando as features selecionadas.
instalar. Por exemplo, nenhuma feature tem um nome parecido com “draw2d”.

Edição 38 •  Java Magazine 59

 jm38.indb 59 17/7/2006 14:13:23


Google Search
Incremente suas aplicações Java com con

T odo usuário de internet percebe o


papel que o Google representa na
vida on-line. Desde o inicialmente
modesto site de busca, com uma caixa de
texto e dois botões, até o sofisticado Google
Instalação e uso
Para usar a Google Sea rch API, basta fa-
zer o download do kit de desenvolvimento,
descompactá-lo em algum local do disco e
obter uma chave. O site google.com/apis lista
Buscas
As buscas são feitas definindo uma
expressão de consulta, usando o metodo
setQueryString()  – semelhante ao que seria
feito normalmente no site google.com – e de-
Earth, poucos são os internautas que não os passos necessários. Para obter a chave, pois invocando o método doSearch(), que re-
usam um dos produtos Google: Gmail, clique no link fornecido no segundo passo torna um objeto da classe GoogleSearchResult.
Calendar, Finance, Pages, Analytics, Maps, (“Create a Google Account”). Como se vê, Este objeto contém os resultados da busca
Desktop, Talk, SketchUp, Spreadsheets... e é necessário ter uma conta do Google, que e algumas informações adicionais, como
a lista não para de crescer. pode ser criada no mesmo site (se você o tempo de busca e o total estimado de
Mas mudar a maneira de como usamos tem uma conta no GMail ou no Orkut, já resultados. Um exemplo de uso do método
a internet parece não ser suficiente para tem uma conta no Google). Tendo a conta doSearch() pode ser visto na Listagem 1.
o Google, que está oferecendo cada vez criada, faça o login e uma chave será en- A melhor maneira de se encontrar as
mais ferramentas e APIs para que desen- viada para seu e-mail no GMail. A chave informações desejadas usando o Google
volvedores possam explorar os produtos e permite a realização de até mil pesquisas é construir uma boa consulta. Por exem-
tecnologias da empresa em suas próprias automatizadas por dia. plo, buscar por Java Magazine (sem aspas)
aplicações. Neste artigo, veremos como O kit de desenvol- usando a API, dificilmente retornará o site
usar a Google Search API, para realizar vimento contém o desta revista como o primeiro dos resulta-
 buscas de vários tipos, obter sugestões  JAR da biblioteca e dos. Uma primeira melhoria seria ao invés
de correção ortográfica e ler páginas exemplos de uso de buscar separadamente os termos  Java e
armazenadas em cache, entre outras em Java, C# e  Magazine, buscar o termo composto pelas
operações. Visu al Basic. duas palavras na ordem dada, colocando
Além destas, o conjunto entre aspas. Um detalhe é que,
pode ser usada para fazer isso no programa Java, as aspas
qualquer outra devem ser “escapadas” com o caractere “ \ ”
linguagem que para que façam parte da string ao invés
suporte web servi- de delimitá-la, ou seja, a consulta seria
ces: o kit de desenvolvi- “\”Java Magazine\””.
mento inclui o descritor do Se a consulta fosse feita através de
web service publicado pelo um navegador web, o problema estaria
Google (GoogleSearch.wsdl) e resolvido. Mas o web service utilizado
exemplos de requisições (no pela API não recebe as informações de
diretório soap-samples ). localidade submetidas pelo navegador,
Em Java, basta adicionar a bi- e sites de peso em língua inglesa como
 blioteca googleapi.jar ao classpa- Amazon e JavaWorld tendem a aparecer
th, instanciar um objeto da classe primeiro nos resultados. Um contorno se-
com.google.soap.search.GoogleSearch e ria excluí-los manualmente dos resultados
configurar nele a chave usando com o operador “-“, executando a consulta
o método setKey(), como mostra- “\”Java Magazine\” -JavaWorld -Amazon”.
do na Listagem 1. A classe Há um mecanismo mais elegante para
GoogleSearch  contém métodos limitar consultas. O método setRestrict()
para busca, sugestão ortográ- da classe GoogleSearch  permite que sejam
fica e obtenção de páginas em impostas restrições de idioma, de país
cache, como será mostrado ou de tópicos. Por exemplo, se antes de
a seguir.  buscar por “Java Magazine” configurarmos

60  Java Magazine • Edição 38

 jm38.indb 60 17/7/2006 14:13:27


Use o poder do mecanismo

API
sultas ao Google
de busca que revolucionou
a internet dentro de suas
aplicações Java, e conheça
técnicas avançadas de pesquisa

JULIO FAERMAN

a restrição “countryBR ”, o site da JM será o as paginas do site da JM com artigos deste


primeiro resultado (veja a Listagem 1). autor. A lista completa de operadores su-
O quadro “Restrições” mostra outras res- portados pela API, com exemplos de uso,
trições suportadas. pode ser vista no quadro “Operadores”.
Além do método setRestrict() , outros Conhecer um pouco do funcionamento da
limitadores e termos especiais podem internet também ajuda na hora de montar
ser incluidos na própria expressão suas consultas. Por exemplo, para buscar
de consulta. Por exemplo, a consulta documentos sobre (digamos) CMMI em
“Faermansite :www.javamagazine.com.br” retorna arquivos PDF ou DOC, uma boa consulta

Listagem 1.Exemplo de uso da Google Search API

package jm; //Sugestoes Ortograficas


  sugerirOrtografia(“filosofy”);
import com.google.soap.search.GoogleSearch;   sugerirOrtografia(“philosophy”);
import com.google.soap.search.GoogleSearchResult;   sugerirOrtografia(“filosopia”);
import com.google.soap.search.GoogleSearchResultElement;   sugerirOrtografia(“lumbriga”);

public class GoogleSearchDemo { //Pagina em cache


static final GoogleSearch busca = new GoogleSearch();   obterPagina(“www.java.com”);
}
public static void main(String[] args) throws Exception { 
String clientKey = null; public static void buscar(String consulta) throws Exception {
if (args.length == 1) { busca.setQueryString(consulta);
clientKey = args[0]; GoogleSearchResult result = busca.doSearch();
} System.out.printf(“Busca: %s Tempo: %f s Resultados: %d\n”,
else { result.getSearchQuery(), result.getSearchTime(),
  System.err.println( result.getEstimatedTotalResultsCount());
“uso: java -cp <classpath_incluindo_googleapi.jar>”
+ “ GoogleSearchDemo <clientKey>”); for (GoogleSearchResultElement element :
  System.exit(-1); result.getResultElements())
} {
  System.out.println(“######”);
  //Configuração System.out.println(“Titulo: “ + element.getTitle());
   busca.setKey(clientKey); System.out.println(“URL:” + element.getURL());
busca.setMaxResults(5); System.out.println(“Trecho: “ + element.getSnippet());
}
}
  //Buscas 
buscar("Java Magazine"); public static void sugerirOrtografia(String palavra)
 buscar("\"Java Magazine\" -JavaWorld -Amazon"); throws Exception
  busca.setRestrict("countryBR"); {
buscar(“Java Magazine”); String sugestao = busca.doSpellingSuggestion(palavra);
  busca.setRestrict(“linux.-lang_en”); if (sugestao == null) {
  buscar(“blackdown”);   System.out.println(
buscar(“jsf OR struts”); “Sem sugestões para \”” + palavra + “\”.”);
buscar(“Faerman site:www.javamagazine.com.br”); }
buscar(“jsf inurl:java”); else {
buscar(“hibernate intitle:OnJava”);   System.out.println(
buscar(“java daterange:2453371-2453736”); “Voce quis dizer \”” + sugestao + “\”?”);
buscar(“allintext:Service Oriented Architecture”); }
buscar(“CMMI filetype:doc OR filetype:pdf”); }
buscar(“-inurl:htm -inurl:html intitle:\”index of\”” 
+ “+(\”/ebooks\”|\”/book\”)+( public static void obterPagina(
chm|pdf|zip) lewis alice wonderland”); String pagina) throws Exception {
  buscar(“info:www.javamagazine.com.br”); System.out.println(new String(
  buscar(“link:www.javamagazine.com.br”);   busca.doGetCachedPage(pagina)));
  buscar(“related:www.java.com”); }
}

Edição 38 •  Java Magazine 61

 jm38.indb 61 17/7/2006 14:13:31


Usando a Google Search API

seria “CMMI filetype:doc OR filetype:pdf”. Entre- intitle:\”index of\” +(\”/ebooks\”|\”/book\”) +( ao buscar por “Filosofy”, é retornado o
tanto, para buscar um termo comum ou chm|pdf|zip|txt) -inurl:htm -inurl:html lewis alice wonderland. termo correto “Philosophy” (veja Lista-
com muitos documentos relacionados, gem 1).
como o livro “Alice no País das Maravi- Todas essas buscas são exemplificadas
lhas” (Alice’s Adventures in Wonderland)1, na Listagem 1. Páginas em cache
uma busca por tipo de arquivo dificil- No processo de indexação de uma página,
mente retornaria o livro. Neste caso, é Sugestões de ortografia o Google armazena uma cópia em cache.
melhor buscar por páginas de índice de Quando se faz uma consulta no site do Esta versão arquivada pode ser obtida
diretórios, cujo título costuma ser “index Google usando um termo incomum ou usando o método doGetCachedPage() , que
of”, e num diretório de livros, como “book” com erros de digitação/ortografia, como retorna o código HTML da página. Esse do-
ou “ebooks”. Como desejamos o arquivo “javascripiti”, o Google é capaz de verifi- cumento pode ser facilmente reexibido por
do livro, também ajuda acrescentar como car em seu índice gigantesco que esta não um componente gráfico ou uma taglib, ou, é
critério os formatos comuns de livros ele- é a forma mais freqüente da palavra, e claro, ser mostrado em um navegador web.
trônicos – zip, chm, txt ou pdf . E como pági- educadamente sugerir: “Você quis dizer: Uma maneira simples para obter páginas
nas web não interessam, podemos remover  JavaScript?”. em cache é mostrada na Listagem 1.
endereços com extensões de páginas, como A mesma funcionalidade está dis-
htm e html. Por último, adicionamos os ter- ponível na API através do método Limitações
mos da consulta, por exemplo o título do doSpellingSuggestion()  da classe GoogleSearch. A Google Search API é uma oferta
livro e o nome do autor. Sendo assim, uma Basta passar o termo como parâmetro, que
 busca como a seguinte tem boa chance de será retornada a sugestão de ortografia, ou 1
 Obra de Lewis Caroll publicada em 1865 e em domínio
ser bem sucedida: null se não houver sugestão. Por exemplo, público desde o início do século passado.

Operadores
Os termos a seguir possuem interpretação especial e podem ser incluídos na expressão da consulta:

Operador Significado Exemplo Intenção


Incluir o “or” na pesquisa. Normalmente seria ignorado por ser uma
+ Inclui to be +or not to be
palavra muito comum em inglês
- Exclui windows -microsoft Páginas com “windows” e sem “microsoft”
“” Frase “Java Magazine” Busca a frase toda ao invés dos termos separados
OR Ou  jsf or struts Páginas com um ou outro termo
site: No Site gosling site:weblogs.java.net Posts contendo o nome Gosling nos blogs do site java.net
Páginas com o termo “java” publicadas em 2005. Curiosamente, as
daterange: Entre datas  java daterange :2453371-2453736 datas precisam estar no formato Juliano, ou seja, deve ser fornecido
o número de dias corridos desde 1 de Janeiro de 4713 a.c.
intitle: No título hibernate intitle :OnJava Páginas sobre Hibernate cujo titulo contenha “OnJava”
allintitle Todas no título allintitle :Java Magazine Páginas com os termos Java e Magazine no título
inurl: Na URL inurl:google Páginas com o termo “google” no endereço
allinurl: Todas na URL a ll inur l: go og le ske tc hup Pá gi nas com os te rmos “go og le ” e “ske tc hup ” no e nde re ço
Páginas com os termos “open”, “source” e “java” no corpo da pági-
allintext: No texto allintext:open source java
na, ignorando título, links e URL.
Páginas com o termo “google” nos links, ignorando
allinlink s: Nos link s allinlinks:google
o texto, o título e a URL.
Livros sobre o software de gerência de configuração Subversion
f ilet ype : Tipo de arquivo Subversion book filetype: pdf 
em PDF
-filetype: Exceto tipo de arquivo Subversion book -filetype:pdf Livros sobre o Subversion, exceto em formato PDF
info: Sobre info: www.javamagazine.com.br  Informações sobre o site da JM*
link: Referenciam link:www.javamagazine.com.br  Páginas com links para o site da JM*
Related: Relacionados related:www.javamagazine.com.br  Páginas semelhantes à da JM*
Obtém a cópia do cache do Google da página inicial do site
cache: Cópia em cache cache:www.java.com
comercial de Java da Sun.
* Deve ser o único termo da consulta

62  Java Magazine • Edição 38

 jm38.indb 62 17/7/2006 14:13:34


Restrições

R estrições fazem com que a consulta busque


apenas em páginas de um determinado
país, ou que sejam escrit as em um dado idioma,
Tópico – setRestrict()
unclesam (Governo norte-americano), linux (Siste-
maOperacionalLinux), mac ( ComputadoresMacin-
As restrições podem ser combinadas usando os
operadores lógicos mostrados na tabela ao lado.

ou que tratem de alguns tópicos indexados tosh), bsd (Sistema Operacional FreeBSD). Por brevidade, foram apresentadas aqui ape-
separadamente, etc. Abaixo estão exemplos nas uma seleção de idiomas, países e tópicos.
de restrições que podem ser utilizadas e qual Restrições Combinadas – setRestrict() ou A lista completa pode ser vista em google.
método da classe GoogleSearch  usar para con- setLanguageRestrict() com/apis/reference.html .
figurá-las:
Operador Significado Exemplo Descrição
Idioma – setLanguageRestrict()
lang_pt  (Português), lang_en (Inglês),lang_de - Não -lang_pt Exclui resultados em português
(Alemão), lang_fr ( Francês), lang_es (Espanhol).
. E linux.countryBR Resultados apenas do tópico linux de sites no Brasil

País – setRestrict()
| Ou lang_br | lang_en Resultados apenas em português ou inglês
countryBR   (Brasil), countryEU   (União Euro-
péia), countryUS (Estados Unidos), countryPY (Pa- () Precedência (lin ux).(-(countryUS|countryUK)) Resultados do tópico li nux que não estejam nos EUA ou no Reino Unido
raguai), countryPT (Portugal).

experimental do Google, limitada a Por último, a API é muito mais precisa tões de ortografia. Mas com um pouco
aplicações não-comerciais e a apenas mil para termos e sites americanos, pelo volume de criatividade você poderá usar a API
consultas por dia. Não há previsão pública que estes representam no índice total. Por para incrementar praticamente qualquer
de se estender o serviço. Entretanto, para exemplo, a sugestão ortográfica é capaz de aplicação, integrando-a ao mais popular
aplicações corporativas, existe uma API corrigir termos mais comuns em português, mecanismo de busca mundial, e surpre-
semelhante baseada no servidor de busca como “Filosopia”, mas falha em outros pou- ender seus usuários.
corporativo do Google, que é um produto co publicados, como “Lumbriga”.
à parte (veja links).
 Julio Faerman
Outra limitação é que apenas um sub- Executando o exemplo ( [email protected]) é consul-
conjunto dos operadores de busca do site Para testar as consultas sugeridas, bas- tor independente em desenvolvi-
está disponível para a API. Por exemplo, ta executar a classe  jm.Go ogl eSea rchD emo mento de sistemas corporativos e
“stocks:”, “define:”, “movie:”, ou outros (Listagem 1), que está também disponível melhoria de processos de software.
serviços, como Images e Froogle, só po- no site da Java Magazine. Deve ser passada Certificado SCJP, SCWCD, SCBCD, SCDJWS e SCEA(I),
dem ser usados no site. (Estas e outras como parâmetro a chave de uso (além do bacharel em Ciência da Computação, MBA em Gerência
opções de busca podem ser conhecidas classpath, se este não estiver configurado). de Projetos e Mestrando da Universidade Federal de
em  google.com /help/cheatshee t.html ou em Por exemplo (em uma linha): Uberlândia, na área de Inteligência Artificial.
 googleguide.com/advance d_ ope rators _refe -
rence.html.)  java -cp c:\Java \Goog leAPI\ googlea pi.jar; .
 jm.Google SearchDemo  sua_chave  google.com/apis
Site principal da Google Search API
code.google.com
Conclusões Portal para desenvolvedores (geral)
A Google API é poderosa e bastante
funcional. Mas colocar essa biblioteca de code.google.com/enterprise1
consultas em prática numa aplicação pode Portal para desenvolvedores (clientes
não ser tão simples, principalmente pelas corporativos)
limitações da sua versão atual. Algumas www.googleguide.com
destas limitações, no entanto, podem ser Guia de uso para buscas do Google (criado por
dribladas, por exemplo permitindo que terceiros)
cada usuário cadastre sua própria chave undergoogle.blogspot.com
de acesso. As aplicações mais beneficiadas Blog com dicas e notícias do Google
diretamente são aquelas que lidam com
gerência de conteúdo e sites, podendo  javamagazine.com.br/downloads/jm38/ 
mostrar conteúdo semelhante ou suges-  jm-googleapi.zip

Edição 38 •  Java Magazine 63

 jm38.indb 63 17/7/2006 14:13:39


AJAX com Google
Escrevendo Aplicações Web Altamen

O Google Web Toolkit (GWT) é um


framework que define um novo
paradigma de desenvolvimento
de aplicações AJAX. O seu objetivo é
esconder do programador a implemen-
pilador, distribuído no pacote
do próprio framework.
O uso de código Java é
vantajoso, por exemplo, por
permitir que o desenvolvedor
tação de código JavaScript, considerando utilize a IDE Java de sua pre-
que esta tarefa é repetitiva e propensa a ferência, já que o GWT é
erros, e repleta de tarefas tediosas, como independente do ambien-
o tratamento de incompatibilidades entre te de desenvolvimento.
navegadores. Além disso, com o uso
O GWT abstrai a linguagem JavaScript de uma IDE, as van-
a partir de uma biblioteca de classes Java, tagens da lingua-
na qual está disponível uma coleção de gem Java são bem
componentes visuais AJAX (os widgets), aproveitadas;
 já conhecidos dos que usam as aplicações por exemplo,
AJAX do Google, por exemplo o GMail e
o Google Maps.
Este tutorial apresenta o GWT e traz um
exemplo de implementação utilizando o
framework.

Vantagens do uso de
classes Java
A principal novidade apresentada pelo
GWT é o uso de classes Java para represen-
tar os componentes visuais da aplicação.
Estas classes são convertidas em
código JavaScript por um com-

64  Java Magazine • Edição 38

 jm38.indb 64 17/7/2006 14:13:43


Crie aplicações AJAX

Web Toolkit a partir de classes


 Java, utilizando o novo
framework do Google,
e deixe que o trabalho
pesado seja feito para você
te Interativas em Java
DOUGLAS JOSÉ SOARES RODRIGUES

a verificação de tipos pelo compilador e utilizados. A segunda ferramenta é um projeto. Recomenda-se também adicionar
a capacidade de completar código ao ser navegador web local, que evita que o o diretório do GWT à variável de ambiente
digitado. desenvolvedor tenha de converter o seu PATH, para facilitar a criação do projeto.
código Java em JavaScript cada vez que A partir do diretório criado para o proje-
Arquitetura do Framework desejar realizar um teste. O navegador to, execute o comando a seguir:
Um modelo da arquitetura do GWT é local é capaz de exibir os componentes das
apresentado na Figura 1. A arquitetura é  bibliotecas sem a necessidade da conversão projectCreator –eclipse TutorialGWT
dividida em duas grandes camadas. A ca- de código. Isso cria o projeto. Em seguida, execute
mada de bibliotecas contém uma biblioteca este comando (numa mesma linha):
de componentes visuais e uma biblioteca Instalação
applicationCreator–eclipse TutorialGWT
de emulação Java, que traz a implemen- O primeiro passo para utilizar o GWT br.com.javamagazine.client.TutorialGWT
tação de algumas classes dos pacotes é, claro, baixar o pacote a partir da pá-
gina do framework. O GWT encontra-se Será criada a estrutura básica de um
disponível para Windows e Linux. Neste projeto para o Eclipse, com referências às
tutorial iremos apresentar as instruções  bibliotecas já configuradas. No Eclipse,
de configuração para Windows, lembran-  basta importar o projeto criado (item de
do que o procedimento é
 bastante semelhante para o
Linux. Foi utilizada a versão Biblioteca de
Biblioteca de
1.0.21 do GWT; o pacote é emulação Java Bibliotecas
componentes visuais
(java.lang e java.util)
distribuído no formato
ZIP e tem 13.9 MB.
A instalação é bastante
Compilador Java Navegador
simples: basta descom- para JavaScript Local
Ferramentas
pactar o arquivo ZIP
em um diretório de sua
preferência. Neste dire- Figura 1. Arquitetura do Google Web Toolkit.
tório estarão as bibliotecas
do GWT, e alguns utilitários para a
configuração de projetos.
O exemplo deste artigo é i mplemen-
tado utilizando o Eclipse com o WTP
(Web Tools Project). A utilização desse
Eclipse se justifica porque o GWT
traz ferramentas que automatizam o
processo de criação de projetos para
e  java.util . Estas duas bibliotecas
 java.lang esse IDE.
compõem a infra-estrutura básica necessá-
ria para representar os componentes AJAX Criando um projeto
utilizando código Java. O primeiro passo é a criação de um
A outra camada do GWT é composta projeto e uma aplicação. Para isso,
por duas ferramentas. A primeira é o serão utilizados dois utilitários forne-
compilador de Java para JavaScript, que é cidos com o GWT: applicationCreator e
responsável por gerar o código JavaScript  projectCreator. Será necessário criar um
representando os componentes visuais diretório para conter os arquivos do Figura 2. Estrutura do projeto de exemplo.

Edição 38 •  Java Magazine 65

 jm38.indb 65 17/7/2006 14:13:46


AJAX com Google Web Toolkit

Listagem 1.TutorialGWT.html

<html>   </tr>
<head>   <tr>
<title>Tutorial GWT</title> <td id=”removeContact” align=”center” colspan=”2”></td>
<style>   </tr>
  body,td,a,div,.p{font-family:arial,sans-serif}   </table>
  div,td{color:#000000}   </td>
a:link,.w,.w a:link{color:#0000cc}   <td>
  a:visited{color:#551a8b} <table align=”center”>
  a:active{color:#ff0000}   <tr>
.list {width: 100%;}   <td>Nome:&nbsp;</td>
</style> <td id=”firstName”></td>
<meta name=’gwt:module’ content=   </tr>
’br.com.javamagazine.TutorialGWT’>   <tr>
</head>   <td>Sobrenome:&nbsp;</td>
<body> <td id=”lastName”></td>
  </tr>
<script language=”javascript” src=”gwt.js”></script>   <tr>
<iframe id=”__gwt_historyFrame” style=   <td>E-mail:&nbsp;</td>
  ”width:0;height:0;border:0”></iframe> <td id=”email”></td>
<h1>Tutorial GWT</h1>   </tr>
<div id=”input” align=”center”></div>   <tr>
<table align=”center”> <td colspan=”2”>
  <tr> <div id=”insertContact” align=”center”></div>
  <td>   </td>
<table align=center width=”400”>   </tr>
  <tr>   </table>
<td id=”label”></td>   </td>
<td id=”text” width=”100%”></td>   </tr>
  </tr> </table>
  <tr> </body>
<td id=”list” colspan=”2”></td> </html>

Listagem 2. TutorialGWT.java

package br.com.javamagazine.client; public void onClick(Widget sender) {


int i = list.getSelectedIndex();
import java.util.*;   itens.remove(i);
import com.google.gwt.core.client.EntryPoint; filtrarLista(list, filter.getText());
import com.google.gwt.user.client.ui.*; }
});
public class TutorialGWT implements EntryPoint {
private List itens = new ArrayList(); //Contatos cadastrados list.setVisibleItemCount(5); // Numero de itens exibidos
  list.setStyleName(“list”);
public void onModuleLoad() {
final Label label = new Label(“Filtro:”);   RootPanel.get(“label”).add(label);
final ListBox list = new ListBox();   RootPanel.get(“text”).add(filter);
final TextBox filter = new TextBox();   RootPanel.get(“list”).add(list);
final TextBox firstName = new TextBox();   RootPanel.get(“firstName”).add(firstName);
final TextBox lastName = new TextBox();   RootPanel.get(“lastName”).add(lastName);
final TextBox email = new TextBox();   RootPanel.get(“email”).add(email);
final Button insertContact = new Button(“Adicionar”);   RootPanel.get(“insertContact”).add(insertContact);
final Button deleteContact = new Button(“Remover”);   RootPanel.get(“removeContact”).add(deleteContact);
}
// Listener que trata cada caractere
// digitado no campo de filtro private void inserirContato(ListBox list, String firstName,
filter.addKeyboardListener(new KeyboardListenerAdapter() { String lastName, String email, String filter)
public void onKeyUp( {
Widget sender, char keyCode, int modifiers) String novoContato = lastName + “, “ + firstName
{ + “ (“ + email + “)”;
filtrarLista(list, filter.getText());   list.addItem(novoContato);
}   itens.add(novoContato);
}); filtrarLista(list, filter);
}
// Listener que trata o clique no botão ‘Adicionar’
insertContact.addClickListener(new ClickListener() { private void filtrarLista(ListBox lista, String filtro) {
public void onClick(Widget sender) {   lista.clear();
  inserirContato( for (int i = 0; i < itens.size(); i++) {
list, firstName.getText(), lastName.getText(), String item = (String) itens.get(i);
email.getText(), filter.getText()); if (item.toLowerCase().indexOf(
  firstName.setText(“”); filtro.toLowerCase()) != -1)
  lastName.setText(“”); {
  email.setText(“”);   lista.addItem(item);
} }
}); }
}
// Listener que trata o clique no botão ‘Remover’ }
deleteContact.addClickListener(new ClickListener() {

66  Java Magazine • Edição 38

 jm38.indb 66 17/7/2006 14:13:46


menu File>Import>Existing projects into lista irá exibir apenas os elementos que o preenchimento inicial da lista e para rea-
workspace ), para que as configurações correspondam ao filtro digitado. Observe lizar a busca na lista por um determinado
sejam automaticamente aproveitadas. A que todos os componentes usados (campo filtro. O código completo para a classe
estrutura do projeto deve ficar como na de texto, lista) são tipos de campos de pode ser conferido na Listagem 2.
Figura 2. formulários HTML comuns, e que não há
nenhum tipo de requisição feita ao servi- Executando e compilando
Implementando o projeto de exemplo dor web (embora isto possa acontecer na Após editar os arquivos HTML e a classe
Neste tutorial, o problema que iremos solução de outros problemas).  Java, faça a compilação do projeto com um
resolver é a criação de uma busca incre- Abra o arquivo TutorialGWT.html, gerado duplo-clique (dentro do Eclipse) no arqui-
mental, ou seja, uma busca realizada con- pelo toolkit, e o modifique para que corres- vo gerado TutorialGWT-compile.cmd. Isso
forme caracteres são digitados. Usuários ponda ao conteúdo da Listagem 1. Observe gera o código JavaScript e cria o diretório
do navegador Firefox estão acostumados que o arquivo muda pouco, se comparado www/br.com.javamagazine.TutorialGWT ,
com esta funcionalidade (basta pressionar ao que foi gerado. São definidos oito IDs, com arquivos HTML.
Ctrl+F para abrir o painel de busca). O que correspondem aos locais onde serão Para executar o projeto, dê um duplo-
exemplo também demonstra como fazer exibidos os componentes definidos na clique em TutorialGWT-shell.cmd. Serão
um cadastro simples, mantendo os dados classe Java. E o estilo .list  é definido para exibidas duas janelas, uma com o log da
numa coleção em memória. posicionar a lista na tela corretamente. execução da aplicação (Figura 3) e outra
Usaremos uma campo de texto comum O próximo passo é implementar a classe com o navegador exibindo a aplicação em
para conter o filtro para a busca. Assim que TutorialGWT, que irá descrever o comporta- execução (Figura 4).
o conteúdo desse campo for alterado, uma mento da busca incremental. No exemplo,
foi criado um pequeno catálogo de Conclusões
endereços, onde é possível cadas- O GWT mostra-se um framework extre-
trar nome, sobrenome e e-mail de mamente eficiente e bem escrito. No pacote
um contato, e remover os contatos de download já estão inclusas todas as
 já cadastrados. A busca incremen- ferramentas necessárias, e sua integração
tal é usada para filtrar os contatos com a IDE (atualmente, só o Eclipse é su-
 já cadastrados. Nesta classe são portado) é muito simples. É uma solução
Figura 3. Janela de log do navegador local. definidos métodos auxiliares para robusta para o desenvolvimento AJAX com
o suporte de uma empresa renomada.

code.google.com/webtoolkit/ 
Google Web Toolkit
eclipse.org/webtools
Projeto Eclipse Web Tools
 javamagazine.com.br/downloads/jm38/
 jm-gwt.zip

Douglas José
Soares Rodrigues
([email protected] ) é
formado em Ciência da Com-
putação pela Unicamp e trabalha
como consultor Java há quatro anos.
Figura 4. Exemplo de cadastro e busca incremental, exibido no navegador

Edição 38 •  Java Magazine 67

 jm38.indb 67 17/7/2006 14:13:51


Formatação e Conver
Estendendo o framework e aumentando a capa

68  Java Magazine • Edição 38

 jm38.indb 68 17/7/2006 14:14:12


são no Struts Utilize Converters para
resolver problemas de
conversão no Struts e
deixe seus FormBeans mais
completos
cidade da sua aplicação web
ARI DIAS NETO

O Struts oferece muitas


funcionalidades para o
tratamento da entrada
de dados, mas possui ainda
algumas limitações
 branco; ou pior: os valores podem ser trata-
dos de forma equivocada. Por exemplo, em
uma data como 10/03/06, o mês será 10, 03
ou 06? Para nós brasileiros, fica claro que o
mês é março – mas e para o sistema?
 butos do tipo String. Isso porque faremos o
Struts configurar o FormBean com os tipos
corretos, ou seja, o próprio framework irá
converter os dados enviados pelo usuário
para Date e BigDecimal .
nessa área. Quem Uma das soluções mais utilizadas é A Action tem uma implementação sim-
utiliza o framework criar métodos no FormBean para tratar os ples. Ela faz apenas um forward para o JSP
sabe da dificuldade dados enviados. Dessa forma, existiriam com o formulário (veja a Listagem 3). Nos-
para se tratar, por no FormBean dois métodos: um para con- so objetivo aqui é fazer com que o Struts
exemplo, datas e nú- verter para o tipo correto no momento da configure o FormBean com seus devidos
meros decimais, e aca- entrada dos dados, e outro para converter atributos. Não nos importa neste ponto o
 ba utilizando strings para para string no momento da exibição. O que será feito depois com estes valores.
representar muitas informa- problema dessa solução é que ela se repeti- A Listagem 4  mostra o conteúdo do
ções que vêm do usuário. rá para todos os formulários que precisam arquivo struts-config.xml. A configuração
Como sabemos, quando o usuá- da conversão, além de não se aplicar aos é simples. Primeiro definimos um formu-
rio entra com valores em um formulá- DynaActionForms (representações di- lário dentro do elemento <form-beans>,com
rio e os envia, estes chegam ao servidor em nâmicas de formulários configuradas no dois atributos: nome e classe. Usamos o nome
forma de strings. O Struts tenta converter struts-config.xml). Aqui veremos uma solu- formBeanTeste e a classe FormBeanTeste.
essas strings para os formatos mapeados ção alternativa, que oferece vantagens. Logo em seguida, temos a configu-
no FormBean (classe que representa um ração da Action dentro do elemento
formulário), e caso não consiga, recebemos Solução proposta <action-mappings>. Configuramos o path,
erros pouco explicativos ou páginas em Para demonstrar nossa solução, vamos que será a URL chamada pelo formulário
construir uma aplicação simples, com uma no momento da postagem; a classe, através
página JSP, um FormBean e uma Action. do atributo type; e o mais importante: o
Usaremos uma classe concreta para re- nome do FormBean, através do atributo
presentar o formulário, mas poderíamos name. O nome deve ser o mesmo dado na
igualmente utilizar um DynaActionForm. configuração do FormBean. Note que, após
O exemplo completo está disponível no site a execução da Action, iremos retornar
da Java Magazine. para a mesmo formulário (index.jsp) pois
O JSP, como mostra a Listagem 1, constrói também precisamos exibir/formatar os
um formulário com dois campos de texto; dados corretamente. Esse retorno simula,
o primeiro para uma data e o segundo por exemplo, um formulário de edição que
para um número decimal. Note que para  já possui os dados populados, ou quando
a construção do formulário utilizamos as há um processo de validação e o usuário
tags do Struts <html:form> e <html:text>. é redirecionado ao mesmo formulário
O FormBean que representa este formulá- seguido dos erros encontrados.
rio terá dois atributos, um do tipo java.util.Date
e outro do tipo  java.math.BigDecimal . Veja a Primeira parte da solução
Listagem 2; observe que não temos atri- Neste estágio, a aplicação ainda não fun-

Edição 38 •  Java Magazine 69

 jm38.indb 69 17/7/2006 14:14:37


Formatação e Conversão no Struts

cionará. Assim que o usuário preencher o Controller (veja links). Isso significa que e registrar os nossos converters (classes que
formulário e clicar em Enviar, receberá um ele possui um controlador que gerencia executam conversões de tipos, por exem-
erro. Isso acontece porque o Struts tenta o tratamento das solicitações, deixando plo, de String   para Date). Para tal, iremos
converter os dados postados para os t ipos para as Actions a responsabilidade de substituir, no arquivo web.xml, o servlet do
correspondentes no FormBean, e não con- responder à requisição e de definir o que Struts por um servlet nosso (que estende
segue. Por padrão o Struts não vem com os será retornado para o usuário. o do Struts): MeuStrutsServlet. Esse servlet
conversores corretos para BigDecimal e Date. O Front Controller do Struts é o servlet deve fazer tudo que o ActionServlet faz,
É aí que entra a nossa solução. org.apache.struts.action.ActionServlet, que está além de registrar os converters corretos
Você já deve ter ouvido falar que o configurado no arquivo web.xml. É justa- para Date e BigDecimal .
Struts implementa o design pattern Front mente neste servlet que podemos interferir A Listagem 5  mostra como fica nosso
servlet. Observe que apenas iremos rede-
Listagem 1. index.jsp: Página com o formulário de exemplo. finir o método init() e adicionar as linhas
<%@ taglib uri=”/tags/struts-html” prefix=”html” %> que registram os converters corretos,
<html:form action=”/PostFormularioAction”> e continuar chamando o método init()
Data: <html:text property=”data” /><br />
Valor: <html:text property=”valor” /><br /> da superclasse. A Listagem 6 mostra a
  <html:submit/>
</html:form> configuração do web.xml antes e depois
da substituição (apenas a parte alterada).
Listagem 2. FormBeanTeste.java : Classe que representa o formulário, com dois campos: um Date e outro BigDecimal .
Simplesmente trocamos a classe do servlet,
package br.com.jm.formbean; apontando para a nossa.
import java.math.BigDecimal; Vamos agora aos converters. Para o
import java.util.Date;
import org.apache.struts.action.ActionForm;
converter de data, utilizamos a classe
DateLocaleConverter do projeto Jakarta Com-
public class FormBeanTeste extends ActionForm {
private Date data; mons BeanUtils (veja links). Passamos
private BigDecimal valor; como parâmetros o locale e o formato da
//... Métodos get/set data que chegará ao converter. Neste caso,
}
usamos o formato “dd/MM/yyyy”.
Listagem 3. PerformPostAction.java: Action que apenas retorna para o formulário com o forward “sucesso”. Infelizmente, para o conversor de
package br.com.jm.action; BigDecimal não podemos ainda utilizar
o BigDecimalLocaleConverter  (também do
// … imports
BeanUtils), pois há atualmente uma
public class PerformPostAction extends Action { incompatilidade entre esse conversor
public ActionForward execute(ActionMapping mapping, ActionForm form, e o Struts. Então, iremos criar a nossa
HttpServletRequest request, HttpServletResponse response)
throws Exception própria classe que implementa a inter-
{
/* Neste ponto pode-se obter os valores enviados já com os tipos corretos,
face org.apache.commons.beanutils.Converter.
/ por exemplo: Vamos chamá-la de BigDecimalConversor
*
* FormBeanTeste meuForm = (FormBeanTeste)form; (Listagem 7).
* Date dataEnviada = meuForm.getData(); A classe BigDecimalConversor  terá um mé-
*/
return mapping.findForward(“sucesso”); todo converter() que receberá dois parâme-
}
}
tros: um  java.lang.Objec t e o tipo de classe
para qual deverá converter o Object. Como
registramos o conversor para apenas o
Listagem 4. struts-config.xml : com a configuração de um FormBean e uma Action. tipo BigDecimal  converteremos sempre para
<struts-config> esse tipo. Além disso, a implementação de
  <form-beans>
<form-bean name=”formBeanTeste” type=”formbean.FormBeanTeste”/>
exemplo já faz o tratamento de exceções.
  </form-beans> Se houver algum erro, um valor padrão
  <action-mappings> poderá ser retornado.
<action path=”/PostFormularioAction”
type=”br.com.jm.action.PerformPostAction” name=”formBeanTeste”>
<forward name=”sucesso” path=”/index.jsp”/> Testando os conversores
  </action>
  </action-mappings> Agora que já temos os conversores pron-
</struts-config> tos, vamos fazer um teste. Rode a aplicação
em qualquer container web, como o Tom-

70  Java Magazine • Edição 38

 jm38.indb 70 17/7/2006 14:14:43


cat. A primeira página a ser exi bida será a
Listagem 5. MeuStrutsServlet.java: Servlet que registra os converters e substitui o servlet do Struts.
index.jsp. Preencha o formulário conforme
a Figura 1 e envie os dados. package br.com.jm.servlet;

Se tudo correr bem, após a requisição import java.math.BigDecimal;


import java.util.Date;
nenhum erro ocorrerá; ou seja, o Struts import java.util.Locale;
terá utilizado os nossos converters. Mas import javax.servlet.ServletException;
ainda temos um problema. Note que tanto import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.locale.converters.DateLocaleConverter;
a data como o número decimal estão com import org.apache.struts.action.ActionServlet;
formatações erradas após o retorno (veja a
import br.com.jm.converter.BigDecimalConversor;
Figura 2). A data não está formatada para
o padrão configurado no converter, e o public class MinhaStrutsServlet extends ActionServlet {
public void init() throws ServletException {
número decimal não está com a notação   super.init();
 brasileira. Locale locale = new Locale(“pt”, “BR”);
Isso acontece porque os converters tratam //criação dos conversores
a entrada de dados, mas não a exi bição. Os DateLocaleConverter dateConverter =
new DateLocaleConverter(locale,“dd/MM/yyyy”);
dados foram convertidos corretamente, po- BigDecimalConversor bigDecimalConversor =
rém ao ser reexibido o formulário, não foi new BigDecimalConversor(locale, new BigDecimal(“0”), true);
feita a formatação correta. A tag <html:text> //registro dos conversores
ConvertUtils.register(dateConverter, Date.class);
não trata os atributos do FormBean levan- ConvertUtils.register(bigDecimalConversor, BigDecimal.class);
do em conta os padrões locais. Por isso }
}
muitos desenvolvedores colocam métodos

Edição 38 •  Java Magazine 71

 jm38.indb 71 17/7/2006 14:14:52


Formatação e Conversão no Struts

no FormBean para formatar estes dados <html:text>  formate o conteúdo que irá duas abordagens. A primeira é criar uma
antes da exibição. Essa prática, no entanto, exibir. Para isso, iremos substituir a classe nova taglib, ou seja, um novo arquivo
não é recomendada, pois se repetirá para que implementa a taglib. .tld e uma nova classe que estende a tag
todos os formulários que trabalham com do Struts. Esta abordagem segue as boas
dados diferentes de strings, deixando o  Aqui é importante lembrar que as taglibs são práticas de utilização do framework, pois
desenvolvimento mais lento e diminuin- configuradas em arquivos chamados tag library não altera nenhum arquivo original do
do a reutilização do código. descriptors (TLDs), que informam quais atributos Struts e deixa o código nas páginas JSP
a tag pode ter, além de indicar a cl asse que imple- mais légivel, já que utiliza uma taglib
 Segunda parte da solução menta a tag. própria. É a abordagem indicada para
Chegamos à segunda parte da solu- aplicações que estão iniciando o processo
ção. Precisamos fazer com que a tag Para substituir a tag podemos adotar de desenvolvimento.
A segunda, e a que adotaremos aqui, é
Listagem 6.Trecho do web.xml , antes e depois da substituição da Action.
apenas editar o arquivo struts-html.tld e
substituir o nome da classe que implemen-
Antes da substituição ta a tag. Esta solução é indicada para apli-
<servlet-name>action</servlet-name> cações que já estão avançadas no processo
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class> de desenvolvimento, e em que um refac-
Depois da substituição toring de todas as JSPs que utilizam esta
taglib seria realmente muito custoso.
<servlet-name>action</servlet-name>
<servlet-class>br.com.jm.servlet.MinhaStrutsServlet</servlet-class> O arquivo struts-html.tld é utilizado para
configurar várias taglibs, por isso temos
Listagem 7. BigDecimalConversor.java: Converter personalizado para BigDecimal.
que fazer a alteração apenas na parte
package br.com.jm.converter; referente à tag <html:text>. A Listagem 8
import java.math.BigDecimal; mostra o trecho relevante do arquivo de
import java.text.DecimalFormat;
import java.text.ParseException; configuração antes e depois da mudança.
import java.util.Locale; Note que alteramos a linha onde está
import org.apache.commons.beanutils.ConversionException; a definição da classe: o nome da classe
import org.apache.commons.beanutils.Converter;
muda de org.apache.struts.taglib.html.TextTag
public class BigDecimalConversor implements Converter { para br.com.jm.taglib.Mi nhaTextTag.
private Locale locale;
private BigDecimal valorPadrao; AListagem9 mostra a classe da nossa taglib,
private boolean useValorPadrao;
que estende org.apache.struts.taglib.html.TextTag
public BigDecimalConversor(Locale locale, BigDecimal valorPadrao, e redefine formatValue(). Este método será
boolean useValorPadrao)
{ chamado antes da exibição do conteúdo e
this.locale = locale; tem implementação simples. Verificamos
this.valorPadrao = valorPadrao;
this.useValorPadrao = useValorPadrao; o objeto que é passado como argumento,
}

public Object convert(Class classe, Object valor) {


try {
Object resultado = parse(valor);
if (resultado == null || resultado instanceof BigDecimal) {
return resultado;
}
return new BigDecimal(resultado.toString());
}
catch (Exception ex) {
if (useValorPadrao) {
return valorPadrao; Figura 1. Formulário preenchido com valores de teste.
}
else {
throw new ConversionException(“Erro ao instanciar BigDecimal”);
}
}
}

private Object parse(Object valor) throws ParseException {


DecimalFormat formatter =
(DecimalFormat) DecimalFormat.getInstance(locale);
return formatter.parse((String) valor);
}
} Figura 2. Exibição do formulário após seu envio. Data e
Valor com formatação.

72  Java Magazine • Edição 38

 jm38.indb 72 17/7/2006 14:15:08


Edição 38 •  Java Magazine 73

 jm38.indb 73 17/7/2006 14:15:11


Formatação e Conversão no Struts

e caso seja uma instância de BigDecimal, solução para a sua aplicação levando em 3. E por último, no momento da exibição,
fazemos a formatação utilizando a classe conta a legibilidade do código e a facilidade a taglib formatou os dados exatamente
 java.text.DecimalFormat . Mais uma vez, o pa- de manutenção da sua aplicação. como haviam sido digitados.
râmetro Locale(“pt”, “BR”) é utilizado. Já se o
objeto passado for do tipo Date, formatamos Testando a solução Dessa maneira, seus FormBeans poderão
para o padrão de exibição desejado, nesse Vamos testar a solução completa. Reini- ter atributos mapeados para qualquer
caso “dd/MM/yyyy”. cie a aplicação e digite os mesmos dados classe Java, desde que você registre um
Esta segunda abordagem que apenas que usamos na primeira vez, como já mos- conversor responsável para ela e estenda
substitui o nome da classe no arquivo trado na Figura 1. Após clicar no botão as taglibs. Essa mesma solução se aplica
struts-html.tld, pode, em uma fase de manu- Enviar, o formulário deverá aparecer com também para formulários dinâmicos (os
teção, deixar os desenvolvedores um pouco os dados formatados corretamente. DynaActionForms).
confusos, já que praticamente escondemos Note que três coisas aconteceram durante
a nova configuração e a criação da nova o processamento da requisição: Conclusões
taglib. Por outro lado, pode ser a salvação 1.   O Struts converteu os dados e Neste artigo, vimos como registrar con-
para aqueles que já possuem milhares de configurou o FormBean; verters personalizados no Struts e como
 JSPs e não querem ter de alterá-los caso 2.  A Action redirecionou o usuário para formatar formulários para exibição ou
seja criada uma nova tag. Analise a melhor o mesmo formulário; edição. Uma solução mais rica poderia
aceitar a configuração dos converters via
XML. Dessa forma, parâmetros do sistema,
Listagem 8. struts-html.tld  , antes e depois da substituição da classe que implementa a tag.
como o padrão de formatação da data, não
 Antes da substituição estariam diretamente no código, e sim num
<tag>
  <name>text</name> resource da aplicação. E possivelmente
  <tagclass>org.apache.struts.taglib.html.TextTag</tagclass>
...
teríamos apenas um objeto  java.util.Loc ale
</tag> instanciado por sessão do usuário.
Depois da substituição
<tag>
  <name>text</name>  struts.apache.org
  <tagclass>br.com.jm.taglib.MinhaTextTag</tagclass>
... Framework Apache Struts: downloads e
</tag> documentação.
Listagem 9. MinhaTextTag.java: Classe que substituirá a implementação da taglib Text  do Struts.  jakarta.apache.org/commons
package br.com.jm.taglib;
Jakarta Commons, componentes reutilizáveis para
vários fins.
// … imports
 java.sun.com/developer/technicalArticles/ 
public class MinhaTextTag extends TextTag{
public MinhaTextTag(){ Intl/IntlIntro/ 
  super(); Uma visão geral sobre internacionalização
this.type = “text”;
doReadonly = true;
}
 java.sun.com/blueprints/corej2eepatterns/ 
Patterns/FrontController.html 
protected String formatValue(Object value) throws JspException {
Locale locale = new Locale(“pt”,”BR”); Sobre o design pattern Front Controller
if(value instanceof BigDecimal){
  try{  javamagazine.com.br/downloads/jm38/ 
DecimalFormat formatter =  jm-strutsconverters.zip
(DecimalFormat) DecimalFormat.getInstance(locale);
return formatter.format(value);
} catch(Exception e){
return super.formatValue(value); Ari Dias Neto
} ([email protected]) é con-
}
if(value instanceof Date){ sultor Java/JEE com experiência
  try{ de mais de sete anos em tecnogias
SimpleDateFormat sdf = new SimpleDateFormat(“dd/MM/yyyy”);
return sdf.format(value); para web. Atualmente atua em projeto
} catch(Exception e){
return super.formatValue(value);
internacional para IBM e tem certificações SCJP, SCWCD,
} EA(I) e de Borland CaliberRM.
}
return super.formatValue(value);
}
}

74  Java Magazine • Edição 38

 jm38.indb 74 17/7/2006 14:15:21


 jm38.indb 75 17/7/2006 14:15:36

Você também pode gostar