Baixe o app para aproveitar ainda mais
Prévia do material em texto
1 AULA 06: CONSTRUÇÃO DE FORMULÁRIOS ABRINDO O PROJETO Você deve abrir o projeto da aplicação desenvolvida na última aula para que possamos modificar seu conteúdo. Para abrir o projeto da aplicação desenvolvida na última aula, abra a IDE NetBeans, pressione o botão “Abrir Projeto”, selecione a pasta onde salvou o projeto da aula passada (passo 1), marque a opção “Abrir como projeto principal” (passo 2) e pressione o botão “Abrir projeto”. Vide a ilustração: Abra o elemento HelloMIDlet.java (passo 1) e selecione o botão de visualização de fluxo (passo 2), conforme a ilustração a seguir: PREPARANDO A APLICAÇÃO Criaremos um novo formulário com novos componentes e alteraremos o fluxo da aplicação para permitir a execução de diferentes contextos. Um dos contextos que criaremos nesta aula será o de possibilitar a utilização de um “jogo da velha”, que codificaremos na próxima aula. Para iniciarmos, organize a distribuição dos objetos presentes no fluxo e, conforme a ilustração, vá ao grupo “Exibições” (p.1), clique no botão “Formulário” e arraste-o sobre a área de fluxo (passo 2), conforme ilustração: 2 Vá ao grupo “Comandos” (passo 1), clique no botão “Comando Ok” e arraste-o sobre o objeto “form1” (passo 2), conforme a ilustração: Clique no botão “Comando Voltar” e também o arraste sobre o objeto “form1” (passo 2): Agora, conforme a ilustração, clique no botão de visualização da tela (passo 1), altere a visualização para o formulário “form1” (passo 2), vá ao grupo “Itens” (passo 3) e arraste o botão “Item String” sobre a tela “form1” (passo 4): Agora vamos incluir um grupo para escolha de opções. Arraste o botão “Escolha de grupo” sobre a tela “form1” (passo 1): 3 Alteraremos o texto desse componente para “Você deseja” (passos 1 e 2). Também alteraremos o “Tipo” para “Exclusive” a fim de permitir somente uma seleção por escolha (passo 3): Vamos adicionar itens a esse grupo. Selecione o objeto que acabou de alterar (passo 1), clique nele com o botão auxiliar do mouse (passo 2) e selecione “Escolher elemento - Adicionar” (passo 3). Veja a ilustração: Alteraremos o elemento adicionado. Clique nele e altere a “String” para “Começar com 'X'” (passo 1): 4 Adicionaremos mais dois itens ao grupo. Selecione novamente o objeto “Escolha de grupo” (passo 1), clique nele com o botão auxiliar do mouse (passo 2) e selecione “Escolher elemento - Adicionar” (passo 3). Veja a ilustração: PREPARANDO A APLICAÇÃO Alteraremos o elemento adicionado. Clique nele e altere a “String” para “Começar com 'X'” (passo 1): Repita o processo e adicione o último item ao grupo conforme ilustra o passo 1 e altere o rótulo do objeto “Item de String” para “Jogo da Velha” (passo 2). Veja a ilustração: 5 Vamos incluir um novo grupo para escolha de opções. Arraste o botão “Escolha de grupo” sobre a tela “form1” (passo 1): Altere o rótulo para “Opções:” e, de maneira similar, repita o processo para adicionar itens ao grupo e altere a “String” dos objetos, colocando no primeiro “Jogar sozinho(a)” e no segundo “Ler nome do jogador” (passo 1). O resultado deve ficar semelhante a ilustração: 6 Altere o rótulo do objeto “okCommand1” para “Jogar” (passo 1): Renomeie o objeto “okCommand1” para “jogarCommand”. No painel navegador, clique com o botão auxiliar do mouse no objeto “okCommand1” (passo 1), selecione “Renomear” (passo 2), defina o “novo nome” como “jogarCommand” (passo 3) e selecione “Refatorar”(passo 4): PREPARANDO A APLICAÇÃO Agora que tudo está feito, criaremos um menu principal. Pressione o botão de visualização de fluxo (passo 1), selecione o grupo “Exibições” (passo 2) e arreste o objeto “Lista” (passo 3) para a área de fluxo. 7 Vamos adicionar itens ao menu principal. Clique com o botão auxiliar do mouse no objeto “list” e selecione “Novo / Adicionar” (passo 1) e escolha “Elemento da lista - Adicionar”: Selecione o “elemento da lista 1” e altere o texto da “String” para “Saudações”: Vamos adicionar outro item ao menu principal. Clique com o botão auxiliar do mouse no objeto “list” e selecione “Novo / Adicionar” (passo 1) e escolha “Elemento da lista - Adicionar”: 8 Selecione o “elemento da lista 2” e altere o texto da “String” para “Jogo da Velha”: Vamos adicionar o último item ao menu principal. Clique com o botão auxiliar do mouse no objeto “list” e selecione “Novo / Adicionar” (passo 1) e escolha “Elemento da lista - Adicionar”: Selecione o “elemento da lista 3” e altere o texto da “String” para “Sair”: ALTERANDO O FLUXO Antes de prosseguirmos salve o projeto, pressione o botão “Salvar Todos”. Agora que temos todos os objetos preparados, alteraremos o fluxo de funcionamento da aplicação para que a primeira tela a ser aberta seja a de listagem de opções, ou seja, o menu principal. No final do processo o resultado será conforme ilustra a imagem: 9 Para alterarmos o fluxo do programa, arraste a seta que aponta para o objeto “form” e leve-a ao objeto “list” (passo 1), conforme ilustra a imagem: Agora, arraste o elemento da lista “Sair” para o objeto “Dispositivo móvel”: Repita o procedimento, arraste o elemento da lista “Jogo da Velha” para o objeto “form1” (passo 1): 10 Siga o mesmo princípio para todas as modificações, arraste os elementos e componha o fluxo, siga os passos conforme ilustra a imagem: Com isso, transformamos o fluxo e o primeiro elemento acessado é a listagem (objeto “list”). Como podemos observar através da orientação do fluxo, se escolhermos o item “Saudações”, visualizaremos o formulário que fizemos na aula anterior, todavia, se selecionarmos o item “Jogo da Velha” visualizaremos o novo formulário que criamos (objeto “form1”) e se pressionarmos o menu “Voltar”, iremos novamente ao menu principal. Se pressionarmos “Sair” sairemos da aplicação: A CODIFICAÇÃO É importante que você compreenda a codificação que a IDE NetBeans gera, por isso, recomendamos que você depure o programa e veja quais caminhos e objetos são acionados para gerar pode se aperfeiçoar muito estudando a codificação que a IDE NetBeans gera automaticamente quando você constrói e modifica objetos ou fluxos. A fim de facilitar seu estudo, analisaremos um exemplo de código Essa é a codificação de uma MIDlet (linha 7) e os métodos obrigatórios “startApp”, “pauseApp” e “destroyApp” estão presentes. Quando a MIDlet iniciar, o método “startApp” será executado e a variável “current” receberá a referência do que está na tela do dispos não tiver recebido qualquer objeto de nossa aplicação e seu conteúdo for nulo (linha 13), então o objeto “helloScreen” será criado (linha 14). O objeto “helloScreen” é um formulário cuja a codificação está a listada seguir. Repare que após criarmos o objeto, colocamo Através deste exemplo, somos capazes de concluir que o objeto exibido na tela do dispositivo pode ser obtido através de um objeto do tipo “Displayable”. Tamb retorna a tela do dispositivo, onde podemos pegar o objeto que está sendo visualizado(“.getCurrent()”) no momento ou colocar um outro objeto para ser visualizado (“.setCurrent(…)”). Essa é a codificação do “OlaForm”, um Form que implementa a interface “CommandListener” (linha 5), que tem a função de receber os eventos de comando através do método “commandAction”. Quando o Form for carregado, o construtor “OlaForm” será executado (linha 10) e t “midlet” e “exitCommand” serão alimentadas e os elementos do formulário inicializados. A variável “midlet” (linha 12) receberá a MIDlet que criou o formulário e a variável “exitCommand” (linha 13) receberá um objeto de comando que terá a função de encerrar a aplicação. É importante que você compreenda a codificação que a IDE NetBeans gera, por isso, recomendamos depure o programa e veja quais caminhos e objetos são acionados para gerar pode se aperfeiçoar muito estudando a codificação que a IDE NetBeans gera automaticamente quando você constrói e modifica objetos ou fluxos. A fim de facilitar seu estudo, analisaremos um exemplo de código-fonte escrito manualmente: é a codificação de uma MIDlet (linha 7) e os métodos obrigatórios “startApp”, “pauseApp” e “destroyApp” estão presentes. Quando a MIDlet iniciar, o método “startApp” será executado e a variável “current” receberá a referência do que está na tela do dispositivo (linha 12). Se a tela do dispositivo ainda não tiver recebido qualquer objeto de nossa aplicação e seu conteúdo for nulo (linha 13), então o objeto “helloScreen” será criado (linha 14). O objeto “helloScreen” é um formulário cuja a codificação está a listada seguir. Repare que após criarmos o objeto, colocamo-lo na tela do dispositivo (linha 15). Através deste exemplo, somos capazes de concluir que o objeto exibido na tela do dispositivo pode ser obtido através de um objeto do tipo “Displayable”. Também podemos concluir que “Display.getDisplay(this)” retorna a tela do dispositivo, onde podemos pegar o objeto que está sendo visualizado (“.getCurrent()”) no momento ou colocar um outro objeto para ser visualizado (“.setCurrent(…)”). codificação do “OlaForm”, um Form que implementa a interface “CommandListener” (linha 5), que tem a função de receber os eventos de comando através do método “commandAction”. Quando o Form for carregado, o construtor “OlaForm” será executado (linha 10) e tudo será preparado, as variáveis “midlet” e “exitCommand” serão alimentadas e os elementos do formulário inicializados. A variável “midlet” (linha 12) receberá a MIDlet que criou o formulário e a variável “exitCommand” (linha 13) receberá um ndo que terá a função de encerrar a aplicação. 11 É importante que você compreenda a codificação que a IDE NetBeans gera, por isso, recomendamos depure o programa e veja quais caminhos e objetos são acionados para gerar o resultado. Você pode se aperfeiçoar muito estudando a codificação que a IDE NetBeans gera automaticamente quando você fonte escrito manualmente: é a codificação de uma MIDlet (linha 7) e os métodos obrigatórios “startApp”, “pauseApp” e “destroyApp” estão presentes. Quando a MIDlet iniciar, o método “startApp” será executado e a variável itivo (linha 12). Se a tela do dispositivo ainda não tiver recebido qualquer objeto de nossa aplicação e seu conteúdo for nulo (linha 13), então o objeto “helloScreen” será criado (linha 14). O objeto “helloScreen” é um formulário cuja a codificação está a lo na tela do dispositivo (linha 15). Através deste exemplo, somos capazes de concluir que o objeto exibido na tela do dispositivo pode ser obtido ém podemos concluir que “Display.getDisplay(this)” retorna a tela do dispositivo, onde podemos pegar o objeto que está sendo visualizado (“.getCurrent()”) no codificação do “OlaForm”, um Form que implementa a interface “CommandListener” (linha 5), que tem a função de receber os eventos de comando através do método “commandAction”. Quando o udo será preparado, as variáveis “midlet” e “exitCommand” serão alimentadas e os elementos do formulário inicializados. A variável “midlet” (linha 12) receberá a MIDlet que criou o formulário e a variável “exitCommand” (linha 13) receberá um 12 Na próxima aula complementaremos esse programa e você aprenderá mais sobre codificação para desenhar de objetos e construir jogos. Em MIDP 2.0, um novo pacote que fornece recursos para construção de jogos foi introduzido, simplificando o desenvolvimento de atividades que só seriam possíveis em MIDP 1.0 com uma grande quantidade de código repetitivo. Pesquise qual foi esse pacote. Em MIDP 2.0, foi introduzido o pacote javax.microedition.lcdui.game que disponibiliza cinco classes com uma grande variedade de recursos para a produção de jogos, são elas: 1. GameCanvas; 2. Layer; 3. Sprite; 4. TiledLayer; 5. LayerManager: AULA 7: CONSTRUÇÃO DE UM JOGO SIMPLES CRIAÇÃO DE JOGOS Antes de iniciarmos, é preciso ressaltar que o desenvolvimento de jogos requer muito do programador, tanto na lógica, quanto na imaginação. Para dispositivos móveis, o desenvolvimento de jogos usando Java Micro Edition exige, no mínimo, uma boa lógica de programação em liguagem Java e alguns conhecimentos dos objetos da plataforma em que a aplicação será executada. Nesta parte da aula, começaremos com um jogo bem simples, faremos um jogo da velha e criaremos passo-a-passo cada parte do jogo. Você perceberá ao longo da execução do trabalho de desenvolvimento que, apesar da simplicidade do jogo, a tarefa possui um bom grau de complexidade. CRIAÇÃO DO PROJETO DO JOGO DA VELHA Crie um novo projeto pressionando o botão “Novo projeto”, selecione “Java ME”, “Aplicativo móvel” (passo 1) e depois pressione o botão “Próximo” (passo 2): 13 Dê o nome “JogoDaVelhaMobileApplication” para o novo projeto (passo 1), marque a caixa de seleção “Configurar como projeto principal”, desmarque a caixa de seleção “Criar MIDlet Olá” e pressione o botão “Próximo” (passo 3): Mantenha selecionadas as opções “CLDC-1.1” e “MIDP-2.1” (passo 1) e pressione o botão “Finalizar” (passo 2): Para gerarmos um ponto de partida em nossa aplicação, teremos que criar uma classe do tipo “MIDlet”, para tanto, clique com o botão auxiliar do mouse (botão direito) em “<pacote padrão>” (passo 1), selecione “Novo” e, em seguida, clique em “MIDlet…” (passo 2): Na janela “Novo MIDlet”, nomeie o MIDlet como “VelhaMidlet” (passo 1). A fim de organizarmos os códigos-fontes do projeto desta aula, faremos o desenvolvimento dentro de um pacote que chamaremos de “br.edu.estacio.j2me” (passo 2) e pressionaremos o botão “Finalizar” (passo 3), conforme ilustra a imagem: O IDE NetBeans gerará dentro do pacote “br.edu.estacio.j2me” um código-fonte semelhante ao seguinte: 14 PREPARANDO O PONTO DE PARTIDA Nesta etapa, incluiremos funcionalidades para que possamos controlar e definir o que será apresentado nela. Os objetos Display e Displayable fornecem os recursos necessários para tal tarefa e o pacote “javax.microedition.lcdui”, que é nativo da plataforma Java Micro Edition, concede o acesso aos objetos de tela. Observe a codificação a seguir e, prestando atenção nas observações e nas dicas, inclua os códigos-fontes conforme indicam os passos 1 e 2 da ilustração. Java é caso-sensitivo, ou seja, maiúsculas e minúsculas são diferentes para ele. A instrução “import javax.microedition.lcdui.Display” é necessária para o método getDisplay() e “import javax.microedition.lcdui.Displayable” é necessária para o método setDisplayable(). Quando estiver digitando o código, o IDE NetBeans tentará te ajudar exibindo opções e, para poupar trabalho e evitar erros na digitação, quando encontrar a opção desejada pressione a tecla ENTER que o IDE NetBeans completaráa codificação para você. Sempre que quiser que o IDE NetBeans te ajude com alguma codificação, digite uma parte do código, pressione (e mantenha pressionada) a tecla CTRL e depois pressione uma vez a tecla de BARRA DE ESPAÇO. DOCUMENTANDO O PROJETO DO JOGO Daqui por diante, documentaremos todo o código-fonte que fizermos a fim de facilitar uma eventual e futura manutenção ou aprimoramento de nossos códigos. O IDE NetBeans possui bons recursos para documentação e conta com um visualizador de HTML embutido que provê a capacidade de exibir a documentação de atributos e métodos na medida em que você escreve, ou seja, se você documentar um código-fonte, poderá visualizar a documentação que fez quando for reutilizar a codificação, independentemente da parte em que esteja programando. Para documentar, siga os exemplos ilustrados nos passos 1, 2, 3, 4, 5 e 6: 15 Para documentar um método obtendo ajuda do IDE NetBeans, coloque o cursor imediatamente acima do atributo ou método desejado, digite /** e dê ENTER que o IDE preparará o local do texto para que você documente. Você também pode incluir algumas tags de HTML na documentação para destacar partes do texto, pois a visualização dessa documentação ocorrerá ou, em um visualizador de HTML ou, em um navegador WEB. CRIANDO UM FORMULÁRIO DE BOAS-VINDAS Desta vez, experimentaremos desenvolver todo o trabalho de criação do formulário manualmente. Criaremos alguns objetos e, por último, os colocaremos no formulário que iremos construir e exibir. Começaremos pelo texto de boas-vindas, que será exibido através de um objeto StringItem (campo de texto). Precisaremos incluir a importação da biblioteca que dá acesso ao objeto StringItem (passo 1) e codificar o método (passos 2, 3, 4 e 5). Para economizar digitação, você pode começar a programar pelo passo 2, ao digitar StringItem você deve pressionar CTRL e BARRA DE ESPAÇO para incluir automaticamente a importação da biblioteca StringItem na classe, ou seja, o passo 1 é realizado automaticamente. http://estacio.webaula.com.br/Cursos/gon283/docs/15PDM_aula07_doc01.pdf TESTE COM O MENU DO FORMULÁRIO Para testarmos a funcionalidade do menu, alteraremos o novo método para que ele assuma provisoriamente a funcionalidade de sair da aplicação e para realizarmos essa tarefa, seguiremos as instruções da ilustração. Com essas alterações, definimos que os eventos do CommandListener do formulário de boas-vindas serão recebidos em nossa MIDlet através do método setCommandListener(this) (passo 1), criamos um método para sair da MIDlet (passo 2) e fizemos sua documentação (passo 3). Também substituímos o conteúdo do método commandAction (passo 4) para que a aplicação seja encerrada, desde que o evento venha do formulário de boas-vindas e que o botão pressionado seja o botão de menu “OK”. Após a conclusão dessas alterações, o menu “OK” fará nossa aplicação ser finalizada. Para validar o funcionamento das alterações e realizar testes, execute a aplicação pressionando o botão “Executar projeto principal” ou a tecla F6. Parcial 1: código-fonte do projeto Nas próximas etapas desta aula, teremos modificações e a fins de conferência, segue todo o código se no arquivo chamado VelhaMidlet.java. Nas próximas etapas desta aula, teremos modificações e aprimoramentos em nossa codificação, todavia, para fins de conferência, segue todo o código-fonte que escrevemos até o momento. Este código se no arquivo chamado VelhaMidlet.java. 16 primoramentos em nossa codificação, todavia, para fonte que escrevemos até o momento. Este código-fonte encontra- 17 O JOGO DA VELHA E A CLASSE CANVAS A classe Canvas também fornece métodos ao desenvolvedor para lidar com ações de jogo, eventos-chave, e eventos de ponteiro (se for suportado pelo dispositivo). Também são fornecidos métodos para identificar as capacidades do dispositivo e mapeamento de teclas e, assim como acontecem com outras subclasses, como as derivadas de Displayable, a classe Canvas também pode ouvir os comandos de menu. Ao contrário de outros Displayables, para que seja possível usar a classe Canvas, ao menos, uma implementação é necessária na subclasse, pois o método paint é declarado como abstrato (abstract) e, por isso, deve ser implementado. Iniciaremos criando a classe JogoDaVelhaUI. Clique como botão auxiliar do mouse sobre o pacote br.edu.estacio.j2me, depois siga as orientações da ilustração (passos 1, 2, 3, 4 e 5): 18 O seguinte código-fonte será gerado: Faremos com que a classe JogoDaVelhaUI se torne uma subclasse da classe Canvas, para isso, modifique o código-fonte incluindo as instruções “extends Canvas” (passo 1) após o nome da classe. Como dito anteriormente, uma subclasse derivada da classe Canvas necessita implementar o método abstrato paint, portanto, uma marcação de erro ocorre pela falta dessa implementação e você pode aguardar que o IDE NetBeans exiba uma lâmpadazinha a esquerda da linha onde está o nome da classe para contar com ajuda e solucionar o erro com facilidade. Clique nessa lâmpada e depois em “Implementar todos os métodos abstratos” (passo 2) - o IDE NetBeans modifcará nosso código e adicionará todo conteúdo necessário automaticamente: Ao realizar essa ação, observe que foi adicionado em nosso código-fonte um novo método, provido pela classe Canvas, que é capaz de receber o evento para desenho de tela: Faremos algumas modificações no projeto para desenhar e visualizar a interface gráfica. Primeiramente, começaremos pelo desenho, criaremos métodos para limpar a tela e para desenhar o tabuleiro do jogo da velha nela. Faça a codificação seguindo os passos 1, 2, 3 e 4 da ilustração, explicaremos as principais instruções em breve. ATENÇÃO: Java é caso-sensitivo, ou seja, maiúsculas e minúsculas são diferentes para ele. Você deve documentar seu código-fonte, sempre. protected void paint(Graphics g) { 19 Throw new UnsuportedOperationException(“Not supported yet.”); } Quando estiver digitando o código, o IDE NetBeans tentará te ajudar exibindo opções e, para poupar trabalho e evitar erros na digitação, quando encontrar a opção desejada pressione a tecla ENTER que o IDE NetBeans completará a codificação para você. Sempre que quiser que o IDE NetBeans te ajude com alguma codificação, digite uma parte do código, pressione (e mantenha pressionada) a tecla CTRL e depois pressione uma vez a tecla de BARRA DE ESPAÇO. Como último passo dessa etapa, modificaremos o comportamento do menu “OK” para que, ao invés de sair de nossa aplicação, ele abra a classe JogoDaVelhaUI e exiba a tela que criamos. Conforme demonstra a ilustração, selecione e abra o arquivo VelhaMidlet.java (passo 1), depois localize no código-fonte o método commandAction (passos 2). Comente a instrução que sai da aplicação (passo 3) e coloque a instrução this.setDisplayable(new JogoDaVelhaUI()) para exibir na tela a nossa classe JogoDaVelhaUI (passo 4): 20 Após a conclusão dessas alterações, o menu “OK” fará nossa aplicação abrir a tela que monta o desenho do tabuleiro do jogo da velha. Para validar o funcionamento das alterações e realizar testes, execute a aplicação pressionando o botão “Executar projeto principal” ou a tecla F6. ENTENDENDO O CÓDIGO QUE DESENHA O TABULEIRO Quando nosso programa estiver funcionando, o método paint será chamado assim que a classe estiver pronta para ser desenhada e trará consigo um objeto gráfico (Graphics g) que permitirá desenhar na tela. Em nosso exemplo, esse objeto gráfico vem através da variável g que é copiada para a variável de classe graph. Posteriormente, os métodos limparTela e desenharTabuleiro são chamados,conforme demonstra o trecho de código: O método limparTela faz com que o objeto gráfico defina sua cor de desenho como branca e desenhe um retângulo por toda a tela, ou seja, tudo na tela é apagado por um enorme retângulo branco. O método setColor define a cor que o objeto gráfico assumirá e o método fillRect desenha o retângulo, conforme demonstra o trecho de código: Os três números dentro de setColor são para definir a cor (esquema de cores RGB). Você pode experimentar alterar a cor trocando os números, todavia deve respeitar o intervalo entre 0 (zero) e 255 (duzentos e cinquenta e cinco). Os quatro números dentro de filltRect são para definir respectivamente a posição dos eixos x e y, a largura e a altura do retângulo. Você também pode experimentar alterar as dimensões do retângulo alterando os números - tente números entre 0 (zero) e 100 (cem) para obter melhor visualização. O método desenharTabuleiro utiliza os métodos setColor e filltRect para desenhar os traços do tabuleiro e utiliza o método drawString para desenhar um número em cada lacuna do jogo, conforme demonstra o trecho de código: 21 http://estacio.webaula.com.br/Cursos/gon283/docs/15PDM_aula07_doc02.pdf DESENVOLVENDO A ESTRUTURA DO JOGO DA VELHA Precisamos construir a estrutura que controlará o jogo da velha e, nesta parte da aula, teremos que utilizar bastante imaginação e lógica de programação para fazer o jogo funcionar. Para entender essa parte da aula será necessário que você conheça a linguagem de programação Java no que tange o controle de fluxo, arranjos e manipulação de objetos. A partir de agora, investiremos algum tempo para criar aprimorar a interface visual e a lógica do jogo da velha e, somente quando terminarmos boa parte da codificação é que nossa aplicação será colocada em execução. Teremos que ter métodos capazes de emitir avisos (eventos) para as ações que ocorrem durante a partida, portanto, criaremos uma interface com métodos capazes de nos informar a jogada efetuada e o resultado final da partida (quando o jogo acabar). Criaremos uma interface com esses métodos, para usar tanto no controle do jogo da velha quanto na interface gráfica. Siga os passos da ilustração, clique no pacote br.edu.estacio.j2me e selecione a “Novo” (passo 1), depois selecione “Interface Java…” (passo 2). Chame a interface de JogoDaVelhaPartidaInterface (passo 3), verifique se está no pacote br.edu.estacio.j2me (passo 4) e pressione o botão “Finalizar” (passo 5): 22 Seguindo os passos, modificaremos o código-fonte para que ele fique da seguinte forma: Quando nosso jogo estiver concluído, utilizaremos esses métodos para emitir avisos (eventos). A ideia é que o método efetuarJogadaJogoDaVelhaPartidaEvent sirva para informar que uma jogada acabou de acontecer. No primeiro parâmetro (“char peca”) desse método, virá a peça que foi jogada, ou seja, virá um “X” ou um “O” e, no segundo parâmetro (“int posicaoTabuleiro”), virá a posição onde a jogada foi realizada, ou seja, virá um número com intervalo entre 0 (zero) e 8 (oito) para indicar a posição da jogada no tabuleiro, conforme a ilustração: Para o método resultadoJogoDaVelhaPartidaEvent a ideia é que ele sirva para informar que o jogo acabou. No primeiro parâmetro (“boolean haVencedor”) desse método, virá a informação de que há ou não há um vencedor. Havendo um vencedor, os outros parâmetros trarão a peça vencedora (“char peca”) e um arranjo com as posições em que as peças vencedoras se encontram no tabuleiro (“int[] posicoesTabuleiro”). 23 Agora que já temos o conceito, aplicaremos a ideia em nossa classe JogoDaVelhaUI seguindo os passos da ilustração. Primeiro, selecione e abra o arquivo “JogoDaVelhaUI.java” (passo 1) e depois digite “implements JogoDaVelhaPartidaInterface” (passo 2) após a classe Canvas - note que o nome a ser implementado é exatamente igual ao nome do arquivo de interface que criamos sem a extensão (“.java”). Como estamos implementando uma interface, é necessário que nossa classe contenha uma implementação dos métodos dela, portanto, uma marcação de erro ocorre pela falta dessa implementação, todavia você pode aguardar que o IDE NetBeans exiba uma lâmpadazinha a esquerda da linha onde está o nome da classe para contar com ajuda e solucionar o erro com facilidade. Clique nessa lâmpada e depois em “Implementar todos os métodos abstratos” (passo 3) - o IDE NetBeans modifcará nosso código e adicionará todo conteúdo necessário automaticamente. Ao realizar essa ação, observe que foram adicionados dois novos métodos em nosso código-fonte, providos pela interface JogoDaVelhaPartidaInterface: O IDE NetBeans incluiu os métodos e colocou uma instrução dentro de cada um deles para informar que operações não são suportadas ainda. Modificaremos esses métodos para que sejam capazes de desenhar na tela, siga as orientações da ilustração: 24 O método efetuarJogadaJogoDaVelhaPartidaEvent servirá para informar que uma jogada acabou de acontecer. No primeiro parâmetro (“char peca”) desse método, virá a peça que foi jogada, ou seja, virá um “X” ou um “O” e, no segundo parâmetro (“int posicaoTabuleiro”), virá a posição onde a jogada foi realizada, ou seja, virá um número com intervalo entre 0 (zero) e 8 (oito) para indicar a posição da jogada no tabuleiro. No passo 1, o valor da posição do tabuleiro é utilizado para formar uma coordenada x e y a fim de posicionar o desenho da jogada na tela. Se a variável peca trouxer um “X”, um quadrado será desenhado na cor bege, todavia, se a variável peca trouxer um “O” círculo será desenhado na cor roxa, conforme ilustra a imagem: O método resultadoJogoDaVelhaPartidaEvent servirá para informar que o jogo acabou. No primeiro parâmetro (“boolean haVencedor”) desse método, virá a informação de que há ou não há um vencedor. Havendo um vencedor, os outros parâmetros trarão a peça vencedora (“char peca”) e um arranjo com as posições em que as peças vencedoras se encontram no tabuleiro (“int[] posicoesTabuleiro”). Em conformidade com os valores dessas variáveis, o operador ternário (“((expressao) ? verdadeiro : falso)”) irá compor uma mensagem que será armazenada na variável de texto msg e o método drawString desenhará na cor preta o conteúdo dessa variável de texto a 20 pixels acima do final do visor do dispositivo móvel, conforme o exemplo ilustrado na imagem: Para testar a interface visual, alteraremos provisoriamente o método paint para invocar os métodos que criamos a fim de demonstrar se nossa codificação está correta. Para realizar essa ação, siga o passo da ilustração: Após a conclusão dessas alterações, o menu “OK” fará nossa aplicação abrir a tela que monta o desenho do tabuleiro do jogo da 25 velha e a alteração que fizemos provisoriamente no método paint poderá ser visualizada na tela do emulador. Para validar o funcionamento das alterações e realizar testes, execute a aplicação pressionando o botão “Executar projeto principal” ou a tecla F6. http://estacio.webaula.com.br/Cursos/gon283/docs/15PDM_aula07_doc03.pdf DESENVOLVENDO A LÓGICA DO JOGO DA VELHA Precisamos construir a classe do jogo da velha e, nesta parte da aula, teremos que utilizar bastante lógica de programação para fazer o jogo funcionar. Primeiramente, criaremos no pacote br.edu.estacio.j2me uma interface chamada JogoDaVelhaInterface que terá os principais métodos necessários ao jogo. Siga os passos da ilustração, clique no pacote br.edu.estacio.j2me e selecione a “Novo” (passo 1), depois selecione “Interface Java…” (passo 2). Chame a interface de JogoDaVelhaInterface (passo 3), verifique se está no pacote br.edu.estacio.j2me (passo 4) e pressione o botão “Finalizar” (passo 5):O seguinte código-fonte será gerado pelo IDE NetBeans: - Como estamos preparando a estrutura, precisamos pensar em quais métodos precisaremos incluir no jogo da velha. Podemos pensar em vários métodos, mas basicamente precisaríamos de: - Um método para definir a peça que começa a jogar primeiro; - Um método para iniciar a partida; - Um método para realizar a jogada em determinada posição; - Um método para obtermos informações acerca das peças no tabuleiro; - Um método para retornar qual é a peça da vez, ou seja, a peça a ser jogada agora; - Um método para trocar a vez do jogador; - Um método para dizer se o jogo terminou ou não; - Um método para contar as jogadas realizadas; - Um método para sabermos qual é a peça vencedora; Baseando-nos nesse pensamento, modificaremos o código-fonte para que ele incorpore as necessidades do jogo: 26 Você deve documentar seu código-fonte, sempre. Agora que temos a interface pronta, criaremos a classe JogoDaVelha no pacote br.edu.estacio.j2me. Siga os passos da ilustração, clique no pacote br.edu.estacio.j2me e selecione a “Novo” (passo 1), depois selecione “Classe Java…” (passo 2). Chame a classe de JogoDaVelha (passo 3), verifique se está no pacote br.edu.estacio.j2me (passo 4) e pressione o botão “Finalizar” (passo 5): http://estacio.webaula.com.br/Cursos/gon283/docs/15PDM_aula07_doc04.pdf http://estacio.webaula.com.br/Cursos/gon283/docs/15PDM_aula07_doc05.pdf 27 COLOCANDO O JOGO PARA FUNCIONAR Agora que concluímos a parte lógica do jogo da velha, é chagada a hora de colocar o jogo para funcionar. Voltaremos à interface visual para incluir a lógica do jogo da velha nela. Primeiro, selecione e abra o arquivo “JogoDaVelhaUI.java” (passos 1), depois adicione ao código uma variável de classe com as instruções “private JogoDaVelha jogoDaVelha;” (passo 2), daí crie um construtor na classe para inicializar a variável jogoDaVelha, use “this.jogoDaVelha = new JogoDaVelha(this);” (passo 3) e, por último, modifique o método paint (passo 4). Siga os passos e as instruções da ilustração: A seta vermelha indica o local onde comentamos as linhas que tínhamos usado para testes - vamos excluí-las a seguir. Agora que temos uma variável de classe jogoDaVelha inicializada pelo construtor, incluiremos os métodos para início de partida e detecção de teclas. Siga os passos da ilustração e adicione esses dois métodos ao código: 28 Passo 1 Temos o método iniciarPartida, que inicializa a variável graph como nula e diz ao jogo da velha, através da variável de classe jogoDaVelha, para que se prepare para iniciar uma nova partida, definindo a peça inicial com a que foi especificada em seu parâmetro. Passo 2 Documentação do método iniciarPartida. Passo 3 Temos o método keyPressed, que sobrescreve um método que vem da superclasse Canvas. Esse método recebe o código da tecla pressionada e, após um cálculo, atribui o valor à variável posicaoTabuleiro. Esse cálculo faz uma subtração do código provido pela tecla pressionada com o código da tecla zero (KEY_NUM0) a fim de obter o valor numérico da tecla. Quando o resultado é obtido, é realizada a subtração de 1 (um) para compatibilizar o resultado ao intervalo do tabuleiro, que é de 0 (zero) a 8 (oito). Agora, alteraremos a MIDlet para que o método iniciarPartida seja invocado. Siga as orientações da ilustração: 29 Após a conclusão dessas alterações, nosso jogo da velha estará funcionando. O menu “OK” fará nossa aplicação abrir a tela que monta o desenho do tabuleiro do jogo da velha e o jogo da velha estará pronto para funcionar com dois jogadores. Para validar o funcionamento das alterações e realizar testes, execute a aplicação pressionando o botão “Executar projeto principal” ou a tecla F6. Para encerrarmos essa fase do projeto, vamos adicionar dois menus ao código, um para reiniciar a partida e outro para sair da aplicação. Siga as orientações da ilustração: 30 Adicionamos ao código variáveis de classe para os menus e para a interface gráfica do jogo da velha (passos 1, 2, 3, 4, 5 e 6), depois criamos dois métodos que retornam os menus “Novo” e “Sair” (passos 7, 8, 9 e 10). Por fim, modificaremos o método que recebe os eventos de comando dos menus. Codifique conforme as orientações da ilustração: 31 Após a conclusão dessas alterações, o jogo da velha possui menus e estará pronto para funcionar com dois jogadores. Para validar o funcionamento das alterações e realizar testes, execute a aplicação pressionando o botão “Executar projeto principal” ou a tecla F6. http://estacio.webaula.com.br/Cursos/gon283/docs/15PDM_aula07_doc06. pdf CLASSES PARA JOGOS EM JAVA MICRO EDITION Com o lançamento do Mobile Information Device Profile (MIDP) versão 2.0, foi introduzido o pacote javax.microedition.lcdui.game que disponibiliza cinco classes com uma grande variedade de recursos para a produção de jogos, são elas: 1. GameCanvas; 2. Layer; 3. Sprite; 4. TiledLayer; 5. LayerManager: AULA 08: PERSISTÊNCIA DE DADOS ARMAZENAMENTO PERMANENTE Todo dispositivo móvel compatível com MIDP mantém uma área de memória dedicada ao armazenamento persistente de dados da aplicação. Os dados salvos nessa área de memória dedicada são mantidos mesmo se o dispositivo for desligado ou se a fonte de energia do dispositivo for removida, pois os dados são gravados atomicamente na memória do dispositivo móvel. A partir de agora, estudaremos a API RMS, que é uma API que nos permite acessar essa área de memória dedicada ao armazenamento persistente de dados da aplicação e que provê um mecanismo uniforme para criar, destruir e modificar dados. A API RMS garante a portabilidade para MIDlets (aplicações) em diferentes dispositivos, porque mapeia (abstrai) as capacidades que são dependentes da plataforma do dispositivo e as disponibiliza em um formato padrão, simplificando o desenvolvimento, pois os dispositivos móveis podem ser diferentes internamente, tanto no funcionamento de seus circuitos, quanto na localização física e nas capacidades de armazenamento de dados. O OBJETO DE ARMAZENAMENTO Neste tópico, conheceremos os elementos básicos da API RMS, estudaremos alguns conceitos sobre o armazenamento de registros e entenderemos o funcionamento da classe RecordStore (armazém de registros), que pertence a API RMS e que suporta a criação e a gestão de registros: A classe RecordStore representa o banco de dados da aplicação e possui a capacidade de armazenar registros, que são os dados que pretendemos salvar na área de memória dedicada ao armazenamento persistente de dados da aplicação. Uma área de memória persistente reservada pela classe RecordStore pode conter zero, um ou mais registros; Quando uma MIDlet é removida, sua área de memória persistente também é removida, ou seja, todos os dados gravados (salvos) pelo usuário nessa área de memória persistente criada por meio da classe RecordStore através dessa MIDlet também são excluídos. 32 O nome dado a uma área de memória persistente gerado por uma classe RecordStore é caso-sensitivo, ou seja, é sensível a caracteres minúsculos e maiúsculos e, no máximo, pode ter até 32 caracteres no padrão de codificação Unicode; Uma classe RecordStore pode ser compartilhada para outras MIDlets desde que ele esteja dentro de um mesmo MIDlet suite (arquivo JAR) ou desde que a especificação MIDP permita chama-lo externamente em outra MIDlet suite através de um nome único. Veja a ilustração, duas suítes acessam o mesmo banco de dados: Agora que entendemos um pouco sobre a classe RecordStore,veremos a utilização das operações (métodos) para manipulação de registro. CONCEITOS PARA MANIPULAÇÃO DE REGISTROS Para armazenar um dado, é preciso transformá-lo em um registro e, para isso, é preciso atribuir um código identificador a ele, pois a classe RecordStore utilizará esse código na identificação do registro (“ID de registro”) a fim de manipula-lo. Por exemplo, se quiser salvar um contato com nome e telefone, um código único deverá ser atribuído para esse contato para que ambos os campos (nome e telefone) sejam referenciados por esse código único identificador. Se você estiver familiarizado com conceitos de banco de dados, poderá ver o “ID de registro” como o único tipo de chave primária suportada, pois os recursos para manipulação de registros são extremamente simplificados, o tipo de todo “ID de registro” é sempre do tipo inteiro (int). Também não há qualquer suporte para recursos que estão presentes na maioria dos bancos de dados relacionais, tais como tabelas, linhas, colunas, tipos de dados, e assim por diante. Apesar da simplicidade, as operações suportadas para manipulação de registros são suficientes, pois podemos: adicionar um registro ao banco, remover um registro, alterar um registro, obter um registro salvo anteriormente e listar todos os registros existentes através de enumeração. O registro é um arranjo de bytes (byte[]) e o desenvolvedor da aplicação deve definir como os elementos de dados serão colocados e retirados de dentro dele. TRATAMENTO DE ERROS Para utilizar a classe RecordStore é necessário utilizar as instruções de tratamento de erros da linguagem Java (try / catch), pois erros podem ocorrer durante as operações com os dados, tais como os relacionados na ilustração: Nessa ilustração estão os cinco tipos de erros que a especificação da API RMS oferece. Como você pode notar, os erros são 33 herdados de Exception, ou seja, são herdados também de java.lang.Throwable e podem ser manipulados através das instruções de tratamento de erros da linguagem Java (try / catch). http://estacio.webaula.com.br/Cursos/gon283/docs/15PDM_aula08_doc01.pdf BANCO DE DADOS Para que possamos trabalhar com os registros, primeiramente é preciso abrir o banco de dados que a classe RecordStore necessita acessar. Para isso, usamos: RecordStore.openRecordStore("NomeDoBanco", true); Referente ao último parâmetro do método openRecordStore (String, boolean): Quando true indica que o RecordStore será aberto e, se não existir, será criado; Quando false, indica que o RecordStore será aberto se existir, mas não será criado caso não exista. É importante fechar um banco de dados que não esteja em uso, assim você poupa o dispositivo móvel (que pode ter poucos recursos) e garante o fluxo de fechamento dos dados. Para fechar o banco de dados da RecordStore, usamos: objetoRecordStore.closeRecordStore(); A seguir, temos um trecho de codificação com um exemplo: Você deve considerar implementar os métodos pauseApp()e destroyApp() para que eles fechem os objetos do tipo RecordStore quando a aplicação for colocada em espera ou quando for encerrada. 34 MANIPULAÇÃO DE REGISTROS Agora que já entendemos o básico do funcionamento da classe RecordStore estudaremos como funciona a manipulação de registros. Cada registro pode ser lido, localizado, removido ou modificado, segundo seu “ID de registro” e, nos exemplos a seguir, veremos como é feita a manipulação de registros. Buscaremos o entendimento do funcionamento desses métodos da API RMS que fazem a manipulação de registros. Você perceberá que todos os dados são tratados como arranjo de bytes (byte[]) e perceberá também que, para nos auxiliar no tratamento e nas conversões dos tipos de dados, utilizamos objetos das classes ByteArrayInputStream, DataInputStream, ByteArrayOutputStream e DataOutputStream do pacote java.io.* na manipulação dos registros. ADICIONADO UM REGISTRO Para salvar (incluir) um novo registro, usamos o método: public int addRecord(byte[] data, int offset, int numBytes) No exemplo, temos um fragmento de código-fonte modificado de uma aplicação que salva o “código”, a “descrição” e a “quantidade” de um produto. Analise o trecho e observe como o método addRecord recebe os bytes (arranjo de bytes) para adicionar o registro: Na linha 13, a classe ByteArrayOutputStream constrói um objeto capaz de armazenar os bytes que serão salvos posteriormente como arranjo de bytes pelo método addRecord. Na linha 14, a classe DataOutputStream recebe o objeto capaz de armazenar os bytes e cria um novo objeto capaz de gravar nele, através de métodos write (linhas 15, 16 e 17) - repare como é tratado o conteúdo passado no parâmetro do método adicionarRegistro (“codigo", “descricao” e “quantidade”), neste caso temos o método writeUTF para o tipo String (texto) e writeInt para o tipo int (inteiro). Por fim, na linha 18, a variável “registro” recebe o arranjo de bytes com os dados gravados e os armazena através do método addRecord (linha 19) no banco de dados. ALTERANDO UM REGISTRO Para alterar um registro que já foi salvo anteriormente, usamos o método: public void setRecord(int recordId, byte[] newData, int offset, int numBytes) 35 No exemplo, temos um fragmento de código-fonte modificado de uma aplicação que altera o “código”, a “descrição” e a “quantidade” em um registro de produto já existente. Analise o trecho e observe como o método setRecord recebe os bytes (arranjo de bytes) para modificar um registro existente: Perceba que o código é praticamente o mesmo do exemplo anterior, salvo que temos um parâmetro novo que identifica o registro a ser modificado (int id) e que, na linha 19, ao invés de usarmos addRecord usamos setRecord. A mecânica é praticamente a mesma, ou seja, a classe ByteArrayOutputStream constrói um objeto capaz de armazenar os bytes que serão salvos posteriormente como arranjo de bytes pelo método setRecord por meio do código identificador de registro. A classe DataOutputStream recebe o objeto capaz de armazenar os bytes e cria um novo objeto capaz de gravar nele, através de métodos write. Por fim, a variável “registro” recebe o arranjo de bytes com os dados gravados e os armazena através do método setRecord no banco de dados em conformidade com o “ID de registro” (id) especificado. LENDO UM REGISTRO Para obter um registro salvo, usamos o método: public byte[] getRecord(int recordID) Em função do “ID de registro” informado, esse método retorna um arranjo de bytes (byte[]) que contém os dados salvos no registro. No exemplo, analise o trecho de código-fonte e observe como o método getRecord funciona: 36 Na linha 20, o método getRecord armazenará na variável “registro” como um arranjo de bytes (byte[]) o registro do banco de dados em conformidade com o código identificador de registro (id). Na linha 22, esse arranjo de bytes é armazenado em um objeto do tipo ByteArrayInputStream e, na linha 23, associado para um outro objeto do tipo DataInputStream que separará cada campo desse registro, através dos métodos read - observe as linha 26, 27 e 28, note que temos métodos readUTF e readInt. APAGANDO UM REGISTRO Para remover um registro salvo, usamos o método: public void deleteRecord(int recordID) Em função do “ID de registro” informado, esse método remove os dados salvos no registro, veja o exemplo na ilustração: http://estacio.webaula.com.br/Cursos/gon283/docs/15PDM_aula08_doc02.pdf Utilizando os conhecimentos obtidos nessa aula, desenvolver uma classe capaz de manipular dados persistentes com o uso da API RMS. 37 AULA 09: CONTROLE DA APLICAÇÃO COLETOR DE DADOS DE PRODUTOS Nestepasso, criaremos uma nova aplicação capaz de realizar coleta de dados de produtos. Basicamente, nossa aplicação terá três campos para preenchimento, que serão: Código; Descrição (nome do produto); Quantidade. Também incluiremos uma área na aplicação que nos permitirá listar os produtos cadastrados e editá-los. Conceitualmente a ideia da aplicação é bem simples, todavia você verá que teremos algum trabalho para desenvolver todo o controle de fluxo da aplicação, pois teremos que empregar praticamente tudo o que aprendemos até esta aula e prestar bastante atenção nos novos conceitos que ainda serão abordados. Iniciaremos um novo projeto no IDE NetBeans, conforme demonstra a ilustração: Seguindo os passos, primeiramente pressionamos o botão “Novo Projeto…” (passo 1), depois selecionamos “Java ME” (passo 2), daí selecionamos “Aplicativo móvel” (passo 3) e, por último, pressionamos o botão “Próximo >” (passo 4). Seguindo os passos, nomeamos o projeto como “ColetorMobileApplication” (passo 1), deixamos selecionadas as caixas de seleção “Configurar como projeto principal” e “Criar MIDlet Olá” (passo 2) e pressionamos o botão “Próximo >” (passo 3). Seguindo os passos, nós verificamos as configurações, mantemos selecionadas as opções CLDC 1.1 e MIDP 2.1 e pressionamos o botão “Finalizar” (passo 1). 38 CRIANDO UMA CLASSE PARA PERSISTÊNCIA DE DADOS Antes de criarmos qualquer tela e alterarmos qualquer fluxo existente, primeiramente criaremos uma nova classe capaz de salvar os dados através da API RMS. A fim de facilitar o desenvolvimento futuro, construiremos esta classe para ser a mais genérica possível usando o conceito de abstração: Com o botão direito do mouse (botão auxiliar), escolhemos as opções: “Novo” e “Classe Java…” (passo 1). Depois nomeamos a classe como “Persistencia” (passo 2) para o pacote “br.edu.estacio” (passo 3) e pressionamos o botão “Finalizar” (passo 4). Vejamos o resultado: http://estacio.webaula.com.br/Cursos/gon283/docs/15PDM_aula09_doc01.pdf Parcial 1: código-fonte da classe abstrata de persistência Nas próximas etapas desta aula, teremos modificações e aprimoramentos em nossa codificação, todavia, para fins de conferência, segue todo o código-fonte que escrevemos até o momento. Este código-fonte encontra- se no arquivo chamado Persistencia.java. http://estacio.webaula.com.br/Cursos/gon283/docs/15PDM_aula09_doc02.pdf A classe produto Neste passo, construiremos a classe para armazenamento dos dados dos produtos. Essa classe será útil para construir objetos capazes de transferir valores para outros objetos. Siga os passos da ilustração para criar a classe produto: 39 Seguindo os passos, com o botão auxiliar do mouse, selecionamos o pacote “br.edu.estacio” e no menu popup selecionamos “Novo >”, depois “Classe Java…” (passo 1). Na janela “Nova Classe Java”, nomeamos a classe como “Produto” (passo 2) para o pacote “br.edu.estacio” (passo 3) e pressionamos o botão “Finalizar” (passo 4). A seguinte codificação será gerada automaticamente: A seguir, em conformidade com a ilustração, modifique o código para que ele tenha os atributos do produto com seus respectivos tipos e adicione a documentação, conforme indica a seta: Seguindo os passos, criamos os atributos e seus respectivos tipos para a classe (passo 1). A seguir, geraremos automaticamente, através do IDE NetBeans, os métodos do tipo “get” e “set”. Em conformidade com a ilustração que está a seguir, clique sobre a variável “id” (passo 1), depois clique novamente nela (sobre a variável “id”) com o botão auxiliar do mouse e, no menu popup, posicione o mouse sobre o item “Refatorar” (passo 2) e clique em “Encapsular Campos…” (passo 3): 40 Seguindo os passos, geramos através do IDE NetBeans os métodos do tipo “get” e “set”. O resultado obtido deverá ficar conforme demonstra a ilustração: Agora que temos a classe que armazena os valores do produto, construiremos a classe que manipula esses dados a partir da classe abstrata de persistência (Persistencia.java). Antes de prosseguirmos salve o projeto, pressione o botão “Salvar Todos” Parcial 2: código-fonte da classe produto Nas próximas etapas desta aula, teremos modificações e aprimoramentos em nossa codificação, todavia, para fins de conferência, segue todo o código-fonte que escrevemos até o momento. Este código-fonte encontra-se no arquivo chamado Produto.java. 41 A classe de persistência de produto Neste passo, construiremos a classe para armazenamento persistente dos dados dos produtos. Essa classe será útil para manipular dados para objetos de produto. Siga os passos da ilustração para criar a classe de persistência de produto: Seguindo os passos, com o botão auxiliar do mouse, selecionamos o pacote “br.edu.estacio” e no menu popup selecionamos “Novo >”, depois “Classe Java…” (passo 1). Na janela “Nova Classe Java”, nomeamos a classe como “ProdutoPersistencia” (passo 2) para o pacote “br.edu.estacio” (passo 3) e pressionamos o botão “Finalizar” (passo 4). O seguinte código é gerado automaticamente: package br.edu.estacio; /** * * @author */ public class ProdutoPersistencia{ } 42 Faremos com que a nossa classe herde da classe abstrata de persistência e implemente seus métodos. Siga a ilustração, digite “extends Persistencia” (passo 1), e aguarde uma lâmpadazinha surgir a esquerda. Clique na lâmpada e depois em “Implementar todos os métodos abstratos” (passo 2). O IDE NetBeans modifcará nosso código e adicionará todo conteúdo necessário automaticamente: Como resultado, o IDE NetBeans adicionou todo conteúdo necessário automaticamente: Através dessa codificação, temos os pontos de entrada para os métodos de evento que nos permitirão ler e salvar registros quando os eventos de leitura e/ou gravação ocorrerem na classe pai, ou seja, ao ler ou salvar registros, esses eventos efetivarão a leitura ou o salvamento. Note que, em nossa codificação, a importação dos pacotes também foi realizada automaticamente pelo IDE NetBeans nas linhas 3, 4 e 5. Iniciaremos a programação dos métodos para ler, para salvar e para obter o último produto manipulado. http://estacio.webaula.com.br/Cursos/gon283/docs/15PDM_aula09_doc03.pdf ENTENDENDO O FLUXO O método abrirRecordStore chama internamente o método abrirRecordStore da classe pai (classe Persistencia) informando o nome do banco de dados para abrir ou criar. Para o fluxo de salvamento, é preciso observar e entender que este método salvarProduto além de armazenar o produto recebido na variável de classe produto, também chama internamente o método salvarRegistro que está na classe pai (ou seja, na classe Persistencia). O método salvarRegistro, por sua vez, aciona internamente o evento salvamentoRegistroEvent de nossa classe, transcrevendo o produto recebido na variável de classe produto para o objeto dados, salvando-o através do método addRecord ou setRecord. Para entender o fluxo de leitura, é preciso notar que este método lerProduto chama internamente o método lerRegistro que está na classe pai (ou seja, na classe Persistencia). O método lerRegistro aciona internamente o evento leituraRegistroEvent de nossa classe, criando um novo produto na variável de classe produto e abastecendo-o com o valor da variável id e com os valores existentes no objeto dados. Na ilustração a seguir, as setas apontam importantes referências entre classepai e filha: http://estacio.webaula.com.br/Cursos/gon283/docs/15PDM_aula09_doc04.pdf 43 NAVEGANDO ENTRE PRODUTOS Para navegarmos pelos produtos salvos no banco de dados, é preciso incluir na classe ProdutoPersistencia um método que inicie a navegação e que indique a ordenação dos registros. Para realizar essa tarefa, criaremos uma nova classe que posteriormente utilizaremos nesse método. Siga os passos da ilustração para criar uma nova classe de ordenação de produtos: Seguindo os passos, com o botão auxiliar do mouse, selecionamos o pacote “br.edu.estacio” e no menu popup selecionamos “Novo >”, depois “Classe Java…” (passo 1). Na janela “Novo Classe Java”, nomeamos a classe como “ProdutoComparator” (passo 2) para o pacote “br.edu.estacio” (passo 3) e pressionamos o botão “Finalizar” (passo 4). O seguinte código será gerado automaticamente: /* To change this template, choose Tools|Templates and open in the editor*/ package br.edu.estacio; /** * * @author */ public class ProdutoComparator } Faremos nossa classe implementar os métodos da interface RecordComparator. Siga a ilustração, importe o pacote “javax.microedition.rms. RecordComparator” (passo 1), depois digite “implements RecordComparator” a direita do nome da classe (passo 2), e aguarde uma lâmpadazinha surgir a esquerda. Clique na lâmpada e depois em “Implementar todos os métodos abstratos” (passo 3). O IDE NetBeans modifcará nosso código e adicionará todo conteúdo necessário automaticamente: Após a execução desses passos, o seguinte código foi gerado automaticamente: Quando criarmos o método para iniciar a navegação na classe ProdutoPersistencia, utilizaremos essa classe ProdutoComparator e esse método compare será utilizado internamente pelo enumerador de registros ordenação. Note que os argumentos desse método são do tipo arranjo de byte e recebem dois registros que necessitam ser comparados para que a ordenação aconteça. Faremos a codificação para comparar esses registros no quesito “nome do produto”, portanto Comparator{ métodos abstratos” (passo 3). O IDE NetBeans modifcará nosso código e adicionará todo conteúdo necessário os, o seguinte código foi gerado automaticamente: Quando criarmos o método para iniciar a navegação na classe ProdutoPersistencia, utilizaremos essa classe ProdutoComparator e esse método compare será utilizado internamente pelo enumerador de registros ordenação. Note que os argumentos desse método são do tipo arranjo de byte e recebem dois registros que necessitam ser comparados para que a ordenação aconteça. Faremos a codificação para comparar esses registros no quesito “nome do produto”, portanto, siga os passos da ilustração: 44 métodos abstratos” (passo 3). O IDE NetBeans modifcará nosso código e adicionará todo conteúdo necessário Quando criarmos o método para iniciar a navegação na classe ProdutoPersistencia, utilizaremos essa classe ProdutoComparator e esse método compare será utilizado internamente pelo enumerador de registros para ordenação. Note que os argumentos desse método são do tipo arranjo de byte e recebem dois registros que necessitam ser comparados para que a ordenação aconteça. Faremos a codificação para comparar esses Seguindo os passos, importamos os pacotes para manipulação dos dados nos arranjos de byte dos registros recebidos (passo 1) e codificamos uma lógica capaz de determinar se o nome de um produto é alfabeticamente maior ou menor quando comparado a outro produto. Dica: Como cada registro recebido será o registro de um produto observe que extrairmos os dados de seus campos na mesma ordem em que eles foram armazenados, ou seja, se compararemos a ordem dos registros pelo “nome do produto”, então será preciso primeiro extrair o campo de “código do produto” para depois extrair o campo “nome do produto”. Agora que temos a classe ProdutoComparator concluída, incluiremos o método que inicia a navegação e que indica a ordenação dos registros na classe ProdutoPersistencia. Siga os passos da ilustração, inclua o método iniciarNavagacaoProduto na classe ProdutoPersistencia e faça sua documentação: Seguindo os passos, abrimos nossa classe ProdutoPersistencia (passo 1) e incluímos o mé iniciarNavagacaoProduto em nosso código (passo 2). Portanto, concluímos a codificação que cuida do armazenamento e da recuperação dos dados dos produtos. No próximo passo, integraremos nossa interface visual com essas funcionalidades, todavia antes prosseguirmos, salve o projeto, pressione o botão “Salvar Todos”. http://estacio.webaula.com.br/Cursos/gon283/docs/15PDM_aula09_doc05.pdf CONSTRUINDO O FLUXO DA INTERFACE VISUAL A partir de agora, começaremos a unir a interface visual com a programaç Primeiro, selecione a classe da MIDlet (passo 1), depois pressione o botão fluxo (passo 2), depois selecione o formulário “form” (passo 3) e altere o “Título” para “Cadastro de Produtos”. Veja os passos na ilustração: Seguindo os passos, importamos os pacotes para manipulação dos dados nos arranjos de byte dos registros recebidos (passo 1) e codificamos uma lógica capaz de determinar se o nome de um produto é nor quando comparado a outro produto. Como cada registro recebido será o registro de um produto observe que extrairmos os dados de seus campos na mesma ordem em que eles foram armazenados, ou seja, se compararemos a ordem dos registros produto”, então será preciso primeiro extrair o campo de “código do produto” para depois extrair o campo “nome do produto”. Agora que temos a classe ProdutoComparator concluída, incluiremos o método que inicia a navegação e que registros na classe ProdutoPersistencia. Siga os passos da ilustração, inclua o método iniciarNavagacaoProduto na classe ProdutoPersistencia e faça Seguindo os passos, abrimos nossa classe ProdutoPersistencia (passo 1) e incluímos o mé iniciarNavagacaoProduto em nosso código (passo 2). Portanto, concluímos a codificação que cuida do armazenamento e da recuperação dos dados dos produtos. No próximo passo, integraremos nossa interface visual com essas funcionalidades, todavia antes prosseguirmos, salve o projeto, pressione o botão “Salvar Todos”. http://estacio.webaula.com.br/Cursos/gon283/docs/15PDM_aula09_doc05.pdf CONSTRUINDO O FLUXO DA INTERFACE VISUAL A partir de agora, começaremos a unir a interface visual com a programação que fizemos anteriormente. Primeiro, selecione a classe da MIDlet (passo 1), depois pressione o botão fluxo (passo 2), depois selecione o formulário “form” (passo 3) e altere o “Título” para “Cadastro de Produtos”. Veja os passos na ilustração: 45 Seguindo os passos, importamos os pacotes para manipulação dos dados nos arranjos de byte dos registros recebidos (passo 1) e codificamos uma lógica capaz de determinar se o nome de um produto é Como cada registro recebido será o registro de um produto observe que extrairmos os dados de seus campos na mesma ordem em que eles foram armazenados, ou seja, se compararemos a ordem dos registros produto”, então será preciso primeiro extrair o campo de “código do produto” para depois Agora que temos a classe ProdutoComparator concluída, incluiremos o método que inicia a navegação e que Siga os passos da ilustração, inclua o método iniciarNavagacaoProduto na classe ProdutoPersistencia e faça Seguindo os passos, abrimos nossa classe ProdutoPersistencia (passo 1) e incluímos o método iniciarNavagacaoProduto em nosso código (passo 2). Portanto, concluímos a codificação que cuida do No próximo passo, integraremos nossa interface visual com essas funcionalidades, todavia antes de ão que fizemos anteriormente. Primeiro, selecione a classe da MIDlet (passo 1), depois pressione o botão fluxo (passo 2), depois selecione o formulário “form” (passo 3)e altere o “Título” para “Cadastro de Produtos”. Veja os passos na ilustração: 46 Agora, renomearemos o “form” para “produtosForm”. Siga os passos da ilustração: Daremos funcionalidades ao nosso formulário, incluiremos um menu para salvar o produto e outro menu para listar os produtos salvos. Siga os passos da ilustração: Seguindo os passos, selecionamos o grupo “Comandos” e arrastamos o menu tela (Comando Tela) para cima do formulário “produtoForm” por duas vezes (passo 2). Siga o exemplo da ilustração e renomeie os menus apontados com nomes correspondentes a suas funcionalidades. Os nomes serão “sairCommand”, “salvarCommand” e “listarCommand”: 47 Ao concluir, os nomes serão “sairCommand”, “salvarCommand” e “listarCommand”. Altere também o rótulo de cada um dos menus para que exibam os nomes “Sair”, “Salvar” e “Listar”: Adicionaremos uma tela de listagem para exibir todos os produtos cadastrados. Siga os passos da ilustração, inclua o objeto e altere seu título para “Listagem de Produtos”: Utilizando os conhecimentos que você já possui, renomeie o objeto “list” para “produtoList” e arraste o menu “listarCommand” sobre ele. O resultado deverá ficar conforme a ilustração: Dica:Para renomear, clique com o botão auxiliar do mouse no objeto, daí use “Renomear”. 48 Criaremos dois menus, sendo um para editar um produto na listagem e o outro para voltar à tela anterior. Selecione o grupo “Comandos” (passo 1) e siga o segundo passo da ilustração: Seguindo a ilustração, acrescentamos o menu voltar e o menu tela. Renomeie esses menus para que eles tenham seus nomes e seus rótulos em conformidade com sua funcionalidade, ou seja, renomeie o menu “backCommand” para “voltarCommand” e o menu “screenCommand” para “editarCommand” e altere seus rótulos para “Voltar” e “Editar” respectivamente. Para criar um fluxo de retorno, arraste o menu “voltarCommand” sobre o “produtoForm” para definir que voltaremos a essa tela quando esse menu “voltar” for acionado. Seu fluxo deverá ser semelhante ao da ilustração a seguir, observe as setas: 49 Na próxima ilustração, incluiremos nosso último objeto no fluxo. Baseado em seu conhecimento, selecione o grupo “Exibições” (passo 1), depois arraste o objeto “Alerta” para dentro de nosso fluxo (passo 2), daí o renomeie de “alert” para “produtoAlert” (passo 3) e defina seu título como “Informação”. Por último, para que esse “Alerta” possa nos informar do resultado do salvamento quando o menu “Salvar” for pressionado, arraste o menu “salvarCommand” sobre “produtoAlert” (passo 5). Dica: Para renomear, clique com o botão auxiliar do mouse no objeto, daí use “Renomear”. Agora que temos todo o fluxo preparado, o próximo passo é o de desenharmos a tela que realiza o cadastro ou a edição do produto, ou seja, prepararemos o objeto “produtoForm”.Antes de prosseguirmos, salve o projeto, pressione o botão “Salvar Todos”. DESENHANDO E PREPARANDO O FORMULÁRIO Com a MIDlet aberta (passo 1), prepararemos o objeto “produtoForm”, portanto, pressione o botão “Tela” (passo 2) e selecione “produtoForm” (passo 3). Visualize os passos na ilustração: Siga os passos da próxima ilustração para remover o “item de String” que foi criado automaticamente pelo assistente do IDE NetBeans: 50 Agora, siga os passos da próxima ilustração para incluir três “caixas de texto” em nosso formulário de cadastro e edição de produtos: Seguindo a ilustração, selecionamos o grupo “Itens” (passo 1) e arrastamos o item “caixa de texto” (passo 2) em nosso formulário por três vezes, gerando os campos “textField”, “textField1” e “textField2”. Baseado em seus conhecimentos, renomeie os campos “textField”, “textField1” e “textField2” para, respectivamente, “codigoTextField”, “nomeTextField” e “quantidadeTextField”. Altere também os rótulos de cada campo para “Código”, “Descrição” e “Quantidade”. Quanto terminar, seu formulário deverá estar semelhante ao da próxima ilustração: Dica: Para renomear, clique com o botão auxiliar do mouse no objeto, daí use “Renomear”. 51 Na próxima ilustração, alteraremos o campo “Quantidade” de produtos para que comporte somente números com no máximo quatro dígitos. Selecione o campo “Quantidade” e siga as indicações de valores da ilustração: Seguindo os passos, selecionamos e configuramos as propriedades do campo “Quantidade”, definindo a propriedade “Restrições de entrada” como “NUMERIC” e a propriedade “Tamanho máximo” como “4”. Se quiser testar a aplicação, você pode executar o programa para visualizar os menus e testar o fluxo que construímos até aqui. Você poderá ver que o campo “Quantidade” aceita somente números e que os menus “Listar”, “Salvar” e “Voltar” possuem os comportamentos que definimos no fluxo. Iremos agora para a última etapa, ou seja, a codificação da interface visual. Antes de prosseguirmos, salve o projeto, pressione o botão “Salvar Todos”. ALTERANDO A CODIFICAÇÃO DA INTERFACE VISUAL Para darmos continuidade a integração, selecione o menu “salvarCommand”, depois clique nele com o botão auxiliar do mouse e, no menu popup, clique em “Ir para o código-fonte” (passo 1). 52 Ao realizar essa ação, você será posicionado dentro do método commandAction e poderá realizar a codificação do menu no local apontado pela seta vermelha: Dica: A estrutura de construção dessa codificação poderá variar de acordo com a ordem de suas ações, todavia, você deve observar que dentro do método commandAction, seu cursor estará dentro de um “if” que verifica se displayable é igual a produtoForm e dentro de um outro “if” (aninhado ao primeiro) que verifica se command é igual a salvarCommand. Antes de codificarmos no ponto indicado pela seta vermelha, precisamos incluir algumas variáveis para utilizarmos o produto e a persistência de produto. Siga os passos da ilustração, codifique e documente: Dica: Ao codificar o passo 2, um aviso de erro será informado no construtor. Você deve seguir adiante, ou seja, deve ignorar o aviso de erro e realizar a codificação do passo 3. Esse aviso de erro acontece devido ao uso da instrução “final”, que exige a inicialização da variável dentro do construtor (passo 3). Para que possamos salvar produtos de modo persistente, procure pelo método commandAction no navegador e faça a codificação no menu “Salvar”, ou seja, dentro do “if” que verifica se command é igual a salvarCommand. Faça a codificação da ilustração: 53 Conforme você pode acompanhar pela ilustração, na linha 1, tentamos abrir o banco de dados. Havendo um retorno positivo (true), na linha 2, 3 e 4 pegamos os textos digitados das caixas de texto e, na linha 5, verificamos se há algum texto nelas. Se não houver texto, no objeto de alerta será colocado um texto pedindo para que o usuário preencha os campos antes de salvar, do contrário, na linha 6, verificamos se a variável produto possui um valor nulo e, se um valor nulo for encontrado na variável produto, então colocamos um novo objeto nela. Da linha 9 a linha 15, abastecemos a variável produto com os valores que foram digitados nas caixas de texto - note que o código e o nome do produto são interpretados como texto, todavia a quantidade de produto é interpretada como número inteiro. Na linha 16, salvamos o produto em banco de dados através da variável de objeto produtoPersistencia. Na linha 17, definimos a variável produto como nula para permitir a entrada de outro novo produto. Nalinha 18, fechamos o banco de dados. Nas linhas 19, 20 e 21 limpamos (esvaziamos) as caixas de texto e, na linha 22 colocamos no objeto de alerta um texto indicando sucesso ou erro, de acordo com o resultado da variável salvo. Pronto, neste passo já temos a parte que salva os registros, faremos a parte que lista os registros existentes. Antes de prosseguirmos, salve o projeto, pressione o botão “Salvar Todos”. Precisamos incluir mais uma variável de classe para armazenar o que será carregado na listagem de produtos. Para acumular objetos de produto, utilizaremos uma variável de objeto do tipo vetor, siga os passos da ilustração: Dica: Ao codificar o passo 2, um aviso de erro será informado no construtor. Você deve seguir adiante, ou seja, deve ignorar o aviso de erro e realizar a codificação do passo 3. Esse aviso de erro acontece devido ao uso da instrução “final”, que exige a inicialização da variável dentro do construtor (passo 3). 54 Novamente, devemos ir ao ponto inicial para criar uma lógica capaz de listar os produtos salvos no banco de dados. Procure pelo método commandAction no navegador do IDE NetBeans e faça a codificação dentro do “if” que verifica se command é igual a listarCommand. Faça a codificação conforme está indicado na ilustração: Conforme você pode acompanhar pela ilustração, na linha 1, tentamos abrir o banco de dados. Na linha 2, havendo um retorno positivo (true) do método, acionamos o objeto produtoPersistencia para iniciar a navegação entre produtos. Nas linhas 3 e 4, limpamos (esvaziamos) todo o conteúdo do vetor e da listagem de produtos. Nas linhas 5, 6, 7 e 8 navegamos e adicionamos registros no vetor e na listagem de produtos - usamos os métodos “irParaProximoNavegavel” e “getProduto” para executar essas ações. Na linha 9, fechamos o banco de dados. Pronto, já temos a parte que lista os registros, faremos a parte que edita os registros existentes. Antes de prosseguirmos, salve o projeto, pressione o botão “Salvar Todos”. Programaremos dentro do menu “Editar” da lista de produtos. Procure pelo método commandAction no navegador do IDE NetBeans e faça a codificação dentro do “if” que verifica se command é igual a editarCommand. Faça a codificação conforme está indicado na ilustração: Conforme você pode acompanhar pela ilustração, na linha 1, verificamos se há algum item selecionado na lista de produtos e, se houver, na linha 2, recuperamos da variável de vetor o produto selecionado em conformidade com o índice do item selecionado na lista de produtos. Da linha 3 a 7 criamos um novo objeto de produto e o abastecemos com os dados do produto selecionado. Nas linhas 8, 9 e 10 preenchemos as caixas de texto com os dados do produto, ou seja, com seu código, descrição e quantidade. Na linha 11, voltamos a exibir o formulário de cadastro de produtos. Para esta atividade, como nosso último passo, usando seus conhecimentos, renomeie a MIDlet HelloMIDlet para ColetorMIDlet e o pacote hello para coletor. Pronto, concluímos nossa missão e você já pode testar sua aplicação. Salve o projeto, pressione o botão “Salvar Todos”. Para praticar, faça algumas melhorias, por exemplo, inclua a opção de exclusão de produtos, pesquisa e adicione um menu para limpar os campos. http://estacio.webaula.com.br/Curso Através dos conhecimentos obtidos nessa aula pontuação do jogo da velha de forma persistente utilizando a API RMS e monte um ranking com as 10 (dez) melhores pontuações. A solução é constituída pela utilização da classe RecordStore e da interface RecordEnumeration, podendo conter os seguintes métodos: - openRecordStore da classe RecordStore; - enumerateRecords da classe RecordStore; - hasNextElement da interface RecordEnumeration; - nextRecordId da interface RecordEnumeration; - getRecord da classe RecordStore; - closeRecordStore da classe RecordStore; Saiba mais : Pesquise na internet sites, vídeos e artigos relacionados ao conteúdo visto. Se ainda tiver alguma dúvida, fale com seu professor online utilizando os recursos disponíveis no ambiente de aprendizagem. http://estacio.bvirtual.com.br/editions/1458 biblioteca virtual da Estácio. Aula 10: COMUNICAÇÃO REMOTA O FRAMEWORK GENÉRICO DE CONEXÃO Apesar das bibliotecas da plataforma Java Standard Edition para conectividade a rede possuírem recursos eficientes, devido as características limitadas de hardware, um dispositivo móvel poderia não suportar a quantidade de classes e interfaces presentes nos pacotes java.net e java.io e, por este motivo, esses pacotes foram simplificados e um framework genérico de conexão, também conhecido por GCF, foi desenvolvido para tratar assuntos de i/o e conectividade. O GCF não tinha por objeto ser um novo conjunto de classes, mas sim proporcionar um subconjunto do JSE que estivesse em sintonia com as limitações e as variações que possam ser encontradas em dispositivos de Conforme você pode acompanhar pela ilustração, na linha 1, verificamos se há algum tem selecionado na lista de produtos e, se houver, na linha 2, recuperamos da variável de vetor o produto selecionado em conformidade com o índice do item selecionado na lista de produtos. Da linha 3 a 7 criamos um novo objeto de produto e m os dados do produto selecionado. Nas linhas 8, 9 e 10 preenchemos as caixas de texto com os dados do produto, ou seja, com seu código, descrição e quantidade. Na linha 11, voltamos a exibir o formulário de cadastro de nosso último passo, usando seus conhecimentos, renomeie a MIDlet HelloMIDlet para ColetorMIDlet e o pacote hello para coletor. Pronto, concluímos nossa missão e você já pode testar sua aplicação. Salve o projeto, raticar, faça algumas melhorias, por exemplo, inclua a opção de exclusão de produtos, pesquisa e adicione um menu para limpar os campos. http://estacio.webaula.com.br/Cursos/gon283/docs/15PDM_aula09_doc06.pdf Através dos conhecimentos obtidos nessa aula e na aula passada, armazene a pontuação do jogo da velha de forma persistente utilizando a API RMS e monte um ranking com as 10 (dez) melhores pontuações. A solução é constituída pela utilização da classe RecordStore e da interface podendo conter os seguintes métodos: openRecordStore da classe RecordStore; enumerateRecords da classe RecordStore; hasNextElement da interface RecordEnumeration; nextRecordId da interface RecordEnumeration; loseRecordStore da classe RecordStore; esquise na internet sites, vídeos e artigos relacionados ao conteúdo visto. Se ainda tiver alguma dúvida, fale com seu professor online utilizando os recursos disponíveis no ambiente de http://estacio.bvirtual.com.br/editions/1458-core-j2me-tecnologia-midp.dp – Livro eletrônico Core J2ME da AÇÃO REMOTA O FRAMEWORK GENÉRICO DE CONEXÃO Apesar das bibliotecas da plataforma Java Standard Edition para conectividade a rede possuírem recursos eficientes, devido as características limitadas de hardware, um dispositivo móvel poderia não suportar a ntidade de classes e interfaces presentes nos pacotes java.net e java.io e, por este motivo, esses pacotes foram simplificados e um framework genérico de conexão, também conhecido por GCF, foi desenvolvido para tratar assuntos de i/o e conectividade. não tinha por objeto ser um novo conjunto de classes, mas sim proporcionar um subconjunto do JSE que estivesse em sintonia com as limitações e as variações que possam ser encontradas em dispositivos de 55 esquise na internet sites, vídeos e artigos relacionados ao conteúdo visto. Se ainda tiver alguma dúvida, fale com seu professor online utilizando os recursos disponíveis no ambiente de Livro eletrônico Core J2ME da Apesar das bibliotecas da plataforma Java Standard Edition para conectividade a rede possuírem recursos eficientes, devido as características
Compartilhar