Como assinar um applet

Como assinar um applet

Fonte: http://insonix.blogspot.com/2009/04/como-assinar-um-applet.html

Se você estiver se perguntando, para que precisa assinar meu applet, ai vai a resposta.
Existem várias questões de segurança envolvendo a chamada de arquivos e aplicações externas de dentro do navegador, e para executar alguma função mais específica, ou até mesmo rodar executáveis do sistema operacional a partir do seu applet, você precisa criar uma assinatura digital para ele.
Até mesmo para identificar que este applet é assinado pela empresa ou site cujo ele está sendo executado.

Vamos ao que interessa.

Como exemplo, eu criei um applet Exemplo.java que gerou o binário Exemplo.class.

1 – Criar um JAR
Criar um JAR com a classe envolvida, pois a assinatura será feita em cima do jar.
Na linha de comando, vá até a pasta em que o .class de sua classe está e digite:

jar cvf Exemplo.jar Exemplo.class

Neste momento foi criado um jar chamado Exemplo.jar.

2 – Criar o par de chaves (chave pública e privada)
Na linha de comando digite:

keytool -genkey -dname “cn=Exemplo, ou=Laboratorio, o=Empresa, c=BR” -alias exemplo -storepass 123456 -validity 3655

Detalhes do comando

-dname = dados da organização/empresa/site
-alias = nome da chave criada, no caso “exemplo”
-storepass = pass da chave, quando for assinar um jar com esta chave por exemplo, será necessário digitar este pass
– validity = quantidade de dias de validade da assinatura digital

Esta chave fica guardada na pasta home do usuário, e você poderá utilizar apenas o alias dela quando for assinar o JAR.

3 – Assinar o JAR do applet
Assinar o JAR do applet, criado no passo 1.

Na linha de comando digite:

jarsigner -storepass 123456 Exemplo.jar exemplo

Detalhes do comando

-storepass = pass da chave, conforme explicado no passo 2
Exemplo.jar = arquivo jar criado no passo 1
exemplo = alias da chave, criada no passo 2.

Pronto, é só jogar o seu JAR para sua aplicação, e agora caso você em seu applet, chamava um .class, é só chamar o .JAR.

Seu applet já está assinado.

Criando arquivos .jar

//
// Olá a todos, em primeiro lugar gostaria mais uma vez agradecer o apoio, comentários e críticas de todos vocês.
Nem sempre consigo responder todos os emails e comentários, mas quero que saibam que todos são lidos e são de grande importância para mim, por tanto muito obrigado.

Muitas pessoas tem me perguntado sobre como trabalhar com arquivos compactados .jar, pois na maior parte das vezes a nossa aplicação java não se resume apenas a um arquivo .java, e sim, são compostas de vários arquivos, então como fazer para tornar a vida mais fácil na hora de um “deploy” ou mesmo no manuseio dos mesmo? A forma mais fácil é criar um arquivo .jar contendo todos os arquivos do nosso projeto, hoje veremos como fazer isso utilizando o comando “jar” para criar um pacote “executável” com os arquivos da nossa aplicação.

Gostaria de dedicar esse artigo ao meus amigos que tem me perguntado sobre arquivos .jar em especial ao Adriano, foi por causa de suas perguntas que escrevi esse artigo.

Agora sem mais demora vamos ao que interessa. Para esse artigo iremos precisar de alguns códigos .java para que possamos gerar o pacote da nossa aplicação, como o intuito é explicar como gerar o arquivo .jar, os códigos não serão comentados, são apenas dois códigos simples que escrevi para esta demonstração.

Vamos criar um diretório qualquer para o nosso projeto, eu criei um diretorio chamado “jarfiles”, (que de agora em diante será chamado de diretório RAIZ) e dentro dele criaremos mais alguns diretórios:
src – diretório onde colocaremos nossos arquivos fonte
bin – diretório onde colocaremos os arquivos compilados

E dentro do diretorio “src” criaremos mais um diretório chamado “init”, é um nome qualquer apenas para mostrar como fazer para rodar um arquivo que estará dentro dele, e para demostrar que é possível criar diversos diretórios e colocá-los todos no nosso .jar.

Agora que já temos os diretórios iremos criar duas classes dentro do diretório “src/init”, são elas:

OlaMundo.java

package init;

/**
* @author Dayvid Lima
*/

public class OlaMundo {
public void falaOla(){
System.out.println(“Olá mundo cruel!”);
}
}

UsaOlaMundo.java

package init;

/**
* @author Dayvid Lima
*/

public class UsaOlaMundo {

public static void main(String[] args){
OlaMundo om = new OlaMundo();
om.falaOla();
}
}

Prontinho, agora vamos compilar nossos códigos java para dentro do diretório bin, para isso uma vez estando dentro do diretório RAIZ no prompt do DOS ou em um terminal qualquer, vamos digitar:
javac src/init/*.java -d bin/

Isso fará com que os arquivos .java que estão em /src/init/ sejam compilados e colocados em /bin/init/.

Para ver se está tudo ok iremos rodar nossa aplicação, primeiro entramos no diretório “bin”, e então executamos nossa aplicação com o comando:
java init.UsaOlaMundo

Se tudo der certo veremos a mensagem “Olá mundo cruel!” na tela.

Bom agora que tudo está ok chegou a hora do que realmente interessa, compactar todos esses arquivos em um único arquivo .jar e rodar a aplicação a partir dele.

Para criar o arquivo .jar iremos fazer uso do comando “jar”, existem diversas opções que podemos passar para o comando jar, iremos nesse artigo fazer uso das seguintes:
c – cria um novo arquivo
v – modo “verbose”, mostra na tela o que está acontecendo
f ARQUIVO_JAR – especifica o nome que queremos para o arquivo .jar
m ARQUIVO_DE_MANIFESTO – inclue o arquivo informado como arquivo de manifesto (veremos isso na segunda parte da explicação)

Ainda dentro do diretório bin, tudo que temos que fazer para criar nosso .jar é executar o comando:
jar cvf Ola.jar init/*

Pronto, com isso temos nossa aplicação agora dentro do arquivo Ola.jar, vamos então executá-la, para fazer isso devemos informar no classpath onde está nossa aplicação (no caso a classe init.UsaOlaMundo),
Podemos tanto colocar o arquivo Ola.jar no nosso classpath quanto informar esse parâmetro no momento da execução como no comando abaixo:
java -classpath Ola.jar init.UsaOlaMundo

Muito bom, meus parabéns, agora você tem a sua aplicação toda em um arquivo só, pois bem, vamos facilitar um pouco mais as coisas.

Se olharem dentro do arquivo Ola.jar (abram ele com um compactador qualquer como Winzip ou Winrar, pois ele é apenas um arquivo compactado sem utilizar compressão, isso mesmo, você poderia ter simplesmente criado um arquivo .zip ou .rar com o seu compactador preferido informando a ele para não utilizar compactação, apenas adicionar os arquivos e depois renomear o mesmo para .jar que ainda assim funcionaria.

Enfim, voltando a aplicação, veja que dentro dele temos um diretório META-INF contendo o arquivo MANIFEST.MF, pois bem, esse arquivo contém informações sobre a nossa aplicação, como não criamos esse arquivo, ele tem apenas algumas informações básica, vamos então criar o nosso MANIFEST.MF e ver em que ele pode nos ajudar.

Quando executamos nossa aplicação vocês se lembram que tivemos que infomar no classpath o arquivo Ola.jar para que fosse possível rodar a classe “init.UsaOlaMundo”, agora iremos criar um arquivo de manifesto para que seja possível rodar nossa aplicação informando apenas o arquivo Ola.jar e não mais o nome da classe e pacote (init.UsaOlaMundo).

Para isso criaremos o nosso próprio MANIFEST.MF, salvem o código abaixo em um arquivo chamado MANIFEST.MT dentro do diretório “bin”.

Manifest-Version: 1.0
Created-By: Dayvid Lima
Main-Class: init.UsaOlaMundo

O mais importante aqui é a última linha “Main-Class: init.OlaMundo”, aqui eu digo qual classe será chamada quando o arquivo Ola.jar for executado.

Arquivo salvo, estamos prontos para continuar. Dentro do diretório bin vamos apagar o nosso antigo Ola.jar e criar um novo, agora informando qual arquivo de manifesto que iremos utilizar,
Para isso basta mudar um pouco nosso comando jar como no exemplo abaixo:
jar cvfm Ola.jar MANIFEST.MF init/*

Agora para rodar nossa aplicação precisamos apenas do comando abaixo:
java -jar Ola.jar

E o arquivo MANIFEST.MF se encarrega de dizer a virtual machine qual a classe que queremos que seja executada.

Anexo deixo para download o arquivo jarfiles.zip, contendo os arquivos citados nesse artigo para facilitar o trabalho de todos, mais uma vez espero que este artigo tenha sido satisfatório e que venha a ajudar, até o próximo.

Fonte: http://www.plugmasters.com.br/sys/materias/793/1/Criando-arquivos-.jar

Dayvid Lima Desenvolvedor Java há mais de 5 anos, atualmente consultor java em empresa multinacional utilizando recursos avançados da tecnologia J2EE com servidores de aplicação em plataforma Solaris para gerenciamento de redes e integração de sistemas.

Oracle compra Sun por US$ 7,4 bilhões

Rogil – Após negociação com IBM, Sun é comprada pela Oracle em negócio que pagará US$ 9,5 por ação.

A Oracle comprou a Sun Microsystems por 7,4 bilhões de dólares, impulsionando a desenvolvedora de softwares corporativos no setor de hardware e fazendo com que a Sun seja a mais recente operação de TI englobada pela empresa comandada por Larry Ellison.

A Oracle pagará 9,5 dólares por ação em dinheiro para a Sun, de acordo com a Oracle, aumento de 42% em relação ao preço do seu fechamento na sexta-feira (17/04). Excluindo débitos, a aquisição é avaliada em 5,6 bilhões de dólares.

A aquisição da Sun segue outras compras feitas pela Oracle no setor de tecnologia nos últimos anos, como Siebel, PeopleSoft e BEA Systems.

O acordo é anunciado após a Sun ter se afastado de uma negociação com a IBM há algumas semanas.

Ainda que houvesse boatos sobre uma possível aquisição por parte da Oracle, a empresa nunca tinha tido uma participação nos setores de sistema operacional para servidores ou hardware.

A Oracle afirmou que o acordo com a Sun deve trazer mais receita à companhia no primeiro ano após a compra do que as aquisições da BEA Systems, PeopleSoft e Siebel juntas.

A Sun deverá contribuir com 1,5 bilhão de dólares ao lucro operacional da Oracle no primeiro ano após a fusão, número que deverá ultrapassar a marca dos 2 bilhões de dólares no segundo ano, anunciou a Oracle.

Fonte: http://idgnow.uol.com.br/mercado/2009/04/20/oracle-compra-sun-por-us-7-4-bilhoes/

Instalando e Configurando o Java (JDK) no Ubuntu 8.04

13-08-2008
Escrito por Paulo Cassiano
Fonte: http://paulocassiano.wordpress.com/2008/08/13/instalar-java-ubuntu-804/

Para instalar e configurar o JDK (versão 6) no Ubuntu 8.04, siga esses passos:

1) Abra uma janela de terminal;

2) Digite: $ sudo apt-get -y install sun-java6-bin sun-java6-plugin sun-java6-jre sun-java6-jdk sun-java6-fonts <ENTER>; Em seguinda, digite a senha de root <ENTER>;

3) Apesar de termos usado a opção -y no passo anterior, é necessário rolar a janela do terminal em que ele exibe a Licença de Uso até o final e, ao final, digitar y <ENTER>;

4) Agora digite: $ sudo update-java-alternatives -s java-6-sun <ENTER>

É necessário editar o arquivo /etc/jvm. Ele define a ordem de pesquisa padrão da JVM no sistema. Cada JVM deve listar seu diretório JAVA_HOME compatível neste arquivo. A JVM padrão do sistema é a primeira disponível de cima para baixo. Para abrir o arquivo:

5) Digite: $ sudo gedit /etc/jvm <ENTER>

Certifique-se que a linha /usr/lib/jvm/java-6-sun está adicionada no topo da lista. O arquivo deverá ficar assim:

/usr/lib/jvm/java-6-sun
/usr/lib/jvm/java-gcj
/usr/lib/jvm/ia32-java-1.5.0-sun
/usr/lib/jvm/java-1.5.0-sun
/usr

Salve e feche o arquivo.

Agora vamos configurar as variáveis de ambiente (JAVA-HOME e PATH).

6) Abra o arquivo $HOME/.bash_profile: $ sudo gedit $HOME/.bash_profile <ENTER>

Adicione as seguintes linhas:

export JAVA_HOME=/usr/lib/jvm/java-6-sun
export PATH=$PATH:$JAVA_HOME/bin

Salve e feche o arquivo.

7) Para testar a instalação, digite o seguinte comando no terminal: $ java -version <ENTER>

Se a saída for:

java version “1.6.0_03″
Java(TM) SE Runtime Environment (build 1.6.0_03-b05)
Java HotSpot(TM) Server VM (build 1.6.0_03-b05, mixed mode)

A instalação foi feita corretamente ;-)

Agora vamos criar um programa de teste.

8 ) Digite: $ gedit Teste.java <ENTER>

e acrescente as linhas abaixo:

public class Teste {
public static void main(String[] args) {
System.out.println(”A instalação funcionou!”);
}
}

Salve e feche o arquivo.

Agora vamos compilar o arquivo Teste.java.

9) Digite: $ javac Teste.java <ENTER>

E para executar este pequeno programa,

10) Digite: $ java Teste <ENTER>

Se a saída exibida for:

A instalação funcionou!

Parabéns! O JDK foi instalado corretamente em seu sistema. Agora você já pode desenvolver em Java usando o Ubuntu.

Principais Atalhos da IDE Eclipse

Conteudo retirado do site: http://robsonmedeiros.wordpress.com/2008/06/20/principais-atalhos-da-ide-eclipse/

Alguns dos principais atalhos da IDE Eclipse.

Busca

  • Ctrl+Shift+R
    Busca e abre rapidamente qualquer item do projeto, seja ele uma classe, arquivo XML, arquivo de properties, bytecode etc.
  • Ctrl+T
    Mostra a hierarquia da classe atual, permitindo abrir rapidamente qualquer classe da hierarquia.
  • Ctrl+H
    Abre a janela de pesquisa nos arquivos do workspace. Nela é possível procurar tanto por trechos textuais nos arquivos, quanto por referências a elementos da linguagem como tipos, métodos, pacotes, atributos etc.
  • Ctrl+J
    Busca incremental no arquivo aberto. O cursor é posicionado no trecho de código correspondente à medida em que o programador digita o termo de pesquisa.
  • Ctrl+Alt+G
    Pesquisa no workspace por todas as ocorrências do elemento sobre o qual o cursor está posicionado.

Navegação no código

  • Alt+Left
    Volta para a última posição editada.
  • Alt+Right
    Avança para a próxima posição editada.
  • Ctrl+O
    Mostra a estrutura (outline) do arquivo que está sendo editado e permite navegar até declaração selecionada.
  • Ctrl+G
    Localiza a declaração da classe, interface, atributo ou método selecionado.
  • Crtl+Shift+G
    Localiza todas as referências à classe, interface, atributo ou método selecionado existentes no workspace.
  • Ctrl+3
    Navegação rápida. Navega entre todos os itens abertos em todas as views e perspectivas abertas no momento. Novo no Eclipse 3.3 .

Organização do código

  • Crtl+Shift+F
    Formata automaticamente o trecho de código selecionado de acordo com as configurações definidas em Window > Preferences > Java > Code Style > Formatter
  • Crtl+Shift+O
    Organiza os imports do arquivo aberto, removendo as declarações desnecessárias.
  • Alt+(Seta para cima ou para baixo)
    Move a linha atual para cima ou para baixo.
  • Alt+Shift + (Seta para cima ou baixo)
    Copia a linha atual para cima ou para baixo

Depuração

  • Ctrl+1
    Invoca a funcionalidade de reparo rápido (quick fix) quando o compilador acusa algum erro. O reparo rápido consiste em um pop-up com uma lista de sugestões de modificação que são aplicadas automaticamente ao selecionar.
  • Ctrl+Shift+I
    Inspeciona o valor das variáveis enquanto ocorre a depuração. Disponível apenas na perspectiva Debug.

Refactoring

  • Alt+Shift+R
    Renomeia o elemento.
  • Alt+Shift+L
    Extrair para variável local. Atribui a expressão selecionada a uma váriavel.
  • Alt+Shift+M
    Extrair método. Cria um novo método contendo o trecho de código selecionado.

Configuração

  • Ctrl+Shift+L
    Mostra a lista de atalhos de teclado.
  • Ctrl+Shift+L duas vezes
    Abre a tela de personalização de atalhos de teclado.

Protegendo o seu código java da engenharia reversa

Fonte: http://erkobridee.com/2008/06/19/protegendo-o-seu-cdigo-java-da-engenharia-reversa/

Publicado por Erko Bridee em 19/06/2008 18:02 pm | sobre: Desenvolvimento, JAVA, Segurança, Tutorial, tilidade

Caso você seja um desenvolvedor de aplicações java, é importante compreender que os arquivos binários .class do Java podem ser facilmente descompilados em uma engenharia reversa. Neste post iremos ver como um arquivo .class Java é revertido para um fonte Java e como proteger o seu código disto.

O código fonte java é compilado para um arquivo ,class, o qual possui o código binário. A máquina virtual Java (JVM) precisa apenas desse arquivo para executar a sua aplicação. O problema é que este arquivo .class pode ser facilmente descompilado, recuperando o seu código fonte original, utilizando alguma ferramenta para descompilação do .class e caso você procure no Google irá perceber que não é dificil encontrar uma ferramenta para fazer exatamente isto.

A melhor solução para previnir a engenharia reversa é ofuscar o nosso arquivo .class, o que irá dificultar e muito a engenharia versa. De acordo com o dicionário ofuscar que dizer “tornar algo obscuro, não compreensível“. E é exatamente isto o que muitas ferramentas de ofuscar faz, como será explicado a seguir.

Descompilando um arquivo .class Java

Antes de compreender como um ofuscar um código java, vamos tentar compreender como alguem consegue realziar uma engenharia reversa da sua aplicação java. A seguir 3 passos para explicar como um arquivo .class é recuperado desse o código fonte java original, usando técnicas de engenharia reversa.

1. Crie um HelloWorld.java como o código abaixo:

  1. public class HelloWorld {  
  2.     public static void main (String args[]) {  
  3.         String userMessage = “Hello World!”;  
  4.         int userCount = 100;  
  5.         userCount = userCount + 1;  
  6.         System.out.println(userMessage);  
  7.         System.out.println(userCount);  
  8.     }  
  9. }  
public class HelloWorld {
    public static void main (String args[]) {
        String userMessage = “Hello World!”;
        int userCount = 100;
        userCount = userCount + 1;
        System.out.println(userMessage);
        System.out.println(userCount);
    }
}

2. Compile o programa HelloWorld.java e execute, algo como o feito a seguir:

$ javac HelloWorld.java
$ java HelloWorld
Hello World!
101

O arquivo Java .class contém apenas o byte code. caso você tente ver o conteúdo do arquivo .class, irá notar que é algo que humanamente não é compreensível, como o que é mostrado abaixo:

$ vi HelloWorld.class
Ãþº¾^@^@^@2^@
^@^G^@^P^H^@^Q  ^@^R^@^S
^@^T^@^V^G^@^W^G^@^X^A^@^F<init>^A^@^C()V^A^@^DCode^A^@^OLineNumberTable
^A^@^Dmain^A^@^V([Ljava/lang/String;)V^A^@
SourceFile^A^@^OHelloWorld.java^L^@^H^@ ^A^@^LHello World!^G^@^Y^L^@^Z^@^[^G^@^\^L^@^]^@^^^L^@^]^@^_^A^@
HelloWorld^A^@^Pjava/lang/Object^A^@^Pjava/lang/System^A^@^Cout^A^@^ULjava/io/PrintStream;^A
^@^Sjava/io/PrintStream^A^@^Gprintln^A^@^U(Ljava/lang/String;)V^A^@^D(I)V^@!^@^F^@^G^@^@^@^@^@^B^@^A^@^H^@  ^@^A^@

3. Descompilando o arquivo HelloWorld.class e vendo o código fonte original

Para esta demonstração utilizaremos o decompilador Jad que é gratuíto para um uso não comercial. Realize o download da respectiva versão para o seu sistema operacional. Use o jad para realizar a engenharia reversa do arquivo HelloWorld.class e recuperer o código fonte original, como mostrado a seguir:

$ unzip jadls158.zip
$ ./jad HelloWorld.class
Parsing HelloWorld.class…
Generating HelloWorld.jad
$ vi HelloWorld.jad <Isto irá mostrar o código fonte original, fruto da execução da engenharia reversa>

Ofuscando a sua aplicação java

Agora iremos ver como ofuscar e proteger o seu código fonte da engenharia reversa, usando o ProGuard que é um software gratuíto com licensa GPL.

1. Faça o Download e instale o ProGuard

$ cd /home/jsmith
$ unzip proguard4.2.zip

2. Crie um arquivo de configuração proguard

Crie um myconfig.pro que conterá as informações sobre a sua aplicação java.

-injar : Especifica a localização do seu arquivo jar, o qual contém os arquivos .class da compilação da sua classe java.

-outjar : Este é o arquivo jar que o proguard irá criar após a ofuscação do código. Este conterá todo o código alterado, lacrado, com as nomenclaturas de métodos e variáveis obscurar, o que vai dificultar muito para algum humano converseguir realizar a engenharia reversa.

-printmapping : ProGurad irá gerar uma saída com todas as saídas, em um arquivo com as informações mapeadas, em um arquivo que você especificar.

-keep : Incida os arquivos .class ou os métodos que você não quer que o ProGuard altere.

Para exemplificar, imagineos um mypkg.MainAppFrame como informação de onde está a nossa classe principal da aplicação, sendo esta classe neste exemplo, nós não queremos que seja ofuscada pelo ProGuard, como no exemplo a seguir:

$ cat myconfig.pro
-injars /home/jsmith/myapp.jar
-outjars /home/jsmith/myapp-obfuscated.jar This is the obfuscated jar file
-libraryjars /usr/java/jdk1.5.0_14/jre/lib/rt.jar
-printmapping proguard.map
-verbose
-keep public class mypkg.MainAppFrame

3. Execute o ProGuard

$ cd /home/jsmith/proguard4.2/lib
$ java -jar proguard.jar @myconfig.pro

Isto irá criar 2 arquivos, descritos a seguir:

* myapp-obfuscated.jar: Contém os arquivos das .class ofuscados da sua aplicação. E este você poderá distribuir sem medo algum de que alguem venha tentar realizar uma engenharia reversa, não que seja impossível, mas vai dar muito trabalho, o que acaba fazendo com que desistam da idéia.
* proguard.map: Este arquivo contém as informações do mapeamento para você se referenciar, sobre o que foi feito.

4. Exemplo de arquivo proguard.map

Este exemplo de arquivo proguard.map é o que indica o nome original que havia nos fontes java (nome do .class, métodos, variáveis, etc) e o respectivo nome a ser utilizado.

myapp.AppToolBar -> myapp.ae:
javax.swing.JButton btnNew -> d
javax.swing.JButton btnOpen -> e

5. Exemplo de código java (myapp.AppToolBar) antes de ser ofuscado

  1. btnNew = changeButtonLabel(btnNew, language.getText("new"));  
  2. btnOpen = changeButtonLabel(btnOpen, language.getText("open"));  
btnNew = changeButtonLabel(btnNew, language.getText("new"));
btnOpen = changeButtonLabel(btnOpen, language.getText("open"));

6. Exemplo de código fonte java que foi decompilado de um arquivo .class (myapp.ae) despois deste ter sido ofuscado

  1. d = a(d, n.a("new"));  
  2. e = a(e, n.a("open"));  
d = a(d, n.a("new"));
e = a(e, n.a("open"));

Aqui você pode ver a linha “btnNew = changeButtonLabel(btnNew, language.getText(”new”));” que foi traduzida para “d = a(d, n.a(”new”));”, pelo ProGuard, essa linha de código que não irá fazer sentido nenhum para alguem que venha a decompilar esta classe em uma engenharia reversa.

Tutorial Facelets

Postado por:

Fonte: http://javawora.blogspot.com/search/label/JEE

Olá a todos, este é o primeiro tutorial que aborda o assunto de Facelets aqui no JavaWora. Acredito que todos que gostam de Java Server Faces estão super acostumados com a tecnologia, mas aqueles que usavam Struts e html puro, uma vez no mundo do JSF, uma das principais dificuldades (contornáveis é claro) era compreender a lógica das tags que de certa forma se distância do HTML convencional, o que eu até discordo em partes, afinal acho que um <html:text/> não se aproxima tanto de <input type=”text”/>, mas tudo bem, sabemos que da mesma forma aprender Struts não é uma tarefa das mais fáceis. Enfim vamos ao que interessa.

Um dos pontos que mais desagrada empresas que vão utilizar JSF é a distância do HTML convencional, portanto uma dificuldade de que designers possam efetuar atualizações, manutenções e coisas do gênero em uma página, pois bem, para “simplificar” toda essa dificuldade, foi desenvolvido uma tecnologia chamada de Facelets, aqueles que já viram o Tapestry verão muitas semelhanças, apontada como uma das inspiradoras para o Facelets.
No Tapestry utilizávamos a palavra chave jwcid (Java Web Component Id), para que o Framework substituísse aquele conteúdo por um componente desejado, e eis que apresento a palavra mágica do Facelets: jsfc (Java Server Faces Component). Não se engane isso não é uma cópia descarada, mas uma inspiração do primo de JSF, mas qual a mágica de tal palavrinha no caso de Facelets?O que ganhamos com isso?

Imagine o seguinte, você recebe a pagina HTML do designer, e você tem que alterar tudo aquilo, porque é tudo diferente do que você usa. Seus problemas acabaram! Basta você por uma palavrinha mágica em componentes, por exemplo:

<input type=”text”/>
Adicione:

<input type=”text” jsfc=”h:inputText” value=”#{cadastro.nome}”/>

Mágico, não acham? Um reaproveitamento de código maravilhoso e louvável. Outro ponto que nos interessa em reaproveitamento é a criação de um template, tiles é um bom framework mas deixa a desejar em alguns pontos. Com Facelets podemos definir um template declarativamente, de forma que a página sabe em qual template está inserida, reduzindo o esforço para descobrir seus componentes.
Para criar um template apenas devemos assinar os componentes da página por meio de <ui:insert name=”menu”> dentre as tags do facelets, caso queiramos inserir o conteúdo de um html naquele tag na página que define o template, utilizamos então: <ui:include src=”/templates/menu.xhtml”/>. No momento em que vamos utilizar um determinado template numa página, basta declará-lo: <ui:composition template=”/templates/common.xhtml”>, e inserir o que estmos sobrescrevendo por meio de <ui:define name=”body”>conteúdo</ui:define> no espaço delimitado pelas tags em conteúdo. Mais uma vez, simples, muito simples. O Facelets ainda possui componentização, Ájax integrado, dentre outras funcionalidades, mas vamos nos focar no core aqui, que é templates e reaproveitamento de html original.
O suporte de IDES ao Facelets ainda é fraco, o NetBeans possui um suporte, já no universo eclipse, temos o Exadel e agora o novíssimo Red Hat Developer Studio, os melhores na minha opinião. O exemplo deste tutorial foi desenvolvido com a implementação da Sun e no tomcat 5.5, no tomcat 6 algumas mudanças são necessárias. Os jars necessários são:

  • common-annotations.jar
  • commons-beanutils.jar
  • commons-collections.jar
  • commons-digester.jar
  • commons-logging.jar
  • el-api.jar
  • el-ri.jar
  • jsf-api.jar
  • jsf-facelets.jar
  • jsf-impl.jar
  • jsf-tlds.jar
  • jstl.jar
  • standard.jar


O web-xml necessário está na Figura 1. Criaremos três Classes para nossa lógica, são elas:

Listagem 1 – Login.java
package br.com.facelets.bean;
public class Login {
private String userName;
private String senha;
public Login() {
}
//sets e gets omitidos
@Override
public int hashCode() {
final int PRIME = 31;
int result = 1;
result = PRIME * result + ((senha == null) ? 0 : senha.hashCode());
result = PRIME * result + ((userName == null) ? 0 : userName.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final Login other = (Login) obj;
if (senha == null) {
if (other.senha != null)
return false;
} else if (!senha.equals(other.senha))
return false;
if (userName == null) {
if (other.userName != null)
return false;
} else if (!userName.equals(other.userName))
return false;
return true;
}
}

Listagem 2 – Cadastro.java

package br.com.facelets.bean;
import javax.faces.context.FacesContext;
import br.com.facelets.business.CadastroSaver;
public class Cadastro {
private String nome;
private String senha;
private String userName;
public String getLogin() {
return userName;
}
public void setLogin(String login) {
this.userName = login;
}
//sets e gets omitidos
public String salvar(){
Login login = new Login();
login.setUserName(userName);
login.setSenha(senha);
CadastroSaver.salvar(login, this);
return “ok”;
}
public String logar(){
Login login = new Login();
login.setUserName(userName);
login.setSenha(senha);
Cadastro cadastro = CadastroSaver.busca(login);
if(cadastro!=null){
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(“user”, cadastro);
return “ok”;
}else{
FacesContext.getCurrentInstance().getExternalContext().getRequestMap().put(“erro”, “login/senha inválidos”);
return “erro”;
}
}
}

Listagem 3 – CadastroSaver.java

package br.com.facelets.business;
import java.util.Hashtable;
import br.com.facelets.bean.Cadastro;
import br.com.facelets.bean.Login;
public class CadastroSaver {
private static final Hashtable saver = new Hashtable();
public static void salvar(Login login,Cadastro cadastro){
saver.put(login, cadastro);
}
public static Cadastro busca(Login login){
return saver.get(login);
}
}

E agora o faces-config e as páginas propriamente ditas.

Listagem 4- faces-config.xml

<?xml version=”1.0″ encoding=”UTF-8″?>
<faces-config version=”1.2″ xmlns=”http://java.sun.com/xml/ns/javaee&#8221;
xmlns:xi=”http://www.w3.org/2001/XInclude&#8221;
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221; xsi:schemaLocation=”http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd”&gt;
<managed-bean>
<managed-bean-name>cadastro</managed-bean-name>
<managed-bean-class>br.com.facelets.bean.Cadastro</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>nome</property-name>
<property-class>java.lang.String</property-class>
<value/>
</managed-property>
<managed-property>
<property-name>login</property-name>
<property-class>java.lang.String</property-class>
<value/>
</managed-property>
</managed-bean>
<navigation-rule>
<from-view-id>/pages/dados.xhtml</from-view-id>
<navigation-case>
<from-outcome>ok</from-outcome>
<to-view-id>/pages/inputname.xhtml</to-view-id>
<redirect/>
</navigation-case>
</navigation-rule>
<navigation-rule>
<from-view-id>/pages/login.xhtml</from-view-id>
<navigation-case>
<from-outcome>ok</from-outcome>
<to-view-id>/pages/greeting.xhtml</to-view-id>
<redirect/>
</navigation-case>
<navigation-case>
<from-outcome>erro</from-outcome>
<to-view-id>/pages/login.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
<application>
<view-handler>com.sun.facelets.FaceletViewHandler</view-handler>
<resource-bundle>
<base-name>resources</base-name>
<var>msg</var>
</resource-bundle>
<message-bundle>resources</message-bundle>
</application>
</faces-config>

Listagem 5 – menu.xhtml

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”&gt;
<html xmlns=”http://www.w3.org/1999/xhtml&#8221;
xmlns:ui=”http://java.sun.com/jsf/facelets&#8221;
xmlns:h=”http://java.sun.com/jsf/html&#8221;
xmlns:f=”http://java.sun.com/jsf/core”&gt;
<body bgcolor=”#ffffff”>
<table style=”border:1px solid #CAD6E0″ align=”center” cellpadding=”0″ cellspacing=”0″ border=”0″>
<tbody>
<tr>
<td colspan=”2″ valign=”bottom” height=”1″ bgcolor=”#CAD6E0″>
<table>
<tr>
<td>
<a href=”dados.jsf”>Incluir dados</a>
</td>
</tr>
<tr>
<td>
<a href=”login.jsf”>Login</a>
</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
</body>
</html>

Listagem 6 – common.xhtml

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”&gt;
<html xmlns=”http://www.w3.org/1999/xhtml&#8221;
xmlns:ui=”http://java.sun.com/jsf/facelets&#8221;
xmlns:h=”http://java.sun.com/jsf/html&#8221;
xmlns:f=”http://java.sun.com/jsf/core”&gt;
<span jsfc=”f:loadBundle” basename=”resources” var=”msg”/>
<head>
<title>
<ui:insert name=”pageTitle”>JavaWora</ui:insert>
</title>
<style type=”text/css”>
body {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 14px;
}
.header {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 18px;
}
.bottom {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 9px;
text-align: center;
vertical-align: middle;
color: #8E969D;
}
</style>
</head>
<body bgcolor=”#ffffff”>
<table style=”border:1px solid #CAD6E0″ align=”center” cellpadding=”0″ cellspacing=”0″ border=”0″ width=”400″>
<tbody>
<tr>
<td class=”header” align=”center” valign=”middle” width=”100%” bgcolor=”#E4EBEB”>
<ui:insert name=”pageHeader”>JavaWora Facelets</ui:insert>
</td>
</tr>
<tr>
<td height=”1″ width=”100%” bgcolor=”#CAD6E0″></td>
</tr>
<tr>
<td width=”100%”>
<table width=”100%” style=”height:150px” align=”left” cellpadding=”0″
cellspacing=”0″ border=”0″>
<tbody>
<tr>
<td align=”center” width=”10%” valign=”middle”>
<ui:insert name=”menu”>
<ui:include src=”/templates/menu.xhtml”/>
</ui:insert>
</td>
<td align=”center” width=”75%” valign=”middle”>
<ui:insert name=”body”>Page Body</ui:insert>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td colspan=”2″ valign=”bottom” height=”1″ width=”100%” bgcolor=”#CAD6E0″></td>
</tr>
</tbody>
</table>
</body>
</html>

Listagem 7 – cadastro.xhtml

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”&gt;
<ui:composition xmlns=”http://www.w3.org/1999/xhtml&#8221;
xmlns:ui=”http://java.sun.com/jsf/facelets&#8221;
xmlns:h=”http://java.sun.com/jsf/html&#8221;
xmlns:f=”http://java.sun.com/jsf/core&#8221;
template=”/templates/common.xhtml”>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=ISO-8859-1″ />
<title>Cadastro</title>
</head>
<ui:define name=”body”>
<form jsfc=”h:form” id=”cadastro”>
<table>
<tr>
<td>Nome*:</td>
<td>
<input type=”text” jsfc=”h:inputText” value=”#{cadastro.nome}” id=”nome” label=”#{msg.lbl.nome}” required=”true” requiredMessage=”#{msg.erroRequired}”/>
</td>
<td><h:message for=”nome” id=”erroNome”></h:message> </td>
</tr>
<tr>
<td>login*:</td>
<td>
<input type=”text” jsfc=”h:inputText” value=”#{cadastro.login}” id=”login” label=”#{msg.lbl.login}” required=”true” requiredMessage=”#{msg.erroRequired}”/>
</td>
<td><h:message for=”login” id=”erroLogin”></h:message> </td>
</tr>
<tr>
<td>senha*:</td>
<td>
<input type=”text” jsfc=”h:inputSecret” value=”#{cadastro.senha}” id=”senha” label=”${msg.lbl.senha}” required=”true” requiredMessage=”#{msg.erroRequired}”/>
</td>
<td><h:message for=”senha” id=”erroSenha”></h:message> </td>
</tr>
<tr>
<td>Estado Civil:</td>
<td>
<select jsfc=”h:selectOneMenu” value=”#{cadastro.idEstado}” id=”eCivil” label=”#{msg.lbl.estadoCivil}”>
<option jsfc=”f:selectItem” itemValue=”1″ itemLabel=”Casado”></option>
<option jsfc=”f:selectItem” itemValue=”2″ itemLabel=”Solteiro”></option>
<option jsfc=”f:selectItem” itemValue=”3″ itemLabel=”Divorciado”></option>
</select>
</td>
</tr>
<tr>
<td colspan=”2″ align=”center”>
<input type=”submit” value=”Salvar” jsfc=”h:commandButton” action=”#{cadastro.salvar}”/>
</td>
</tr>
</table>
</form>
</ui:define>
</ui:composition>

Listagem 8 – inputname.xhtml

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”&gt;
<html xmlns=”http://www.w3.org/1999/xhtml&#8221;
xmlns:ui=”http://java.sun.com/jsf/facelets&#8221;
xmlns:h=”http://java.sun.com/jsf/html&#8221;
xmlns:f=”http://java.sun.com/jsf/core&#8221;
xmlns:c=”http://java.sun.com/jstl/core”&gt;
<ui:composition template=”/templates/common.xhtml”>
<ui:define name=”pageTitle”>
Bem Vindo
</ui:define>
<ui:define name=”pageHeader”>
Home
</ui:define>
<ui:define name=”body”>
${msg.prompt}
</ui:define>
</ui:composition>
</html>

Listagem 9 – greeting.xhtml

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”&gt;
<html xmlns=”http://www.w3.org/1999/xhtml&#8221;
xmlns:ui=”http://java.sun.com/jsf/facelets&#8221;
xmlns:h=”http://java.sun.com/jsf/html&#8221;
xmlns:f=”http://java.sun.com/jsf/core”&gt;
<f:loadBundle basename=”resources” var=”msg” />
<ui:composition template=”/templates/common.xhtml”>
<ui:define name=”body”>
#{msg.greeting} <span jsfc=”h:outputLabel” value=”#{sessionScope.user.nome}”/>!
</ui:define>
</ui:composition>
</html>

Listagem 10 – login.xhtml

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”&gt;
<ui:composition xmlns=”http://www.w3.org/1999/xhtml&#8221;
xmlns:ui=”http://java.sun.com/jsf/facelets&#8221;
xmlns:h=”http://java.sun.com/jsf/html&#8221;
xmlns:f=”http://java.sun.com/jsf/core&#8221;
template=”/templates/common.xhtml”>
<ui:define name=”body”>
#{erro}
<form jsfc=”h:form” id=”login”>
<table>
<tr>
<td>Login:</td><td><input jsfc=”h:inputText” value=”#{cadastro.login}” type=”text”/></td>
</tr>
<tr>
<td>Senha:</td><td><input jsfc=”h:inputSecret” value=”#{cadastro.senha}” type=”password”/></td>
</tr>
<tr>
<td colspan=”2″ align=”center”>
<input jsfc=”h:commandButton” action=”#{cadastro.logar}” type=”submit” value=”OK”/>
</td>
</tr>
</table>
</form>
</ui:define>
</ui:composition>

Experimente abrir a pagina de login no firefox, ie, ou qualquer ferramenta WYSIWYG (acho q é isso) e veja que os parametros estão lá, até a pagina, mas como isso é possível? Ora como eu disse trata-se de uma página simples xhml, a propósito podemos trabalhar com xhtml diretamente em facelets, ou mesmo jsps, mas xhtml é mais legal. A aplicação consiste em efetuar um cadastro e logo após um login para verificar se os dados foram armazenados.
Agora vamos as curiosidades. Conforme observado no web.xml, há dois listeners registrados, eles são necessários para o Tomcat 5.5, pois o compilador utilizado no facelets não é o Jasper que vêm nele, mas um próprio.
No web.xml observe a sentença:

<context-param>
<param-name>facelets.DEVELOPMENT</param-name>
<param-value>true</param-value>
</context-param>

Cause um erro em uma página e observe o que ocorre, figura 2:

O compilador descreve o erro e lhe auxilia com a arvores de componentes gerada e os dados do que estavam presentes. Legal né! Pois agora troque a sentença para false. Você verá que o erro agora é apresentado como na figura 3. Bonito não?!

Obrigado e até mais!

Criar um pool de conexões no Apache Tomcat

Fonte: http://www.antoniopassos.pro.br/blog/?p=88

1)Configurando o pool de conexões…

No diretório META-INF da aplicação, crie um arquivo “context.xml” com o seguinte conteúdo…

<?xml version=”1.0″ encoding=”UTF-8″?>
<Context auth=”Container”>
<Resource
name=”jdbc/bd_teste”
type=”javax.sql.DataSource”
url=”jdbc:mckoi://localhost:59999/”
driverClassName=”com.mckoi.JDBCDriver”
username=”admin”
password=”123456″
maxActive=”100″
maxIdle=”20″/>
</Context>

Significado de cada atributo usado no arquivo “context.xml“…

  • auth –> Atribui ao Apache Tomcat a responsabilidade de gerenciar a abertura e o fechamento das conexões
  • name –> Nome dado ao pool de conexões. Deve obedecer o formato JNDIATENÇÃO: O NOME DADO AO POOL DEVERÁ SER O MESMO USADO NO ARQUIVO WEB.XML DA APLICAÇÃO.
  • type –> Especifica o tipo como sendo DataSource
  • url –> Especifica a localização do banco de dados. Deve obedecer o formato URL JDBC
  • driverClassName –> Nome da classe do driver JDBC do banco de dados
  • username –> Nome do usuário do BD
  • password –> Senha do usuário do BD
  • maxActive –> Número máximo de conexões ativas no pool
  • maxIdle –> Número máximo de conexões inativas no pool
  • maxWait –> Tempo máximo de espera por uma conexão, em milissegundos

2)Registrando o pool no aplicativo…

No arquivo “web.xml” da aplicação, insira as linhas abaixo…

<resource-ref>
<res-ref-name>
jdbc/bd_teste
</res-ref-name>
<res-type>
javax.sql.DataSource
</res-type>
<res-auth>
Container
</res-auth>
</resource-ref>

ATENÇÃO: O valor em “<res-ref-name>” deve corresponder ao nome dado ao pool de conexões no arquivo “context.xml”. No caso a “jdbc/bd_teste”.

3)Testando o pool..

3.1) Crie uma classe “ServiceLocator.java” com o seguinte conteúdo…

import java.sql.Connection;
import javax.naming.InitialContext;
import javax.sql.DataSource;

public class ServiceLocator {

public static Connection getConexao(String JNDINome) throws Exception {
Connection con = null;

// Obtém a raiz da hierarquia de nomes
InitialContext contexto = new InitialContext();

// Obtém a origem dos dados
DataSource ds = (DataSource)contexto.lookup(“java:comp/env/” + JNDINome);

// Obtém uma conexão
con = ds.getConnection();

// Retorna a conexão
return con;
}
}

3.2) Crie um servlet, que use a classe ServiceLocator acima para obter uma conexão do pool…

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ServletExemplo extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {

private static final String JNDINome = “jdbc/bd_teste”;

public ServletExemplo() {
super();
}

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType(“text/html”);
PrintWriter out = response.getWriter();
out.println(“<h1>Filmes cadastrados</h1>”);

Connection con = null;
try {
con = ServiceLocator.getConexao(JNDINome);
} catch (Exception e) {
e.printStackTrace();
}

String sql = “SELECT * FROM filmes”;
PreparedStatement stmt;
try {
stmt = con.prepareStatement(sql);
ResultSet rs = stmt.executeQuery();
while (rs.next()){
out.println(“Código -> ” + rs.getInt(1) + ” Título -> ” + rs.getString(2));
}
} catch (SQLException e) {
e.printStackTrace();
}
}

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}

<!–
google_ad_client = “pub-9909948656853681”;
google_ad_output = “textlink”;
google_ad_format = “ref_text”;
google_cpa_choice = “CAAQmbj2_gEaCNYZLJsrWhfIKL264YcBMAA”;
google_ad_channel = “9871635485”;
//–>

Entendendo o serialVersionUID

Por Paulo Silveira em 01/04/2008 –

Fonte: http://blog.caelum.com.br/2008/04/01/entendendo-o-serialversionuid/

O serialVersionUID é uma dúvida constante entre muitos desenvolvedores. Afinal, quando e para que exatamente usá-lo? Devo gerar um número aleatório bem grande, ou um número qualquer? Essas perguntas são comuns, e ao desenvolvedor experiente é necessário conhecer a fundo esse detalhe do processo de serialização do Java.

Quando um objeto é serializado no Java, essa sequência de bytes, além de conter seus atributos de instância não transientes, carrega consigo um número que indentifica a “versão” da classe que foi usada durante o processo. Esse é o chamado serialVersionUID, ou seja, o indentificador de versão de serialização de uma classe. Esse número é utilizado para saber se o objeto que estamos recuperando é de uma versão “compatível” com a versão da classe que foi utilizada quando serializamos o objeto: em outras palavras, os arquivos .class não precisam ser necessariamente os mesmos para que o processo de serialização ocorra com sucesso.

Por exemplo, considere a seguinte classe Usuario:

package br.com.caelum;

public class Usuario implements Serializable {
  private String login;
}

Essa classe possui o serialVersionUID igual a 2806421523585360625L. Esse número não é aleatório! Ele é um hash (SHA) calculado em cima dos nomes dos seus atributos, e assinaturas dos métodos em uma ordem bem definida pela especificação do processo de serialização. E como eu sei esse número? O JDK vem com a ferramenta serialver, que implementa esse mesmo hash:

serialver br.com.caelum.Usuario

Se o serialVersionUID utilizado durante a serialização não bater exatamente com o serialVersionUID da classe que está sendo usada para recuperar essa informação, uma exception é lançada: java.io.InvalidClassException.

Por exemplo, se adicionarmos um novo atributo na nossa classe Usuario:

public class Usuario implements Serializable {
  private String login;
  private String senha;
}

Agora teremos o serialVersionUID valendo 416295346730660862L. Caso você serialize um Usuario com a primeira classe aqui definida, e tentar recuperar essa informação usando essa nova versão de classe, receberemos a conhecida java.io.InvalidClassException. Esse é o comportamente que em muitos casos queremos, mas algumas vezes fazemos pequenas modificações na classe as quais percebemos que não impactarão no processo de serialização, e precisamos manter compatibilidade com a versão antiga daquela classe. Para isso, basta definirmos explicitamente qual é o nosso serialVersionUID, e no caso de querer manter compatibilidade com a classe Usuario anterior, vamos utilizar o valor de serialVersionUID que seria gerado pela JVM: 2806421523585360625L. O código ficaria:

public class Usuario implements Serializable {
  private static final long serialVersionUID = 2806421523585360625L;
  private String login;
  private String senha;
}

Às vezes recebemos um warning do Eclipse, e ele pede para que seja definido o serialVersionUID da classe em questão. Isso ocorre porque você implementa Serializable ou uma de suas mães a implementa. O Eclipse então te abre três opções: utilizar o @SurpressWarnings para você assumir o risco, usar um valor default, ou usar o valor gerado. O gerador de UIDs do Eclipse é exatamente o mesmo gerador utilizado pelo Java SE para criar os UIDs padrão! Reforçando, esse número não é um número aleatório!

serialVersionUIDQuando alguém esquece de manter o mesmo serialVersionUID para duas versões compatíveis de uma classe, podemos ter problemas em usar diferentes versões do software que são teoricamente compatíveis. Isso muitas vezes acontece em servidores de aplicação, e se seu cliente esta desatualizado em relação a versão dos jars necessários pelo servidor, podemos ter alguns InvalidClassExceptions que poderiam ser facilmente evitados se o serialVersionUID tivesse sido corretamente aplicado. Claro que algumas outras vezes as versões realmente não são compatíveis e a exception procede.

Esse grave problema pode acontecer mesmo usando classes do Java SE entre diferentes versões, como é o caso da classe java.text.AttributedCharacterIterator.Attribute (utilizada pela java.awt.Font). Do Java 1.3 para o Java 1.4 essa classe foi levemente alterada, e o serialVersionUID gerado pelo algoritmo da JVM desta classe mudou de -1514471214376796190L para -9142742483513960612L. Quando alguém serializava uma java.awt.Font em uma versão não podia desserializa-la em outra, sendo que as versões tecnicamente são compatíveis: a não definição explícita do serialVersionUID gerou um bug no Java SE. Como isto foi resolvido? Definiram o serialVersionUID como -1514471214376796190L, que é o valor que seria gerado pela JVM na versão anterior da classe.

Como então devemos proceder para escolher um serialVersionUID apropriado? É muito simples: se essa classe está nascendo neste momento, você pode se dar ao luxo de utilizar um serialVersionUID, como por exemplo:

public class Usuario implements Serializable {
  private static final serialVersionUID = 1L;
  private String login;
}

Porém se você está definindo o serialVersionUID de uma classe já em produção, e sabe que a mudança que está fazendo é compatível com a versão anterior, você deve utilizar o serialVersionUID que seria gerado pela JVM na primeira versão, como foi o caso aqui quando adicionamos o atributo senha na classe Usuario, e também foi o caso da correção do bug da classe java.text.AttributedCharacterIterator.Attribute. Quando você fizer uma alteração onde percebe que o cliente precisará de atualização das classes envolvidas, basta definir um serialVersionUID diferente dos anteriormente utilizados.

Para completar, implementar uma interface que não define métodos (Serializable) e ser forçado a escrever um atributo sem um contrato mais burocrático é um tanto estranho em uma linguagem como o Java. Sem dúvida, se esse mecanismo todo tivesse sido inventado já com a existência de anotações, Serializable seria uma anotação e version um atributo dela, talvez obrigatório, criando algo como @Serializable(version=12345L). Boas serializações e invocações remotas!

Criptografia em 3 linhas

Fonte: http://jchrisos.wordpress.com/2008/03/26/criptografia-em-3-linhas/

Olá pessoal!!!

Todos sabem como é importante uma aplicação ter segurança, tanto ela sendo para web, desktop, dispositivos móveis, etc. Por isso existem vários conceitos de segurança de software e um deles é a criptografia. Para saber mais sobre criptografia clique aqui e segurança da informação clique aqui. Neste post mostrarei um exemplo de como criptografar uma senha utilizando o algoritmo MD5.

Eu já vi muitos tutoriais ensinando como criptografar informações, mas todos faziam uma implementação horrível, utilizavam arrays de bytes que depois cada elemento era tranformado em um valor hexadecimal e mais outras coisas. A classe no final tinha 20 a 30 linhas, lembrando até aqueles tutoriais ou livros de Java 1.2!!

Como eu não estava contente com essas implementações, dei uma fuçada no google e achei uma implementação que é muito simples. Essa implementação tem três linhas de código e gera o mesmo resultado dos monstrengos de 30 linhas.

Segue o código:


import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class TesteCriptografia {

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

String input = "123456";

MessageDigest md = MessageDigest.getInstance("MD5");
BigInteger hash = new BigInteger(1, md.digest(input.getBytes()));
String output = hash.toString(16);

System.out.println(output.toUpperCase());

}

}

Quando é referenciada uma instância de MessageDigest é necessário tratar a exception NoSuchAlgorithmException, porque pode ser lançada caso seja passado um algoritmo que não exista, por exemplo MDiii5. Mas pra que você vai colocar um algoritmo que não exista?!

Eu testei a mesma senha nesta e em mais 2 implementações diferentes e todas deram o mesmo resultado. Então esta é uma implementação que trabalha da mesma forma trazendo os mesmos resultados, porém de uma implementação muito mais simples.

Até o proximo post!

Introdução ao Eclipse RCP

Conheça a plataforma que está revolucionando a maneira de desenvolver sistemas desktop com Java.

 

Autor: André Castiliano

Fonte: http://www.devmedia.com.br/articles/viewcomp.asp?comp=4352

 

A plataforma RCP do eclipse fornece uma maneira simples, poderosa e flexível de desenvolver sistemas desktop usando a linguagem de programação Java.

SWT

O Eclipse utiliza o toolkit gráfico SWT (Standard Widget Toolkit) no lugar do tradicional Swing. Existe muito debate sobre qual o melhor deles, cada qual com suas vantagens e desvantagens. O SWT difere do Swing basicamente por não tentar emular componentes, ele usa os controles e diálogos do sistema operacional sobre o qual a JVM está sendo executada. Isto faz com que as aplicações escritas com base no SWT se pareçam com aplicações nativas, como as escritas em Visual Basic ou Delphi, por exemplo, enquanto que o swing desenha os próprios widgets, que mantêm a consistência nas várias plataformas onde é executado, mas com pequenas falhas por não utilizar componentes nativos (um exemplo clássico sendo a tela de ‘Abrir arquivo’ que, apesar de parecer “real”, é falsa, não propiciando ao usuário as mesmas características que a tela nativa do sistema operacional).

Sem querer entrar no mérito da questão, a característica do SWT de herdar o visual das aplicações nativas (e mais do que isso, de usar os componentes nativos do sistema) é o foco de sua existência, e de extrema importância em alguns ambientes onde já se criou resistência ao Java como linguagem de programação para desktop.

O efeito “eu não acredito que isto é Java” provocado pelo SWT/Eclipse realmente existe. Você verá.

É importante notar que, apesar do SWT ser um componente chave da plataforma eclipse, trata-se de uma biblioteca independente, que pode ser utilizada isoladamente para construir aplicações Java para desktop, de maneira simples e rápida.

JFace

Além do SWT, o eclipse usa extensivamente a biblioteca JFace, que extende o SWT básico, adicionando-lhe novos diálogos, controles e classes úteis.

O JFace também pode ser utilizado fora da plataforma eclipse, adicionando mais poder às suas aplicações SWT.

A figura 01 abaixo mostra a relação entre os componentes da plataforma RCP.

inteclrcpfig01.jpg

Figura 01: Eclipse Workbench

Obviamente existem vários outros componentes dentro da plataforma RCP, mas o ‘workbench’ (este e outros termos serão esclarecidos posteriormente) do eclipse é construído usando-se as bibliotecas SWT e JFace.

Se desejar maiores informações sobre o uso das bibliotecas SWT e JFace fora da plataforma eclipse, leiam o artigo SWT, JFace e Componentes – Parte 1 aqui mesmo na DevMedia.

Plugins

No eclipse, tudo são plugins. O próprio eclipse (IDE) é constituído de um conjunto de plugins inter-relacionados. Suas aplicações RCP são também conjuntos de plugins. O “peso” da plataforma RCP gira em torno de 12MB (Eclipse 3.2) variando de acordo com os recursos utilizados.

Para um maior entendimento, vamos criar o famoso exemplo “Hello World” usando a plataforma Eclipse. Afinal, o que seria de um artigo introdutório à uma nova técnica de programação sem um exemplo Hello World ?

Primeiro, caso ainda não o tenha feito, baixe o Eclipse SDK, do site oficial do projeto. No momento em que este artigo estava sendo escrito a versão estável mais recente era a 3.2.1.

Faça também o download do NL1 (Language Pack) para ter seu eclipse traduzido para pt-BR.

A instalação do eclipse é extremamente simples, basta descompactá-lo numa pasta qualquer e executar o eclipse.exe. Claro, estamos presumindo que você já tenha o J2SE JDK instalado em seu computador. Se ainda não tiver, faça o download no site oficial do Java. Cuidado para não baixar o pacote da JDK6 que vem com o NetBeans junto. J

Hello World

Agora que você está com o ambiente pronto, vamos criar o nosso plugin de teste.

No Eclipse, vá em Arquivo à Novo à Projeto conforme ilustrado na figura 02 mostrada abaixo:

inteclrcpfig02.jpg

Figura 02: Novo projeto no eclipse

Surgirá a tela “Novo projeto mostrada na figura 03:

inteclrcpfig03.jpg

Figura 03: Assistente de novo projeto

Selecione a opção Projeto de Plug-In e clique sobre o botão Avançar.

Agora o assistente de novo projeto exibe uma tela semelhante à figura 04 mostrada abaixo:

inteclrcpfig04.jpg

Figura 04: Configurações iniciais do projeto

Nome do projeto: br.com.devmedia.HelloWorld

Aceite o restante das configurações padrão apresentadas nesta tela.

Clique novamente sobre o botão Avançar e a tela agora se parecerá com a figura 05:

inteclrcpfig05.jpg

Figura 05: Detalhes da configuração do plugin

Esta tela tem 2 opções realmente importantes:

A primeira, dentro do grupo “Opções de Plug-in” informa se este plugin fará ou não contribuições à UI (User Interface) do Eclipse. Num projeto de porte médio ou grande você provavelmente terá plugins que não são gráficos, fornecendo apenas recursos aos demais plugins. Por exemplo um plugin com as classes que servem de interface para a camada de persistência.

A segunda opção está dentro do grupo “Aplicativo de Cliente Rich” e permite a você informar se este plugin é a base de um programa RCP. Por padrão vem marcado como Não, mas para o nosso exemplo será necessário alterar esta configuração para Sim, conforme mostrado na figura 05.

Após preencher as opções desta tela, clique novamente sobre o botão “Avançar” e a tela se parecerá com a figura 06:

inteclrcpfig06.jpg

Figura 06: Modelos de aplicativos RCP para escolher

Uma grata surpresa! O assistente de novo projeto do eclipse nos apresenta uma tela com 4 modelos de aplicativos Rich Client para escolher. Estes modelos servem como base para a criação do seu sistema, evitando que muita coisa precise ser escrita “no braço”.

Utilizando um destes modelos, o próprio Eclipse se encarrega de gerar um esqueleto do projeto com todas as classes necessárias para inicializar corretamente o seu aplicativo.

Para o nosso programa de testes, iremos utilizar o modelo que tem o sugestivo nome de “Hello RCP”. Selecione-o na listagem mostrada, conforme indicado pela figura 06.

Você pode agora clicar sobre o botão “Concluir” e deixar que o Eclipse faça a geração do código necessário ou clicar em “Avançar” e preencher mais algumas informações sobre o projeto, como mostrado na figura 07 abaixo:

inteclrcpfig07.jpg

Figura 07: Ultimas informações sobre o novo plugin

Ao clicar em “Concluir” o Eclipse irá gerar todos os arquivos necessários ao seu projeto. Para executar o seu primeiro programa RCP, clique sobre o link “Ativar um Aplicativo Eclipse” na aba que estará aberta após a confirmação no assistente de novo projeto, conforme ilustrado pela figura 08:

inteclrcpfig08.jpg

Figura 08: Editor de configurações do plugin

Executando o nosso plugin Hello World, obtemos:

inteclrcpfig09.jpg

Figura 09: Primeira aplicação RCP

Agora que você já conhece a plataforma Eclipse e o assistente para criação de novos plugins, sugiro que explore os outros modelos apresentados. Estude as classes geradas pelo assistente e leia a documentação disponível no site oficial do projeto eclipse.

Nos próximos artigos, irei aprofundar mais nos meandros da plataforma Eclipse, mostrando dicas e boas práticas ao trabalhar com a plataforma. Iniciaremos a construção de um pequeno sistema de vendas, que nos permitirá abranger áreas bem distintas, que vão desde a construção de telas internas usando SWT/JFace, os detalhes da camada de persistência até os relatórios finais em jasper reports.Até o próximo artigo.

Primeiro passo para SCJP 5.0 – 310-055

Autor: Angelo Vicente Filho (angelomicrolins@gmail.com)

 

Para fazer uma certificação não é necessário ser um excelente programador Java, mas sim, um conhecedor das peculiaridades da linguagem, por conseqüência, aprendemos a trabalhar nossos programas muito mais profissionalmente.

 

Mas como começamos a estudar essa linguagem? Primeiramente, sabemos que tipo de linguagem é Java? Interpretada ou compilada? Ou ambas? Bem, para que possamos entender vamos ver o que faz a JVM (Java Virtual Machine). Essa máquina pega um arquivo e interpreta-o, mas não pode ser totalmente interpretada, pois se isso fosse verdade ela leria automaticamente os arquivos .java, então o compilador javac compila os arquivos com final .java e a JVM os interpreta o que torna a linguagem Java interpretada e pós-compilada.

 

O que é um programa Java?

Um programa Java nada mais é do que uma coleção de objetos conversando com outros objetos por invocação por métodos. Esses objetos são tipos e esses tipos são definidos por classes e interfaces. Então podemos dizer que os programas Java utilizam coleções de objetos de vários tipos diferentes.

 

»                Classe: É um tipo definido pelo usuário que possui especificações (características e comportamentos) que o identifiquem. De uma maneira mais genérica podemos dizer que uma classe nada mais é do que um molde que será usado para construir objetos que representam elementos de vida real.

Classe = Características + Comportamentos;

 

»                Objetos: Digamos que temos um molde chamado Produtos e se eu perguntasse o que é um produto para você o que você iria responder? Para cada pessoa, um produto pode se diferenciar de uma pessoa para outra, isto é, o que pra mim um produto é um carro, para outro um produto pode ser um livro, basta ver o que foi que nós pensamos na hora de que foi feita a pergunta. Imaginamos que o produto fosse um livro. Core Java com preço de R$ 150,00. Quando nos lembramos de um produto isso ficou meio abstrato em nossa cabeça, mas quando falamos que o produto é um livro, veio a nossa cabeça vários livros e isso faz com que a abstração seja mais restrita e quando eu falei que o livro era o Core Java veio o livro em nossas mentes. O que eu quero dizer com isso? Bem, quando falamos em objetos falamos que o molde tomou forma, o objeto nada mais é do que a forma de como instanciamos as classes, e ele tem vida independente entre si apesar de compartilharem o mesmo molde. Exemplo é o ovo de chocolate da páscoa, tem um molde (Classe) e é feito vários ovos (objetos) e cada ovo é diferente do outro o que faz dizer que eles têm vida própria. Um objeto é criado quando utilizamos o operador new.

 

»                Métodos: Através dos métodos definimos as operações que podem ser executadas com ou sobre um objeto. Popularmente diz-se que os métodos definem o comportamento da classe.

 

Fundamentos da Linguagem

Lembrando que aqui usarei todos os padrões do JavaBeans, porém temos que saber que o que manda para a prova da Sun é o que o compilador executa.

 

Lembre-se também que colocarei aqui o que é necessário para que você possa ler e separar para criar a sua lista de estudos, então o que estiver dentro de caixas são muito importante e se você colocar separado em um arquivo e depois ler vai fazer um resumo de tudo aquilo que está aprendendo. E para começar veremos a parte de identificadores.

 

Identificadores Legais

Tecnicamente os identificadores legais são compostos somente por caracteres Unicode, números, símbolos de moeda ($), e conexão de caracter, conhecido como underline ou underscores. Aqui coloquei o que você precisa saber.

 

Identificadores somente começam com letras, símbolo de moeda e underscore ( _ ). Identificadores não podem começar com números!

Depois do primeiro caracter poderá haver a combinação de letras, números e símbolos.

Você não pode usar palavras reservadas Java como identificador. A lista de palavras reservadas aparecerá logo abaixo.

Identificadores Java são case-sensitive; logo foo e FOO são dois identificadores diferentes. {Não existe identificador com letras maiúsculas}

 

Exemplo de identificadores legais:

int _a;

int $c;

int __________2_w;

int _$;

int este_e_um_identificador_valido;

 

Exemplo de identificadores ilegais:

int :b;

int –d;

int #e;

int .fff;

int 7up;

 

avfpripscjpfig01.jpg 

Esta é a lista de palavra reservada

 

Sei que este artigo está meio teórico, mas isso somente acontecerá nos dois primeiros artigos, quando trabalharemos práticas de programação. Até a próxima.

Criando um site dinâmico – Parte I

Autor:

Marcelo Castellani (castellani@itautec.com) é analista de sistemas sênior na Itautec S/A e atua na área de desenvolvimento desde 1996, passando por linguagens como Visual Basic, C, C++ e Java. Mantém o blog hype quino (www.hypequino.com) aonde fala de novas tecnologias em matérias curtas.

 

Fonte: http://www.devmedia.com.br/articles/viewcomp.asp?comp=7241

 

O que é um site dinâmico ?

Temos dois tipos de projeto Web disponíveis no Eclipse, o dynamic web project e o static web project. A diferença entre ambos é que o dynamic, como o próprio nome diz, possibilita o uso de recursos do J2EE que tornam o site dinâmico, como servlets, arquivos JSP, filtros e metadados associados, além de recursos disponíveis para sites do tipo static. Este tipo de projeto web suporta apenas tecnologias padrão, como imagens, páginas HTML, CSS e afins.

 

Projetos dynamic estão sempre encapsulados em um projeto do tipo Enterprise Application Project (EAR), e  o assistente de criação de um projeto dynamic sempre cria um projeto EAR caso este não exista. O assistente também atualiza o descritor de distribuição do projeto EAR para definir o novo Web Project como um elemento do módulo.

 

Criando um novo projeto com o assistente

Com o Eclipse aberto vá em File – New – Project. A janela abaixo será mostrada:


mfccsdp1fig01.jpg

Na lista selecione a opção Web – Dynamic Web Project e clique no botão Next.


mfccsdp1fig02.jpg

A janela abaixo será mostrada.


mfccsdp1fig03.jpg

Você deverá informar as definições do projeto, a saber:

l  Project name: é o nome do projeto, no nosso caso será Projeto01;

l  Project Contents: é o diretório de destino dos arquivos do projeto. Mantendo a opção Use Default marcada faz com que o Eclipse salve as informações no workspace atual, desmarcando permite escolher outro destino. No nosso caso manteremos a opção Use Default marcada;

l  Target Runtime: é o servidor de aplicação a ser usado para rodar o projeto. Em nosso caso vamos adicionar um novo servidor, clicando no botão New. A janela abaixo será mostrada:

 

 mfccsdp1fig04.jpg

 

l  Selecione o Apache Tomcat v5.5 e clique em Next. Você deverá informar o diretório raiz de instalação do Tomcat, um nome para o servidor e qual a JRE a usar, como na figura abaixo. Feito isso clique em Finish;

 

mfccsdp1fig05.jpg

 

l  EAR Membership: caso o projeto vá fazer parte de um projeto do tipo EAR já existente marque a opção add project to an EAR e selecione o projeto na caixa de combinação abaixo. No nosso caso, como falamos ao Eclipse que nosso projeto vai rodar direto no servidor de aplicações, a opção é desabilitada e um novo projeto EAR será criado automaticamente, com o nome de nosso projeto principal, como pode ser visto na imagem abaixo:

 

mfccsdp1fig06.jpg

 

Com tudo definido clique em Finish para iniciar a criação de nosso projeto. Caso seja aberta uma janela com um contrato de licença da Sun apenas clique em Accept. É interessante prestar atenção no topo da página pois nela serão mostradas dicas em caso de problemas. Abaixo você pode ver uma dica, que diz que o nome do projeto não pode estar em branco.

 

mfccsdp1fig07.jpg

 

Entendendo a estrutura de diretórios criada

O Eclipse irá criar automaticamente a estrutura de diretórios e arquivos de nosso projeto, como abaixo:

 

mfccsdp1fig08.jpg

 

Esta estrutura é definida pela J2EE, no documento Sun Microsystems Java™ Servlet 2.5 Specification, aonde toda a estrutura de uma aplicação web é detalhada, definindo a localização de páginas web, arquivos class, caminhos, descritores de distribuição e outros mais.

 

A pasta principal (no nosso caso Projeto01) contém todos os artefatos relacionados a nossa aplicação web e dentro dela encontramos diversos elementos, descritos a seguir. É importante ressaltar que esta estrutura de pastas mapeia a estrutura de um arquivo de aplicação web (Web application archive – WAR), definido também pela Sun Microsystems.

 

A edição deste arquivo, no Eclipse, é feito através de uma interface gráfica, bastando clicar sobre Deployment Descriptor: Projeto01, no project explorer.

mfccsdp1fig09.jpg

 

l  Java Resource (src): Contém o código fonte Java de servlets, classes e beans. O conteúdo deste diretório não é adicionado automaticamente ao WAR que for gerado, apenas se for implicitamente adicionado quando o WAR for criado. Os arquivos deste diretório são compilados diretamente no diretório WEB-INF/classes, em WebContent;

l  WebContent: Diretório principal, aonde encontramos todos os recursos de web, como páginas, arquivos gráficos e afins. Também ficam aqui os arquivos JSP. Dentro dela encontramos as pastas META-INF e WEB-INF.

 

Em META-INF encontramos o arquivo MANIFEST.MF, que é usado para mapear caminhos de classes que sejam dependências de nosso projeto.

 

Em WEB-INF temos o diretório lib, aonde devem ser colocadas bibliotecas que sejam necessárias a aplicação.

Aprendendo Java com o Bope

Fonte: http://jf.eti.br/aprendendo-java-com-o-bope/

Seguimos com novos exemplos inspirados na triste realidade da polícia carioca.


/**
 * O Bope foi criado para atuar quando a policia perde o controle
 * E no rio de janeiro isso acontece com bastante frequencia
 */

class Bope{

	private String nome;
	private int qtdeVitimas = 1; // ja começa bem!
	public Bope(String nome){
		this.nome = nome;

	}

	// sobrecarga do método ondeTaOBaiano
	public void ondeTaOBaiano(Estudante e){
		e.sabeVoarEstudante();
	}

	public void ondeTaOBaiano(Traficante t){
		t.levaSacoNaCabeca();
	}

	// exemplo de método final!

	public final Doze encontreiOBaiano(Baiano b){
		return b.naCaraNaoQueEhPraNaoEstragarVelorio();
	}

}
public class Treinamento{

	public void missao(CapitaoNascimento cn){
		cn.sentaOdedoNessaPorra();
	} // Sugestão do leitor Luciano Silva

	public static void main(String [] xxx){
//Apresento o capitão nascimento

	Bope capitao = new Bope(”01″); //Capitao Nascimento
	try{

//de cada 100 policiais que fazem o curso do Bope,
//so se formam 5, e eu, quando me formei parceiro,
//eramos apenas 3.

	Turma.tentaFazerCursoBopeCom(capitao);

while(aluno.count >= 3){
	aluno.pedePraSair();
	   if(aluno istanceof Cafetao){
		 capitao.say(”Pede pra sair!”);
		 capitao.say(”Seu Lugar Eh Com Puta!”);
	   }
	   if(aluno istanceof PorraLoka){
		   capitao.say(”Tira essa farda preta!”);
		   capitao.say(”Voce nao eh cavera. voce eh MULEQUE!”);
	   }
	   if( aluno.isXerife() ) aluno.desiste();
}
} catch (PolicialCorruptoEncontrado pce){
} catch (PolicialFracoEncontrado pfe){
} catch (PolicialSemABandoleiraNessaAlturadoCampeonato e) {
}
}
}

SEUS FANFARRÕES!

VCS TEM 10 SEGUNDOS PARA COMPLETAR ESSE CÓDIGO!

– O zero-dois NÃO está escrevendo!

– SEU zero-dois, porque o senhor não escreveu nenhuma linha?

– A-a minha IDE não terminou de carregar, senhor…

– Agora a sua IDE ja carregou, seu zero-dois?

– S-sim senhor…

– Então, seu zero-dois, termine o seu programa, senão todos os seus colegas terão que usar o EDIT do MS-DOS até o fim do curso E A CULPA EH DO ZERO-DOIS!

HOMEM DE PRETO QUAL É A SUA MISSÃO?

É APRENDER JAVA SEM PRECISAR DE CERTIFICAÇÃO!

HOMEM DE PRETO O QUE É QUE VC FAZ?

FAÇO CODIGO FONTE QUE ASSUSTA O SATANÁS!

Estratégia, do inglês, Strategy…

– Senhor, o zero-cinco está dormindo…


Alterado e modificado por Frankley Francalino

Fonte: http://peczenyj.blogspot.com/

Agenda em JSF, com CSS, Ajax e MySQL – Parte I

Autor:
Cláudio Santos das Virgens (claudiosvirgens@gmail.com), está cursando Pós Graduação em Sistemas de Informação com Ênfase em Componentes Distribuídos e WEB, na Faculdade Ruy Barbosa,cursou o Superior em Gestão de Redes de Computadores da Unifacs – Universidade Salvador, e tambem é Analista de Sistemas da AvanSys no CEDASC. 

 

Neste artigo vamos criar uma agenda usando JSF, CSS,Ajax,MySQL e como IDE vou usar Netbeans 5.5 mas isso não impede que você use o Eclipse, provavelmente alguem vai dizer:”Outro exemplo de agenda!”, bom esse existentem poucos tutorias em português que retratem o uso de tabelas em JSF, uso de CSS com JSF, dentre outras coisas que serão mostradas no decorrer do artigo.

 

Eu escrevi recentemente um tutorial sobre uso de arquivos de propriedades (Resource Blundle)  cuja a extensão é .properties, aonde vimos o quanto eles podem ser uteis, principalmente para a internacionalização de aplicativos, em nossa agenda usaremos uma arquivo de propriedade, chamado mensagens.properties.

 

Este é o conteúdo do arquivo br.com.nitewing.agenda.mensagens.properties:

# Sample ResourceBundle properties file

Titulo=Agenda com Netbeans,CSS,JSF,Ajax e MySQL

Nome=Nome

Endereco=Endereco

Telefone=Telefone

Bairro=Bairro

Cidade=Cidade

Cep=CEP

Estado=Estado

mensagens.properties

 

Vamos criar o Bean AgendaBean, aplicações em JSF usam bean java(managed bean) para controlar ações que serão requisitadas pela aplicação, para isso crie uma classe java com o nome de AgendaBean no pacote br.com.nitewing.agenda, com o seguinte contéudo:

 

/*

 * AgendaBean.java

 * Created on 9 de Setembro de 2007, 11:24

 * @author claudiosvirgens@nitewing

 */

 

package br.com.nitewing.agenda;

 

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.sql.Statement;

import javax.naming.NamingException;

import javax.servlet.jsp.jstl.sql.Result;

import javax.servlet.jsp.jstl.sql.ResultSupport;

import org.apache.taglibs.standard.tag.common.core.NullAttributeException;

 

public class AgendaBean {

   

    private Connection conn;

   

    public void abrirConexao() throws SQLException,NamingException,ClassNotFoundException{

        if(conn !=null) return;

        Class.forName(“com.mysql.jdbc.Driver”);

        conn = DriverManager.getConnection(“jdbc:mysql://localhost:3306/agenda”,”root”,””);

       

    }

    public Result getDados() throws SQLException, NamingException, ClassNotFoundException{

        try{

            abrirConexao();

            Statement stmt = conn.createStatement();

            ResultSet result = stmt.executeQuery(“SELECT *  FROM registros”);

            return ResultSupport.toResult(result);

        }finally{

            fecharConexao();

        }

    }   

    public void fecharConexao() throws SQLException{

        if(conn == null)return;

        conn.close();

        conn = null;

    }       

}

 

Como vocês podem ter percebido no código de AgendaBean uma instância da conexão só é criada se não existir uma instância do mesmo, o que impede que seja criada inúmeras instâncias do objeto de conexão.

 

Vamos exibir para um usuário uma tabela contendo os registros existentes na base de dados, e para melhorar a aparência da tabela iremos usar css.

Crie um arquivo .css contendo a folha de estilos que usaremos no nosso artigo. o nome do arquivo é estilo.css, ele devera ser salvo numa pasta chamada css, na raiz(root) do seu projeto web(web,webcontent), e seu conteúdo é mostrado a seguir:

 

/*

Document   : estilo.css

Created on : 09/09/2007, 14:19

Author     : claudiosvirgens@nitewing

Description: Folha de estilo agenda em netbeans

*/

.cabecalho {

   font-family: Arial, Helvetica, sans-serif;

   font-weight: bold;

   font-size: 14px;

   color: white;

   background-color: #3D77C0;

   text-align: center;

}

.linha1 {

font-family: Arial, Helvetica, sans-serif;

font-size: 12px;

color: black;

background-color: beige;

text-indent: 11px;

}

.linha2 {

font-family: Arial, Helvetica, sans-serif;

font-size: 12px;

color: black;

background-color: #E1ECF7;

text-indent: 11px;

}

 

Agora faremos algumas modificações no arquivo faces-config.xml

 

<?xml version=”1.0″ encoding=”UTF-8″?>

<!DOCTYPE faces-config PUBLIC “-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN” “http://java.sun.com/dtd/web-facesconfig_1_1.dtd”&gt;

<!– =========== FULL CONFIGURATION FILE ================================== –>

<faces-config xmlns=”http://java.sun.com/JSF/Configuration”&gt;

  <managed-bean>

    <description>

            Bean para trazer os dados do MySQL

        </description>

    <managed-bean-name>agenda</managed-bean-name>

    <managed-bean-class>br.com.nitewing.agenda.AgendaBean</managed-bean-class>

    <managed-bean-scope>session</managed-bean-scope>

  </managed-bean>

</faces-config>

 

O seu web.xml deve ficar parecido com o mostrado abaixo se você estiver no netbeans:

 

<?xml version=”1.0″ encoding=”UTF-8″?>

<web-app version=”2.4″ xmlns=”http://java.sun.com/xml/ns/j2ee&#8221; xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221; xsi:schemaLocation=”http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd”&gt;

    <context-param>

        <param-name>com.sun.faces.verifyObjects</param-name>

        <param-value>false</param-value>

    </context-param>

    <context-param>

        <param-name>com.sun.faces.validateXml</param-name>

        <param-value>true</param-value>

    </context-param>

    <context-param>

        <param-name>javax.faces.STATE_SAVING_METHOD</param-name>

        <param-value>client</param-value>

    </context-param>

    <servlet>

        <servlet-name>Faces Servlet</servlet-name>

        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>

        <load-on-startup>1</load-on-startup>

        </servlet>

    <servlet-mapping>

        <servlet-name>Faces Servlet</servlet-name>

        <url-pattern>*.faces</url-pattern>

    </servlet-mapping>

    <session-config>

        <session-timeout>

            30

        </session-timeout>

    </session-config>

    <welcome-file-list>

            <welcome-file>

            index.jsp

        </welcome-file>

    </welcome-file-list>

</web-app>

 

As seções <servlet-mapping>  e <welcome-file> são as que merecem atenção e no arquivo mostrado acima.

 

Caso esteja usando o Eclipse certifique que o conteúdo deles estejam como mostrado abaixo:

 

    <servlet-mapping>

        <servlet-name>Faces Servlet</servlet-name>

        <url-pattern>*.faces</url-pattern>

    </servlet-mapping>

            <welcome-file-list>

            <welcome-file>

            index.jsp

        </welcome-file>

    </welcome-file-list>

 

O  parâmetro url-pattern pode ter os seguintes valores mapeados:

*.jsf , *.faces ou ainda /faces/*

 

Agora crie um arquivo JSP e chame-o de index.jsp e acrescente o seguinte conteúdo:

 

<%@page contentType=”text/html”%>

<%@page pageEncoding=”UTF-8″%>

<%@ taglib uri=”http://java.sun.com/jsf/core&#8221; prefix=”f” %>

<%@ taglib uri=”http://java.sun.com/jsf/html&#8221; prefix=”h” %>

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”

http://www.w3.org/TR/html4/loose.dtd”&gt;

<html>

    <f:view>

        <head>

            <f:loadBundle basename=”br.com.nitewing.agenda.mensagens” var=”msgs”/>

            <meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8″>

            <title><h:outputText value=”#{msgs.Titulo}”/></title>

            <link rel=”stylesheet” type=”text/css” href=”./css/estilo.css”>

        </head>

        <body>

            <div align=”center”>

                <h:form>

                    <h:form>

                        <h3><h:outputText value=”#{msgs.Titulo}”/></h3>

                        <h:dataTable value=”#{agenda.dados}” var=”agenda”                                                      border=”0″ headerClass=”cabecalho”                                                                                                     rowClasses=”linha1,linha2″>  

                            <h:column>

                                <f:facet name=”header”>

                                    <h:outputText value=”#{msgs.Nome}” />                               

                                </f:facet>

                                <h:outputText value=”#{agenda.nome}”/>

                            </h:column>

                            <h:column>

                                <f:facet name=”header”>

                                    <h:outputText value=”#{msgs.Endereco}” />                               

                                </f:facet>

                                <h:outputText value=”#{agenda.endereco}”/>

                            </h:column>

                            <h:column>

                                <f:facet name=”header”>

                                    <h:outputText value=”#{msgs.Bairro}” />                               

                                </f:facet>

                                <h:outputText value=”#{agenda.bairro}”/>

                            </h:column>

                            <h:column>

                                <f:facet name=”header”>

                                    <h:outputText value=”#{msgs.Cidade}” />                               

                                </f:facet>

                                <h:outputText value=”#{agenda.cidade}”/>

                            </h:column>

                            <h:column>

                                <f:facet name=”header”>

                                    <h:outputText value=”#{msgs.Estado}” />                               

                                </f:facet>

                                <h:outputText value=”#{agenda.estado}”/>

                            </h:column>

                            <h:column>

                                <f:facet name=”header”>

                                    <h:outputText value=”#{msgs.Cep}” />                               

                                </f:facet>

                                <h:outputText value=”#{agenda.cep}”/>

                            </h:column>

                            <h:column>

                                <f:facet name=”header”>

                                    <h:outputText value=”#{msgs.Telefone}” />                               

                                </f:facet>

                                <h:outputText value=”#{agenda.telefone}”/>

                            </h:column>

                        </h:dataTable>

                    </h:form>                   

                </h:form>

            </div>           

        </body>

    </f:view>   

</html>

 

Logo após as tags <f:view> e <head> nos utilizamos a tag:

<f:loadBundle basename=”br.com.nitewing.agenda.mensagens” var=”msgs”/>

onde informamos que o arquivo que iremos usar se encontra no pacote br.com.nitewing.agenda e que se chama mensagens (sem o .properties) e declaramos o item var como msgs, ou seja a partir de agora iremos nos referir ao arquivo como msgs.

 

Na linha <h:outputText value=”#{msgs.Titulo}”/> nós fazemos referencia ao arquivo de propriedade quando passamos o valor #{msgs.Titulo} para renderizar o valor do Titulo.

 

Na linha a seguir nós usamos a tag <h:dataTable> para para pegar os dados retornados pelo bean agenda, declaramos a variável   agenda e ainda mapeamos as classes existentes no arquivo estilo.css com os  objetos headerClass e rowClasses:

 

<h:dataTable value=”#{agenda.dados}” var=”agenda” border=”0″ headerClass=”cabecalho”             rowClasses=”linha1,linha2″>

 

Agora vamos compilar e executar a primeira parte do nosso artigo, excute o nosso seu editor preferido e o resultado deverá ser uma tela como a mostrada na Figura

 

cvajcamsp1fig01.jpg

Figura1

 

Não faz parte do escopo deste artigo ensinar o usuário a usar o MySQL mas segue anexo os comandos necessários para criação do banco de dados:

 

CREATE DATABASE agenda;

use agenda

CREATE TABLE registros(

id int (11) not null  autoincrement,

nome varchar(50) not null,

endereco varchar(40),

bairro varchar(25),

cidade varchar(40),

estado char(2),

cep varchar(8),

telefone(11),

primary key(id));

 

Para inserir registros na tabela utilize o camando INSERT como mostrado abaixo:

 

INSERT INTO registros (nome,endereco,bairro,cidade,estado,cep,telefone) WHERE (‘Alexandre Soneca’, ‘Av La paz’,’Pituba’,’Ba’, ‘Salvador’, ‘40000000’,’88562356′);

 

execute o comando INSERT com outros valores a para termos uma quantidade melhor de

 

Na segunda parte de nosso artigo iremos acrescentar os métodos responsáveis pela inserção, alteração e atualização de dados e também acrescentaremos os recursos da tecnologia Ajax com a ferramenta Ajax4Jsf.

 

Sobre este artigo:

IDE utilizada: Netbeans 5.5

Versão do Bd: MySQL 5.x

Navegadores Utilizados: Firefox 2.x, Opera 9.x

Java ganha preferência em desenvolvimentos para SOA

por IT Web

21/08/2007
Pesquisa da Evans Data mostra queda de quase 20% no uso de .Net em implementações de arquitetura orientada a serviços

O número de companhias com projetos de arquitetura orientada a serviços (SOA, sigla em inglês) em plataforma Java subiu levemente nos últimos seis meses. Em contrapartida, houve queda de quase 20% nos desenvolvimentos utilizando .Net. A conclusão é resultado de pequisa da empresa de análise de mercado Evans Datas, que consultou cerca de 400 desenvolvedores e gerentes de TI norte-americanos, em junho.

Os desenvolvimentos em .Net para SOA ainda predominam no mercado, com 31% do total. Mas 28% dos entrevistados já consideram trabalhar com Java. As plataformas rivais estão virtualmente integradas, pois uma em cada cinco companhias esperam suportar ambas em seus projetos SOA.

Segundo John Andrés, CEO da Evans Data, atualmente há muita atividade sobre SOA no mundo open source, principalmente nas comunidades Eclipse. Ele explica que a maioria dos grandes players naquele espaço estão introduzindo novas soluções para SOA, e são quase invariavelmente baseadas em Java. “SOA em código aberto parece destinada a tornar-se uma força real na indústria e consequentemente, um sério concorrente a .Net”.

A pesquisa também mostra que três quartos de todas as companhias que construíram ou estão fazendo web services planejam implementar SOA. Mais de uma em cada cinco já partiu para a adoção em ampla escala na companhia.

Outras conclusões do estudo:

Mais de 70% dos entrevistados que usam web services experimentaram redução de custo. Reuso de código e automação de processos foram as principais razões primárias.

Teste e validação de web services são o grande desafio para desenvolver uma arquitetura orientada a serviços, mas determinar o retorno sobre o investimento é um desafio quase tão grande.

Implementações B2B são os usos mais comuns de web services, seguidos por integração de dados.

Camadas JavaEE

Sobre o autor:
Marcelo Elias Del Valle (mvallebr@gmail.com) trabalha com Java e desenvolvimento de software em geral desde 1998, já tendo trabalhado em várias multinacionais relacionadas com o setor de TI em várias áreas, desde telecomunicações e área bancária até desenvolvimento de software científico. Marcelo é SCJP 1.4, tem SCEA parte 1 e superior incompleto em engenharia elétrica na USP. Usa seu raro tempo livre estudando processos de desenvolvimento de software e imaginando arquiteturas possíveis para jogos de computador. 

 

Quais são as camadas na arquitetura de referência JavaEE e o que significam

A arquitetura de referência J2EE define terminologias e conceitos muito úteis quando estamos definindo e discutindo arquiteturas de aplicações. Um dos conceitos mais básicos, que infelizmente parece ser pouco conhecido entre os profissionais J2EE, são as camadas de aplicação e alguns conceitos relacionados.

O objetivo desse artigo é dar uma visão geral sobre esses conceitos.

Pré-requisitos

Esse artigo requer muito pouco conhecimento técnico para ser lido, podendo inclusive ser interessante para gerentes ou outras pessoas de áreas não técnicas terem uma idéia do que significa desenvolvimento J2EE.

Arquitetura de referência JavaEE

Dentre as várias formas de classificar os tipos possíveis de arquiteturas de software, existe uma que as divide entre arquiteturas de sistema e arquiteturas de referência.

Arquitetura de sistema refere-se à arquitetura de um sistema específico, na qual são definidos diagramas de instalação, design, interfaces, classes, etc. É a especificação técnica de como o sistema vai lidar com requisitos não funcionais.

Continuar lendo

Introdução à java persistence api – JPA

saudações java!

após algum tempo de estouro do hibernate, surge o java persistence api, sendo muito utilizado na comunidade para a camada de persistência.

O JPA é um framework utilizado na camada de persistência (ver figura 01) para o desenvolvedor ter uma maior produtividade, com impacto principal num modo para controlarmos a persistência dentro de java. pela primeira vez, nós, desenvolvedores temos um modo “padrão” para mapear nossos objetos para os do banco de dados. persistência é uma abstração de alto-nível sobre jdbc.

jpa
figura 01.

o java persistence api – JPA define um caminho para mapear plain old java objects pojos para um banco de dados, estes pojos são chamados de beans de entidade. beans de entidades são como qualquer outra classe java, exceto que este tem que ser mapeado usando java persistence metadata, para um banco de dados.

a nova java persistence specitication define mapeamento entre o objeto java e o banco de dados utilizando orm, de forma que beans de entidade podem ser portados facilmente entre um fabricante a outro.

o que é orm?

em resumo, mapeamento objeto/relacional é automatizado (e transparente) persistência de objetos em aplicações java para tabelas em um banco de dados relacional, usando metadata que descreve o mapeamento entre os objetos e o banco de dados.

para uma simples comparação, vamos dá uma olhada em dois códigos para demostrar como JPA é muitissímo utíl para uma aplicação java. primeiro irei criar um exemplo utilizando jdbc, e um outro utilizando JPA.

segue a estrutura da tabela:

create table bug (

id_bug int(11) not null auto_increment,

titulo varchar(60) not null,

data date default null,

texto text not null,

primary key (id_bug)

);

na utilização do JPA é necessário o os dois jar’s do toplink:

toplink-essentials.jar e o toplink-essentials-agent.jar

link para download:

http://www.oracle.com/technology/products/ias/toplink/JPA/download.html

adicione esses dois jar’s no classpath do seu projeto, e adicione também o driver jdbc do seu banco 😉

vamos dá uma olhada no código utilizando jdbc.

listagem 01. jdbccode.java.

package jdbc;

import java.sql.*;

/**

*

* @author adm

*/

public class jdbccode {

private static connection con = null;

/** creates a new instance of jdbccode */

public jdbccode() {

}

public static connection open(){

string user = “root”;

string pass = “123456”;

string url = “jdbc:mysql://localhost/bug”;

try{

class.forname(“com.mysql.jdbc.driver”);

con = drivermanager.getconnection(url,user,pass);

}catch( exception e ){

e.printstacktrace();

}

return con;

}

public static void main( string args[] ) throws exception{

string sql = “select * from bug”;

con = open();

try {

statement st= con.createstatement();

resultset rs= st.executequery(sql);

while( rs.next() ){

system.out.println(“titulo: “+ rs.getstring(“titulo”));

}

} catch (sqlexception ex) {

ex.printstacktrace();

}finally{

con.close();

}

}

}

uma classe bem simples, que lista os titulos dos bugs, mas são muitas linhas para escrever…. agora vamos dá uma olhada no código para selecionar um determinado registro utilizando JPA.

listagem 02. sniped code.

public object findbypk( int pkey ) {

entitymanager em = getentitymanager();

return em.find(bug.class, pkey);

}

pronto!!! mas isso é só para você comparar como nós ganhamos produtividade na camada de persistência, e portanto tendo mais tempo para os objetos da lógica negócio.

agora vamos ao exemplo real, segue o objeto bug ou o entity bean bug:

nossa classe deve implementar serializable e ter um campo id. os arrobas em cima dos atributos, são as anotações para mapear o seu objeto para a tabela bug.

a figura 02 mostra o mapeamento entre o objeto java e a tabela no banco de dados.
figura 02.

listagem 03. bug.java.

/*

* bug.java

*

*/

package exemplo;

import javax.persistence.*;

/**

*

* @author wendell miranda

*/

@entity

@table(name=”bug”)

public class bug implements java.io.serializable {

private integer id_bug;

private string titulo;

private java.util.date data;

private string texto;

/** creates a new instance of bug */

public bug() {

}

/*

a notação @generatedvalue(strategy=generationtype.sequence) informa que o id será gerado automaticamente pelo db.

*/

@id

@generatedvalue(strategy=generationtype.sequence)

@column(name=”id_bug”)

public integer getid_bug() {

return id_bug;

}

public void setid_bug(integer id_bug) {

this.id_bug = id_bug;

}

@column(name=”titulo”)

public string gettitulo() {

return titulo;

}

public void settitulo(string titulo) {

this.titulo = titulo;

}

@temporal(temporaltype.date)

@column(name=”data”)

public java.util.date getdata() {

return data;

}

public void setdata(java.util.date data) {

this.data = data;

}

@column(name=”texto”)

public string gettexto() {

return texto;

}

public void settexto(string texto) {

this.texto = texto;

}

@override

public string tostring(){

return “id: “+this.id_bug;

}

}

conclusões

utilizar java persistence api facilita muito o trabalho do desenvolvedor java, principalmente quando lidamos com muitas tabelas. este artigo foi apenas para quem nunca utilizou JPA e gostaria de saber um pouco sobre a tecnologia, no próximo artigo irei demonstrar um exemplo persistindo, atualizando, excluindo e listando os bugs.

referências

http://www.oreilly.com/catalog/entjbeans5/

http://www.oracle.com/technology/products/ias/toplink/JPA/tutorials-index.html

http://www.oracle.com/technology/products/ias/toplink/JPA/tutorials/jsf-JPA-tutorial.html

Como criar um JFrame com imagem de fundo

Imagens de fundo (backgrounds) são extremamente essenciais para certos layouts. Um simples gradient ou uma marca d’água representam um grande diferencial e tornam a aplicação mais agradável.

 

Infelizmente, o componente JFrame, até a versão 6.0 do JDK, não possui uma propriedade específica que possibilite configurar uma imagem como plano de fundo. Nesse caso é necessário implementar uma maneira, das várias possíveis, para disponibilizar esse recurso.

 

Definindo uma imagem de fundo

Para o exemplo do artigo, será usada uma imagem simples representando um gradient com dimensões 1024×768, que é a resolução mais utilizada atualmente nos desktops e armazenada no “C:\” como indica a Figura 01.

 

ascjfiffig01.jpg

Figura 01

 

O caminho da imagem que será utilizado pelo Java nesse caso será: “C:\bg_gradient.jpg”.

 

O método paintComponent

Como citado anteriormente, para se criar a possibilidade de definição de uma imagem de fundo, é necessário implementá-la manualmente.

 

Os JFrames possuem uma propriedade chamada contentPane que é o componente padrão onde são adicionados todos os componentes específicos como botões, labels, áreas de texto, etc.

 

Este contentPane possui um método chamado paintComponent que é o método responsável por desenhá-lo (o que é exibido para o usuário). E é ele quem será implementado.

 

A Listagem 01 exibe uma private class que será utilizada mais adiante no artigo. Primeiramente é interessante focar na implementação de paintComponent.

 

private class NewContentPane extends JPanel{

//método implementado de JPanel

protected void paintComponent(final Graphics g) {

               super.paintComponent(g);

               g.drawImage(bImage, 0, 0, this);

        }

}

Listagem 01 – Classe interna que implementa paintComponent

 

A classe interna NewContentPane é uma classe filha de JPanel e será o novo contentPane de JFrame.

 

Super.paintComponent(g) chama o respectivo método, porém, de JPanel, para que não sejam perdidas as visualizações-padrão de um JPanel. Em seguida, o método drawImage “desenha” bImage (imagem utilizada como background – descrita na próxima etapa do artigo).

 

Com isso tem-se uma classe filha de JPanel, porém com uma imagem desenhada ao invés de uma cor padrão.

 

O JFrame com o novo contentPane

Será desenvolvido agora o JFrame adaptado com o novo contentPane.

 

A Listagem 02 representa o código-fonte da classe JFrameWithBackground com a classe interna criada anteriormente.

 

package br.com.jm.jframes;

 

import java.awt.Graphics;

import java.awt.Image;

import java.awt.Toolkit;

 

import javax.swing.JFrame;

import javax.swing.JPanel;

 

public class JFrameWithBackground extends JFrameFactory{

       

        Image bImage;

       

        public JFrameWithBackground(String path){

               this.bImage = this.createImage(path);

               this.initComponents();

        }

       

        public void initComponents(){

               super.setContentPane(new NewContentPane());

               super.setExtendedState(JFrame.MAXIMIZED_BOTH);              

        }

       

        private Image createImage(String path){

               return Toolkit.getDefaultToolkit().createImage(path);

        }

       

        private class NewContentPane extends JPanel{

               protected void paintComponent(final Graphics g) {

                       super.paintComponent(g);

                       g.drawImage(bImage, 0, 0, this);

               }

        }

}

Listagem 02 – JFrameWithBackground

 

O construtor da classe recebe uma String que representa o caminho da imagem e em seguida chama o método createImage. Esse método chama a função createImage da classe Toolkit (java.awt.Toolkit) que retorna uma imagem de acordo com esse caminho. A variável, anteriormente citada, bImage agora representa a imagem de fundo do JFrame.

 

É dentro do método initComponents que se faz a alteração do contentPane que agora será uma instância de NewContentPane (classe interna criada no início do artigo e que implementa paintComponent).

 

Como isso tem-se um JFrame que possui um contentPane diferente do padrão; que possui uma imagem de fundo.

 

Testando o novo JFrame

Falta apenas testar o novo JFrame e sua nova capacidade (possuir uma imagem de fundo). A Listagem 03 exibe uma classe simples com um panel adicionado.

 

import java.awt.BorderLayout;

import java.awt.Dimension;

 

import javax.swing.BorderFactory;

import javax.swing.JLabel;

import javax.swing.JPanel;

import javax.swing.JScrollPane;

import javax.swing.JTextArea;

import javax.swing.UIManager;

 

import br.com.jm.jframes.JFrameWithBackground;

 

public class TesteJFrameWithBackground {

        public static void main(String[] args) {

               try{

                       UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

               } catch(Exception exception){

                      

               }

              

               JPanel jPanel3 = new JPanel(new BorderLayout());

               jPanel3.add(new JLabel(“teste-background”), BorderLayout.NORTH);

               jPanel3.add(new JLabel(“texto:”), BorderLayout.WEST);

               jPanel3.add(new JScrollPane(new JTextArea()), BorderLayout.CENTER);

               jPanel3.add(new JLabel(“teste-background-fim”), BorderLayout.SOUTH);

               jPanel3.setPreferredSize(new Dimension(400,500));

               jPanel3.setBorder(BorderFactory.createTitledBorder(“jPanel3”));

               jPanel3.setOpaque(false);

              

               JFrameWithBackground jFrame = new JFrameWithBackground(“C:\\bg_gradient.jpg”);

               jFrame.setLayout(new BorderLayout());

               jFrame.getContentPane().add(jPanel3, BorderLayout.NORTH);

               jFrame.setVisible(true);

        }

}

Listagem 03 – Classe de testes

 

A imagem passada como parâmetro para JFrameWithBackground é a citada no início do artigo.

 

Conclusão

Implementando paintComponent de JPanel e armazenando essa implementação como novo contentPane de um JFrame foi possível criar um frame com uma imagem de fundo. À medida que essa nova classe vai sendo desenvolvida, pode-se criar métodos set e get que permitam atualizar, em tempo de execução, a imagem de fundo, tornando-a dinâmica.

 

Um grande abraço,

Adriano S. Castro