Luizgustavoss's Weblog

19, Agosto 2009

Configurando um Datasource para o Microsoft SQL Server 2005 no WebSphere 6.1

Arquivado em: Tutorial — Tags:, , , , — luizgustavoss @ 9:48 pm

por: Luiz Gustavo Stábile de Souza

versão PDF

Este tutorial tem o objetivo de ajudar na configuração de um datasource (origem de dados) para o SQL Server 2005 no WebSphere 6.1.
A idéia de criar este tutorial surgiu de uma necessidade pessoal, de encontrar um passo-a-passo na internet, que fosse específico para esta versão do banco no WebSphere 6.1.
Para a elaboração deste tutorial, usei uma versão trial do servidor, que pode ser encontrada no site da IBM, que consta das referências no final do artigo.
Ao longo do artigo, os termos datasource e origem de dados serão usados para indicar a mesma coisa.

Configurando as credenciais de usuário para a conexão com banco através da JNDI

O WebSphere armazena todas as informações de usuário e senha de forma centralizada e faz isso em uma área diferente do console administrativo. Uma vez que a conexão JNDI requer um nome de usuário e senha, teremos que configurá-los antecipadamente.
A partir do menu esquerdo, selecione a opção Segurança > Administração, Aplicativos e Infra-estrutura Seguros.
Na tela que aparece, expanda o item Java Authentication and Authorization Service à direita, e selecione o item Dados de autenticação J2C:

Dados de autenticação J2C

Dados de autenticação J2C

A próxima tela apresenta a lista de identidades já cadastradas. Selecione a opção para incluir uma nova identidade, e após o cadastro clique em Salvar, para confirmar a operação:

Tela de cadastro de identidades

Tela de cadastro de identidades

Configurando um Provedor JDBC

No WebSphere é preciso configurar um provedor para um driver JDBC que pretendemos usar para um datasource. Segundo a IBM: “O objeto provedor JDBC encapsula a classe de implementação específica do driver JDBC para o datasource definido, e o associa ao provedor.”
Para configurar o provedor JDBC, escolha o item Recursos no menu à esquerda do painel administrativo, e então o item Provedores de JDBC.
Na tela apresentada, escolha o escopo adequado para a criação do recurso, no combo box apresentado, e escolha a opção para cadastrar um novo provedor JDBC.
Você pode cadastrar um provedor JDBC para o driver já oferecido pelo servidor por padrão. Para isso escolha na lista de tipo de provedor a opção WebSphere embedded ConnectJDBC:

Cadastro de provedor JDBC

Cadastro de provedor JDBC

Resumo dos dados do provedor JDBC cadastrado

Resumo dos dados do provedor JDBC cadastrado

Criando o Datasource

Agora, voltando à lista de provedores JDBC, selecione o provedor que acabamos de configurar, clicando sobre o mesmo. Na tela que aparece selecione o link Origem de Dados, à direita. Na tela que aparece em seguida, escolha a opção para cadastrar um novo datasource. A tela de cadastro aparece parcialmente preenchida, com os dados do provedor de conexão:

Tela de cadastro do datasource (origem de dados)

Tela de cadastro do datasource (origem de dados)

Preencha o campo de nome JNDI e escolha o alias de autenticação a ser usado, de acordo com o que foi cadastrado anteriormente.

Na próxima tela serão solicitadas informações adicionais para a configuração do datasource:

Dados adicionais para o datasource

Dados adicionais para o datasource

Após a configuração e confirmação, você poderá realizar o teste da conexão do datasource:

Teste do datasource criado executado com sucesso

Teste do datasource criado executado com sucesso

Instâncias Nomeadas do SQL Server

O Microsoft SQL Server suporta múltiplas instâncias de um banco de dados executando em um mesmo servidor. Uma instância é identificada por um nome de instância.
Para se conectar a uma instância nomeada utilizando uma URL de conexão, use o seguinte formato de URL:

jdbc:sqlserver://server_name\\instance_name

Observação: a primeira barra invertida (\) em \\instance_name é um caractere de escape.

onde:

server_name é o endereço ip ou hostname do servidor.
instance_name é o nome da instância com a qual se deseja uma conexão no servidor.

Seguindo este padrão de nomenclatura, caso quiséssemos uma conexão com uma instância chamada  openserver2005 em um servidor chamado openserver, a URL de conexão seria a seguinte:

jdbc:sqlserver://openserver\\openserver2005

Para o caso da configuração de um datasource para um banco cuja instância é nomeada, colocaríamos o seguinte, na identificação do servidor:


openserver\openserver2005

Configuração para uma instância nomeada do banco de dados

Configuração para uma instância nomeada do banco de dados

Configurando um Driver JDBC alternativo

Muitas vezes, o driver JDBC fornecido por padrão pelo servidor de aplicações pode não ser adequado, sendo necessário utilizar uma outra versão, baixada à parte.
O download do driver JDBC para o SQL Server 2005 pode ser feito a partir da página de downloads da Microsoft, que consta nas referências no final do artigo.
Tendo o driver do SQL Server em mãos, acesse o console administrativo.
No meu esquerdo do console administrativo, escolha a opção Ambiente > Variáveis do WebSphere:

sqlserver_was_img9

Ao escolher esta opção, um painel se abrirá, onde é possível visualizar as variáveis de ambiente do WebSphere. Dentre as variáveis encontradas neste painel, procure pela variável WAS_INSTALL_ROOT . O valor dela indicará um diretório, no qual existe um diretório lib, e dentro deste um diretório chamado ext. É para este diretório (ext) que deverá ser copiado o driver JDBC do SQL Server.

Variáveis de ambiente do WebSphere

Variáveis de ambiente do WebSphere

No mesmo painel, crie uma variável de ambiente, digamos MSSQLSERVER2005_JDBC_DRIVER_PATH, para apontar para o diretório onde estará o driver JDBC do SQL Server:

Criação de variável de ambiente

Criação de variável de ambiente

Na próxima tela apesentada, confirme clicando em Salvar:

sqlserver_was_img12

Criando o Provedor JDBC

Agora precisamos criar um provedor JDBC para o driver JDBC alternativo.
No menu do console administrativo selecione Recursos > JDBC > Provedores de JDBC. Selecione a opção para cadastrar um novo provedor.
No campo Tipo do Banco de Dados informe “Definido pelo usuário”. Em Nome da Classe de Implementação informe o nome da classe que implementa o datasource,  fornecido pelo driver. No caso do driver que estou usando essa classe é “com.microsoft.sqlserver.jdbc.SQLServerConnectionPoolDataSource”.

Criação de um provedor JDBC para o driver alternativo

Criação de um provedor JDBC para o driver alternativo

Na próxima tela, informe o caminho até o driver JDBC:

Configuração do caminho para o driver alternativo

Configuração do caminho para o driver alternativo

Após confirmar as configurações, salve as alterações realizadas.

Criando o datasource para o Driver JDBC alternativo

Agora, voltando à lista de provedores JDBC, selecione o provedor que acabamos de configurar, clicando sobre o mesmo. Na tela que aparece, caso necessário, modifique as informações do driver jdbc, como o nome do arquivo .jar ou a classe de implementação:

Propriedades do provedor JDBC

Propriedades do provedor JDBC

Depois das devidas alterações feitas (caso necessário), selecione o link Origem de Dados, à direita. Na tela que aparece, escolha a opção para cadastrar uma nova origem de dados. A tela de cadastro aparece parcialmente preenchida, com os dados do provedor de conexão:

Tela de cadastro do datasource (origem de dados)

Tela de cadastro do datasource (origem de dados)

Preencha o campo de nome da origem de dados, de nome JNDI e escolha o alias de autenticação a ser usado, de acordo com o que foi cadastrado anteriormente.
Na próxima tela, no campo Nome da Classe Auxiliar do Data Store  informe “com.ibm.websphere.rsadapter.GenericDataStoreHelper” (padrão):

Informações do banco de dados para o datasource

Informações do banco de dados para o datasource

Ainda precisamos configurar o nome do banco de dados e o nome do servidor. Na tela de propriedades do datasource, clique na opção Propriedades Personalizadas, localizada à direita:

Propriedades do datasource

Propriedades do datasource

Na tela que se abre, cadastre duas propriedades, conforme a imagem a seguir:

Propriedades adicionais para o datasource (referentes ao banco de dados)

Propriedades adicionais para o datasource (referentes ao banco de dados)

O número da porta é opcional, portanto não o configurei. Para ser mais exato, ao tentar configurar o número da porta, obtive um erro, que informava não ser possível encontrar a versão correta do servidor:

Erro ao testar o datasource quando se informa o número da porta

Erro ao testar o datasource quando se informa o número da porta

Mas ao remover a propriedade, o teste de conexão do datasource funcionou normalmente, com apenas um aviso no log do servidor:

[19/08/09 16:25:30:375 BRT] 0000002e DSConfigurati W   DSRA0174W: Aviso: GenericDataStoreHelper está sendo utilizado.

É isso! Espero que este tutorial seja útil para quem precisa executar esta tarefa, muitas vezes tediosa.

Referências

Named Instances
http://e-docs.bea.com/wls/docs81/jdbc_drivers/mssqlserver.html#1074583

Trial: IBM WebSphere Application Server
http://www.ibm.com/developerworks/downloads/ws/was/

Microsoft SQL Server JDBC Driver
http://msdn.microsoft.com/en-us/data/aa937724.aspx

Setting up a JNDI data source in WebSphere 6.0/6.1
http://www.enavigo.com/2007/05/14/setting-up-a-jndi-data-source-in-websphere-6061/

SQL SERVER 2005 Support in Websphere Application Server V6.0.1:
http://www.theserverside.com/discussions/thread.tss?thread_id=41808

1, Agosto 2009

ERRO: detached entity passed to persist

Arquivado em: Code Tip — luizgustavoss @ 12:15 pm

Durante o desenvolvendo um projeto pessoal me deparei com este erro, que indicava que uma entidade
detached estava sendo passada para um método de inclusão:

javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: model.Criterio

O método em questão salvava, na verdade, uma entidade de outra classe:

Chave chave = new Chave();
chave.setNome(nomeChave);
chave.setPeso(new BigDecimal(pesoChave));
chave.setCriterioCollection(new ArrayList<Criterio>()); 

for(Criterio c : getCriteriosChave()){
 c.setCodChave(chave);
 chave.getCriterioCollection().add(c);
}

getBusinessDelegate().cadastrar(chave);

Tudo indicava que as entidades da classe Criterio, passadas à coleção da classe sendo salva, estavam vindo do banco de dados,
através de um gerenciador de persistência, mas não era este o caso. As entidades retornadas pelo método getCriteriosChave(),
neste caso, são criadas no momento da população da tela, ou seja, não são retornadas do banco.
Durante algum tempo bati cabeça, tentando entender o porquê deste erro, até que em um post encontrei uma dica que foi valiosa:
o identificador do objeto em questão, estava associado a um componente de tela:

<rich:column>
 <h:inputHidden id="hdncodigoCriterio" value="#{criterio.codigo}"/>
 <h:inputText id="txtNomeChave" required="true"
 disabled="#{!configuracaoGuiaBean.habilitarModificacoesChave}"
 value="#{criterio.descricao}" size="100" maxlength="60">
 <f:validateLength minimum="5" maximum="60"/>
 </h:inputText>
 </rich:column>

Como isso pode influenciar no erro?
Ao associar o identificador da entidade a um componente de tela, o valor do mesmo, quando não atribuído explicitamente, será zero, e não nulo.
O gerenciador de persistência entenderá esse valor como sendo um identificador válido, como se a entidade tivesse sido obtida do banco de dados.
Para resolver o problema, bastou fazer um teste antes do momento da atribuição: se o valor do identificador for zero, o que indica
uma nova entidade, atribui-se nulo para seu valor:


for(Criterio c : getCriteriosChave()){
 c.setCodigo(c.getCodigo() == 0 ? null : c.getCodigo());
 c.setCodChave(chave);
 chave.getCriterioCollection().add(c);
}

Está dada a dica!

16, Maio 2009

Projeto Money Count – Idealização

Arquivado em: Uncategorized — luizgustavoss @ 9:00 am

Uma dificuldade que percebo nas pessoas que começam a aprender Java (assim com qualquer tecnologia) é conseguir juntar tudo que se lê a respeito em algo executável, ou seja, conseguir entender todas as tecnologias e padrões envolvidos no desenvolvimento de um sistema.

Para Java essa curva de aprendizado é relamente mais acentuada, ainda mais quando alguém se dispõe a aprender por conta própria.

Ainda me lembro de quando vi Java pela primeira vez, na faculdade. Na ocasião o professor chegou nos mostrando um programinha com poucas linhas que apresentava uma janelinha (JOptionPane) que solicitava uma informação e a apresentava na tela novamente. Aquilo me encantou, mas eu não sabia nem por onde começar, nem como instalar a JDK. Era um longo caminho pela frente (que eu ainda estou trilhando, diga-se de passagem).

Depois disso tivemos Java como linguagem para aprender OO, e mais um semestre em que vimos algo a mais de Java (a contragosto da maioria da sala). Na época não usávamos IDEs como Netbeans ou Eclipse; era tudo no JCreator. Me lembro de ter feito várias e várias telas na mão, com Swing, direto no JCreator, sem os recursos de arrastar e soltar.

Levei tempos até conseguir entender coisas como o que são drivers JDBC, pra entender como fazer uma conexão com o banco de dados, como usar padrões, etc, etc, etc.

Até conseguir criar algo considerável, um sisteminha desktop “bobinho” com conexão à base de dados, validações em formulários, e separação em camadas, penei muito nos fóruns, em cima de livros, e posso garantir que a maior dificuldade é realmente organizar todas as informações encontradas em algo funcional.

Quando criei este blog, a minha intenção era de compartilhar um pouco daquilo que aprendi desde então, nos anos que venho trabalhando com tecnologia. Fica claro que o foco é Java, mas prentendo continuar postando sobre tudo aquilo que julgar proveitoso em outras tecnologias. A intenção do blog continua a mesma, mas refletindo sobre essa dificuldade inicial dos estudantes da tecnologia, pensei em estruturar de uma maneira melhor as postagens, “colocá-las nos trilhos” para que aqueles que estão começando possam aproveitar em algum momento posts mais avançados, sem ficarem confusos. Para resumir, pensei em criar um passo-a-passo, que vai do básico até temas mais avançados.

Para conseguir isso, pensei em criar um projeto de estudo de caso, que possa passar pelos processos de análise, projeto, e desenvolvimento, passando pelas tecnologias básicas até as mais avançadas.

A idéia de ter um projeto padrão é poder, a apartir de um momento, não se importar com “o que” desenvolver, mas com o “como”, podendo ainda fazer comparativos entre as tecnologias para o desenvolvimento do mesmo sistema.

Para este objetivo elegi o primeiro sistema que desenvolvi em Java, com conexão a banco de dados e tudo o mais. É um projeto bem simples, mas funcional, e que está até hoje em funcionamento. Esse projeto surgiu da necessidade de um amigo, que me solicitou um sistema para contagem de unidades monetárias, há muito tempo atrás. A seguir darei o escopo do projeto, e a partir de agora alguns posts serão referentes a este projeto, começando do básico até alcançarmos conceitos e tecnologias mais avançadas.

Money Count

A necessidade do cliente resume-se ao seguinte:

O cliente necessita efetuar pagamentos a funcionários e fornecedores em dinheiro vivo, e para isso calcula todos os pagamentos a serem efetuados no dia e realiza saques no banco. O problema é que a soma dos valores é sacada em notas grandes, e geralmente faltam moedas e notas menores para efetuar o pagamento de valores “quebrados”. Como o cálculo dos valores é realizado por funcionários, de uma maneira não automatizada, erros são possíveis.

O que o sistema a ser desenvolvido deverá realizar:

O cliente solicitou o desenvolvimento de um sistema que permita o cadastro de contas em um banco de dados, para que posteriormente possa emitir relatórios de pagamentos diários de maneira fácil.

O sistema deverá permitir que se saiba, ao final de um relatório, quais e quantas unidades monetárias serão necessárias para se efetuar todos os pagamentos do dia.

Parece fácil não? E é!

Olhando esta especificação, muito simples, é fácil entender a necessidade do cliente e imaginar o sistema a ser desenvolvido.

O problema é o desenvolvimento desse sistema por uma pessoa que está começando agora.

No próximo post começaremos a analisar este sistema mais a fundo (processo de análise), elegendo as classes conceituais que irão compor o sistema, trabalhando com diagramação UML (só o necessário) e nos preparando para o desenvolvimento.

Até lá!

5, Abril 2009

Testes Unitários com JUnit

Arquivado em: Tutorial — Tags:, , , — luizgustavoss @ 7:59 am

Versão PDF

Motivação

Apesar de já fazer um certo tempo que escrevi a primeira versão deste tutorial, o assunto de testes unitários, e a utilização do JUnit ainda são para alguns uma novidade.
Acredito que tanto a utilização de testes unitários quanto a utilização do JUnit deverão ser, cada vez mais, constantes no dia-a-dia dos profissionais.
Portanto, eis aqui a minha contribuição para quem está começando!

O que são Testes Unitários?

Falando de forma simples e direta, um teste unitário é um teste realizado para verificar a funcionalidade de um determinado trecho de código, verificar se ele realmente faz o que se propõe a fazer.
O objetivo de testes unitários não é testar toda a funcionalidade do sistema, ou a integração de várias partes do sistema de uma única vez, mas realizar testes isolados, testando blocos específicos do sistema, mais comumente os métodos das classes.
Para entender melhor esse conceito, vamos a exemplos práticos, primeiramente vendo como seria executar um teste sem a utilização de um framework de testes.

Testes sem o JUnit – Um exemplo prático

Para a realização dos exemplos deste tutorial, vou utilizar o IDE Netbeans. Aconselho que você também siga este tutorial executando os exemplos no Netbeans, pois alguns passos são específicos para este IDE, a exemplo da última parte. Mas saiba que a criação de testes unitários não é de forma alguma dependente de uma IDE, e você também poderá criar testes unitários para suas classes, por exemplo, no Eclipse. A escolha aqui é meramente “didática”.

Vamos começar criando um projeto Java simples com o nome de Calculadora. Neste projeto crie uma classe chamada Calculadora, e inclua nesta classe o código abaixo:

public class Calculadora{

        // atributo
        private int resultado = 0;

        // método somar
        public double somar( int n1, int n2 ){

            resultado = n1 + n2;
            return resultado;
        }

        // método subtrair
        public double subtrair( int n1, int n2 ){

            resultado = n1 - n2;
            return resultado;
        }        

        // método multiplicar
        public double multiplicar( int n1, int n2 ){

            resultado = n1 * n2;
            return resultado;
        }

        // método dividir
        public double dividir( int n1, int n2 ){

            resultado = n1 / n2;
            return resultado;
        }
}

Repare que, no método dividir, propositadamente retiramos o teste que verifica a possibilidade de uma divisão por zero.

Crie agora uma classe chamada PrincipalCalculadora, que utilizará a primeira classe:

import javax.swing.JOptionPane;

public class PrincipalCalculadora{

    public static void main( String args[] ){

        int x, y;
        String sX, sY;

        sX = JOptionPane.showInputDialog( null, "Digite o primeiro número:",
        "Primeiro número", JOptionPane.QUESTION_MESSAGE );

        x = Integer.parseInt( sX );

        sY = JOptionPane.showInputDialog( null, "Digite o segundo número:",
        "Segundo número", JOptionPane.QUESTION_MESSAGE );

        y = Integer.parseInt( sY );    

        // instanciação de um objeto da classe calculadora
        Calculadora calc = new Calculadora();

        JOptionPane.showMessageDialog(null, "somar: " +  calc.somar( x, y ) );
        JOptionPane.showMessageDialog(null, "subtrair: " +  calc.subtrair( x, y ) );
        JOptionPane.showMessageDialog(null, "multiplicar: " +  calc.multiplicar( x, y ) );
        JOptionPane.showMessageDialog(null, "dividir: " +  calc.dividir( x, y ) );    

        System.exit( 0 );
    }
}

junit_img_1

Vamos agora criar uma classe chamada TesteCalculadora para testar nossa classe Calculadora. Adicione a ela o seguinte trecho de código:

public class TesteCalculadora {

    public static void main(String[] a){

        Calculadora c = new Calculadora();

        int valorUm = 5;
        int valorDois = 5;

        double valorTotal = c.somar(valorUm, valorDois);

        if(valorTotal == 10){
            System.out.println("valor correto!");
        }
        else{
            System.out.println("valor errado!");
        }
    }

}

Clique sobre a classe TesteCalculadora com o botão direito e escolha a opção Executar Arquivo (Run File). A execução deve apresentar o resultado esperado, ou seja, o teste foi executado e o método se comportou como esperado:

junit_img_2

Nossa classe de teste é funcional, mas para a boa prática de programação, erros devem ser tratados com exceções (blocos try-catch), e não com avaliações condicionais. Criar testes desta maneira, com controle de exceções, além de poluir o código com blocos try-catch, é muito trabalhoso.
É nesse momento que se mostra útil a utilização de um framework de testes.

O Framework de Testes JUnit

Existem vários frameworks para testes unitários na plataforma Java, e o mais famoso deles é o JUnit, um projeto open-source que atualmente está em sua versão 4.5. Na página do projeto [1] você poderá encontrar mais informações, além de tutoriais.
O Netbeans 6 dá suporte à versão mais recente do JUnit, que incorpora o uso de anotações para facilitar a criação de testes. A integração do Netbeans com o JUnit nos permite criar classes de teste rapidamente.

Testes com JUnit – Um exemplo prático

Agora que já vimos como criar uma classe de teste sem o JUnit, e vimos alguns dos inconvenientes dessa abordagem, vamos criar uma classe de teste para a nossa classe Calculadora, utilizando os recursos de integração do Netbeans ao JUnit.
Clique com o botão direito do mouse sobre a classe Calculadora. No menu que aparece, escolha a opção Ferramentas > Criar testes JUnit (Tools > Create JUnit Tests). Na próxima janela que aparece, escolha a opção JUnit 4.x e clique em Select. A seguinte tela será apresentada:

junit_img_3

Nesta tela encontramos alguns recursos a serem configurados para a classe de teste, como a presença de métodos de inicialização e finalização de casos de testes, o nível de acesso dos métodos a serem testados, e a possibilidade de geração de comentários nos códigos. Repare também que é sugerido um nome para a classe de teste (CalculadoraTest). Podemos aceitar as opções sugeridas, clicando em OK. Após este procedimento, será criada a classe de teste no diretório Pacote de Testes (Test Packages):

junit_img_4

Além dos casos de teste simples, criados para cada método da classe Calculadora, foram criados outros 4 métodos que merecem comentário, são eles:

@BeforeClass
setUpClass()

Neste método devem ser colocados códigos que precisam ser executados antes da criação de um objeto da classe de teste, ou seja, um código do qual todos os métodos de teste podem tirar algum proveito. Pode ser a criação de uma conexão com o banco de dados, por exemplo, ou a leitura de um arquivo no sistema de arquivos.
A anotação que acompanha o método (@BeforeClass) pode ser adicionada a qualquer método, e nesse caso, todos os métodos que tiverem essa anotação serão executados na ordem em que aparecem declarados, e antes de qualquer caso de teste específico.

@AfterClass
tearDownClass()

Neste método deverão ser colocados códigos que precisam ser executados assim que todos os casos de teste tiverem sido executados. Tais códigos podem ser referentes a liberação de recursos adquiridos no método setUpClass(), como o fechamento de conexões com o banco de dados, ou à liberação de arquivos.
Assim como acontece com a anotação @BeforeClass, a anotação @AfterClass pode acompanhar qualquer método, e nesses casos todos os métodos serão executados para a liberação de recursos, na ordem em que aparecem declarados.

@Before
setUp()

O método setUp() pode ser utilizado para a inicialização de recursos antes da execução de cada método de teste. É o local ideal para obter e inicializar recursos que precisam ser reiniciados a cada teste.
Assim como as outras anotações, @Before pode ser adicionado a outros métodos.

@After
tearDown()

O método tearDown() é utilizado para a liberação de recursos ao final de cada método de teste. Estes recursos geralmente são os que foram obtidos no método setUp().
A anotação @After pode, assim como as demais, ser utilizada com outros métodos.

Agora vamos observar o método de teste criado para o método somar da classe Calculadora:

junit_img_5

A anotação @Test indica que este método de teste deve ser executado pelo framework. Quando não quisermos que um método de teste seja executado basta remover a anotação.
O que o método de teste faz é criar uma instância da classe Calculadora, e passar dois parâmetros para o método somar, verificando em seguida o resultado.
Como você pode observar, os valores iniciais das variáveis de teste não são nada otimizados, isto porque o framework não tem como conhecer as regras pertinentes ao nosso sistema, colocando então valores padrões. Cabe a nós a “lapidação” do caso de teste, passando valores mais adequados para o teste.
Repare também que a verificação do resultado é feita através de um método de asserção, chamado assertEquals(), que recebe dois parâmetros. O que este método faz é verificar a igualdade entre os parâmetros, e caso estes valores não sejam iguais, é retornada uma exceção, e o teste falha. Veja que não precisamos utilizar blocos condicionais, nem estruturas de controle de exceções, o que torna nosso código de teste mais limpo e direto.
O comando fail() força a falha do teste, e no geral deve ser removido (a não ser que se queira realmente forçar a falha de um teste).
Vamos refinar nosso caso de teste:

junit_img_6

Repare que melhoramos os valores das variáveis utilizadas no teste do método testSomar, e no método assertEquals, passamos um terceiro parâmetro, que especifica uma variação decimal aceitável para a comparação de números de ponto-flutuante.
Para rodar o teste, clique com o botão direito do mouse sobre o ícone que representa a classe CalculadoraTest, na árvore de recursos de projeto (à esquerda), e escolha a opção Executar Arquivo (Run File). Você verá que todos os métodos de teste anotados com @Test serão executados, e como retiramos o comando fail somente da classe de teste testSomar, todos os outros testes falharão:

junit_img_7

Vamos ajustar os demais testes. O código final da classe de testes, até agora, deverá ser o seguinte:

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;

public class CalculadoraTest {

    public CalculadoraTest() {
    }

    @BeforeClass
    public static void setUpClass() throws Exception {
    }

    @AfterClass
    public static void tearDownClass() throws Exception {
    }

    @Before
    public void setUp() {
    }

    @After
    public void tearDown() {
    }

    /**
     * Test of somar method, of class Calculadora.
     */
    @Test
    public void testSomar() {
        System.out.println("somar");
        int n1 = 5;
        int n2 = 5;
        Calculadora instance = new Calculadora();
        double expResult = 10.0;
        double result = instance.somar(n1, n2);
        assertEquals(expResult, result, 0);
    }

    /**
     * Test of subtrair method, of class Calculadora.
     */
    @Test
    public void testSubtrair() {
        System.out.println("subtrair");
        int n1 = 5;
        int n2 = 3;
        Calculadora instance = new Calculadora();
        double expResult = 2;
        double result = instance.subtrair(n1, n2);
        assertEquals(expResult, result, 0);
    }

    /**
     * Test of multiplicar method, of class Calculadora.
     */
    @Test
    public void testMultiplicar() {
        System.out.println("multiplicar");
        int n1 = 2;
        int n2 = 3;
        Calculadora instance = new Calculadora();
        double expResult = 6;
        double result = instance.multiplicar(n1, n2);
        assertEquals(expResult, result, 0);
    }

    /**
     * Test of dividir method, of class Calculadora.
     */
    @Test
    public void testDividir() {
        System.out.println("dividir");
        int n1 = 5;
        int n2 = 2;
        Calculadora instance = new Calculadora();
        double expResult = 2.5;
        double result = instance.dividir(n1, n2);
        assertEquals(expResult, result, 0);
    }

}

Substitua o código da classe de testes pelo código acima e execute o teste. O último teste, do método dividir falha. Vamos analisar o que aconteceu:

junit_img_8

O método de teste para o método dividir determina que a divisão de 5 por 2 deve resultar em 2.5. Isto está correto, e devemos então verificar o método dividir na nossa classe Calculadora, para encontrar a causa do problema.
Ao analisar o código do método dividir, da classe Calculadora, vemos que ele retorna como resultado o valor da divisão direta de dois números inteiros. Qualquer operação que envolva um número inteiro retornará um número inteiro, e quando fazemos a divisão de 5 por 2, ele retorna somente o valor inteiro 2, é esse o problema de nosso método. Vamos alterar o código de nosso método dividir, na classe Calculadora para o seguinte:

public double dividir( int n1, int n2 ){

    double d1 = Double.valueOf(n1);
    double d2 = Double.valueOf(n2);

    double r = d1 / d2;
    return r;
}

Agora, sem nenhuma alteração em nossa classe de teste, execute os testes. Agora todos os testes passam:

junit_img_9

Conforme vimos até agora, temos um caso de teste para cada método da nossa classe Calculadora. Isso é bom, mas não o bastante. Precisamos criar casos de teste para outras situações. Por exemplo, vamos testar o comportamento de nosso método multiplicar para o caso de parâmetros com valores negativos:

junit_img_10

Como se pode ver, passamos dois valores negativos ao método multiplicar, e o mesmo nos retornou um valor positivo.

Consulte a API do framework JUnit na web e conheça os diversos métodos assertivos disponíveis. Há métodos assertivos para comparação de Strings, para garantir que um valor não é nulo, etc…

Gerando Relatórios de Teste com JunitReport

Podemos aplicar algumas modificações em um script de configuração do Netbeans para que sejam gerados relatórios dos testes realizados.
Na tela de arquivos (Files) procure pelo arquivo build-imp.xml. Trata-se de um arquivo de script ant, que o Netbeans utiliza para algumas configurações internas:

junit_img_11

Clique duas vezes sobre o arquivo, para abri-lo no editor. Procure pela tag de fechamento </junit> e abaixo dela digite o seguinte código:

<junitreport todir=”${test.src.dir}”>
<fileset dir=”${build.test.results.dir}”>
<include name=”TEST-*.xml”/>
</fileset>
<report todir=”${test.src.dir}/html”/>
</junitreport>

junit_img_12

Depois dessa modificação, clique sobre o projeto com o botão direito e escolha a opção Teste. Você perceberá que será criada uma estrutura a mais junto com as classes de teste. Esta estrutura passa a armazenar as páginas que apresentam os testes executados.

junit_img_13

Clique com o botão direito do mouse sobre o arquivo index.html e escolha a opção View:

junit_img_14

É isso pessoal! Espero que este pequeno tutorial seja útil.

Até o próximo!

Referências

[1] – http://www.junit.org/

31, Março 2009

Instalando o Plugin do WebSphere AS Community Edition 2.1 no Eclipse

Arquivado em: How-To — Tags:, — luizgustavoss @ 2:04 pm

Versão em PDF

Ontem comecei minha saga de tentar instalar o plugin de suporte ao WebSphere AS Community Edition (WASCE) no Eclipse Ganymede. Até então só havia utilizado para projetos o JBoss, Glassfish e Tomcat.

Inicialmente contei com o tutorial criado por Juliano Martins, mas como é de costume a Lei de Murphy me perseguir, não consegui instalar o plugin da maneira que o tutorial mostrava. Basicamente a instalação era interrompida perto dos 94%. Tentei várias vezes, sem sucesso.

Procurando um pouco mais na internet, encontrei o update site para o plugin do WASCE. Além de conter o update site para instalação do plugin através do Update Manager, ele contém o link para o arquivo compactado do plugin, e com este último fica fácil fazer uma instalação offline do plugin, bastando descompactar o arquivo dentro do diretório de instalação do Eclipse. O site contém as versões 2.0 e 1.1 do plugin, assim como a versão mais recente do mesmo, que é a 2.1. O plugin mais recente suporta as versões 2.0 e 2.1 do WASCE.

Bom, depois de alguma informação vamos colocar a mão na massa. Vou mostrar como configurar o plugin através do update site.

Adicione a URL http://download.boulder.ibm.com/ibmdl/pub/software/websphere/wasce/updates/ como um site no Update Manager do Eclipse:

wsace1

Além do plugin para o WASCE, também aproveitei pra instalar os adaptadores e runtimes do Gerônimo.

wsace2

Depois de clicar em install, será iniciado o download dos arquivos necessários. Uma tela de confirmação será apresentada para os itens a serem instalados.

wsace3

Confirme e continue. Aceite também os termos de licenças apresentados.

wsace4

wsace5

Depois de reiniciado o IDE, você encontrará as opções de configuração para os servidores. Aqui eu havia instalado previamente o WASCE 2.1.1.

Ao escolher a opção do servidor 2.1, indiquei o local de instalação que eu havia feito previamente.

wsace6

Após isso, clique em next para a próxima etapa, que é a configuração do usuário e senhaa (usuário: system/senha: manager) para acesso ao web console do WASCE.

wsace7

Ao confirmar, você terá sua configuração pronta. Inicie o servidor.

Assim que o servidor tiver iniciado, acesse http://localhost:8080. Você deverá ver a página inicial que acompanha a instalação do servidor. Através dela é possível ter acesso ao Administrative Console.

wsace8

Clicando no link do Administrative Console, serão solicitadas as credenciais de acesso.

wsace9

Ao informá-las, você será direcionado para o painel de administração do servidor.

wsace10

A utilização deste não é o foco deste how-to, então vou ficando por aqui.
Fica a dica!

16, Março 2009

Modem Huawei E226 no Ubuntu 7.10

Arquivado em: How-To — Tags:, — luizgustavoss @ 8:13 pm

Em dezembro resolvi contratar o serviço de banda larga móvel da Claro. Ao conversar com o atendente, fui informado de que nenhum dos modens tinha suporte ao Linux, e que o modem Huawei E226 tinha suporte ao Windows e ao Mac. Pois bem, esta foi minha escolha.huawai_claro


O atendente ainda me disse que alguns de seus clientes já tinham relatado o sucesso na configuração do modem no linux, então tive a esperança de encontrar na internet algum artigo que explicasse esta tal configuração.
Resolvi então procurar alguma coisa na internet, e de cara encontrei um artigo que dizia ser muito fácil esta configuração. Um dos artigos prometia a tal configuração em apenas 3 minutos.
Pois bem, depois de mais de uma hora tentando configurar o modem, ainda não tinha conseguido realizar uma conexão. O modem estava funcionando, constatação feita pelo led que indica a atividade do aparelho, mas nada de conexão.
Em um outro artigo, encontrei a explicação para o problema: apesar de o modem funcionar, os endereços DNS obtigos pelo modem não respondem.
Era necessário então mudar os endereços DNS após a inicialização do aparelho.
Tentei utilizar os endereços informados no artigo, mas não obtive sucesso com os mesmos.
Só consegui realizar a conexão, por fim, utilizando um outro endereço DNS encontrado em um outro artigo, que não é um dos endereços DNS da Claro.

Abaixo segue um resumo do que eu fiz para que o modem funcionasse, no meu caso.

Criei o arquivo wvdial-huawei.conf, no diretório /etc, com o seguinte conteúdo:

[Dialer Defaults]
Carrier Check = off
Init1 = ATZ
Init2 = ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0
Password = claro
Ask Password = 0
Check Def Route = 1
Phone = *99#
Idle Seconds = 0
Modem Type = Analog Modem
Stupid Mode = 1
Compuserve = 0
Baud = 460800
Dial Command = ATDT
Modem = /dev/ttyUSB0
ISDN = 0
Username = claro
[Dialer claro3g]
Stupid Mode = on
Password = claro
Auto Reconnect = off
Username = claro
Phone = *99#
Auto DNS = 0
Check DNS = 0

Depois criei o arquivo resolv.huawei.conf, também no diretório /etc, com o seguinte conteúdo:

nameserver 4.2.2.2

Como comentei acima, um dos artigos indicava a utilzação dos endereços de DNS 200.255.121.39 e 200.169.117.14, mas com estes eu não tive sucesso.

Criei, no diretório /home/gustavo/huawei o arquivo huawei.sh, com o seguinte conteúdo:

wvdial –config /etc/wvdial-huawei.conf

Este comando inicializa o modem, e deve ser executado todas as vezes que se deseja inicializar o mesmo.

Criei no diretório /home/gustavo/huawei o arquivo changeresolv.sh, com o seguinte conteúdo:

cat /etc/resolv.huawei.conf > /etc/resolv.conf

Este comando é responsável por modificar os endereços DNS obtidos automaticamente pelo modem, pelo endereço DNS que realmente funciona.

Depois de todos estes arquivos criados, quando quero me conectar, sigo os seguintes passos:

  1. Com o modem já conectado, me logo no console e executo, como root, o arquivo huawei.sh.
  2. Após o término da configuração do modem (isso é visível no modem pelo led azul que fica constantemente aceso, ou pelos logs no console que indicam a obtenção dos endereços de IP e de DNS) executo o arquivo changeresolv.sh.

Feito isso deve ser possível efetuar uma conexão. Escrevo este artigo a partir de uma conexão de sucesso ;)

Leiam os artigos indicados, e atentem para o fato de que é necessário ter o módulo usbserial instalado, que já está presente no Kernel 2.6.

Fica dada a dica!

15, Março 2009

Instalando e Configurando o PHP 5 e o Apache 2.2 no Windows

Arquivado em: How-To — Tags:, — luizgustavoss @ 7:21 pm

Motivação

Apesar de parecer banal e fácil para quem já conhece, e de ser facilmente encontrado na internet, um roteiro de instalação do PHP5 + Apache 2.2 pode não ser (e geralmente não é) tão trivial para quem está aprendendo esta linguagem.

Objetivos

O objetivo deste how-to não é falar exaustivamente sobre o servidor Apache, nem sobre o PHP. Para isso outras fontes podem ser consultadas. Vamos direto à instalação e configuração em um ambiente Windows. Ao final farei uma nota sobre a instalação no Ubuntu.

Downloads

Vamos fazer o download do servidor Apache e do PHP5.apache

Para o servidor Apache podemos baixar o executável apache_2.2.11-win32-x86-openssl-0.9.8i.msi (Win32 Binary including OpenSSL), encontrado na página de downloads do projeto: http://httpd.apache.org/download.cgi

php2No caso do PHP5, ao invés de baixarmos um binário vamos baixar um arquivo compactado. É apenas uma questão de preferência. No meu caso estou usando o arquivo php-5.2.8-Win32.zip, que pode ser encontrado na página de downloads: http://www.php.net/downloads.php. Caso exista uma versão mais recente, você poderá usá-la.

Instalação

Apache

A instalação do Apache não requer nada de especial.

Instalação do Servidor Apache

Instalação do Servidor Apache

Aceite o termo de uso e as opções padrão sugeridas pelo instalador. Ao final do processo, um ícone será apresentado na barra de tarefas (próximo ao relógio do sistema). Trata-se do monitor do serviço do Apache que, aliás, já é automaticamente iniciado após a instalação. Clicando duas vezes sobre o ícone do gerenciador é possível iniciar/parar/reiniciar o serviço:

Monitor do Serviço do Servidor Apache

Monitor do Serviço do Servidor Apache

Pronto! O servidor Apache já está instalado.

PHP5

Para instalar o PHP5 crie um diretório chamado php5 na raiz do sistema (C:\php5). Copie para este diretório o arquivo compactado que baixamos da área de downloads e descompacte-o .

Pronto! O PHP está instalado. Realmente simples, só falta agora efetuarmos as configurações.

Configurações

Vamos iniciar as configurações editando o arquivo httpd.conf do servidor Apache, que é o principal arquivo de configurações. Para isso, pare o serviço do servidor Apache, através do monitor do serviço. Feito isso, acesse o menu de programas, como indica a imagem abaixo:

Editar o httpd.conf

Editar o httpd.conf

Assim que for aberto para edição, coloque as seguintes linhas ao final do arquivo:

LoadModule php5_module “c:/php5/php5apache2_2.dll”
AddType application/x-httpd-php .php
PHPIniDir “c:/php5/”

Agora procure no arquivo o seguinte trecho:

<IfModule dir_module>
DirectoryIndex index.html
</IfModule>

e configure os valores para index.html index.htm index.php. O resultado deve ser:

<IfModule dir_module>
DirectoryIndex index.html index.htm index.php
</IfModule>

Bom, isso é tudo que precisamos fazer no httpd.conf.

Precisamos agora fazer algumas configurações no arquivo php.ini, do php.

No diretório do php (C:\php5) você encontratá um arquivo chamado php.ini-dist. Faça uma cópia deste arquivo, no mesmo diretório, e a renomeie para php.ini apenas. Neste arquivo encontre e descomente as seguintes linhas (para descomentar, basta remover o ponto-e-vírgula na frente da linha):

extension=php_mysql.dll
extension=php_mysqli.dll

Isso é necessário pois no php5 o suporte ao MySQL não é padrão. Esse “mysqli” é referente a um suporte melhorado ao MySQL. Depois disso o arquivo php.ini pode ser salvo.

Ainda no C:/php5/ existe uma dll chamada libmysql.dll. Copie esta dll e o arquivo php.ini para o diretório System32 (aqui cabe um comentário: fiquei quase 1 semana pra descobrir que tinha que colocar essa bendita dll no System32, porque a documentação não cita nada, mas é necessário).

Testando o resultado

Sua instalação está pronta!

Para testar se o PHP realmente está funcionando, acesso o diretório C:\Arquivos de programas\Apache Software Foundation\Apache2.2\htdocs. É nesse diretório que deverão ficar seus projetos em PHP. Apague o arquivo que está nesse diretório, e crie um arquivo chamado index.php. Edite este arquivo e adicione o seguinte conteúdo:


<?php phpinfo(); ?>

Feito isso, inicie o servidor Apache através do monitor do serviço, e acesse em seu navegador o endereço http://localhost. Se tudo correr bem você verá a seguinte página:

Página de informações do PHP

Página de informações do PHP

É isto, você tem seu ambiente configurado e já pode começar a programar.Em breve farei postagens sobre o PHP também, vale a pena dar uma conferida.

PHP5 e Apache no Ubuntu

Para o pessoal que usa Ubuntu a coisa é mais simples. O servidor HTTP Apache já vem instalado, e é necessário apenas instalar o PHP. Durante a instalação as configurações necessárias já são realizadas, sendo que ao término na instalação já é possível começar a programar.

Para instalar o PHP5 no Ubuntu execute (como root) o seguinte comando no prompt:

# sudo apt-get install php5

A única informação digna de nota, no momento, é que o diretório de publicação do Apache fica em /var/www/.

Até o próximo post!

Dropbox no Ubuntu – Armazenamento gratuito de arquivos on-line

Arquivado em: How-To — Tags:, , — luizgustavoss @ 2:01 pm

Lendo uma notícia no site da Folha descobri o Dropbox, um serviço de armazenamento on-line.
A opção gratuita do serviço oferece 2GB de armazenamento (há uma opção para de 5 GB). Para ter acesso ao serviço é necessário fazer o cadastro no site.
O gerenciamento dos arquivos pode ser feito por meio do site, mas o serviço oferece um software gratuito, compatível com Windows, Mac e Linux, que cria no computador uma pasta chamada Dropbox, onde ficam armazenados os arquivos da sua conta. É possível, desta maneira, manter sincronizados os arquivos armazenados no site com os computadores onde houver instalado o sistema. O serviço facilita também o compartilhamento de arquivos com outros usuários, cadastrados no serviço ou não.

Download e Instalação para o Ubuntu

Além dos binários e fontes, disponíveis para instalação nos sistemas operacionais citados, estão disponíveis repositórios para o Ubuntu nas distribuições 8.10, 8.04, e 7.10. Os requisitos são:

* GTK 2.12 or higher
* GLib 2.14 or higher
* Nautilus 2.16 or higher
* Libnotify 0.4.4 or higher
* Wget 1.10 or higher

Para realizar a instalação através dos repositórios, basta adicionar no arquivo /etc/apt/sources.list, ou no Gerenciador de Pacotes Synaptic, as seguintes linhas, de acordo com a distribuição:

Ubuntu 8.10

deb http://linux.getdropbox.com/ubuntu intrepid main
deb-src http://linux.getdropbox.com/ubuntu intrepid main

Ubuntu 8.04

deb http://linux.getdropbox.com/ubuntu hardy main
deb-src http://linux.getdropbox.com/ubuntu hardy main

Ubuntu 7.10

deb http://linux.getdropbox.com/ubuntu gutsy main
deb-src http://linux.getdropbox.com/ubuntu gutsy main

Após a configuração dos repositórios, execute o comando:

# sudo apt-get install nautilus-dropbox

Depois de instalado, execute o comando:

# killall nautilus

nota: se você estiver executando o compiz, este procedimento poderá travar sua máquina – faça um logout e se logue novamente ao invés disso.

Criando sua Conta

Tenho que admitir que encontrar o formulário de cadastro não é fácil. A maneira mais rápida que encontrei foi tentar me logar, e uma vez que não estou cadastrado no sistema é apresentada a opção de cadastro:

Formulário de cadastro

Formulário de cadastro

Depois de feito o cadastro no serviço, inicie o Dropbox através do ícone presente na sua barra de tarefas, próximo ao relógio do sistema:

Serviço Dropbox

Serviço Dropbox

Após isso, será apresentada a tela de instalação:

Início da instalação

Início da instalação

Depois de poucas configurações (basicamente informar suas credenciais) o diretório do Dropbox, criado em seu diretório, será sincronizado com sistema:

Diretório sincronizado

Diretório sincronizado

A partir de agora, todo arquivo que você copiar para este diretório, será sincronizado automaticamente com o serviço.

Para maiores informações, leia os tutoriais disponíveis no site do serviço.
Está dada a dica!

[]’s

6, Fevereiro 2009

Visão geral da tecnologia Java

Arquivado em: Artigo — Tags: — luizgustavoss @ 6:13 am

Motivação

Estava eu aqui, escrevendo alguns tópicos da minha monografia que falam sobre a tecnologia Java, e me veio a idéia de publicar o conteúdo na forma de um artigo, dando uma visão geral da tecnologia.
Por um momento pensei que seria perda de tempo, afinal, já existe muito material por aí que fala sobre a história da linguagem, e sobre a tecnologia como um todo.

Mas escrevendo os tópicos da monografia percebi o quanto é difícil encontrar, em um único lugar, várias informações sobre a plataforma Java, o que é muito importante para quem está começando a se aventurar nesta tecnologia.

Portanto resolvi criar este artigo para registrar em um único lugar algumas informações relevantes sobre a tecnologia. As fontes de referência serão citadas ao final, e nelas poderão ser encontradas informações adicionais.
Críticas e sugestões são bem vindas na forma de comentários (até porque a monografia ainda não foi entregue até a presente data).

Se você chegou até aqui à procura de informações sobre a tecnologia Java, espero que este artigo possa ser interessante e atender às suas espectativas.

JavaTM

A tecnologia JavaTM há algum tempo, tem sido a principal escolha do mercado de TI para o desenvolvimento de sistemas distribuídos.

Segundo o ínice TIOBE, de fevereiro de 2009, Java ainda é a linguagem mais popular para o desenvolvimento de sistemas.

tpci_trends

É importante observar que este índice não se refere a melhor linguagem de programação, ou a linguagem com a qual se escreveu a maior quantidade de linhas de código até o momento. Este é um índice que leva em consideração, entre outras coisas, a quantidade de profissionais capacitados ao redor do mundo, cursos disponíveis e produtos no mercado.
Esta convergência para a tecnologia JavaTM se deve, principalmente, ao reconhecimento por parte do mercado de TI das qualidades inerentes da linguagem e da plataforma JavaTM como um todo.

Histórico

A tecnologia Java surgiu de uma pesquisa corporativa interna, financiada pela Sun Microsystems, em 1991. O objetivo era o desenvolvimento de uma linguagem que atendesse ao mercado de dispositivos eletrônicos inteligentes.
O resultado foi a criação de uma linguagem baseada em C e C++, que teve o nome inicial de Oak. Pouco tempo depois, rebatizada de Java, a linguagem se mostrou adequada para o desenvolvimento de páginas web dinâmicas, e em 1995 foi apresentada formalmente pela Sun Microsystems em uma conferência. Nascia aí a plataforma Java.

Hoje, muito mais do que uma linguagem, Java é uma plataforma rica, que permite o desenvolvimento de aplicações para dispositivos móveis, como celulares e PDAs, até aplicações corporativas complexas, baseadas em web services, passando ainda por aplicações desktop e discos blue-ray.

A linguagem de programação JavaTM

Ao criar a linguagem de programação Java, os engenheiros da Sun se basearam em duas das linguagens de implementação mais utilizadas até então, C e C++. Isso permitiu que Java estivesse facilmente acessível a uma enorme base de desenvolvedores ao redor do mundo, a maioria dos quais envolvidos no desenvolvimento de sistemas operacionais, sistemas de bancos de dados, telecomunicações e aplicativos para computadores pessoais.
Foram removidos da linguagem os recursos mais confusos, complexos, e propensos a erros encontrados em C e C++, mantendo assim a linguagem concisa, com aquilo que havia de melhor das duas linguagens.
Foram incluídos na linguagem recursos realmente necessários à grande maioria dos desenvolvedores, como strings, imagens gráficas, componentes de interface gráfica com o usuário, tratamento de exceções, multithreading, multimídia, processamento de arquivos, processamento de bancos de dados, redes cliente/servidor baseados na Internet e na World Wide Web e em computação distribuída, e estruturas de dados pré-empacotadas.
Java foi também a primeira linguagem verdadeiramenteo multiplataforma, implementando o conceito de “write once, run everywhere”, graças à sua arquitetura baseada em uma máquina virtual, que interpreta um código intermediário, conhecido como bytecode. A existência de máquinas virtuais para sistemas operacionais específicos permite que um mesmo bytecode gerado por um código compilado de uma classe Java seja executado em qualquer sistema operacional sem a necessidade de recompilação.

Desde sua criação, muitas características vem sendo adicionadas à linguagem Java e à plataforma Java como um todo. Todas estas características tornam a linguagem Java adequada, ao contrário do que muitos pensam, para o desenvolvimento de uma ampla variedade de sistemas, que incluem aplicações desktop, aplicações multimídia, applets, aplicações para Internet, intranet, extranet, portais, aplicações distribuídas baseadas em web services, aplicações para dispositivos móveis, discos blue-ray, aplicações para tv digital, e muito mais.

A plataforma tecnológica JavaTM

A tecnologia JavaTM não está limitada somente à linguagem de programação Java. Antes disso, JavaTM é uma ampla plataforma de desenvolvimento, constituída de várias APIs e ambientes de execução.
Apesar de ter sido desenvolvida inicialmente pela Sun, hoje a evolução da especificação da plataforma JavaTM é determinada por uma comunidade de empresas e indivíduos denominada JCP (Java Community Process) que, com suas experiências, ajudam a definir os rumos da plataforma, contribuindo com o melhor de cada segmento. Este modelo de evolução da plataforma permite que qualquer empresa possa implementar a espefificação da plataforma Java, na forma de um produto.
A platafoma JavaTM é dividida em três segmentos, ou edições principais: JSE, JEE e JME. Cada edição engloba e licencia um conjunto de APIs e ambiente de execução da plataforma Java para atender às necessidades específicas dos desenvolvedores de aplicações.

A JSE, ou Java Standard Edition, é o segmento base da plataforma JavaTM . É nele que encontramos as principais APIs a plataforma, que servem de base para os outro dois segmentos, além de APIs para o desenvolvimento de aplicações desktop.
A imagem abaixo apresenta o segmento JSE da plataforma JavaTM .

api_jse

Como é possível ver na imagem, a linguagem Java está no topo de uma série de tecnologias que compõem a plataforma JSE.
É possível visualizar também, nesta imagem, além das APIs que compõem a plataforma JSE, as ferramentas que acompanham o kit de desenvolvimento (JDK) e as tecnologias de implantação que acompanham ambiente de execução (JRE).

A JEE, ou Java Enterprise Edition, é o segmento da plataforma JavaTM que apresenta APIs para o desenvolvimento e aplicações corporativas distribuídas, transacionais, baseadas principalmente em tecnologias web.
A imagem abaixo ilustra a distribuição das APIs da plataforma JEE de acordo com o tipo de container JEE.

overview-j2eearchitecture

Como pode-se ver, a plataforma JSE é a base para todas as outras tecnologias presentes na plataforma JEE.

A JME, ou Java Micro Editon, é o segmento da plataforma Java destinado a dispositivos móveis como celulares, PDAs, e outros dispositivos embarcados que suportam JavaTM , mas não toda a API JSE ou JEE, e de certa forma é porção da tecnologia JavaTM que vai ao encontro das intenções originais ao se criar a linguagem Java.
Hoje, a plataforma JME evoluiu para uma arquitetura organizada de tecnologias distintas para dispositivos embarcados, e está dividida conforme a imagem abaixo.

fig2

Conclusão

Como pode-se ver, Java vai muito além da linguagem de programação. É uma plataforma completa, um conjunto de soluções para o desenvolvimento de aplicações de diversos tipos.
Apesar das novas tecnologias que surgem, Java ainda é uma tecnologia de destaque no mercado de desenvolvimento de aplicações, e as constantes melhorias na plataforma tendem a consolidar ainda mais a tecnologia, durante os próximos anos, como uma das principais do mercado.

Referências

http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html

http://java.sun.com/j2se/1.5.0/docs/

http://developers.sun.com/mobility/getstart/articles/survey/

http://java.sun.com/javaee/5/docs/tutorial/doc/

Deitel & Deitel – Java Como Programar 4ª Ed.

Érico Casella Tavares de Mattos – Programação de Softwares em Java

Érico Casella Tavares de Mattos – Programação Java para Wireless

Rick Cattell, Jim Inscore – Criando aplicações comerciais com a plataforma Java 2 Enterprise Edition

15, Janeiro 2009

Jogo da Memória em Java

Arquivado em: Tutorial — Tags:, , — luizgustavoss @ 1:03 am

Neste post irei publicar os fontes de um jogo que fiz há um tempo atrás, quando ainda estava na faculdade.

Este jogo foi um pequeno desafio pessoal que me propus quando comecei a aprender Java e que depois acabou virando um trabalho de sala.

Na faculdade havíamos feito um jogo da memória em C, para console.Nesta época eu estava começando a aprender Java, e estava encantado com a possibilidade de criar interfaces gráficas sem a necessidade de uma IDE. Por esta razão, nenhuma IDE será necessária para criar este jogo.

Na ocasião eu utilizei o JCreator como editor de código, mas você poderá digitar as classes no bloco de notas e compilar no console se preferir, funciona também ;)

Basicamente é um jogo que utiliza pacotes do core de Java, e não é necessária a utilização de nenhuma biblioteca adicional às já encontradas na JRE para seu funcionamento.

São quatro classes e algumas imagens, que você deverá dispor da seguinte forma:

- Jogador.java
- MyButton.java
- TelaUm.java
- TelaJogo.java
- – imagens (diretório)
- – - duke (diretório)
- – - tux (diretório)
- – - jogo (diretório)

As imagens usadas, mais especificamente dos diretórios tux e duke, foram encontradas na internet. As demais, do diretório jogo, foram encontradas também na internet, e algumas são montagens que fiz.

Cada diretório de imagem, com exceção do diretório “jogo”, representam os possíveis jogos presentes para se escolher. Quando eu fiz esse jogo pela primeira vez, ele tinha 20 diretórios, ou seja, era possível escolher vários desenhos diferentes para os jogos.

Bom, depois de tanto falar, vamos aos fontes. Uma vez criados os arquivos .java citados acima, copie os conteúdos das classes abaixo para seus devidos arquivos:

Jogador.java


public class Jogador{

    private String nome;
    private int pontos;

    public Jogador(String nomeJogador){

        nome = (nomeJogador.equals("")? "Jogador sem nome...coitado! ": nomeJogador );
        pontos = 0;
    }

    public String obterNome(){

        return nome;
    }

    public int obterPontos(){

        return pontos;
    }

    public void incrementarPontos(){

        pontos += 5;
    }

    public void decrementarPontos(){

        pontos--;
    }

} // fim da classe pessoa

MyButton.java


import javax.swing.*;

public class MyButton extends JButton{

    private Icon imagemPadrao;
    private Icon imagemBotao;

    public MyButton(Icon imagemPadrao, Icon imagemBotao){

        super();

        this.imagemBotao = imagemBotao;
        this.imagemPadrao = imagemPadrao;

        setImagemPadrao();
    }

    public void setImagemPadrao(){

        this.setIcon(imagemPadrao);
    }

    public void setImagemBotao(){

        this.setIcon(imagemBotao);
    }    

    public Icon getImagemBotao(){

        return this.imagemBotao;
    }
}

TelaUm.java


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class TelaUm extends JFrame implements ActionListener, ItemListener{    

    private Container container;
    private JButton botaoSair, botaoIniciarJogo;
    private JPanel painelBotoes, painelDados, painelCabecalho;
    private JPanel painelCentro, painelRodape, painelImagem;
    private Icon imagemPainel, imagemRodape, imagemJogar, titulo;
    private Icon imagemJogarRoll, imagemSair, imagemSairRoll;
    private JLabel labelImagemPainel, nomeJogador, temaJogada;
    private JLabel texto1, desenvolvimento, autor;
    private GridLayout gridBotoes, gridDados, gridCabecalho, gridRodape;
    private JComboBox temasJogada;
    private int indiceTema = 1;
    private Jogador objJogador;
    private TelaJogo objTelaJogo;
    private JTextField fieldNomeJogador;
    private Font fonte18, fonte10;
    private JTextArea telaSaida = new JTextArea();
    private boolean jogoFacil = false;
    private ButtonGroup dificuldadeGroup;
    private JMenu menuDificuldade;
    private JMenuBar barraMenu;
    private JRadioButtonMenuItem facil, dificil;
    private JLabel nivelDificuldade;

    String nomeObjJogador;

    // os temas para os jogos
    private String nomesTemas[] =
    { "Duke", "Tux"};    

    // índices dos temas para os jogos
    private int indiceTemas[] =
    { 1, 2 };    

    public TelaUm(){                   

        super( "Bem-vindo ao Jogo da Memória!" );                

        // adiciona um listener à janela
        addWindowListener(            

            // classe interna anônima
            new WindowAdapter(){

                // trata o evento de quando o usuário fecha a janela
                public void windowClosing( WindowEvent windowEvent ){

                    saidaPrograma();
                }
            }// fim da classe interna anônima    

        );

        nivelDificuldade = new JLabel("Nível de dificuldade: DIFÍCIL");
        nivelDificuldade.setForeground(Color.red);

        // gerenciadores de layout
        gridBotoes = new GridLayout( 1, 2, 5, 5 );
        gridDados = new GridLayout( 6, 1, 10, 10 );
        gridCabecalho = new GridLayout( 1, 1, 10, 10 );
        gridRodape = new GridLayout( 1, 1, 10, 10 );

        // painel da imagem (esquerda)
        imagemPainel = new ImageIcon(getClass().getResource("/imagens/jogo/painel.gif"));
        labelImagemPainel = new JLabel( imagemPainel );
        painelImagem = new JPanel();
        painelImagem.add( labelImagemPainel );
        painelImagem.setBackground( Color.white );

        fonte10 = new Font( "Verdana", Font.ITALIC, 10 );

        // imagens dos botões
        imagemJogar = new ImageIcon(getClass().getResource("/imagens/jogo/jogar.gif"));
        imagemJogarRoll = new ImageIcon(getClass().getResource("/imagens/jogo/jogarRoll.gif")); // imagem Rollover
        imagemSair = new ImageIcon(getClass().getResource("/imagens/jogo/sair.gif"));
        imagemSairRoll = new ImageIcon(getClass().getResource("/imagens/jogo/sairRoll.gif")); // imagem Rollover        

        // botão Iniciar Jogo
        botaoIniciarJogo = new JButton( "Iniciar Jogo", imagemJogar );
        botaoIniciarJogo.setRolloverIcon( imagemJogarRoll );
        botaoIniciarJogo.addActionListener( this );
        botaoIniciarJogo.setSize( 250, 15 );
        botaoIniciarJogo.setHorizontalAlignment( SwingConstants.LEFT );

        // botão Sair
        botaoSair = new JButton( "Abandonar o Jogo", imagemSair );
        botaoSair.setRolloverIcon( imagemSairRoll );
        botaoSair.addActionListener( this );
        botaoSair.setSize( 250, 15 );
        botaoSair.setHorizontalAlignment( SwingConstants.RIGHT );
        botaoSair.setHorizontalTextPosition( SwingConstants.LEFT );

        // painel de botões (inferior)
        painelBotoes = new JPanel();
        painelBotoes.setBackground( Color.lightGray );
        painelBotoes.setLayout( gridBotoes );
        painelBotoes.add( botaoSair );
        painelBotoes.add( botaoIniciarJogo );        

        //cabeçalho
        titulo = new ImageIcon(getClass().getResource("/imagens/jogo/titulo.gif"));
        texto1 = new JLabel( titulo );
        texto1.setHorizontalAlignment( SwingConstants.CENTER );        

        // painel de cabeçalho
        painelCabecalho = new JPanel();
        painelCabecalho.setLayout( gridCabecalho );
        painelCabecalho.setBackground( Color.lightGray );
        painelCabecalho.add( texto1 );

        // label do nome do jogador
        nomeJogador = new JLabel("Informe seu nome:");
        nomeJogador.setHorizontalAlignment( SwingConstants.LEFT );

        // campo do nome do jogador
        fieldNomeJogador = new JTextField( 15 );
        fieldNomeJogador.setHorizontalAlignment( SwingConstants.LEFT );

        // label do tema da jogada
        temaJogada = new JLabel( "Escolha o tema:" );
        temaJogada.setHorizontalAlignment( SwingConstants.LEFT );

        // ComboBox do tema da jogada
        temasJogada = new JComboBox( nomesTemas );
        temasJogada.addItemListener( this );
        temasJogada.setMaximumRowCount( 4 );

        // configuração do painel central
        painelCentro = new JPanel();
        painelCentro.setLayout( gridDados );
        painelCentro.setBackground( Color.lightGray );
        painelCentro.add( temaJogada );
        painelCentro.add( temasJogada );
        painelCentro.add( nomeJogador );
        painelCentro.add( fieldNomeJogador );
        //painelCentro.add( som );
        painelCentro.add(nivelDificuldade);

        menuDificuldade = new JMenu("Nível de Dificuldade");
        menuDificuldade.setBackground( Color.lightGray );

        dificuldadeGroup = new ButtonGroup();

        dificil = new JRadioButtonMenuItem("Difícil (6X6)");
        dificil.setSelected(true);

        dificil.addActionListener(new ActionListener(){

            public void actionPerformed(ActionEvent evt){
                jogoFacil = false;
                nivelDificuldade.setText("Nível de dificuldade: DIFÍCIL");
                nivelDificuldade.setForeground(Color.red);
            }
        });

        facil = new JRadioButtonMenuItem("Fácil (4X4)");

        facil.addActionListener(new ActionListener(){

            public void actionPerformed(ActionEvent evt){
                jogoFacil = true;
                nivelDificuldade.setText("Nível de dificuldade: FÁCIL");
                nivelDificuldade.setForeground(Color.blue);
            }
        });

        dificuldadeGroup.add(dificil);
        dificuldadeGroup.add(facil);

        menuDificuldade.add(dificil);
        menuDificuldade.add(facil);

        barraMenu = new JMenuBar();
        setJMenuBar(barraMenu);
        barraMenu.setBackground( Color.lightGray );

        barraMenu.add(menuDificuldade);        

        // imagem do rodapé
        imagemRodape = new ImageIcon(getClass().getResource("/imagens/jogo/java.gif"));

        // texto do rodapé
        desenvolvimento = new JLabel(
        "Desenvolvido em Java",
        imagemRodape, SwingConstants.CENTER );
        desenvolvimento.setFont( fonte10 );        

        // configuração do painel de rodapé
        painelRodape = new JPanel();
        painelRodape.setLayout( gridRodape );
        painelRodape.setBackground( Color.white );
        painelRodape.add( desenvolvimento );        

        // configuração do painel de dados (que possui o painel de cabeçalho,
        // o painel central e o painel de botões
        painelDados = new JPanel();
        painelDados.setLayout( new BorderLayout( 10, 10 ));
        painelDados.setBackground( Color.lightGray );
        painelDados.add( painelCabecalho, BorderLayout.NORTH);
        painelDados.add( painelCentro );
        painelDados.add( painelBotoes, BorderLayout.SOUTH );        

        // configuração do container (que tem toda essa bagunça aí!!! =)
        container = getContentPane();
        container.setLayout( new BorderLayout( 5, 5 ) );
        container.setBackground( Color.lightGray );
        container.add( painelRodape, BorderLayout.SOUTH );
        container.add( painelImagem, BorderLayout.WEST );
        container.add( painelDados );        

        setSize( 550, 380 );
        setVisible( true );
        setResizable( false );

    }

    private void saidaPrograma(){

        telaSaida.setText(

            "tJogo da Memória - 2005nn"+
            "tDesenvolvido por: Luiz Gustavo Stábile de Souzan"+
            "tGraduando em Análise de Sistemas pela "+
            "Faculdade de Ciências e Tecnologia de Birigui  n"+
            "tContato: luizgustavoss@gmail.comnn"+
            "tLinguagem de Desenvolvimento: Java (TM) 2 Standard Edition nn"+
            "tRequisitos: J2RE - Java(TM) 2 Runtime Environmentnn"+
            "tEste jogo foi desenvolvido com fins educacionais, portanto sem nenhum tipo de garantia.nn"

        );

        JOptionPane.showMessageDialog(null, telaSaida,
        "Informações sobre o Jogo", JOptionPane.PLAIN_MESSAGE);
        System.exit( 0 );
    }

    public void actionPerformed( ActionEvent event ){

            // se o evento for do botão sair
            if ( event.getSource() == botaoSair ){

                saidaPrograma();

            }

            // senão é do botão iniciar jogo
            else if ( event.getSource() == botaoIniciarJogo ){                

                nomeObjJogador = fieldNomeJogador.getText();
                objJogador = new Jogador( nomeObjJogador );

                if(jogoFacil)
                    objTelaJogo = new TelaJogo( objJogador, indiceTema, 4 );
                else
                    objTelaJogo = new TelaJogo( objJogador, indiceTema, 6 );
            }
    }

    public void itemStateChanged( ItemEvent event ){

        if ( event.getSource() == temasJogada ){

            if ( event.getStateChange() == ItemEvent.SELECTED )

                indiceTema = indiceTemas[ temasJogada.getSelectedIndex() ];
        }
    }

    public static void main( String args[] ){

        TelaUm application = new TelaUm();

        application.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        application.setLocationRelativeTo( null );
    }

} // fim da classe TelaUm

TelaJogo.java


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class TelaJogo extends JFrame implements ActionListener{

    /**
     * Construtor da classe
     * @Param jog - Objeto jogador, com os dados do jogador
     * @Param codJog - O tema escolhido
     * @Param fatorJogo - Inteiro que determina se o jogo é 4X4 ou 6X6
     */    

         //ClassLoader cl = this.getClass().getClassLoader();
         public TelaJogo( Jogador jog, int codJog, int fatorJogo ){        

        super( "Jogo da Memória" );    

        setLocation( 200, 10 );            

        addWindowListener(new WindowAdapter(){

                public void windowClosing( WindowEvent windowEvent ){

                    mostrarResumoJogo();
                }
        });        

        fator = fatorJogo;

        objJogadorJogada = jog;
        temaJogada( codJog );
        preparaArrayImagens();
        container = getContentPane();

        labelPontosJogador = new JLabel( "Jogador: " + objJogadorJogada.obterNome() + " >> Pontos: " );

        pontosJogador = new JLabel( ""+objJogadorJogada.obterPontos() );

        imagemSair = new ImageIcon(getClass().getResource("/imagens/jogo/sair.gif"));
        imagemSairRoll = new ImageIcon(getClass().getResource("/imagens/jogo/sairRoll.gif"));        

        // configura o botão sair
        botaoSair = new JButton(" Sair do Jogo ", imagemSair);
        botaoSair.setRolloverIcon( imagemSairRoll );
        botaoSair.addActionListener( this );        

        painelImagens = new JPanel();
        painelPontos = new JPanel();        

        // configurando o painel superior
        painelPontos.setBackground( Color.white );
        painelPontos.add( labelPontosJogador );
        painelPontos.add( pontosJogador );        

        grid = new GridLayout( fator, fator, 5, 5 );

        painelImagens.setLayout( grid );                

        imagemPadrao = new ImageIcon(getClass().getResource("/imagens/jogo/standard.gif"));

        posicoesFiguras = new MyButton[( fator * fator )];                

        for ( int cont = 0; cont < ( fator * fator ); cont++ ){

            posicoesFiguras[ cont ] = new MyButton(imagemPadrao, imagens[cont]);
            posicoesFiguras[ cont ].addActionListener( this );
            painelImagens.add( posicoesFiguras[ cont ] );
        }

        container.add( painelPontos, BorderLayout.NORTH);
        container.add( botaoSair, BorderLayout.SOUTH );
        container.add( painelImagens );

        double d_largura = (fator == 4?82.5:80);

        d_largura *= fator;

        int i_largura = (int) d_largura;

        setSize( i_largura, i_largura+70 );
        setVisible( true );
        setResizable( false );
    }

    /**
     * Prepara o Array de Imagens
     *
     */
    private void preparaArrayImagens(){

        int posicaoNoArray, x, y;

        this.imagens8 = new Icon[(fator * fator)/2];

        for ( x = 0; x < ((fator*fator)/2); x++ ){

            this.imagens8[ x ] = new ImageIcon(getClass().getResource(tema + ( x + 1 ) + ".GIF"));
        }

        this.imagens = new Icon[ (fator*fator) ];

        for ( x = 0; x < 2; x++ ){

            for ( y = 0; y < ((fator*fator)/2); y++ ){

                do{
                    posicaoNoArray = ( int ) ( Math.random() * (fator*fator) );        

                }while( this.imagens[ posicaoNoArray ] != null );

                this.imagens[ posicaoNoArray ] = imagens8[ y ];

            }
        }
    }

    /**
     * Descobre o tema escolhido
     * @Param codTema - Código do tema escolhido
     */
    private void temaJogada( int codTema ){

        switch( codTema ){

                case 1: this.tema = "/imagens/duke/";
            break;

            case 2: this.tema = "/imagens/tux/";
            break;

        }
    } 

    /**
     * Mostra o resumo do jogo ao sair
     *
     */
    private void mostrarResumoJogo(){

        resumoJogo = "Jogador: " + objJogadorJogada.obterNome() + "nn" +
        "Pontos: " + objJogadorJogada.obterPontos() + "nn" +
        "Quantidade de tentativas: " + qtdeTentativas;

        JOptionPane.showMessageDialog( null, ""+resumoJogo, "Resumo do Jogo",
        JOptionPane.INFORMATION_MESSAGE ); 

        setVisible( false );
        System.gc();
    }

    public void actionPerformed( ActionEvent event ){        

        // Se o evento for do botão Sair...
        if ( event.getSource() == botaoSair ){

            mostrarResumoJogo();
        }

        // Caso contrário é evento de botões de imagem
        else{

            // testa se é o primeiro clique
            if( primeiroClique ){

                qtdeTentativas++; 

                // testa se o jogador errou na jogada anterior
                if ( !acertou ){

                    botaoUm = (MyButton) botaoClicadoUm;
                    botaoDois = (MyButton) botaoClicadoDois;

                    botaoUm.setImagemPadrao();
                    botaoDois.setImagemPadrao();
                }

                botaoClicadoUm = event.getSource();

                botaoUm = (MyButton) botaoClicadoUm;
                botaoUm.setImagemBotao();                

                // indica que este foi o primeiro clique
                primeiroClique = !primeiroClique;
            }

            // se não for o primeiro clique
            else{                

                botaoClicadoDois = event.getSource();
                botaoDois = (MyButton) botaoClicadoDois;                                

                // verifica se o jogador clicou no mesmo botão
                if ( botaoClicadoDois == botaoClicadoUm ){

                    acertou = false;

                    JOptionPane.showMessageDialog( null, "Ação não permitida!",
                    "Ação Não Permitida", JOptionPane.WARNING_MESSAGE );
                }

                // se não for o mesmo botão...
                else{            

                    // coloca a imagem no botão
                    botaoDois.setImagemBotao();

                    // compara com o primeiro botão clicado
                    if ( botaoUm.getImagemBotao().equals( botaoDois.getImagemBotao())){

                        acertou = true;
                        qtdeAcerto++;                            

                        // Desabilita os botões
                        botaoUm.setEnabled( false );
                        botaoDois.setEnabled( false );                            

                        // incrementar pontos
                        objJogadorJogada.incrementarPontos();

                        pontosJogador.setText( ""+objJogadorJogada.obterPontos() );                            

                        // se foi o último par encontrado, apresenta resumo do jogo e fecha a janela
                        if ( qtdeAcerto == ((fator*fator)/2) ){

                            mostrarResumoJogo();
                            setVisible( false );
                            System.gc();
                        }
                    }

                    // se não for o mesmo botão
                    else{

                        acertou = false;                            

                        //decrementar pontos
                        objJogadorJogada.decrementarPontos();

                        pontosJogador.setText( ""+objJogadorJogada.obterPontos() );
                    }                    

                    // indica que este foi o segundo clique
                    primeiroClique = !primeiroClique;
                }
            }
        }
    } 

    private Object botaoClicadoUm = new Object();
    private Object botaoClicadoDois = new Object();
    private JLabel pontosJogador, labelPontosJogador;
    private JPanel painelImagens, painelPontos;
    private JButton botaoSair;
    private Icon imagemSair, imagemSairRoll, imagens[], imagemPadrao, imagens8[];
    private GridLayout grid;
    private Container container;
    private String tema, resumoJogo = "";
    private Jogador objJogadorJogada;
    private int fator, qtdeAcerto, qtdeTentativas = 0;
    private boolean primeiroClique = true;
    private boolean acertou = true;
    private MyButton botaoUm, botaoDois, posicoesFiguras[];    

} // fim TelaJogo

Os arquivos de imagem necessários estarão disponíveis para download ao final do post.

Não vou explicar o jogo passo-a-passo (ahhhhhhh) mas se você está começando a aprender Java, esse pequeno jogo é uma boa oportunidade para aprender a usar componentes de tela básicos, assim como aprender a usar tratamento de eventos desses componentes.

Depois de compiladas as classes (com o comando javac [nome-da-classe.java], pelo console), basta executar a classe TelaUm.java (java TelaUm, pelo console).

Jogo em execução

Jogo em execução

Imagens para o Jogo

Queria colocar todas as imagens compactadas para download, mas não é possível (até onde eu sei). Portanto, colocarei aqui as imagens referentes a cada diretório. No caso das imagens dos diretórios “tux” e “duke”, que eram muitas, eu dei um printscreen na tela e postarei uma imagem só, com todas (separadas, uma única imagem para o diretório “tux” e uma única imagem para o diretório “duke”). Vocês terão o trabalho de recortar cada uma, no tamanho de 70×70 pixels. Aproveitem para renomear cada uma de acordo com o que se vê nas imagens.

No caso das imagens do jogo (imagens de tela, botões…), por apresentarem tamanhos diversos optei por colocar uma a uma. Vamos a elas:

(importante 1: clique sobre as imagens para que elas sejam abertas no tamanho original, para só depois salvarem as mesmas)

Imagens do diretório “duke”

imagens-duke

Imagens do diretório “tux”

imagens-tux

Imagens do diretório “jogo”

titulo standard sairroll sair painel jogarroll jogar java

Se tiverem dúvidas, fique à vontade para postar comentários!

Posts mais antigos »

Blog no WordPress.com.