fundaÇÃo universidade regional de blumenau · apostila de oo e furbot ... alguns objetos do tipo...

120
FUNDAÇÃO UNIVERSIDADE REGIONAL DE BLUMENAU CENTRO DE CIÊNCIAS EXATAS E NATURAIS DEPARTAMENTO DE SISTEMAS E COMPUTAÇÃO Apostila de OO e FURBOT – versão 1.12 11/9/2008 Material de Apoio as Disciplinas: Programação de Computadores (SIS) Programação Orientada a Objetos (SIS) Programação Orientada a Objetos I (BCC) PROFESSORES: Mauro Marcelo Mattos Adilson Vahldick Marcel Hugo Maurício Capobianco Lopes

Upload: vukien

Post on 07-Nov-2018

213 views

Category:

Documents


0 download

TRANSCRIPT

FUNDAÇÃO UNIVERSIDADE REGIONAL DE

BLUMENAU

CENTRO DE CIÊNCIAS EXATAS E NATURAIS

DEPARTAMENTO DE SISTEMAS E COMPUTAÇÃO

Apostila de OO e FURBOT – versão 1.12 11/9/2008

Material de Apoio as Disciplinas:

Programação de Computadores (SIS)

Programação Orientada a Objetos (SIS)

Programação Orientada a Objetos I (BCC)

PROFESSORES:

Mauro Marcelo Mattos

Adilson Vahldick

Marcel Hugo

Maurício Capobianco Lopes

2

Figura 1- Ambiente do FURBOT. ................................................................................................................................... 5

Figura 2 - Exemplo de mundo especificado através de um arquivo xml. ........................................................................ 5

Figura 3 - Mundo criado a partir da especificação em xml. ............................................................................................ 6

Figura 4 - Ambiente netbeans com o exercicio carregado. ............................................................................................ 6

Figura 5 - componentes de um algoritmo. .................................................................................................................. 43

Figura 6 - Relação entre a classe principal e a classe do modelo .................................................................................. 46

Figura 7 - Ativação de outras classes a partir do main. ................................................................................................ 49

Figura 8 - Componentes do pacote javax.swing .......................................................................................................... 62

Figura 9 - primeira janela. .......................................................................................................................................... 65

Figura 10- Janela com rótulos ..................................................................................................................................... 67

Figura 11- Janela redecorada. .................................................................................................................................... 67

Figura 12- Rótulo com imagem................................................................................................................................... 69

Figura 13- Janela com 2 botões .................................................................................................................................. 71

Figura 14- ativação da dica do botão .......................................................................................................................... 71

Figura 15 - Hierarquia dos principais listeners............................................................................................................. 74

Figura 16- Método actionPerformed sendo ativado. ................................................................................................... 75

Figura 17- Calculadora ............................................................................................................................................... 77

Figura 18 - Criando um projeto. .................................................................................................................................. 78

Figura 19 - Janela "novo projeto". .............................................................................................................................. 78

Figura 20 - detalhes do projeto. ................................................................................................................................. 79

Figura 21 – Selecionando criar um novo pacote. ........................................................................................................ 79

Figura 22 - criando um novo pacote. .......................................................................................................................... 79

Figura 23 - Criando um formulário jframe. .................................................................................................................. 80

Figura 24 - finalizando a criação de um formulário jframe........................................................................................... 80

Figura 25 - Jframe criado. ........................................................................................................................................... 81

Figura 26 - definindo gerenciador de layout: borderlayout. ........................................................................................ 81

Figura 27 - Paleta de componentes. ........................................................................................................................... 82

Figura 28 - Paleta de configuração de um jpanel. ........................................................................................................ 82

Figura 29 - Inserindo três componentes jpanel ao jframe. .......................................................................................... 83

Figura 30 - Programando um tratador de evento. ....................................................................................................... 83

Figura 31 - Método construtor da classe..................................................................................................................... 84

Figura 32 - Projeto completo. ..................................................................................................................................... 84

Figura 33 - Modelo de mundo do jogo PacMan. ....................................................................................................... 100

Figura 34- Tela para a escolha da versão do JDK. ...................................................................................................... 111

Figura 35- Download Center. .................................................................................................................................... 111

Figura 36- Acordo de Licenciamento do Software. .................................................................................................... 112

Figura 37- Selecionar a plataforma e o instalador do JDK. ......................................................................................... 112

Figura 38- Abrir o arquivo para iniciar o download. .................................................................................................. 113

Figura 39- Execução do Gerenciador de Download. .................................................................................................. 113

3

Figura 40- Termos de Licença do Software. .............................................................................................................. 114

Figura 41- Opções para o download. ........................................................................................................................ 114

Figura 42- Andamento do download. ....................................................................................................................... 115

Figura 43- Site do NetBeans > download. ................................................................................................................. 115

Figura 44-Licença de Uso do Software. ..................................................................................................................... 116

Figura 45- Configuração da Instalação. ..................................................................................................................... 116

Figura 46- Configuração da Instalação. ..................................................................................................................... 117

Figura 47- Instalação Completa. ............................................................................................................................... 117

4

1. INTRODUÇÃO sse é um documento de apoio das disciplinas de programação dos cursos de Bacharelado em Ciências da Computação, de Sistemas de Informação e de Licenciatura em Computação da FURB.

O documento foi produzido a partir de uma compilação de várias fontes, particularmente a partir de:

� documentação produzida nas sucessivas versões do FURBOT produzidas pelo Prof. Adilson Vahldick;

� apostila desenvolvida pelo Prof. Maurício Capobianco Lopes (fundamentação de OO e algoritmos);

� da apostila desenvolvida pelo Prof. Marcel Hugo (interfaces gráficas com o usuário) e

� pelas contribuições dos monitores Fernanda Gums (tutorial de instalação do Netbeans, Eclipse e JDK) e Eduardo Coelho (geração de gabaritos de exercícios propostos).

O FURBOT é um ambiente de apoio ao ensino de lógica de programação. Foi concebido

em 2008-1 pela equipe de professores: Adilson Vahldick, Mauro Marcelo Mattos e Carlos

Henrique Correia com o propósito de disponibilizar a você um ambiente com forte apelo

na área de jogos e que possibilitasse o desenvolvimento de algoritmos de controle de

personagens de tal forma a criar uma atmosfera facilitadora ao aprendizado.

Durante o primeiro semestre de 2008 foram disponibilizadas várias versões as quais

incorporaram os recursos necessários para a solução de problemas propostos ao longo

do semestre.

Incrementos na última versão do Furbot produziram a versão 1.0 liberada no início do

segundo semestre de 2008 e que deverá ser a versão de partida para as atividades deste

semestre.

A Figura 1 apresenta um exemplo de ambiente do Furbot onde coabitam: um objeto do

tipo Robô, alguns objetos do tipo Alien, alguns objetos do tipo Numero e alguns objetos do

tipo Logico (boolean). Existem 3 botões para disparar a execução de um programa,

reinicializar um programa e parar a execução de um programa. Além disso, há um espaço

de comunicação do Furbot com o usuário na base da janela.

E

FIGURA 1- AMBIENTE DO FURBOT.

Conforme será apresentado mais adiante, a configuração de ambiente do FURBOT é

baseada em um arquivo do tipo XML (Extended Markup Language). A Figura 2 apresenta

uma especificação de mundo que contém 8 linhas por 8 colunas e estabelece que o robô

inicia na posição (0,0). Para fins de referência, as coordenadas de mundo iniciam no

canto superior esquerdo. Assim, andar para a direita significa incrementar o valor de x e

andar para baixo significa incrementar o valor de y. Além disso, o robô explode ao atingir

uma das paredes do mundo.

<furbot> <enunciado> Exercicio 1. &lt;br&gt; Faca o robo andar ate a ultima posicao da linha. &lt;br&gt; Lembre-se de que as coordenadas sempre serao fornecidas como (x,y).&lt;br&gt; A primeira coluna e linhas sao a de numero ZERO. </enunciado> <mundo> <qtdadeLin>8</qtdadeLin> <qtdadeCol>8</qtdadeCol> <explodir>true</explodir> </mundo> <robo> <x>0</x> <y>0</y> </robo> </furbot>

FIGURA 2 - EXEMPLO DE MUNDO ESPECIFICADO ATRAVÉS DE UM ARQUIVO XML.

A Figura 3 apresenta a imagem de mundo criada a partir da especificação em XML

apresentada na Figura 2.

FIGURA 3 - MUNDO CRIADO A PARTIR DA ESPECIFICAÇÃO EM XML.

Uma aplicação Furbot possui 1 requisito importante: o nome do arquivo .xml deve ser o

mesmo nome do arquivo .java. No exemplo, o arquivo de especificação do modelo de

mundo denomina-se Exercicio1.xml e o arquivo que especifica a lógica de funcionamento

do robô denomina-se Exercicio1.java. A Figura 4 apresenta o exercício já carregado no

ambiente Netbeans.

FIGURA 4 - AMBIENTE NETBEANS COM O EXERCICIO CARREGADO.

7

2. ALTERANDO O COMPORTAMENTO DO ROBÔ – UMA

PEQUENA INTRODUÇÃO. A classe que contém a inteligência do robô deve atender aos seguintes requisitos:

1. Deve ser herdar as características de Furbot acrescentando-se a declaração da classe as palavras extends Furbot (conforme o quadro abaixo):

public class Exercicio1 extends Furbot { …. }

Observação : na medida em que você for avançando na disciplina, o conceito de herança

será elucidado. Por enquanto vale destacar que já foi especificado um comportamento

padrão para o robô que é ficar parado. De fato o que vamos realizar é uma alteração

neste comportamento para fazer o robô passear pelo mundo.

2. Deve implementar dois métodos: inteligencia() e main() conforme o quadro

abaixo:

public class Exercicio1 extends Furbot { public void inteligencia() throws Exception { …. } public static void main (String[] args) { MundoVisual.iniciar(“Exercicio1.xml”); } }

3. Dentro do método main, deve haver somente a declaração que inicializa o mundo segundo a especificação contida no arquivo xml que é informado entre aspas conforme exemplo no quadro abaixo:

MundoVisual.iniciar(“Exercicio1.xml”);

Atendidos estes requisitos, o ambiente está pronto para ser utilizado. Neste primeiro

momento, você poderá modificar o comportamento do furbot alterando o método

inteligencia() conforme exemplificado na Figura 3. Para tanto lançamos mão de uma das

primitivas de movimentação do Furbot: andarDireita().

Considerando que o mundo é modelado como uma grade de 8 x 8 células e que o robô

nasce na posição 0,0 (canto superior esquerdo) , para que ele atenda a especificação,

que é andar até a parede direita, basta que construamos a seguinte seqüência de

comandos:

8

public class Exercicio1 extends Furbot { public void inteligencia() throws Exception { andarDireita(); andarDireita(); andarDireita(); andarDireita(); andarDireita(); andarDireita(); andarDireita(); andarDireita(); diga(“Cheguei!”); } public static void main (String[] args) { MundoVisual.iniciar(“Exercicio1.xml”); } }

Ao executarmos esta seqüência de comandos, o furbot deslocar-se-á desde a posição

inicial até a última coluna da primeira linha.

Como você pode ver, programar o furbot consiste em desenvolver uma seqüência finita

de comandos válidos que fazem com que o furbot execute uma determinada tarefa. Em

linhas gerais, esta é a definição de um algoritmo e é o que iremos desenvolver ao longo

deste semestre.

9

3. FURBOT: COMANDOS Nesta seção são descritos os comandos que afetam o comportamento do furbot.

3.1. COMANDOS DE CONTROLE DE MOVIMENTAÇÃO Conforme apresentado na introdução, o furbot possui alguns comandos básicos que

permitem a você controlar a movimentação do mesmo no mundo.

São eles:

� andarDireita():void : Faz com que o robô ande uma célula à direita. Se houver um obstáculo ou for o fim do mundo, o robô explode

� andarEsquerda():void : Faz com que o robô ande uma célula à esquerda. Se houver um obstáculo ou for o fim do mundo, o robô explode.

� andarAcima():void : Faz com que o robô ande uma célula para cima. Se houver um obstáculo ou for o fim do mundo, o robô explode.

� andarAbaixo():void : Faz com que o robô ande uma célula para baixo. Se houver um obstáculo ou for o fim do mundo, o robô explode.

Um exemplo de uso destes comandos é apresentado no quadro abaixo:

public class Exercicio1 extends Furbot { public void inteligencia() throws Exception { andarDireita(); andarDireita(); andarAbaixo(); andarEsquerda(); andarAcima(); } public static void main (String[] args) { MundoVisual.iniciar(“Exercicio1.xml”); } }

3.2. COMANDOS DE COMUNICAÇÃO Para que seja possível fazer com que o furbot comunique-se com você, foi disponibilizado

o comando diga. Este comando faz com que o fubot possa enviar mensagens para a área

de comunicação da tela. Este recurso é muito útil para que você possa avaliar e

acompanhar o comportamento do furbot durante a execução de alguma tarefa.

Existem duas formas do comando. São elas:

10

� diga (String):void : Faz com que a mensagem enviada como parâmetro seja apresentada na tela. Toda mensagem deve ser escrita entre os parêntesis e grafada entre aspas duplas

� diga (Object):void : Permite que seja passado como parâmetro um objeto que contém a mensagem a ser apresentada na tela. Este recurso é avançado e você só vai utilizá-lo mais adiante.

� limparConsole():void : Limpa a área de mensagens do mundo. Geralmente utilizamos para facilitar a visualização de mensagens importantes.

Um exemplo de uso destes comandos é apresentado no quadro abaixo:

public class Exercicio1 extends Furbot { public void inteligencia() throws Exception { diga (“este é um exemplo de mensagem”); String msg = “Este é um objeto que contém a msg a ser apresentada na tela”; diga (msg); limparConsole(); } public static void main (String[] args) { MundoVisual.iniciar(“Exercicio1.xml”); } }

Como resultado da execução do código acima será apresentado na área de comunicação

o seguinte:

Este é um exemplo de mensagem Este é um objeto que contém a msg a ser apresentada na tela

3.3. COMANDOS DE AVALIAÇÃO DA SITUAÇÃO DO

MUNDO O furbot pode movimentar-se no mundo. Contudo, ao executar um movimento, ele pode

chocar-se com obstáculos que podem ser os limites do mundo ou outros objetos que

ocupam alguma célula no mudo.

Para evitar que o choque ocorra, foram disponibilizados os seguitnes comandos:

� ehVazio(Direcao):boolean : permite que o furbot verifique se a célula indicada por “Direção” é vazia (neste caso o furbot retorna um valor verdadeiro – true) ou se está ocupada (neste caso o furbot retorna um valor falso – false), mas não indica quem está ocupando aquela posição. Observe que se a célula na direção apontada fica além dos limites do mundo, esse método retorna verdadeiro!.

� ehFim(Direcao):boolean : o robô verifica se a célula na direção passada como parâmetro fica além do mundo. Se ela for além do mundo retorna verdadeiro (true) senão retorna falso (false).

Um exemplo de uso destes comandos é apresentado no quadro abaixo:

11

public class Exercicio1 extends Furbot { public void inteligencia() throws Exception { if (eVazio(DIREITA) ) diga (“A célula a direita está vazia!”) else diga (“A célula a direita está ocupada!”); if (eFim(DIREITA) ) diga (“Encontramos o fim do mundo a direita!”) else diga (“Podemos andar para a direita!”); } public static void main (String[] args) { MundoVisual.iniciar(“Exercicio1.xml”); } }

As seguintes constantes foram disponibilizadas para estabelecimento da orientação de

direção:

� ESQUERDA

� DIREITA

� ACIMA

� ABAIXO

� AQUIMESMO

Observe que as mesmas são grafadas com todas as letras em maiúsculo.

3.4. COMANDOS PARA OBTENÇÃO DE COORDENADAS Como já foi dito, o mundo do furbot é baseado em um agregado de células. Cada célula

possui um par de coordenadas (x,y).

Para que seja possível obter as coordenadas da posição atual do furbot utilizam-se os

seguintes comandos:

� getX():int : Retorna um valor inteiro contendo o número da coluna em que está o robô. Lembre-se de que a primeira coluna é ZERO.

� getY():int: Retorna um valor inteiro contendo o número da linha em que está o robô. Lembre-se de que a primeira linha é ZERO.

3.5. COMANDOS DE MANIPULAÇÃO DE OBJETOS Todos os personagens que habitam um determinado mundo no furbot são considerados

objetos.

12

Para tornar possível a interação entre estes objetos e viabilizar ações de detecção de

colisões entre objetos, remoção de objetos, movimentação de objetos entre outros, os

seguintes comandos são disponibilizados:

� getObjeto(Direcao):ObjetoMundo : O robô "agarra" no objeto da célula que foi indicada como parâmetro. Se não tiver nada nessa célula, ou for além dos limites do mundo, então esse método retorna null. Veja mais abaixo na seção constantes os valores disponíveis para Direcao.

� ehObjetoDoMundoTipo (String, Direcao):boolean : Verifica se existe um objeto do tipo passado como parâmetro na direção informada.

public class Exercicio1 extends Furbot { public void inteligencia() throws Exception { boolean ehUmAlien = ehObjetoDoMundoTipo("Alien", ACIMA); if (ehUmAlien == true ) diga (“A célula acima contém um objeto do tipo ALIEN”) else diga (“A célula acima está livre”); } public static void main (String[] args) { MundoVisual.iniciar(“Exercicio1.xml”); } }

No exemplo do quadro acima é declarada uma variável do tipo boolean que será

inicializada com o valor de retorno da chamada do método ehObjetoDoMundoTipo. Essa

linha verifica se existe um objeto do tipo "Alien" na célula acima de onde está o robô. Se

existir retorna true.Não existe uma restrição fixa do que pode ser passado no primeiro

parâmetro. Entretanto, atualmente (versão 0.6) podem ser usados as Strings "Alien",

"Parede" e "Numero".

Outros métodos que podem ser utilizados são:

� adicionarObjetoNoMundo(ObjetoDoMundo, Direcao):void : Adiciona um objeto no mundo na posição relativa à direção informada.

� adicionarObjetoNoMundoXY(): Adiciona um objeto no mundo na coordenada x,y.

� removerObjetoDoMundo() : Remove um objeto do mundo passado como parâmetro

� getObjetoXY(): Retorna um objeto na coordenada x,y

3.6. DEMAIS COMANDOS A SEREM DETALHADOS: Os comandos constantes na tabela abaixo serão descritos na próxima versão desta

apostila... aguarde!!!

13

� ehDependenteEnergia():boolean : Retorna true se o robô precisa de energia para executar os métodos;

� getMaxEnergia():int :Retorna a quantidade máxima de energia que pode ser armazena no robô.

� getEnergia():int : Retorna a quantidade atual de energia.

� esperar(segundos:int):void : O robô espera a quantidade de segundos passado como parâmetro antes de executar o próximo método.

� esperarAlguem():ObjetoMundo : O robô espera até algum objeto cruzar a mesma célula em que ele está, e retorna esse objeto. Caso se passem 5 segundos e nenhum objeto ter cruzada a célula, então retorna null.

� getVelocidade() : Retorna a velocidade do robô

� setVelocidade() : Altera a velocidade do robô

� sortear() : Sorteia um valor entre 0 e o valor máximo passado como parâmetro

� jahExplodiu() : Retorna true se o robô já explodiu.

� adicionarObjetoNoMundoEmbaixo()

� ehBloqueado() : Verifica se o objeto é bloqueado ou não.

� bloquear() : Bloqueia um objeto

� desbloquear() : Desbloqueia um objeto

� getSouDoTipo() : Retorna o tipo do objeto.

14

4. EXERCÍCIOS RESOLVIDOS

Nesta seção são apresentados os gabaritos para a primeira lista de exercícios.

4.1. LISTA DE EXERCÍCIOS 1

A primeira lista de exercícios tem por objetivo ambientar você com o furbot.

Os exercícios de 1 a 4 são resolvidos utilizando estruturas simples de programação. Já os

exemplos 5 e 6 já demandam a utilização de estruturas de controle de repetição “while”.

Exercícios:

1) Faça o robô andar até a ultima posição da linha. Lembre-se de que as coordenadas sempre serão fornecidas como (x, y). A primeira coluna e linhas são a de numero ZERO.

2) Faça o robô andar ate a ultima posição na mesma coluna. Lembre-se de que as coordenadas sempre serão fornecidas como (x, y). A primeira coluna e linhas são a de numero ZERO.

3) Faça o robô andar ate uma posição de linha e coluna diferente da linha e coluna iniciais. Lembre-se de que as coordenadas sempre serão fornecidas como (x, y). A primeira coluna e linhas são a de numero ZERO.

4) Faça o robô andar ate os extremos do mundo retornando a posição inicial. Cada vez que o robô atingir um dos extremos, faça informar que ele chegou ate aquela posição. Lembre-se de que as coordenadas sempre serão fornecidas como (x, y). A primeira coluna e linhas são a de numero ZERO.

5) Faça o robô chegar ate a coluna 4 na mesma linha em que ele nasceu. Se ele encontrar um obstáculo deve desviar por baixo. É garantido que não exista um obstáculo na ultima linha. A primeira coluna e linhas são a de numero ZERO.

6) Faça o robô andar ate uma posição de linha e coluna diferente da linha e coluna iniciais. Lembre-se de que as coordenadas sempre serão fornecidas como (x, y). A primeira coluna e linhas são a de numero ZERO.

4.2. RESOLUÇÃO DOS EXERCÍCIOS PROPOSTOS

15

4.2.1. LISTA 1 – EX1 - MODELO DE MUNDO EM XML

<furbot> <enunciado> Exercicio 1. &lt;br&gt; Faca o robo andar ate a ultima posicao da linha. &lt;br&gt; Lembre-se de que as coordenadas sempre serao fornecidas como (x, y). &lt;br&gt; A primeira coluna e linhas sao a de numero ZERO. </enunciado> <mundo> <qtdadeLin>8</qtdadeLin> <qtdadeCol>8</qtdadeCol> <explodir>true</explodir> </mundo> <robo> <x>0</x> <y>0</y> </robo> </furbot>

4.2.1.1. LISTA 1 –EX1 – SOLUÇÃO

Lembre-se que a especificação em XML <qtdadeLin>8</qtdadeLin> implica que haverão

9 linhas (numeradas de 0 a 9) e que <qtdadeCol>8</qtdadeCol> denota que teremos 9

colunas (numeradas de 0 a 9). Portanto, deslocar-se até a última posição na linha 0 (que

é a linha onde o furbot é criado) implica em executarmos 9 passos para a direita de modo

a deslocar o robo da coluna 0 até a coluna 8.

import br.furb.furbot.Furbot; import br.furb.furbot.MundoVisual; public class Exercicio1 extends Furbot{ public void inteligencia() throws Exception { diga("exercicio1"); andarDireita(); //o furbot anda uma célula para a direita posicionando-se na segunda coluna andarDireita(); //o furbot anda uma célula para a direita posicionando-se na terceira coluna andarDireita(); //o furbot anda uma célula para a direita posicionando-se na quarta coluna andarDireita(); //o furbot anda uma célula para a direita posicionando-se na quinta coluna andarDireita(); // o furbot anda uma célula para a direita posicionando-se na sexta coluna andarDireita(); // o furbot anda uma célula para a direita posicionando-se na sétima coluna andarDireita(); // o furbot anda uma célula para a direita posicionando-se na oitava coluna andarDireita(); // o furbot anda uma célula para a direita posicionando-se na nona coluna } public static void main(String[] args) { MundoVisual.iniciar("Exercicio1.xml"); // inicia o mundo do furbot } }

4.2.2. LISTA 1 – EX2 - MODELO DE MUNDO EM XML

16

<furbot> <enunciado>Exercicio 2. &lt;br&gt; Faca o robo andar ate a ultima posicao na mesma coluna. &lt;br&gt; Lembre-se de que as coordenadas sempre serao fornecidas como (x, y). &lt;br&gt; A primeira coluna e linhas sao a de numero ZERO.</enunciado> <mundo> <qtdadeLin>8</qtdadeLin> <qtdadeCol>8</qtdadeCol> <explodir>true</explodir> </mundo> <robo> <x>0</x> <y>0</y> </robo> </furbot>

4.2.2.1. LISTA 1 – GABARITO DO EXERCÍCIO 2

Lembre-se que a especificação em XML <qtdadeLin>8</qtdadeLin> implica que haverão

9 linhas (numeradas de 0 a 9) e que <qtdadeCol>8</qtdadeCol> denota que teremos 9

colunas (numeradas de 0 a 9). Portanto, deslocar-se até a última posição na coluna 0

(que é a coluna onde o furbot é criado) implica em executarmos 9 passos para baixo de

modo a deslocar o robo da linha 0 até a linha 8.

import br.furb.furbot.Furbot; import br.furb.furbot.MundoVisual; public class Exercicio2 extends Furbot{ public void inteligencia() throws Exception { diga("exercicio2"); andarAbaixo(); //o furbot anda uma célula para baixo posicionando-se na segunda linha andarAbaixo();//o furbot anda uma célula para baixo posicionando-se na terceira linha andarAbaixo();//o furbot anda uma célula para baixo posicionando-se na quarta linha andarAbaixo();//o furbot anda uma célula para baixo posicionando-se na quinta linha andarAbaixo();//o furbot anda uma célula para baixo posicionando-se na sexta linha andarAbaixo();//o furbot anda uma célula para baixo posicionando-se na sétima linha andarAbaixo();//o furbot anda uma célula para baixo posicionando-se na oitava linha } public static void main(String[] args) { MundoVisual.iniciar("Exercicio2.xml"); } }

4.2.3. LISTA 1 – EX3 - MODELO DE MUNDO EM XML

<furbot>

17

<enunciado>Exercicio 3. &lt;br&gt; Faça o robô andar ate uma posicao de linha e coluna diferente da linha e coluna iniciais. &lt;br&gt; Lembre-se de que as coordenadas sempre serao fornecidas como (x, y). &lt;br&gt; A primeira coluna e linhas sao a de numero ZERO.</enunciado> <mundo> <qtdadeLin>8</qtdadeLin> <qtdadeCol>8</qtdadeCol> <explodir>true</explodir> </mundo> <robo> <x>0</x> <y>0</y> </robo> </furbot>

4.2.3.1. LISTA 1 – GABARITO DO EXERCÍCIO 3

Lembre-se que a especificação em XML <qtdadeLin>8</qtdadeLin> implica que haverão

9 linhas (numeradas de 0 a 9) e que <qtdadeCol>8</qtdadeCol> denota que teremos 9

colunas (numeradas de 0 a 9).

import br.furb.furbot.Furbot; import br.furb.furbot.MundoVisual; public class Exercicio3 extends Furbot{ public void inteligencia() throws Exception { diga("exercicio3"); andarAbaixo();//o furbot anda uma célula para baixo posicionando-se na segunda linha (primeira coluna) andarDireita(); //o furbot anda uma célula para a direita posicionando-se na segunda coluna (segunda linha) andarAbaixo(); //o furbot anda uma célula para baixo posicionando-se na terceira linha (segunda coluna) andarDireita(); //o furbot anda uma célula para a direita posicionando-se na terceira coluna (terceira linha) andarAbaixo(); //o furbot anda uma célula para baixo posicionando-se na quarta linha (terceira coluna) andarAbaixo(); andarAbaixo(); andarAbaixo(); andarAbaixo(); } public static void main(String[] args) { MundoVisual.iniciar("Exercicio3.xml"); } }

4.2.4. LISTA 1 – EX4 - MODELO DE MUNDO EM XML.

<furbot> <enunciado>Exercicio 4. &lt;br&gt;

18

Faca o robo andar ate os extremos do mundo retornando a posicao inicial. &lt;br&gt; Cada vez que o robo atingir um dos extremos, faca-o informar que ele chegou ate aquela posicao. &lt;br&gt; Lembre-se de que as coordenadas sempre serao fornecidas como (x, y). &lt;br&gt; A primeira coluna e linhas sao a de numero ZERO.</enunciado> <mundo> <qtdadeLin>8</qtdadeLin> <qtdadeCol>8</qtdadeCol> <explodir>false</explodir> </mundo> <robo> <x>0</x> <y>0</y> </robo> </furbot>

4.2.4.1. LISTA 1 – GABARITO DO EXERCÍCIO 4

Lembre-se que a especificação em XML <qtdadeLin>8</qtdadeLin> implica que haverão

9 linhas (numeradas de 0 a 9) e que <qtdadeCol>8</qtdadeCol> denota que teremos 9

colunas (numeradas de 0 a 9). Portanto, deslocar-se no perímetro implica em fazer o

furbot ir até a última posição na linha 0 (que é a linha onde o furbot é criado), depois

descer até a linha 8 mantendo-se na coluna 8 (chegando ao canto inferior direito); depois

deslocando-se para a esquerda até a coluna 0 e mantendo-se na linha 8 (chegando ao

canto inferior esquerdo) e, finalmente, deslocando-se para cima até a linha 0 e mantendo-

se na coluna 0 (chegando ao canto superior esquerdo – coordenadas 0,0 – onde o furbot

foi criado.

A solução para este problema utilizou o recurso ehFim (direção). Este recurso retorna

verdadeiro se a posição indicada por “direção” encontra-se fora do mundo. Portanto

executando a operação de repetição while ( ! ehFim(DIREITA)) denota que: enquanto não

for encontrado o fim do mundo na próxima posição a direita podemos deslocar o robô

para a próxima posição a direita de onde ele esta.

Observe que o símbolo ! denota negação da expressão que está sendo testada.

import br.furb.furbot.Furbot; import br.furb.furbot.MundoVisual; public class Exercicio4 extends Furbot{ public void inteligencia() throws Exception { diga("exercicio4"); while (!ehFim(DIREITA)) { //anda até o canto superior direito andarDireita(); }; diga ("cheguei no canto superior direito"); while (!ehFim(ABAIXO)) { //anda até o canto inferior direito

19

andarAbaixo(); }; diga ("cheguei no canto inferior direito"); while (!ehFim(ESQUERDA)) { //anda até o canto inferior esquerdo andarEsquerda(); }; diga ("cheguei no canto inferior esquerdo"); while (!ehFim(ACIMA)) { //anda até o canto superior esquerdo andarAcima(); }; diga ("retornei ao inicio"); } public static void main(String[] args) { MundoVisual.iniciar("Exercicio4.xml"); } }

4.2.5. LISTA 1 – EX5 - MODELO DE MUNDO EM XML

<furbot> <enunciado>Exercicio 5. &lt;br&gt; Faca o robo chegar ate a coluna 4 na mesma linha em que ele nasceu. &lt;br&gt; Se ele encontrar um obstaculo deve desviar por baixo. &lt;br&gt; E garantido que nao exista um obstaculo na ultima linha. &lt;br&gt; A primeira coluna e linhas sao a de numero ZERO.</enunciado> <mundo> <qtdadeLin>5</qtdadeLin> <qtdadeCol>5</qtdadeCol> <explodir>true</explodir> </mundo> <robo> <x>randomX</x> <y>0</y> </robo> <objeto class="br.furb.furbot.Alien"> <x>3</x> <y>0</y> </objeto> <objeto class="br.furb.furbot.Alien"> <x>3</x> <y>2</y> </objeto> <objeto class="br.furb.furbot.Alien"> <x>3</x> <y>3</y> </objeto> </furbot>

20

4.2.5.1. LISTA 1 – GABARITO DO EXERCÍCIO 5

Lembre-se que a especificação em XML <qtdadeLin>5</qtdadeLin> implica que haverão

5 linhas (numeradas de 0 a 4) e que <qtdadeCol>5</qtdadeCol> denota que teremos 5

colunas (numeradas de 0 a 4). Portanto, deslocar-se até a linha 4 (significa o mesmo que

ir até a última coluna.

A solução para este problema utilizou o recurso ehVazio(direção). Este recurso retorna

verdadeiro se a posição indicada por “direção” encontra-se ocupada por algum objeto

(Parede, Alien, Número, etc).

Foi utilizado também o recurso getX() o qual retorna um valor numérico indicando a

coordenada x em que o furbot se encontra.

Também foi utilizado o recurso ehFim (direção) o qual, como explicado anteriormente,

retorna verdadeiro se a posição indicada por “direção” encontra-se fora do mundo.

Portanto executando a operação de repetição while ( ! ehFim(DIREITA)) denota que:

enquanto não for encontrado o fim do mundo na próxima posição a direita podemos

deslocar o robô para a próxima posição a direita de onde ele esta.

A operação if ( ! ehVazio (DIREITA) ) denota que: estamos verificando se a posição a

direita de onde encontra-se o furbot está vazia. Se estiver, o furbot pode deslocar-se para

a direita. Caso contrário, ele deverá executar uma operação de desvio por baixo, ou seja,

deslocar-se para baixo, deslocar-se duas vezes para a direita e retornar uma posição

acima (caracterizando-se um desvio por baixo conforme o enunciado!).

Observe que o símbolo ! denota negação da expressão que está sendo testada.

import br.furb.furbot.Furbot; import br.furb.furbot.MundoVisual; public class Exercicio5 extends Furbot{ public void inteligencia() throws Exception { diga("exercicio5"); while (getX()<5) { //enquanto a coordenada em que o furbot encontra-se for menor que 5 (0..4) if (ehVazio(DIREITA)){ //se a posição a direita for vazia if (!ehFim(DIREITA)) //e se a posição a direita não for fim do mundo andarDireita(); //desloca-se para a direita } else { // significa que a posição a direita estava ocupada, portanto andarAbaixo(); // desloca-se uma posição abaixo andarDireita(); //desloca-se uma posição a direita andarDireita(); //desloca-se outra posicao a direita andarAcima(); //retorna para a posição seguinte ao obstáculo caracterizando o desvio } };

21

diga ("cheguei na coluna 4"); } public static void main(String[] args) { MundoVisual.iniciar("Exercicio5.xml"); } }

4.2.6. LISTA 1 – EX6 - MODELO DE MUNDO EM XML

<furbot> <enunciado>Exercicio 6. &lt;br&gt; Faca o robo chegar ate a coluna 4 na mesma linha em que ele nasceu. &lt;br&gt; Se ele encontrar um obstaculo deve desviar por baixo. &lt;br&gt; E garantido que nao exista um obstaculo na ultima linha mas os aliens sao aleatorios. &lt;br&gt; A primeira coluna e linhas sao a de numero ZERO.</enunciado> <mundo> <qtdadeLin>5</qtdadeLin> <qtdadeCol>5</qtdadeCol> <explodir>true</explodir> </mundo> <robo> <x>0</x> <randomY /> </robo> <objeto class="br.furb.furbot.Alien"> <randomX /> <y>0</y> </objeto> <objeto class="br.furb.furbot.Alien"> <x>3</x> <randomY /> </objeto> <objeto class="br.furb.furbot.Alien"> <randomX /> <y>3</y> </objeto> </furbot>

4.2.6.1. LISTA 1 – GABARITO DO EXERCÍCIO 6

Esta é uma variaçao do exercício anterior incluindo o complicador que podem haver mais

obstáculos o que envolve o aprimoramento da rotina de desvio por baixo.

import br.furb.furbot.Furbot; import br.furb.furbot.MundoVisual; public class Exercicio6 extends Furbot{ public void inteligencia() throws Exception { diga("exercicio6"); while (getX()<5) { if (ehVazio(DIREITA)){ if (!ehFim(DIREITA)) {

22

andarDireita(); } } else { if (ehVazio(ABAIXO)){ while (!ehVazio(DIREITA)) { if (!ehFim(ABAIXO)) { andarAbaixo(); } else { //eh fim abaixo //tem que mudar a direcao para cima while (!ehVazio(DIREITA)){ if (!ehFim(ACIMA)) { andarAcima(); } }//while } };//while } else diga ("estou encurralado!!!"); }; } diga ("cheguei na coluna 4"); } public static void main(String[] args) { MundoVisual.iniciar("Exercicio6.xml"); } }

23

4.3. LISTA DE EXERCÍCIOS 2

A segunda lista de exercícios tem por objetivo ampliar o seu domínio sobre os recursos do

furbot.

Exercícios:

1) Faça o robô andar até a última coluna contando os aliens. No final o robô deve falar a quantidade de aliens encontrados. Atenção: não se esqueça do tratamento do singular e plural. Se for mais que um Alien, o robô deve dizer “aliens”;

2) Faça o robo andar ao redor do mundo e contar os alines que ele encontrou no caminho. No final ele deve falar a quantidade de aliens encontrados;

3) Faça o robô andar ao redor do mundo e contar os alines que ele encontrou no caminho. O robô deve voltar a célula de nascença para então falar a quantidade de aliens;

4) Faça o robô andar ao redor do mundo e contar os aliens que ele encontrou no caminho. O robô deve voltar a célula de origem para então falar a quantidade de aliens encontrados, respectivamente, no total, na coluna zero, na última coluna e na última linha;

5) Faça o robô andar até a célula (0,0). Em seguida o faça andar pelo mundo todo contando os aliens que encontra pelo caminho. Quando ele alcançar a última célula deve falar a quantidade de aliens encontrados;

6) Faça o robô andar ao redor do mundo e contar os aliens que ele encontrou pelo caminho. O robô deve voltar a célula de origem para então falar a quantidade de aliens encontrados, respectivamente, no total, nas linhas pares, nas linhas ímpares, nas colunas pares e nas colunas ímpares.

4.3.1. LISTA 2 – EX1 – MODELO DE MUNDO

< furbot> <enunciado>Lista de Exercícios - Exercício 1.<br> Faça o robô andar até a ultima coluna contando os aliens.<br> No final deve falar a quantidade de aliens encontrados.<br> Atenção: não esqueça do tratamento do singular e plural.<br> Se for mais que 1 alien, ele deve dizer "aliens".</enunciado> <mundo> <qtdadeLin>4</qtdadeLin> <qtdadeCol>8</qtdadeCol> <explodir>true</explodir> </mundo> <robo> <x>0</x> <randomY /> </robo> <!-- aliens --> <objeto class="br.furb.furbot.Alien"> <random limiteInfX="1" /> <bloqueado>false</bloqueado> </objeto> <objeto class="br.furb.furbot.Alien"> <random limiteInfX="1" /> <bloqueado>false</bloqueado>

24

</objeto> <objeto class="br.furb.furbot.Alien"> <random limiteInfX="1" /> <bloqueado>false</bloqueado> </objeto> <objeto class="br.furb.furbot.Alien"> <random limiteInfX="1" /> <bloqueado>false</bloqueado> </objeto> <objeto class="br.furb.furbot.Alien"> <random limiteInfX="1" /> <bloqueado>false</bloqueado> </objeto> <objeto class="br.furb.furbot.Alien"> <random limiteInfX="1" /> <bloqueado>false</bloqueado> </objeto> </furbot>

4.3.1.1. LISTA 2 - GABARITO DO EXERCÍCIO 1

import br.furb.furbot.Furbot; import br.furb.furbot.MundoVisual; public class Lista1Exercicio1 extends Furbot { public void inteligencia() throws Exception { diga("Exercicio 1"); int qtdAliens = 0; while (!ehFim(DIREITA)) { if (!ehVazio(DIREITA)) { qtdAliens++; } andarDireita(); } if (qtdAliens == 1) { diga ("1 alien encontrado"); } else { diga (qtdAliens + " aliens encontrados"); } } public static void main(String[] args) { MundoVisual.iniciar("Lista1Exercicio1.xml"); } }

4.3.2. LISTA 2- EX2 - MODELO DE MUNDO EM XML.

<furbot> <enunciado>Lista de Exercícios - Exercício 2.<br> Faça o robô andar ao redor do mundo e contar os aliens<br> que ele encontrou no caminho. No final ele deve falar a<br> quantidade de aliens encontrados.</enunciado> <mundo> <random limiteInfY="3" limiteSupY="8" limiteInfX="3" limiteSupX="8" />

25

<explodir>true</explodir> </mundo> <robo> <x>0</x> <y>0</y> </robo> - <!-- aliens --> <objeto class="br.furb.furbot.Alien"> <random /> <bloqueado>false</bloqueado> </objeto> <objeto class="br.furb.furbot.Alien"> <random /> <bloqueado>false</bloqueado> </objeto> - <objeto class="br.furb.furbot.Alien"> <random /> <bloqueado>false</bloqueado> </objeto> <objeto class="br.furb.furbot.Alien"> <random /> <bloqueado>false</bloqueado> </objeto> <objeto class="br.furb.furbot.Alien"> <random /> <bloqueado>false</bloqueado> </objeto> <objeto class="br.furb.furbot.Alien"> <random /> <bloqueado>false</bloqueado> </objeto> </furbot>

4.3.2.1. LISTA 2 - GABARITO DO EXERCÍCIO 2

import br.furb.furbot.Furbot; import br.furb.furbot.MundoVisual; public class Lista1Exercicio2 extends Furbot { public void inteligencia() throws Exception { diga("Exercicio 2"); int qtdAliens = 0; while (!ehFim(ABAIXO)) { if (!ehVazio(ABAIXO)) { qtdAliens++; } andarAbaixo(); } while (!ehFim(DIREITA)) { if (!ehVazio(DIREITA)) { qtdAliens++; } andarDireita(); } while (!ehFim(ACIMA)) { if (!ehVazio(ACIMA)) { qtdAliens++; } andarAcima(); }

26

while (!ehFim(ESQUERDA)) { if (!ehVazio(ESQUERDA)) { qtdAliens++; } andarEsquerda(); } if (qtdAliens == 1) { diga ("1 alien encontrado"); } else { diga (qtdAliens + " aliens encontrados"); } } public static void main(String[] args) { MundoVisual.iniciar("Lista1Exercicio2.xml"); } }

4.3.3. LISTA 2 – EX3- MODELO DE MUNDO EM XML.

<furbot> <enunciado>Lista de Exercícios - Exercício 3.<br> Faça o robô andar ao redor do mundo e contar os aliens<br> que ele encontrou no caminho. O robô deve voltar a célula <br> de nascença para então falar a quantidade de aliens.</enunciado> <mundo> <random limiteInfY="3" limiteSupY="8" limiteInfX="3" limiteSupX="8" /> <explodir>true</explodir> </mundo> <robo> <random /> </robo> - <!-- aliens --> <objeto class="br.furb.furbot.Alien"> <random /> <bloqueado>false</bloqueado> </objeto> <objeto class="br.furb.furbot.Alien"> <random /> <bloqueado>false</bloqueado> </objeto> <objeto class="br.furb.furbot.Alien"> <random /> <bloqueado>false</bloqueado> </objeto> <objeto class="br.furb.furbot.Alien"> <random /> <bloqueado>false</bloqueado> </objeto> <objeto class="br.furb.furbot.Alien"> <random /> <bloqueado>false</bloqueado> </objeto> <objeto class="br.furb.furbot.Alien"> <random /> <bloqueado>false</bloqueado> </objeto> </furbot>

27

4.3.4. LISTA 2 – EX3 - GABARITO DO EXERCÍCIO 3

import br.furb.furbot.Furbot; import br.furb.furbot.MundoVisual; public class Lista1Exercicio3 extends Furbot { public void inteligencia() throws Exception { diga("Exercicio 3"); int qtdAliens = 0; int inicialX = getX(); int inicialY = getY(); while (!ehFim(ESQUERDA)) { andarEsquerda(); } while (!ehFim(ABAIXO)) { if (!ehVazio(ABAIXO)) { qtdAliens++; } andarAbaixo(); } while (!ehFim(DIREITA)) { if (!ehVazio(DIREITA)) { qtdAliens++; } andarDireita(); } while (!ehFim(ACIMA)) { if (!ehVazio(ACIMA)) { qtdAliens++; } andarAcima(); } while (!ehFim(ESQUERDA)) { if (!ehVazio(ESQUERDA)) { qtdAliens++; } andarEsquerda(); } // volta a celula inicial int linhaAtual = 0; while (linhaAtual < inicialY) { if (!ehVazio(ABAIXO)) { qtdAliens++; } andarAbaixo(); linhaAtual++; } int colunaAtual = 0; while (colunaAtual < inicialX) { andarDireita(); colunaAtual++; } if (qtdAliens == 1) { diga ("1 alien encontrado"); } else { diga (qtdAliens + " aliens encontrados"); } } public static void main(String[] args) { MundoVisual.iniciar("Lista1Exercicio3.xml");

28

} }

4.3.5. LISTA 2 – EX4 - MODELO DE MUNDO EM XML.

<furbot> <enunciado>Lista de Exercícios - Exercício 4.<br> Faça o robô andar ao redor do mundo e contar os aliens<br> que ele encontrou no caminho. O robô deve voltar a célula <br> de nascença para então falar a quantidade de aliens encontrados:<br> no total, na coluna 0, na linha 0, na última coluna e na <br> última linha.</enunciado> <mundo> <random limiteInfY="3" limiteSupY="8" limiteInfX="3" limiteSupX="8" /> <explodir>true</explodir> </mundo> <robo> <random /> </robo> <!-- aliens --> <objeto class="br.furb.furbot.Alien"> <random /> <bloqueado>false</bloqueado> </objeto> <objeto class="br.furb.furbot.Alien"> <random /> <bloqueado>false</bloqueado> </objeto> <objeto class="br.furb.furbot.Alien"> <random /> <bloqueado>false</bloqueado> </objeto> <objeto class="br.furb.furbot.Alien"> <random /> <bloqueado>false</bloqueado> </objeto> <objeto class="br.furb.furbot.Alien"> <random /> <bloqueado>false</bloqueado> </objeto> <objeto class="br.furb.furbot.Alien"> <random /> <bloqueado>false</bloqueado> </objeto> </furbot>

<bloqueado>false </bloqueado> </objeto>

<objeto class="br.furb.furbot.Alien"> <random /> <bloqueado>false </bloqueado>

</objeto> <objeto class="br.furb.furbot.Alien"> <random /> <bloqueado>false </bloqueado>

</objeto> </furbot>

29

4.3.5.1. LISTA 2 - GABARITO DO EXERCÍCIO 4

import br.furb.furbot.Furbot; import br.furb.furbot.MundoVisual; public class Lista1Exercicio4 extends Furbot { public void inteligencia() throws Exception { diga("Exercicio 4"); int qtdAColuna0, qtdaLinha0, qtdAUltimaColuna, qtdAUltimaLinha, qtdACantos, total; qtdAColuna0 = qtdaLinha0 = qtdAUltimaColuna = qtdAUltimaLinha = qtdACantos = total = 0; int inicialX = getX(); int inicialY = getY(); while (!ehFim(ESQUERDA)) { andarEsquerda(); } while (!ehFim(ABAIXO)) { if (!ehVazio(ABAIXO)) { qtdAColuna0++; } andarAbaixo(); } if (!ehVazio(AQUIMESMO)) { qtdACantos++; qtdAUltimaLinha++; } while (!ehFim(DIREITA)) { if (!ehVazio(DIREITA)) { qtdAUltimaLinha++; } andarDireita(); } if (!ehVazio(AQUIMESMO)) { qtdACantos++; qtdAUltimaColuna++; } while (!ehFim(ACIMA)) { if (!ehVazio(ACIMA)) { qtdAUltimaColuna++; } andarAcima(); } if (!ehVazio(AQUIMESMO)) { qtdACantos++; qtdaLinha0++; } while (!ehFim(ESQUERDA)) { if (!ehVazio(ESQUERDA)) { qtdaLinha0++; } andarEsquerda(); } if (!ehVazio(AQUIMESMO)) { qtdACantos++; qtdAColuna0++; } int linhaAtual = 0;

30

while (linhaAtual < inicialY) { if (!ehVazio(ABAIXO)) { qtdAColuna0++; } andarAbaixo(); linhaAtual++; } int colunaAtual = 0; while (colunaAtual < inicialX) { andarDireita(); colunaAtual++; } total = qtdAColuna0 + qtdaLinha0 + qtdAUltimaColuna + qtdAUltimaLinha - qtdACantos; if (total == 1) { diga ("Total: 1 alien"); } else { diga ("Total: "+total+" aliens"); } if (qtdAColuna0 == 1) { diga ("Coluna0: 1 alien"); } else { diga ("Coluna0: "+qtdAColuna0+" aliens"); } if (qtdaLinha0 == 1) { diga ("Linha0: 1 alien"); } else { diga ("Linha0: "+qtdaLinha0+" aliens"); } if (qtdAUltimaColuna == 1) { diga ("UltColuna: 1 alien"); } else { diga ("UltColuna: "+qtdAUltimaColuna+" aliens"); } if (qtdAUltimaLinha == 1) { diga ("UltLinha: 1 alien"); } else { diga ("UltLinha: "+qtdAUltimaLinha+" aliens"); } } public static void main(String[] args) { MundoVisual.iniciar("Lista1Exercicio4.xml"); } }

31

4.3.6. LISTA 2 – EX5 - MODELO DE MUNDO EM XML.

<furbot> <enunciado>Lista de Exercícios - Exercício 5.<br> Faça o robô andar até a célula (0,0). <br> Em seguida faça ele andar pelo mundo todo<br> e contando os aliens. Quando ele alcançar<br> a última célula deve falar a quantidade<br> de aliens encontrados.</enunciado> <mundo> <random limiteInfY="3" limiteSupY="8" limiteInfX="3" limiteSupX="8" /> <explodir>true</explodir> </mundo> <robo> <random /> </robo> <!-- aliens --> <objeto class="br.furb.furbot.Alien "> <random /> <bloqueado>false</bloqueado> </objeto> <objeto class="br.furb.furbot.Alien "> <random /> <bloqueado>false</bloqueado> </objeto> <objeto class="br.furb.furbot.Alien "> <random /> <bloqueado>false</bloqueado> </objeto> <objeto class="br.furb.furbot.Alien "> <random /> <bloqueado>false</bloqueado> </objeto> <objeto class="br.furb.furbot.Alien "> <random /> <bloqueado>false</bloqueado> </objeto>

</furbot>

4.3.6.1. LISTA 2 - GABARITO DO EXERCÍCIO 5

import br.furb.furbot.Furbot; import br.furb.furbot.MundoVisual; public class Lista1Exercicio5 extends Furbot { public void inteligencia() throws Exception { diga("Exercicio 5"); ////////////////////////////////// // goto (0,0) while (getX() > 0) andarEsquerda(); while (getY() > 0) andarAcima(); ////////////////////////////////// // percorre o mundo boolean sentidoDireita = true; int qtdAliens = 0; while (!ehFim(ABAIXO)) {

32

if (!ehVazio(AQUIMESMO)) qtdAliens++; if (sentidoDireita) { while (!ehFim(DIREITA)) { if (!ehVazio(DIREITA)) { qtdAliens++; } andarDireita(); } } else { while (!ehFim(ESQUERDA)) { if (!ehVazio(ESQUERDA)) { qtdAliens++; } andarEsquerda(); } } if (!ehFim(ABAIXO)) andarAbaixo(); sentidoDireita = !sentidoDireita; } if (!ehVazio(AQUIMESMO)) qtdAliens++; if (sentidoDireita) while (!ehFim(DIREITA)) { if (!ehVazio(DIREITA)) { qtdAliens++; } andarDireita(); } else while (!ehFim(ESQUERDA)) { if (!ehVazio(ESQUERDA)) { qtdAliens++; } andarEsquerda(); } if (qtdAliens == 1) { diga ("1 alien encontrado"); } else { diga (qtdAliens + " aliens encontrados"); } } public static void main(String[] args) { MundoVisual.iniciar("Lista1Exercicio5.xml"); } }

4.3.7. LISTA 2 –EX6 - MODELO DE MUNDO EM XML.

<furbot> <enunciado>Lista de Exercícios - Exercício 6.<br> Faça o robô andar ao redor do mundo e contar os aliens<br> que ele encontrou no caminho. O robô deve voltar a célula <br> de nascença para então falar a quantidade de aliens<br> encontrados: no total, nas linhas pares, nas linhas ímpares,<br> nas colunas pares e nas colunas ímpares.</enunciado>

33

<mundo> <random limiteInfY="3" limiteSupY="8" limiteInfX="3" limiteSupX="8" /> <explodir>true</explodir> </mundo> <robo> <random /> </robo> <!-- aliens --> <objeto class="br.furb.furbot.Alien "> <random /> <bloqueado>false</bloqueado> </objeto> <objeto class="br.furb.furbot.Alien "> <random /> <bloqueado>false</bloqueado> </objeto> <objeto class="br.furb.furbot.Alien "> <random /> <bloqueado>false</bloqueado> </objeto> <objeto class="br.furb.furbot.Alien "> <random /> <bloqueado>false</bloqueado> </objeto> <objeto class="br.furb.furbot.Alien "> <random /> <bloqueado>false</bloqueado> </objeto> <objeto class="br.furb.furbot.Alien "> <random /> <bloqueado>false</bloqueado> </objeto>

</furbot>

4.3.7.1. LISTA 2 - GABARITO DO EXERCÍCIO 6

import br.furb.furbot.Furbot; import br.furb.furbot.MundoVisual; public class Lista1Exercicio6 extends Furbot { public void inteligencia() throws Exception { diga("Exercicio 6"); while (getX() > 0) andarEsquerda(); while (getY() > 0) andarAcima(); // percorre o mundo boolean sentidoDireita = true; int qtdALinhaImpar, qtdALinhaPar, qtdAColunaImpar, qtdAColunaPar, total; qtdALinhaImpar = qtdALinhaPar = qtdAColunaImpar = qtdAColunaPar = total = 0; while (!ehFim(ABAIXO)) { if (!ehVazio(AQUIMESMO)) { if (getX() %2 == 0) qtdALinhaPar++; else qtdALinhaImpar++; if (getY()%2 == 0) qtdAColunaPar++; else qtdAColunaImpar++; total++; }

34

if (sentidoDireita) { while (!ehFim(DIREITA)) { if (!ehVazio(DIREITA)) { if (getX()%2 == 0) qtdALinhaPar++; else qtdALinhaImpar++; if (getY()%2 == 0) qtdAColunaPar++; else qtdAColunaImpar++; total++; } andarDireita(); }//while } else { //sentido a esquerda while (!ehFim(ESQUERDA)) { if (!ehVazio(ESQUERDA)) { if (getX()%2 == 0) qtdALinhaPar++; else qtdALinhaImpar++; if (getY()%2 == 0) qtdAColunaPar++; else qtdAColunaImpar++; total++; } andarEsquerda(); }//while } if (!ehFim(ABAIXO)) andarAbaixo(); sentidoDireita = !sentidoDireita; } if (!ehVazio(AQUIMESMO)) { if (getX()%2 == 0) qtdALinhaPar++; else qtdALinhaImpar++; if (getY()%2 == 0) qtdAColunaPar++; else qtdAColunaImpar++; total++; } if (sentidoDireita) while (!ehFim(DIREITA)) { if (!ehVazio(DIREITA)) { if (getX()%2 == 0) qtdALinhaPar++; else qtdALinhaImpar++; if (getY()%2 == 0) qtdAColunaPar++; else qtdAColunaImpar++; total++; } andarDireita(); }//while else while (!ehFim(ESQUERDA)) { if (!ehVazio(ESQUERDA)) { if (getX()%2 == 0) qtdALinhaPar++; else qtdALinhaImpar++; if (getY()%2 == 0) qtdAColunaPar++; else qtdAColunaImpar++; total++; } andarEsquerda(); }//while if (total == 1) {

35

diga ("Total: 1 alien"); } else { diga ("Total: "+total+" aliens"); } if (qtdALinhaPar == 1) { diga ("Linha Par: 1 alien"); } else { diga ("Linha Par: "+qtdALinhaPar+" aliens"); } if (qtdALinhaImpar == 1) { diga ("Linha Impar: 1 alien"); } else { diga ("Linha Impar: "+qtdALinhaImpar+" aliens"); } if (qtdAColunaPar == 1) { diga ("Coluna Par: 1 alien"); } else { diga ("Coluna Par: "+qtdAColunaPar+" aliens"); } if (qtdAColunaImpar == 1) { diga ("Coluna Impar: 1 alien"); } else { diga ("Coluna Impar: "+qtdAColunaImpar+" aliens"); } } public static void main(String[] args) { MundoVisual.iniciar("Lista1Exercicio6.xml"); } }

36

5. INTRODUÇÃO A PROGRAMAÇÃO ORIENTADA A OBJETOS

Orientação a objetos modela o mundo a partir dos objetos existentes no mundo real.

OBJETOS são elementos que existem concretamente, seja em forma física ou conceitual.

Os objetos têm características e comportamentos próprios.

CLASSES definem categorias de objetos com características e comportamentos

similares.

A Programação Orientada a Objetos (POO) consiste na construção de modelos de

classes adequados para o domínio de um determinado problema a ser trabalhado, de

forma a se criar objetos que permitam a solução do problema.

Algumas características importantes da OO são:

� encapsulamento: os objetos têm uma interface para se comunicar com o seu mundo exterior.

� herança1: objetos podem herdar informações de outros objetos.

� polimorfismo1: objetos similares podem ter comportamentos diferentes.

� associação1: objetos podem se associar a outros objetos.

� abstração: classes devem ser modeladas considerando apenas aquilo que é relevante para a solução de um determinado problema.

A implementação de uma solução computacional utilizando OO requer, portanto, a

construção de um modelo de classes e objetos.

5.1. CLASSES

As CLASSES são categorias de objetos com dados e comportamentos similares.

Uma classe é um modelo que contém ATRIBUTOS (DADOS ou PROPRIEDADES) e

MÉTODOS (OPERAÇÕES ou MENSAGENS) possíveis sobre um determinado objeto.

Os ATRIBUTOS são SUBSTANTIVOS ou LOCUÇÕES ADJETIVAS que definem as

características de um objeto.

Os MÉTODOS são VERBOS que definem os comportamentos ou as ações realizadas

pelo ou sobre o objeto.

Exemplos de CLASSES:

1 Estes conceitos serão abordados nas disciplinas posteriores de programação.

37

ALUNO Atributos : número de matrícula, nome, sexo, curso Métodos : matricular-se, informar número de matrícula CONTA CORRENTE Atributos : número da conta, dígito verificador, nome do correntista, cpf, saldo Métodos : abrir conta, depositar, retirar, ver saldo, ver dados correntista ENDEREÇO Atributos : rua, número, bairro, cidade, uf Métodos : cadastrar endereço, alterar endereço, ver endereço

A representação diagramática mais comum de uma classe é feita através de uma caixa

dividida em três partes: a primeira deve conter o nome da classe, a segunda, deve conter

os atributos da classe e a terceira deve conter os métodos da classe.

O diagrama com esta representação é apresentado a seguir:

Exemplos:

Existem atributos de uma classe que podem ser outras classes. Por exemplo, na classe

Aluno, o atributo Curso poderia ser uma outra classe, contendo o código do curso, nome

do curso, currículo e assim por diante.

A identificação de classes candidatas a um sistema é feita através da análise dos

SUBSTANTIVOS do enunciado de um problema.

número de matrícula

nome

sexo

matricular-se

informar número de matrícula

Conta Corrente

número da conta

dígito verificador

nome do correntista

abrir conta

depositar

retirar

Endereço

rua

número

bairro

cadastrar endereço

alterar endereço

Nome da Classe

atributos

métodos

Aluno

38

� no problema 1 analisado anteriormente, o aluno é um candidato a ser uma classe, pois sobre ele definem-se outras informações tais como nome e notas.

� no problema 2, a classe candidata poderia ser a sala, pois é sobre ela que se sabe a largura e o comprimento e se deseja calcular a área.

5.2. OBJETOS

Um OBJETO é o que chamamos de INSTÂNCIA da classe, ou seja, quando atribuímos

valores aos DADOS.

Um objeto só existe a partir da definição de uma classe.

A representação diagramática de um objeto é similar a de uma classe inserindo o sinal de

: (dois pontos) seguido do nome da classe.

Por convenção o nome de uma classe é grafado em letra maiúscula e o de um objeto é

grafado em letra minúscula.

O diagrama com esta representação é apresentado a seguir:

Podem existir diversas instâncias de uma mesma classe.

aluno : Aluno

número de matrícula: 100 nome: Bento de Oliveira sexo: M curso: Ciência da Computação

Matricular-se

Consultar Dados

contaCorrente :

Conta Corrente

número da Conta: 100 dígito verificador: 2 nome do correntista: Rica de Menezes CPF: 123456789-0 Saldo: R$1.000.000,00

Abrir conta

Depositar

Retirar

endereço :

Endereço

rua: Rua das Acácias número: 123 bairro: Jovem cidade: Blumenau uf: SC

Cadastrar Endereço

Alterar Endereço

39

Um objeto é a materialização de uma classe. Para ser usado um objeto deve ser criado.

5.2.1. EXERCÍCIOS PROPOSTOS

1. Defina pelo menos 3 atributos e 3 métodos para as seguintes classes. Apresente a

representação através de um diagrama:

a) funcionário; b) livro; c) círculo; d) carro; e) locadora de vídeos f) DVD; g) jogo de truco; h) jogador de truco; i) carta de baralho;

2. Crie pelo menos 2 objetos para cada uma das classes do exercício anterior,

considerando os atributos e métodos definidos. Apresente a representação através de

um diagrama.

5.3. ATRIBUTOS

Conforme visto anteriormente, ATRIBUTOS são as informações que caracterizam uma

classe.

Os ATRIBUTOS também são chamados de PROPRIEDADES de uma classe.

Mas quando eu devo definir um atributo?

aluno1 : Aluno

número de matrícula: 100 nome: Bento de Oliveira sexo: M curso: Ciência da Computação

Matricular-se

Consultar Dados

aluno2 : Aluno

número de matrícula: 157 nome: Maria da Silva sexo: F curso: Psicologia

Matricular-se

Consultar Dados

aluno3 : Aluno

número de matrícula: 89 nome: Cleto Marques sexo: M curso: Sistemas de Informação

Matricular-se

Consultar Dados

40

� Via de regra, um dado deve ser definido como atributo quando ele não tem dependência de outros dados.

� Dados dependentes devem ser definidos como atributos apenas quando são muito usados. Entretanto, deve-se ter em mente que a cada dado alterado que influencie em seu valor, o mesmo também precisa ser alterado.

Exemplo: considere o exercício 1 onde o professor tem que calcular a média de um aluno

a partir de suas 3 notas. Quem são os atributos do aluno?

� nota1, nota2 e nota3 são atributos uma vez que são dados independentes.

� média não deve ser atributo pois depende das notas, ou seja, é um dado calculado.

Os ATRIBUTOS têm tipos que os definem.

5.3.1. TIPOS DOS ATRIBUTOS

Todo ATRIBUTO tem um tipo de dado associado. O tipo de dado determina:

� que valores ele pode assumir;

� as operações às quais ele pode ser submetida;

� o espaço que ele ocupa na memória do computador.

Os tipos de dados básicos ou primitivos são:

� inteiro: define valores numéricos do tipo inteiro, ou seja, sem casas decimais. (Ex: 10, 15, 138)

� real: define valores numéricos do tipo real (ponto flutuante), ou seja, com casas decimais. (Ex. 0.15, 45.2, 1.3465)

� caractere: define valores alfanuméricas compostas de apenas um caractere. (Ex. ‘A’, ‘?’ ‘@’)

� lógico: define variáveis do tipo VERDADEIRO ou FALSO.

� Outro tipo de dado muito comum é denominado de string ou cadeia de caracteres, pois permite agrupar diversos caracteres. (Ex. “João da Silva”, “ABC123”, “Computador”).

Para as classes dos exemplos anteriores, poderíamos definir os seguintes tipos de dados

(o tipo do dado normalmente vem à frente do nome do atributo).

41

5.3.2. EXERCÍCIOS PROPOSTOS

1. Descreva os tipos de dados para os atributos definidos no exercício 1 da seção 5.2.1.

5.4. MÉTODOS

Conforme visto anteriormente, MÉTODOS são os comportamentos ou as ações

realizadas por um objeto.

Os métodos também são chamados de funções, pois, assim como na Matemática, eles

recebem valores e retornam um resultado.

Os métodos operam sobre dados. Assim, normalmente os métodos têm valores de

Entrada e Saída.

Os dados de ENTRADA sobre os quais os métodos operam podem ser:

� ATRIBUTOS: são dados que já existem dentro da própria classe;

� PARÂMETROS: são dados que não existem na classe, mas que são necessários para o processamento do método.

A SAÍDA gerada por um método pode ser:

� ATRIBUTO: neste caso o resultado da execução do método fica armazenado na própria classe;

� RETORNO: neste caso, o método devolve o resultado para quem solicitou, como um resultado de uma função.

inteiro número de matrícula

string nome

caracter sexo

matricular-se

consultar dados

Conta Corrente

inteiro número da conta

inteiro dígito verificador

string nome do correntista

abrir conta

depositar

retirar

Endereço

string rua

inteiro número

string bairro

cadastrar endereço

alterar endereço

Aluno

42

5.4.1. ASSINATURA DOS MÉTODOS

A Assinatura de um método é o seu cabeçalho, ou seja, é o que descreve o método.

Para construir um método é necessário:

1. definir o seu nome (nomeMetodo);

2. identificar os dados de Entrada;

3. classificar os dados de entrada como ATRIBUTO ou PARÂMETRO. Se for PARÂMETRO é obrigatório especificá-lo na assinatura do método. Atributo não.

4. identificar os dados de Saída;

5. classificar os dados de Saída como ATRIBUTO ou RETORNO. Se for RETORNO é obrigatório especificá-lo na assinatura do método. Atributo não.

Assim, a assinatura de um método é feita do seguinte modo:

tipo nomeMetodo (parametros)

O TIPO descreve o tipo de dado do valor de retorno do método. Quando ele é omitido, é

porque a saída é um atributo.

Nos PARÂMETROS deve ser colocado o tipo de dado e um nome para o parâmetro.

Quando os parâmetros são omitidos, é porque a(s) entrada(s) é(são) atributo(s).

5.4.2. ALGORITMO

O ALGORITMO de um método são as instruções que ele deve executar para realizar as

operações que são de sua responsabilidade.

Um ALGORITMO é similar a uma receita para resolver tarefas específicas. Estas tarefas

não podem ser redundantes nem subjetivas na sua definição, devendo ser claras e

precisas.

Também precisam ter uma SEQÜÊNCIA LÓGICA para que o problema seja resolvido

corretamente.

Via de regra todo algoritmo opera sobre DADOS (denominados de VARIÁVEIS), sendo

um processo que precisa de RECURSOS (dados de entrada) e produz RESULTADOS

(dados de saídas).

FIGURA 5 - COMPONENTES DE UM ALGORITMO.

Deixando de lado a questão da orientação a objetos, experimente descrever algoritmos

para os problemas a seguir. Não se esqueça de descrever os recursos necessários e o

resultado esperado para cada um:

� fazer uma limonada;

� pegar um livro na biblioteca;

� desenhar e recortar um quadrado em uma folha de papel;

� calcular o perímetro de um triângulo;

� jogar truco.

Um algoritmo precede a tarefa de programação à medida em que ele descreve como o

programa deve ser feito.

Um algoritmo é composto de INSTRUÇÕES e EXPRESSÕES.

As INSTRUÇÕES mais comuns em algoritmos são:

� ATRIBUIÇÃO: existem informações em um programa que precisam ser armazenadas. Um atributo, por exemplo, precisa armazenar seu conteúdo. Nestes casos, utiliza-se uma expressão de atribuição.

� ESTRUTURAS DE CONTROLE EM NÍVEL DE INSTRUÇÃO (SELEÇÃO E REPETIÇÃO): em um programa podem existir comandos executados apenas em determinadas situações. Nestes casos utilizam-se as estruturas de seleção. Em outras situações, um comando precisa ser executado repetidas vezes. Nestes casos, utilizam-se as estruturas de repetição.

� CHAMADAS DE OUTROS MÉTODOS: muitas vezes em um programa, a solução de um método, requer a execução de outros métodos. Nestes casos, deve-se seguir a assinatura do método a ser ativado (chamado).

� TRATAMENTOS DE ERROS: muitas situações na programação de computadores requerem cuidado pois podem gerar diversos tipos de erros. Nas linguagens mais modernas, existem estruturas específicas para o tratamento destes erros.

As EXPRESSÕES tem por finalidade verificar ou transformar os dados em um algoritmo.

As expressões contam com OPERADORES que permitem realizar as ações sobre os

dados de um determinado algoritmo.

44

Os OPERADORES dependem de linguagens e normalmente são representados por

símbolos:

� operador de atribuição (=);

� operadores aritméticos (+, - , * , /);

� operadores relacionais (>, <, <=, <=, <>, =)

� operadores lógicos (e, ou, não).

Existem diversas formas de representar um algoritmo, entre as quais destacam-se:

� texto: é um tipo de representação meramente textual, onde descreve-se, em linhas gerais, os passos para a execução do algoritmo;

� português estruturado ou portugol: é chamado de “pseudo-linguagem”, pois apresenta algumas estruturas similares à uma linguagem de programação;

� diagramas: representa as estruturas de um programa através das mais diversas formas geométricas. Os mais comuns são: fluxograma, Diagrama de Chapin e diagrama de estados.

Convenciona-se começar um algoritmo com a palavra início e terminar com a palavra fim.

5.4.3. EXERCÍCIOS PROPOSTOS

1. Descreva a assinatura e o algoritmo dos métodos do exercício 1 da seção 5.2.1.

5.5. ENCAPSULAMENTO

A orientação a objetos define regras de acesso aos atributos e métodos, para garantir a

segurança e qualidade do código desenvolvido.

Existem diversos qualificadores para atributos e métodos. Neste curso destacaremos

dois:

� privado: neste caso, o atributo ou método só pode ser utilizado dentro da própria classe.

� público: neste caso, o atributo ou método pode ser utilizado por qualquer outra classe.

O princípio do ENCAPSULAMENTO estabelece, entretanto que:

� TODO ATRIBUTO DEVE SER PRIVADO. Só os métodos podem ser públicos2.

2 Existem algumas exceções no caso de herança de classes que não serão vistas por enquanto.

45

� MÉTODOS DE ACESSO (setters&getters)

Uma vez que os atributos são encapsulados, deve existir uma forma de atribuir valores a

eles ou de verificar seus valores.

Nestes casos existem métodos especiais denominados de MÉTODOS DE ACESSO.

Existem dois tipos de métodos de acessos:

� de ATRIBUIÇÃO: utilizado para definir um valor para o atributo. Denominado comumente de método set.

� de VERIFICAÇÃO: utilizado para verificar o valor de um atributo. Denominado comumente de método get.

O método de ATRIBUIÇÃO tem a seguinte assinatura e o seguinte algoritmo:

publico setAtributo (tipoAtributo parametro) inicio atributo = parâmetro fim

O método de VERIFICAÇÃO tem a seguinte assinatura e o seguinte algoritmo:

tipoAtributo getAtributo () inicio retornar atributo fim

5.6. CONSTRUTORES

Os objetos são instâncias de uma classe.

Para serem utilizados os objetos precisam ser CRIADOS.

A criação de objetos é feita através de MÉTODOS especiais denominados de

CONSTRUTORES.

Os CONSTRUTORES normalmente são utilizados para a inicialização de atributos de um

objeto. Neste caso eles podem substituir os métodos de acesso de ATRIBUIÇÃO

(setters).

A estrutura de um construtor é dada como segue:

publico nomeDaClasse (<parametros>) inicio <expressões> fim

Um CONSTRUTOR é um método público e tem o mesmo nome da classe.

46

CONSTRUTORES não têm retorno, mas podem ter parâmetros com os valores de

inicialização dos atributos.

IMPORTANTE: um atributo TEM QUE ser inicializado no CONSTRUTOR quando ele é

fundamental para a existência do objeto.

5.7. ESTRUTURA DE UM PROGRAMA OO

A boa prática de programação recomenda que o programador deva separar a parte lógica

do programa da interface com o usuário.

Assim, em nossos programas orientados a objetos SEMPRE teremos no mínimo 2

classes:

� a classe principal: responsável pela interface com o usuário (leitura e escrita dos dados) e criação dos objetos necessários para a solução do problema. Doravante esta classe será denominada de main;

� a classe do modelo: responsável por executar as tarefas que solucionam a situação-problema proposta.

Neste caso dizemos que há uma associação entre as classes.

Deste modo, usaremos o seguinte modelo de arquitetura em nossas aplicações:

FIGURA 6 - RELAÇÃO ENTRE A CLASSE PRINCIPAL E A CLASSE DO MODELO

A classe principal tem a função de prover as funcionalidades descritas nos casos de uso.

Deste modo ela terá sempre as seguintes tarefas fundamentais:

� CRIAR O(S) OBJETO(S) da(s) classe(s) do modelo;

� OBTER do usuário através do dispositivo de entrada (teclado) OS DADOS necessários para inicializar a classe do modelo;

� PASSAR OS DADOS obtidos para a classe do modelo;

� CHAMAR OS MÉTODOS da classe do modelo necessários para a slução do problema proposto;

� OBTER da classe do modelo OS RESULTADOS do problema;

CLASSE PRINCIPAL

(classe main)

CLASSE DO MODELO

(Lógica do

Problema)

47

� INFORMAR ao usuário através do dispositivo de saída (vídeo) OS RESULTADOS obtidos;

A classe do modelo terá sempre as seguintes tarefas fundamentais:

� RECEBER os dados da classe principal;

� PROCESSAR os dados recebidos da classe principal;

� DISPONIBILIZAR os resultados do processamento para a classe principal.

48

6. INTRODUÇÃO À LINGUAGEM JAVA

Origem da linguagem:

� linguagem originalmente desenvolvida para eletrodomésticos, portanto, simples e portável;

� foi projetada para ser uma linguagem com características modernas de programação;

� nasceu considerando a Internet como ambiente operacional.

Principais características:

� propósito geral;

� orientada a objetos e fortemente tipada;

� independente de plataforma ou sistema operacional (hardware e software);

� vários fornecedores de ambientes de desenvolvimento;

� gerência automática de memória (garbage collector) sem ponteiros e alocação direta de memória;

� escalabilidade das aplicações.

Como funciona:

� compilação do Fonte (.java) para bytecode da Java Virtual Machine (JVM)

� interpretação e execução do bytecode (.class)

Leia mais em:

JANDL JÚNIOR, Peter. Java 5: guia de consulta rápida. São Paulo : Novatec, 2006. 136 p, il. pg. 4.

6.1. ESTRUTURA DE UM PROGRAMA JAVA

Um programa Java pode ser executado de diversas formas: no contexto de uma aplicação

desktop, como um applet na WEB, ou como uma aplicação JSP. No nosso contexto,

trataremos de uma aplicação desktop.

Para poder ser executado um programa em Java como uma aplicação desktop, tem que

existir uma classe com uma função denominada main() , através da qual o programa em

Java é iniciado.

A classe com a função main() , também denominada Principal, pode ativar outras classes

conforme pode ser visualizado na figura a seguir.

FIGURA 7 - ATIVAÇÃO DE OUTRAS CLASSES A PARTIR DO MAIN.

Normalmente uma classe Principal não tem atributos ou métodos, mas apenas a criação

de outras classes e inicialização do programa. Isto não é uma regra e varia do gosto de

cada programador. Entretanto, é uma boa prática de programação.

O exemplo a seguir permite verificar a declaração de uma função main() em um classe

Principal:

public class Principal { public static void main(String[] args) { System.out.println (“Minha primeira classe em Java”); }

A classe System, apresentada no exemplo, permite escrever um texto em modo

caractere.

A estrutura básica de uma classe em Java é apresentada a seguir:

public class Nome_da_classe { //declaração dos atributos //método construtor public Nome_da_classe() { } //declaração e implementação dos métodos }

Deve-se notar o uso de chaves para iniciar ({) e fechar (}) uma classe em Java.

O construtor é um método de inicialização da classe. Ele também é delimitado por

chaves, assim como todos os métodos em Java. O construtor e os métodos serão vistos

mais adiante.

Por convenção o nome de uma classe sempre é iniciado por letra maiúscula.

Exemplo: codificação da classe para calcular a largura da sala. /** Esta classe define uma sala

50

* @author Maurício Capobianco Lopes * @version %I%, %G% */ public class Sala { //contém as dimensões da sala private double largura; private double comprimento; /**Método construtor da classe */ public Sala () { } /**Define a largura da sala */ public void setLargura (double largura) { this.largura = largura; } /**Define o comprimento da sala */ public void setComprimento (double comprimento) { this.comprimento = comprimento; } /** Calcula a área da sala */ public double calcularArea() { return largura * comprimento; } }

É importante ressaltar que novas e boas práticas de programação nos permitirão melhorar

esta classe no futuro.

Leia mais em:

JANDL JÚNIOR, Peter. Java 5: guia de consulta rápida. São Paulo : Novatec, 2006. 136

p, il. pgs. 5 a 7.

6.2. PALAVRAS RESERVADAS E IDENTIFICADORES EM JAVA

Palavras reservadas são todos os nome pré-existentes na linguagem que tem algum

significado e não podem ser utilizadas pelo programador para definir nomes criados por

ele.

Exemplos de palavras reservadas: public, class, int, double, etc.

Identificadores são todos os nomes criados pelo programador. Os identificadores são

utilizados para nomear classe, atributos e métodos.

51

Um identificador em Java deve sempre iniciar com uma letra, podendo a seguir ter

qualquer combinação de letras (a..z), números (0..9) e do caractere sublinhado (_).

Observe que nenhum outro símbolo ou espaço em branco é permitido em um

identificador.

Java é chamada de case-sensitive, ou seja, as letras minúsculas e maiúsculas são

diferentes. Exemplo: teste é diferente de TESTE que por sua vez é diferente de Teste que

é diferente de TestE e assim por diante.

Leia mais em:

JANDL JÚNIOR, Peter. Java 5: guia de consulta rápida. São Paulo : Novatec, 2006. 136

p, il. pg. 6, 8 e 9.

6.3. TIPOS DE DADOS PRIMITIVOS

Os tipos de dados primitivos são os tipos básicos de uma linguagem.

Em Java eles são:

� Numéricos (inteiros):

Tipo Tamanho (em bits)

Domínio

byte 8 -128 .. 127 short 16 -32.768 .. 32.767

int 32 -2.147.483.648 .. 2.147.483.647

long (literal: L) 64 -2^64 .. 2^64-1

� Numéricos (reais):

Tipo Tamanho (em bits)

Domínio Dígitos Significativos

float (literal: f) 32 1.4 * 10-45 .. 3.4 * 1038 7-8

double (literal: d) 64 5.0 * 10-324 .. 1.8 * 10308 15-16

� Alfanuméricos:

Tipo Tamanho (em bits)

Armazenamento

char 16 1 caracter UNICODE

� Lógicos:

Tipo Tamanho (em bits)

Armazenamento

boolean 1 true ou false

52

O Java possui ainda o tipo void que não armazena nenhum conteúdo.

Leia mais em:

JANDL JÚNIOR, Peter. Java 5: guia de consulta rápida. São Paulo : Novatec, 2006. 136

p, il. pg. 7.

6.3.1. CONVERSÃO DE TIPOS DE DADOS

Os tipos de dados em Java podem ser convertidos utilizando-se o nome do tipo à frente

da operação que se deseja converter.

Esta operação é denominada de typecast.

Exemplos: char a = ‘5’; double y = 7.6; int i; long j = 10; double x; //converter um caractere para um número inteiro. Não é atribuído 5 mas sim o código UNICODE do símbolo 5 i = (int) a; //converter um real para inteiro i = (int) x; //converter um inteiro para um real x = (double) j;

Leia mais em:

JANDL JÚNIOR, Peter. Java 5: guia de consulta rápida. São Paulo : Novatec, 2006. 136

p, il. pg. 75.

6.3.2. CLASSE STRING

Uma cadeia de caracteres em Java é denominada de String.

Uma String não é um tipo primitivo, mas sim uma classe e, portanto, seu nome é iniciado

com uma letra maiúscula.

O tamanho de uma String é limitado à memória disponível.

Um char é representado entre apóstrofos (Ex: ‘a’), enquanto uma String é representado

entre aspas (Ex: “a”).

53

6.3.2.1. OPERADORES E MÉTODOS DE STRINGS

A classe String tem o operador + para a concatenação entre strings.

String nome = “Silva” + “sauro”;

Principais métodos da classe String

Funcionalidade Método comparar dois strings e retornar verdadeiro ou falso boolean equals(String s) comparar dois strings ignorando maiúscula e minúsculas

boolean equalsIgnoreCase(String s)

retornar o número de caracteres da String int length() procurar o string s e retornar a posição onde encontrou. Se não encontrou retorna -1

int indexOf(String s)

retornar o caractere na posição i da string char charAt(int i)

6.3.2.2. CONVERSÃO DE STRINGS

Uma necessidade muito comum dos programadores Java é converter uma String para um

tipo primitivo ou vice-versa.

A tabela a seguir apresenta os principais métodos de conversão:

Funcionalidade Método String para inteiro Integer.parseInt (String s); String para real Double parseDouble (String S) Qualquer tipo primitivo para String String.valueOf (valor)

Leia mais em:

JANDL JÚNIOR, Peter. Java 5: guia de consulta rápida. São Paulo : Novatec, 2006. 136 p, il. pg. 75.

6.4. DEFINIÇÃO DE ATRIBUTOS

A definição de atributos em uma classe Java pode ser feita do seguinte modo:

qualificador tipo nome_atributo; ou qualificador tipo nome_atributo = valor; ou qualificador final tipo nome_atributo = valor; onde: qualificador: informa se o atributo é público ou privado; tipo : é o tipo do atributo; nome_atributo : é o nome dado ao atributo; valor : inicialização do atributo; final : é um qualificador (palavra reservada) que indica que o valor do atributo não pode ser alterado.

54

Exemplos : private char letra; private int numero = 10; private final double tamanho = 50;

Em função do encapsulamento, os atributos devem ser precedidos do seu qualificador de

acesso. Neste caso usaremos sempre a palavra private.

Leia mais em:

JANDL JÚNIOR, Peter. Java 5: guia de consulta rápida. São Paulo : Novatec, 2006. 136

p, il. pg. 9 e 30.

6.5. MÉTODOS

Métodos são as funções que permitem realizar operações sobre o objeto.

A definição de métodos em uma classe em Java pode ser feita do seguinte modo:

qualificador tipo nome_método ([parâmetros]) { bloco de instruções [return expressão] } onde: qualificador : informa se o método é público ou privado; tipo : é o tipo do valor de retorno do método; nome_método : é o nome dado ao método; parâmetros : são os dados de entrada passados para o método para que o mesmo possa ser executado. Estão entre colchetes ([]), pois são opcionais em um método; bloco de instruções : são as instruções realizadas pelo método para o processamento dos dados; return : indica que o método deve ser finalizado retornando o valor que é o resultado da expressão. Também é opcional no caso de um método do tipo void.

As instruções são dadas por comandos ou expressões.

Em Java as instruções sempre terminam com ponto-e-vírgula (;).

Leia mais em:

JANDL JÚNIOR, Peter. Java 5: guia de consulta rápida. São Paulo : Novatec, 2006. 136 p, il. pg. 31.

6.6. EXPRESSÕES

As expressões denotam chamadas de métodos ou operações sobre os dados de uma

classe. As expressões envolvem o uso de operadores.

55

6.6.1. OPERADOR DE ATRIBUIÇÃO

O operador de atribuição na linguagem Java é o sinal de igual que representa a atribuição

da expressão à direita a variável à esquerda.

Exemplos: x = 100; y = x + 3;

6.6.2. OPERADORES ARITMÉTICOS

Os operadores aritméticos em Java são:

Operador Exemplo Comentário ++ ++x ou x++ Soma 1 em x antes ou depois de usar a variável -- --x ou x-- Subtrai 1 em x antes ou depois de usar a variável + x + y Soma o conteúdo de x e y - x - y Subtrai o conteúdo de y do conteúdo de x * x * y Multiplica x por y / x / y Obtém o quociente de x por y

% x % y Obtém o resto da divisão de x por y

Outros operadores aritméticos são:

Operador Exemplo Comentário + = X + = Y Equivale a x = x + y - = X - = Y Equivale a x = x - y * = X * = Y Equivale a x = x * y / = X / = Y Equivale a x = x / y

% = X % = Y Equivale a x = x % y

6.6.3. OPERADORES RELACIONAIS

Os operadores relacionais em Java são:

Operador Exemplo Comentário == x == y Conteúdo de x é igual ao de y != x != y Conteúdo de x é diferente de y <= x <= y Conteúdo de x é menor ou igual ao de y >= x >= y Conteúdo de x é maior ou igual ao de y < x < y Conteúdo de x é menor que o de y > x > y Conteúdo de x é maior que o de y

56

6.6.4. OPERADORES LÓGICOS

Os operadores lógicos são:

Operação Operador E &&

OU || NEGAÇÃO !

Leia mais em:

JANDL JÚNIOR, Peter. Java 5: guia de consulta rápida. São Paulo : Novatec, 2006. 136

p, il. pgs. 14 a 16.

6.7. ENCAPSULAMENTO

Conforme já visto anteriormente, em uma linguagem orientada a objetos, os atributos são

encapsulados, ou seja, só podem ser acessados através de métodos.

Assim, para que se possa atribuir um valor ao atributo ou pegar o seu conteúdo deve-se

criar métodos específicos para esta tarefa denominados comumente de set e get .

O método set permite definir um valor para o atributo.

O método get permite obter um valor de um atributo.

6.7.1. MÉTODO SET

O método set tem a seguinte estrutura:

public void setNomeAtributo (tipo nomeParametro) { this.nomeParametro = nomeParametro; } Exemplo: //classe public class Pessoa { //atributo da classe private String nome; //método que permite à pessoa receber um nome public void setNome (String nome) { this.nome = nome; } }

Deste modo, o valor passado como parâmetro - denominado de nomeParametro - é

atribuído ao valor do atributo da classe.

57

O qualificador this é usado para referenciar o objeto dentro da própria classe.

O método set pode ter consistências para verificar se um determinado valor pode ser

armazenado no objeto.

6.7.2. MÉTODO GET

O método get tem a seguinte estrutura:

public tipo getNomeAtributo () { return nomeAtributo; } Exemplo: (continuando o exemplo de pessoa apresentado anteriomente no set) //método que permite verificar o nome da pessoa public String getNome () { return nome; }

Neste caso, o conteúdo armazenado no atributo é retornado para o método que solicitou a

informação ao objeto.

O método get deve ter um tipo idêntico ao do atributo que ele irá retornar.

O qualificador return é usado para encerrar a execução de um método e retornar o valor

que se deseja.

Leia mais em:

JANDL JÚNIOR, Peter. Java 5: guia de consulta rápida. São Paulo : Novatec, 2006. 136

p, il. pg. 32 e 37.

6.8. CONSTRUTOR

Para que um objeto seja utilizado ele precisa ser criado.

Um construtor é executado no momento de criação de um objeto.

Os construtores normalmente são utilizados para a inicialização de atributos com valores

diferentes do valor default.

Os construtores devem ter o mesmo nome da classe e não podem retornar um valor.

58

Estrutura de um construtor:

//método construtor public Nome_da_classe() { }

Os construtores podem ter parâmetros para a inicialização dos atributos.

6.9. CRIAÇÃO DE UM OBJETO

Um objeto em Java é criado chamando-se o método new().

A chamada do método new() cria um endereço de memória (handle) para o objeto,

permitindo que o mesmo possa ser utilizado (receber e informar valores e proceder

cálculos ou operações).

O endereço de memória alocado para o objeto deve ser armazenado em uma variável do

tipo da classe do objeto que se deseja criar.

Exemplo de uso da classe Sala:

import java.util.Scanner; public class SalaTXT { public static void main(String[] args) { //criar o objeto Sala sala = new Sala(); //criar o objeto de leitura dos dados Scanner s = new Scanner (System.in); //ler dados e enviá-los ao objeto sala System.out.println("Digite o comprimento"); sala.setComprimento(s.nextDouble()); System.out.println("Digite a largura"); sala.setLargura(s.nextDouble()); //calcular e informar a área System.out.println("Área="+sala.calcularArea()); } }

Leia mais em:

JANDL JÚNIOR, Peter. Java 5: guia de consulta rápida. São Paulo : Novatec, 2006. 136

p, il. pg. 34.

59

6.10. PACOTES E CLASSES ESTÁTICAS

A linguagem Java oferece muitas classes prontas, com funções para realizar as mais

diversas tarefas.

Estas classes são agrupadas em pacotes (packages).

Os pacotes agrupam classes com características comuns.

Os pacotes disponibilizados pela linguagem podem ser conhecidos em

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

Assim, ao utilizar uma função de um pacote em java é necessário fazer sua importação

através da diretiva import.

No item sobre criação de objetos há um exemplo de importação da classe Scanner.

import java.util.Scanner;

O programador pode criar seus próprios pacotes.

Algumas classes não precisam ser importadas e nem instanciadas. Estas classes têm a

característica de serem estáticas e já estarem disponíveis pela API da linguagem. É o

caso da classe System.

Leia mais em:

JANDL JÚNIOR, Peter. Java 5: guia de consulta rápida. São Paulo : Novatec, 2006. 136

p, il. pg. 42 e 61.

6.11. CLASSES E FUNÇÕES DE ENTRADA E SAÍDA

Existem diversas classes para entrada e saída de dados em Java. Neste curso usaremos

as seguintes:

� Scanner para entrada;

� System para saída.

A classe Scanner precisa da criação de um objeto para ser utilizada, do seguinte modo:

Scanner s = new Scanner (System.in);

O parâmetro System.in no constructor da classe indica que a leitura é feita do teclado.

Alguns métodos disponíveis para ler os valores são:

60

� nextInt(): lê um valor inteiro;

� nextDouble(): lê um número real;

� next(): lê um string;

� nextBoolean(): lê um valor lógico;

Um exemplo de uso destes métodos pode ser visto no item sobre criação de objetos.

A classe Scanner pertence ao pacote java.util.Scaner e portanto de vê ser importada.

Para a escrita de dados em vídeo utiliza-se diretamente a classe System sem a

necessidade de criação de um objeto.

Na classe System utiliza-se o objeto out e em seguida podem ser usados os métodos:

� println: para exibir texto ou valores sem formatação;

� printf: para exibir texto ou valores formatados.

Exemplos de uso do método System.out.println já foram passados anteriormente.

Leia mais em:

JANDL JÚNIOR, Peter. Java 5: guia de consulta rápida. São Paulo : Novatec, 2006. 136

p, il. pg. 10.

6.12. DOCUMENTAÇÃO DE PROGRAMAS

A documentação de programas tem diversos objetivos, entre os quais se destacam:

� facilitar sua manutenção;

� manter um histórico de utilização;

� facilitar a consulta e reuso das implementaçlões realizadas

Em java a documentação é feita do seguinte modo:

� De única linha //

// Exibe apenas a linha como comentário

� De uma ou mais linhas /* */

/* comentário que vai se estendendo até fechar com */

� De documentação /** */

/** Indicam que o comentário deve ser inserido em qualquer documentação gerada automaticamente pelo javadoc . */

61

O javadoc é uma documentação padrão em arquivos HTML para programas Java. A

documentação em Java deve inserir diversos tags que permitem identificar informações

sobre a classe. Algumas tag importantes são:

� @author : descreve o autor da classe

� @version : descreve o número da versão atual

� @param : descreve os parâmetros de um método

� @return : descreve o valor retornado por um método

Além de uma boa documentação, os programas devem conter uma identação, ou seja,

recuos com espaços em branco para facilitar a visualização de sua estrutura.

Leia mais em:

JANDL JÚNIOR, Peter. Java 5: guia de consulta rápida. São Paulo : Novatec, 2006. 136

p, il. pg. 6.

6.13. EXERCÍCIOS PROPOSTOS

1. Um banco tem o número e o saldo da conta corrente de um cliente. Baseado nisto, forneça uma solução utilizando a metodologia proposta que permita a retirada e o saque de dinheiro da conta, atualizando e informando o seu saldo.

2. Uma pessoa tem seu nome, cpf, rg e data de nascimento (dia, mês e ano). Descreva uma solução utilizando a metodologia proposta onde dada uma data qualquer (dia, mês, ano), informe a idade da pessoa (em anos) nesta data.

7. INTERFACE GRÁFICA

Nesta seção são abordados os aspectos relacionados a criação de aplicações gráficas,

conhecidas inicialmente como AWT – Abstract Windows Toolkit. Nas sucessivas versões

do Java, o AWT foi substituído pelo Swing, uma biblioteca pertencente a biblioteca JFC-

Java Foundation Classes. Existem diversas APIs para construção de interfaces gráficas

em Java. Entre elas destacam-se: AWT, SWT, Swing e JSF.

Pela característica das aplicações desenvolvidas na disciplina será utilizada a API Swing.

A API Swing apresenta diversos componentes gráficos para construção de interfaces com

o usuário em Java.

A diferença básica entre as classes do Swing em relação às do pacote AWT está na

forma de denominar os componentes. Em Swing acrescenta-se a letra “J” no início do

nome da classe de cada compontente. Asim, a classe Button (AWT) passou a denominar-

se JButton (Swing).

As aplicações gráficas são aquelas que possibilitam a criação de uma GUI (Graphical

User Interface – Interafce Gráfica do Usuário). Assim, ao desenvolver uma aplicação

dotada de uma GUI, é necessário definir quais componentes serão utilizados e qual a

disposição dos mesmos na janela.

O swing possui inúmeras classes que podem ser utilizadas na construção de uma GUI.

Estes componentes pertencem ao pacote javax.swing e estão destacados na figura a

seguir:

FIGURA 8 - COMPONENTES DO PACOTE JAVAX.SWING

Todas as classes elaboradas nesta seção necessitam de diversas classes externas tanto

do pacote swing como do pacote AWT. Assim, via de regra, os programas terão pelo

menos três linhas com a diretiva “import” apontando para as classes externas, conforme

as declarações a seguir:

import java.awt.*; //permite a utilização de classes do pacote AWT e de constantes numéricas import Java.awt.event.*;// usado para proces. de eventos como clique do mouse, Enter,etc import javax.swing.*;// permite a utilização de diversas classes do pacote swing.

A Figura 9 ilustra a estrutura de um código mesclando recursos de AWT (bOld ou Button

na versão AWT) e swing (bNew ou Button na versão swing).

FIGURA 9 - EXEMPLO DE FRAME AWT X SWING.

Fonte: http://www-static.cc.gatech.edu/classes/cs4812_99_winter/

A Figura 10 apresenta o resultado da execução do código apresentado na Figura 9.

FIGURA 10 - EXEMPLO DE BOTÃO AWT E SWING.

Fonte: http://www-static.cc.gatech.edu/classes/cs4812_99_winter/

7.1. FRAMES

Um Frame é uma classe do pacote AWT responsável pela criação de janelas (similares

aquelas criadas no ambiente Windows).

A classe Frame gera uma janela com barra de título, bordas e pode ter outros

componentes em seu interior(Figura 11).

FIGURA 11 - ARQUITETURA DE UM JFRAME.

A classe JRootPane é um container que possui um JLayeredPane (contendo o Menu e o

ContentPane) e um componente GlassPane (transparente) onde são instalados novos

componentes. A Figura 12 ilustra esta estrutura..

FIGURA 12 - JROOTPANE.

O exemplo a seguir ilustra a criação de uma janela através da utilização da classe JFrame

do pacote swing (Furgeri; 2006,pág 181).

import java.awt.*; //permite a utilização de classes do pacote AWT e de constantes numéricas import Java.awt.event.*;// usado para proces. de eventos como clique do mouse, Enter,etc import javax.swing.*;// permite a utilização de diversas classes do pacote swing. public InterfaceGUI() { //construtor da classe this.setTitle("Titulo da janela"); setSize(400,50); //dimensões da janela: largura, comprimento em pixels setLocation(150,150); //posição do canto esquerdo e topo da tela setResizable(false); //a janela não pode ser redimensionada } void fecharJanela() { //método que registra a operação de fechar a janela ao clicar sobre o "x". this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public static void main (String args[]) { //método para teste da janela JFrame janela = new InterfaceGUI(); //cria um objeto do tipo Janela janela.setVisible(true); //a janela é criada e exibida na tela } }

A execução do código acima apresenta a janela da Figura 13.

FIGURA 13 - PRIMEIRA JANELA.

O método setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) é responsável por

implementar o comportamento padrão para a saída da aplicação quando o botão é

pressionado. Outras constantes que podem ser utilizadas são (Furgeri; 2006,pág 181):

� JFrame.HIDE_ON_CLOSE : oculta a janela quando fechada

� JFrame.DO_NOTHING_ON_CLOSE : não faz nada, apenas desativa o botão de encerramento;

� JFrame.DISPOSE_ON_CLOSE: a janela desaparece e os recursos utilizados pela classe são liberados.

Conforme Furgeri (2006,pág 178), os métodos mais utilizados da classe JFrame são:

� JFrame() : cria uma janela vazia

� JFrame(String titulo): cria uma janela vazia com o título definido pela String “titulo”

� getTitle(): método que retorna o título da janela

� isResizable(): método que retorna se a janela é ou não redimensionável

66

� setResizable(): método que define se a janela é ou não redimensionável

� setTitle(String titulo): método que especifica o título da janela

7.1.1. INCLUSÃO DE TEXTOS NA JANELA

Para a inclusão de textos nos JFrames utiliza-se a classe JLabel. É possível controlar

várias propriedades do texto a ser utilizado, tais como: alinhamento, tipo de letra,

tamanho, cor, etc.

import java.awt.*; import javax.swing.*; public class InterfaceGUILabel extends JFrame { public InterfaceGUILabel() { setTitle("Teste de inserção de rótulos (labels) numa janela"); setSize(350,120); setLocation(50,50); //cria um objeto a ser utilizado como cor de fundo no padrao RGB. //Os números entre parentesis referem-se as tonalidades das cores vermelha,verde e azul. //Os numeros para cada tonalidade podem variar de no mímino 0 ao máximo de 255 e //sua mistura forma uma cor específica. Color corDeFundo = new Color(220,220,220); getContentPane().setBackground(corDeFundo);//define a cor de fundo da janela no padrão RGB JLabel label1 = new JLabel(" Rótulo 1: ",JLabel.LEFT);//cria um rótulo alinhado a esquerda label1.setForeground(Color.red); //define a cor do texto JLabel label2 = new JLabel(" Rótulo 2:",JLabel.CENTER); Font fonteDoTexto = new Font ("Arial",Font.ITALIC,20); label2.setFont(fonteDoTexto); label2.setForeground(Color.blue);//define a cor do texto getContentPane().setLayout(new GridLayout(4,1)); // gerenciamento de layout getContentPane().add(label1); //adiciona o label ao frame na primeira linha //outra forma de utilizar o método getContentPane() Container panel = getContentPane(); panel.add(label2);//adiciona o label ao frame na segunda linha } void fecharJanela() { //método que registra a operação de fechar a janela ao clicar sobre o "x". this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } }

A classe acima pode ser testada a partir do seguinte trecho de código:

.... JFrame janela2 = new InterfaceGUILabel(); //cria um objeto do tipo Janela janela2.setVisible(true); //a janela é criada e exibida na tela .....

A Figura 19 apresenta a janela construída a partir do código acima.

FIGURA 14- JANELA COM RÓTULOS

ATENÇÃO: o método getContentPane() retorna uma referência ao objeto que controla a

janela que estamos construindo. Como a janela é representada por um objeto, para que

seja possível operar sobre o mesmo precisamos de uma referência. Uma outra forma

mais explícita de realizar a mesma operação poderia ser descrita da seguinte forma:

.... Container panel = getContentPane(); panel .add(label2);//adiciona o label ao frame na segunda linha .....

A classe Container pertence ao pacote AWT e representa um objeto que contém todos os

demais componentes de uma janela.

A título de curiosidade, a janela da Figura 14 pode ser reconfigurada de forma a

apresentar uma aparência diferente daquela padrão do Windows. O trecho de código

abaixo ilustra esta possibilidade:

.... JFrame janela3 = new InterfaceGUILabel(); //cria um objeto do tipo Janela janela3.setUndecorated(true); //desenha um frame completamente sem bordas e botões janela3.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);//altera o modo de exibição janela3.setVisible(true); //a janela é criada e exibida na tela .....

A Figura 15 apresenta o resultado:

FIGURA 15- JANELA REDECORADA.

O método setWindowDecorationStyle() define um novo estilo de janela. No exemplo,

JRootPane.FRAME define o estilo padrão utilizado pela JVM com os botões de minimizar,

maximizar e encerrar.

Você pode testar outras variações que podem ser obtidas utilizando-se as constantes:

� JRootPane.NONE;

� JRootPane.COLOR_CHOOSER_DIALOG;

� JRootPane.ERROR_DIALOG;

� JRootPane.FILE_CHOOSER_DIALOG;

� JRootPane.INFORMATION_DIALOG;

� JRootPane.PLAIN_DIALOG;

� JRootPane.QUESTION_DIALOG;

� JRootPane.WARNING_DIALOG.

Conforme Furgeri (2006,pág 182), os métodos mais utilizados da classe JLabel são:

� JLabel() : cria um rótulo vazio, ou seja, sem texto;

� JLabel(String txt) : cria um rótulo com o texto passado como parâmetro;

� JLabel(String txt, int alin): cria um rótulo com o alinhamento explícito;

� JLabel(String txt, Image im): cria um rótulo com texto e imagem ;

� JLabel(String txt, Image im, int alin): cria um rótulo com texto, imagem e alinhamento;

� getText(): retorna o texto de um rótulo;

� setText(): altera o conteúdo do texto de um rótulo.

O seguinte trecho de código ilustra a utilização da imagem ao lado do rótulo:

.... ImageIcon icone = new ImageIcon ("./imagem.gif"); JLabel label2 = new JLabel(" Rótulo 2:",icone,JLabel.CENTER); .....

Isto resulta na seguinte janela:

69

FIGURA 16- RÓTULO COM IMAGEM

7.2. GERENCIADORES DE LAYOUT

Cada componente a ser visualizado nas janelas gráficas, tais como: rótulos, botões,

caixas de texto, etc., devem ser inseridos em locais predefinidos na janela. Este espaço é

denominado: célula.

Para dividir uma janela em células, é preciso utilizar um gerenciador de layout, ou seja,

um método que controla a maneira como os componentes serão dispostos na janela. Esta

é a função do método setLayout(). Este método é utilizado para definir como o frame será

dividido. No caso do exemplo acima, esta sendo estabelecido que o frame será composto

por uma grade de quatro linhas e uma coluna (4,1) conforme esboçado abaixo:

Célula 1

Célula 2

Célula 3

Célula 4

Caso não tivesse sido definido o tipo de layout a ser utilizado pela janela, o sistema

consideraria que o frame contém somente uma célula.

Por padrão, o Java vem com cinco Gerenciadores de Layout: BorderLayout , BoxLayout ,

FlowLayout , GridBagLayout , GridLayout e um adicional, o CardLayout .

ATENÇÃO: O IDE NetBeans disponibiliza mais opções de Layout. Neste tutorial utilizam-

se o BorderLayout, o GridLayout e o FlowLayout .

� O BorderLayout tenta organizar os objetos em um dentre cinco locais geográficos, representados por constantes na classe BorderLayout (NORTH, SOUTH, EAST, WEST e CENTER), possivelmente com algum afastamento entre eles (NEIMEYER, p.473).

� O GridLayout organiza os componentes em linhas e colunas, como se fosse uma tabela. Eles são adicionados da esquerda para direita e de cima para baixo em uma grade.

� Já o FlowLayout organiza os componentes de forma similar aquela utilizada nos editores de texto, ou seja, preenche a linha até que haja espaço; ao terminar o espaó, muda para a linha seguinte.

70

7.3. EVENTOS

A interação do usuário do programa com as classes definidas pelo programador

normalmente é implementada através de eventos.

Os eventos são blocos de comandos que associam a ocorrência de alguma ação

realizada sobre o sistema a uma possível reação.

Em uma interação baseada em eventos as ações só são realizadas a partir do instante

em que ocorre um evento.

Um evento pode estar associado a:

� clique ou movimento do mouse;

� acionamento do teclado;

� operações sobre janelas (abrir, fechar, criar, redimensionar, mover);

� um temporizador (timer);

� uma falha de hardware ou software.

� etc.

7.3.1. INCLUSÃO DE BOTÕES NAS JANELAS

Para a inclusão de botões nos frames, é utilizada a classe JButton. Da mesma forma que

no JLabel, muitas propriedades podem ser manipuladas em JButton. O exemplo a seguir

ilustra a utilização deste componente (Furgeri; 2006,pág 182):

import java.awt.*; import javax.swing.*; public class InterfaceGUIBotoes extends JFrame implements ActionListener { JButton botao1, botao2; //declara 2 botoes ImageIcon icone = new ImageIcon("./imagem.gif"); public InterfaceGUIBotoes() { //construtor setTitle("Interface com botoes"); setSize(350, 100); setLocation(50, 50); getContentPane().setBackground(new Color(180, 180, 180)); botao1 = new JButton("Busca", icone); botao1.setHorizontalTextPosition(AbstractButton.LEFT); botao1.setBackground(new Color(100, 180, 180)); //cor de fundo botao1.setForeground(Color.black); //cor do título botao1.setFont(new Font("Times", Font.BOLD, 20)); //define a fonte botao1.setEnabled(true); botao1.addActionListener( this);//esta classe deverá tartar os eventos gerados nos botões

botao1.setToolTipText(" Pressione neste botão para realizar uma busca");//dica botao1.setMnemonic(KeyEvent.VK_B); botao2 = new JButton("Cancelar"); botao2.addActionListener(this); //esta classe deverá tartar os eventos gerados nos botões botao2.setMnemonic(KeyEvent.VK_C); botao2.setToolTipText("Pressione aqui para cancelar"); getContentPane().setLayout(new FlowLayout()); //define um gerenciador de layout getContentPane().add(botao1); //adiciona um botão a janela getContentPane().add(botao2);//adiciona o outro botão a janela } //declara o método tratador dos eventos associados aos botões public void actionPerformed (ActionEvent e) { if (e.getSource() == botao1) { System.out.println("O botão 1 foi pressionado!"); } else if (e.getSource() == botao2) { System.out.println("O botão 2 foi pressionado!"); } } void fecharJanela() { //método que registra a operação de fechar a janela ao clicar sobre o "x". this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } }

A execução desta classe constrói a janela apresentada na Figura 17.

FIGURA 17- JANELA COM 2 BOTÕES

Ao passar-se com o mouse sobre o botão Busca, surgirá a dica cadastrada através do

método botao1.setToolTipText(“texto”) conforme apresentado na Figura 18.

FIGURA 18- ATIVAÇÃO DA DICA DO BOTÃO

Para adicionar uma tecla de atalho ao botão, utiliza-se o método setMnemonic() passando como parâmetro uma letra

Da mesma forma que um objeto JLabel, um objeto do tipo botão pode ser inicializado de

três maneiras:

72

� Somente com um texto (o título de um botão);

� Com uma imagem ou,

� Com ambos um texto e uma imagem.

Para definir a posição do texto do botão em relação à imagem inserida no mesmo, utiliza-

se o método setHorizontalTextPosition(. Esta propriedade deve ser definida quando o

botão possuir imagem e texto ao mesmo tempo. A convenção padrão estabelece que a

imagem aparece ao lado esquerdo do texto, contudo, isto pode ser modificado pela

constante LEFT que fará com que o texto apareça ao lado esquerdo da imagem. Da

mesma forma, pode-se alterar o alinhamento vertical do texto através do método:

setVerticalTextPosition() utilizando as constantes TOP (topo) ou BOTTOM (abaixo)

(Furgeri; 2006,pág 184).

Além destas, outra propriedade importante refere-se ao fato de que um botão pode ser

criado e não estar habilitado para o usuário clicar. Em algum momento futuro, em função

da lógica da aplicação , o botão terá função e, neste caso, será habilitado. Para

implementar esta funcionalidade, utiliza-se o método setEnabled(true/false).

Em qualquer aplicação em que as ações do usuário devem ser interpretadas pelo

programa quando o mesmo interagir com a janela (clicar em um botão, por exemplo), é

necessária a implementação de uma interface padrão do Java. No exemplo acima, foi

utilizada a interface ActionListener (existem outras interfaces disponíveis que não serão

tratadas neste momento) através da declaração implements ActionListener (Furgeri;

2006,pág 183):

.... public class InterfaceGUIBotoes extends JFrame implements ActionListener { ..... } .....

Quando uma implementação de interface é utilizada, torna-se obrigatório inserir na

aplicação um ou vários métodos que realizarão o processamento dos eventos (seção

7.3.2). Ao contrário de outras linguagens como Delphi e Visual Basic (entre outras), Java

permite definir métodos receptores de eventos, independentemente do objeto que o

gerou. Em outras palavras, é possível utilizar um mesmo método para controlar o clique

em todos os botões de uma mesma janela (Furgeri; 2006,pág 183).

73

7.3.2. TRATADORES DE EVENTOS

Conforme Gonçalves (2007, p. 103), para o processamento dos eventos gerados na

interação com o usuário, o Java utiliza de um pacote chamado java.awt.event. Para os

outros tipos de eventos, que são específicos da biblioteca Swing, é utilizado o pacote

java.swing.event.

As interações dos usuários com os componentes de interface geram eventos. Segundo

Schvepe (2006, p. 17), o mecanismo de tratamento de eventos em Java é formado por

três partes:

a) o objeto origem, isto é, o componente que gerou o evento; b) o evento propriamente dito, ou seja, um objeto que encapsula as informações

necessárias para processar o evento gerado; c) o objeto ouvinte (listener), ou seja, o objeto que é notificado pelo objeto origem

quando ocorre um evento e que usa a informação da notificação para responder ao evento.

Em Java um evento é denominado de Listener . Os listeners são classes criadas

especificamente para o tratamento de eventos. Um Listener é um objeto que é notificado

quando um evento acontece.

O processamento do evento é delegado ao listener no aplicativo. Quando ocorre um

evento existe um mecanismo de aviso (dispatch ) para os listeners daquele evento. O

dispatch nada mais é do que uma delegação para que o listener cuide do tratamento de

evento (RUIZ, 2006).

No Erro! Fonte de referência não encontrada. são descritos os principais eventos que podem

ocorrer em uma aplicação, e em que momento elas ocorrem.

ActionEvent ActionEvent Ocorre quando um botão é pressionado, quando um item de lista recebe um duplo clique ou quando um item de menu é selecionado.

ComponentEvent Ocorre quando um componente é ocultado, movido, redimensionado ou se torna visível.

FocusEvent Ocorre quando um componente recebe ou perde o foco do teclado. ItemEvent Ocorre quando é selecionado um item em uma lista de itens. KeyEvent Ocorre quando se manipula o teclado. MouseEvent Ocorre quando se manipula o mouse (mover, clicar, etc.). WindowEvent Ocorre quando se manipula uma janela (mover, fechar, maximizar, etc.).

QUADRO 1- PRINCIPAIS EVENTOS

Os vários tipos de listeners são especificados através de um uma interface. A Figura 19

exibida abaixo mostra uma hierarquia dos principais listeners do pacote java.awt.

Fonte: Fernandes (2002).

FIGURA 19 - HIERARQUIA DOS PRINCIPAIS LISTENERS.

Um dos métodos, comuns a todos os objetos, chama-se actionPerformed . Como não há

um método para cada evento dos objetos de uma janela, dentro do método

actionPerformed é necessário identificar qual dos objetos é responsável pela geração do

evento. A figura abaixo destaca esta situação:

.... public class InterfaceGUIBotoes extends JFrame implements ActionListener { .... //declara o método tratador dos eventos associados aos botões public void actionPerformed (ActionEvent e) { if (e.getSource() == botao1) { System.out.println("O botão 1 foi pressionado!"); } else if (e.getSource() == botao2) { System.out.println("O botão 2 foi pressionado!"); } } .....

O método e.getSource() retorna uma referência ao objeto que gerou o evento. Através de

um comando IF, verifica-se se o evento foi produzido, por exemplo, pelo objeto botão1.

A figura abaixo caracteriza o funcionamento do método actionPerformed :

FIGURA 20- MÉTODO ACTIONPERFORMED SENDO ATIVADO.

Conforme Furgeri (2006,pág 186), os métodos mais utilizados da classe JButton são:

� JButton() : cria um botão sem texto;

� JButton(String texto): cria um botão com um rótulo;

� JButton(String texto, Image img): cria um botão com rótulo e imagem;

� getLabel(): retorna o rótulo do botão;

� setLabel(String texto): altera o rótulo do botão;

� setEnabled(boolean): define se o botão está habilitado (true) ou não (false);

� setHoritontalTextPosition(): define o tipo de alinhamento horizontal (LEFT/RIGHT);

� setMnemonic(..): define uma tecla que será usada como acionadora do evento em conjunto com a tecla ALT;

� setToolTipText: possibilita atrelar uma mensagem de dica ao botão. Quando o ponteiro do mouse estaciona sobre o botão, a mensagem é exibida;

� setVerticalTextPosition(): define o tipo de alinhamento vertical do texto em relação a uma imagem (TOP/BOTTOM).

A Figura 21 ilustra a utilização de ícones associados a um botão e que alteram a imagem

em função do mouse estar sobre o botão ou não (http://www-

static.cc.gatech.edu/classes/cs4812_99_winter/).

FIGURA 21 - BOTÃO COM ÍCONE ROLLOVER.

7.3.3. INCLUSÃO DE CAIXAS DE TEXTO

A classe JTextField é utilizada para inserir caixas de texto nos frames. Da mesma forma

que os componentes anteriores, há uma série de propriedades cujos conteúdos podem

ser modificados.

O exemplo abaixo demonstra a utilização dos vários componentes a partir de uma

interface de uma calculadora.

import java.awt.*; import javax.swing.*; public class InterfaceGUICaixaTexto extends JFrame implements ActionListener { JButton bt1, bt2, bt3, bt4, bt5; JLabel lab1, lab2, lab3; JTextField txt1, txt2, txt3; public InterfaceGUICaixaTexto() { setTitle("Calculadora"); setBounds(300, 50, 350, 90); getContentPane().setBackground(new Color(150, 150, 150)); getContentPane().setLayout(new GridLayout(3, 4)); lab1 = new JLabel("Num.1"); lab1.setForeground(Color.black); lab2 = new JLabel("Num.2"); lab2.setForeground(Color.black); lab3 = new JLabel("Total"); lab3.setForeground(Color.red); bt1 = new JButton("+"); bt1.addActionListener(this); bt2 = new JButton("-"); bt2.addActionListener(this); bt3 = new JButton("x"); bt3.addActionListener(this); bt4 = new JButton("/"); bt4.addActionListener(this); bt5 = new JButton("Limpar"); bt5.addActionListener(this); bt5.setBackground(Color.black); bt5.setForeground(Color.white);

txt1 = new JTextField(); txt2 = new JTextField(); txt3 = new JTextField(); txt3.setEditable(false); getContentPane().add(lab1); getContentPane().add(txt1); getContentPane().add(bt1); getContentPane().add(bt2); getContentPane().add(lab2); getContentPane().add(txt2); getContentPane().add(bt3); getContentPane().add(bt4); getContentPane().add(lab3); getContentPane().add(txt3); getContentPane().add(bt5); } public void actionPerformed(ActionEvent e) { if (e.getSource() == bt5) { txt1.setText("0"); txt2.setText("0"); txt3.setText(""); return; } float n1 = 0, n2 = 0, result = 0; try { n1 = Float.parseFloat(txt1.getText()); n2 = Float.parseFloat(txt2.getText()); } catch (NumberFormatException erro) { txt3.setText("Erro de formato"); return; } if (e.getSource() == bt1) { result = n1 + n2; } else if (e.getSource() == bt2) { result = n1 - n2; } else if (e.getSource() == bt3) { result = n1 * n2; } else if (e.getSource() == bt4) { result = n1 / n2; } txt3.setText("" + result); } void fecharJanela() { //método que registra a operação de fechar a janela ao clicar sobre o "x". this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } }

A Figura 22 ilustra o resultado da execução do código acima.

FIGURA 22- CALCULADORA

7.4. CRIANDO UM PROJETO COM INTERFACE GRÁFICA USANDO A

FERRAMENTA DO NETBEANS

Esta seção visa fornecer uma simples introdução ao uso do IDE NetBeans, sendo guiado

através de uma aplicação Java com interface de interação com o usuário.

Para criarmos um projeto na IDE os seguintes passo deverão ser seguidos:

d) inicie o NetBeans; e) no IDE, escolha <Arquivo > < Novo Projeto >, como é mostrado na Figura 23;

FIGURA 23 - CRIANDO UM PROJETO.

f) na janela Novo Projeto , expanda a categoria Geral e selecione Aplicação Java como é mostrado na Figura 24;

FIGURA 24 - JANELA "NOVO PROJETO".

g) na página apresentada na Figura 25, em Nome e Localização faça o seguinte:

a. - no Campo Nome do Projeto , escreva “Computador ”, b. - desmarque a opção “Criar Classe Principal ”, c. - clique em Finalizar ;

FIGURA 25 - DETALHES DO PROJETO.

h) expanda o item Pacotes de Código-Fonte (Figura 26). Clique com o botão direito do mouse em <pacote padrão > e selecione <Novo > < Pacote Java >;

FIGURA 26 – SELECIONANDO CRIAR UM NOVO PACOTE.

i) na guia Nome e Localização (Figura 27), digite no campo Nome do Pacote o

nome desejado, por exemplo, “Interface ” e clique em Finalizar . Você poderá observar que o pacote “Interface ” ficou subordinado aos Pacotes de Código-Fonte ;

FIGURA 27 - CRIANDO UM NOVO PACOTE.

j) agora vamos criar a nossa primeira janela, a qual terá por finalidade simular um computador, com teclado e monitor. Clique com o botão direto do mouse em <Interface > e selecione <Novo > e novamente “Formulário JFrame ” (Figura 28);

FIGURA 28 - CRIANDO UM FORMULÁRIO JFRAME.

k) digite um nome para o “Formulário ”, por exemplo, “InputOutput ” e clique no botão

Finalizar (Figura 29);

FIGURA 29 - FINALIZANDO A CRIAÇÃO DE UM FORMULÁRIO JFRAME.

l) pronto, seu formulário foi criado (Figura 30). Apenas é necessário incluir os

componentes para que o formulário fique semelhante ao que conhecemos como um computador. Mas antes de começar a incluir os componentes, vamos abrir um parêntese e falar sobre o Gerenciador de Layout (consulte a seção: 0).

FIGURA 30 - JFRAME CRIADO.

m) continuando com a execução do tutorial, vamos adicionar no JFrame o

Gerenciador de Layout BorderLayout . Para isto, basta clicar com o botão direito do mouse em <JFrame > e < Definir Layout > e finalmente <Border Layout >(Figura 31);

FIGURA 31 - DEFININDO GERENCIADOR DE LAYOUT: BORDERLAYOUT.

n) na Paleta, estão os componentes que podem ser utilizados no JFrame . Para que

eles sejam apenas adicionados, basta clicar uma vez sobre o componente desejado e no desenho do JFrame (Figura 32);

FIGURA 32 - PALETA DE COMPONENTES.

o) para criar o nosso simulador de um computador, colocaremos três JPanel , dois JScrollPane , um JTextArea , um JTextField e dois JLabel (Figura 33). Para tanto execute os seguintes passos:

FIGURA 33 - PALETA DE CONFIGURAÇÃO DE UM JPANEL.

a. colocar no JFrame o JPanel1 , o JPanel2 e o JPanel3 . O JPanel1 deverá

ficar alinhado a Esquerda. Para isto, vá às propriedades do componente, procure o item Direção e escolha “West ”. Faça o mesmo procedimento com

o JPanel2 (configurando-o para East) e o JPanel3 (configurando-o para North ),

b. na propriedade preferredSize coloque para o JPanel1 e o JPanel2 o valor [200,100] e para o JPanel3 [150,30],

c. desmarque a opção enabled do JPanel2 , d. no JPanel3 , use o Gerenciador de Layout GridLayout , e. agora adicionar no JPanel1 um JScrollPane . Dentro do JScrollPane

adicionar um JTextField , f. no JPanel2 , adicione um JScrollPane , depois um JTextArea . Desmarque a

opção editable nas propriedades do JTextArea , g. no JPanel3 , adicione dois JLabel . No JLabel da esquerda coloque a

propriedade text como “Teclado ” e no JLabel da direita como “Monitor ”, conforme a imagem representada naFigura 34;

FIGURA 34 - INSERINDO TRÊS COMPONENTES JPANEL AO JFRAME.

p) a tela de simulação de um computador já está criada. Agora basta programar um

evento que faça com que tudo o que for digitado no “Teclado” seja propagado para o “Monitor” após pressionada a tecla <ENTER>. Para isso, clique com o botão direito do mouse em <jTextField1 > <Eventos > <Action > <actionPerformed >. Uma janela que contém o código fonte será aberta e lá você poderá programar o evento. A Figura 35 apresenta o corpo do método para fazer com que o texto digitado no “Teclado” seja mostrado no “Monitor”, após um <ENTER>;

FIGURA 35 - PROGRAMANDO UM TRATADOR DE EVENTO.

q) no método construtor da classe InputOutput vamos definir um tamanho para o

frame através do método setSize() e também não permitir que o tamanho do frame seja modificado através do método setResizable() . O código fonte do método é apresentado na Figura 36;

FIGURA 36 - MÉTODO CONSTRUTOR DA CLASSE.

r) agora para executar e ver o resultado (Figura 37), salve o projeto e clique no Menu <Executar > <Executar Projeto Principal > ou então utilize o atalho F6 no teclado. Agora seu projeto Computador está pronto.

FIGURA 37 - PROJETO COMPLETO.

85

8. INTEGRANDO O FURBOT COM INTERFACE GRÁFICA

Esta seção descreve como o Furbot pode ser integrado a um ambiente de interface

gráfica.

Até agora você precisava definir um modelo de mundo em XML para que o Furbot

pudesse operar. Existe uma outra forma de fazê-lo utilizando componentes de interface

gráfica.

A nova arquitetura do Furbot que suporta este recurso é detalhada a seguir:

import br.furb.furbot.Furbot; public class ExemploDeFurbot extends Furbot { public ExemploDeFurbot () { //no construtor do furbot, você deve estabelecer os parâmetros gerais de funcionamento do mesmo. this.setTempoEspera(20); //estabelece a “velocidade de execução do furbot this.desbloquear(); // estabelece que o mesmo está desbloqueado } public void inteligencia() throws Exception { // faz o furbot andar pelo mundo ...... } ........ }

O exemplo acima implementa a funcionalidade do robô. Você pode utilizar todos os

recursos estudados até agora. A principal diferença está em que você deve acrescentar

na funcionalidade do construtor a configuração de funcionamento do furbot (que

anteriormente era recuperada a partir do arquivo XML).

O quadro a seguir apresenta uma estrutura geral da tela gráfica a partir da qual são

criados o mundo sobre o qual o furbot irá se movimentar e a própria instancia de furbot

(definida no quadro acima).

Exemplos: import br.furb.furbot.MundoFurbot; // classe que viabiliza a interação com a interface com o usuário import br.furb.furbot.suporte.TamanhoCelula; //classe que estabelece o tamanho da célula public class Apresentacao extends javax.swing.JFrame { //cria um mundo de Furbot com 8 x 5 celulas e tamanho da celula pequena

private MundoFurbot mundo = new MundoFurbot(8,5,TamanhoCelula.Pequena); private ExemploDeFurbot robo; //classe declarada no quadro anterior

86

// cria um JFrame - ver seção 7. public Apresentacao() { initComponents(); setLocationRelativeTo(null); jScrollPane1.setViewportView(mundo ); robo = new ExemploDeFurbot (); mundo.addObjeto(robo,0,0); //a seguir indica ao mundo quais são os botões da interface grafica que comandam // o inicio e fim das operações ( Esta indicação é opcional) mundo.setBotaoExecutar(jButton2); mundo.setBotaoParar(jButton3); // Indica ao mundo qual a area de texto (JTextArea ) que exibira o que o robô // falar (metodo diga) mundo.setConsole(jTextArea1); } // o código abaixo é gerado pelo Netbeans private void initComponents() { jScrollPane1 = new javax.swing.JScrollPane(); jButton2 = new javax.swing.JButton(); jButton3 = new javax.swing.JButton(); jPanel1 = new javax.swing.JPanel(); jLabel1 = new javax.swing.JLabel(); jTextField1 = new javax.swing.JTextField(); jButton1 = new javax.swing.JButton(); jScrollPane2 = new javax.swing.JScrollPane(); jTextArea1 = new javax.swing.JTextArea(); jLabel2 = new javax.swing.JLabel(); jComboBox1 = new javax.swing.JComboBox(); …………. setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); …………. private void jButton3ActionPerformed(java.awt.event .ActionEvent evt) { mundo.parar(); } private void jButton2ActionPerformed(java.awt.event .ActionEvent evt) { robo.setFazCalculo(jComboBox1.getSelectedIndex()); robo.mudarPosicao(0, 0); jTextArea1.setText(""); mundo.executar(); } private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { InteiroPositivo ip = new InteiroPositivo(); ip.setValor(Integer.parseInt(jTextField1.getText())); mundo.addObjeto(ip); jTextField1.selectAll(); jTextField1.requestFocus(); }

87

public static void main(String args[]) { java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new Apresentacao().setVisible(true); } }); } }

O exemplo acima implementa a funcionalidade do robô. Voce pode utilizar todos os

recursos estudados até agora. A principal diferença está em que você deve acrescentar

na funcionalidade do construtor a configuração de funcionamento do furbot (que

anteriormente era recuperada a partir do arquivo XML).

88

9. ESTRUTURAS DE CONTROLE EM NÍVEL DE INSTRUÇÃO

As estruturas de controle em nível de instrução são (entre parênteses está sua

representação em Java):

� SELEÇÃO: executam instruções de acordo com uma determinada condição.

o simples: se (if)

o encadeada: se-então (if – else)

o múltipla: escolha (switch case)

� REPETIÇÃO: executam instruções em um número repetido de vezes. Também são chamadas de “laços” ou loop.

o para-faça (for)

o enquanto-faça (while / do – while)

9.1. SELEÇAO SIMPLES (IF)

As estruturas de seleção simples apresentam apenas uma condição.

Exemplos: Se está chovendo então abra o guarda-chuva Se a biblioteca está aberta então empreste o livre Se tem açúcar então adoce a limonada Se não está frio então tire o casaco

Sintaxe em Português Estruturado:

se <expressão-lógica> então <seqüência-de-comandos> fimse Sintaxe em Java:

if (expressão-lógica) { <seqüência-de-comandos em Java> }

Em Java, se houver apenas um comando a ser executado dentro da estrutura de controle,

as chaves podem ser dispensadas. No caso de mais de um comando, elas são

obrigatórias.

Exemplo simplificado para verificar se um aluno está aprovado em uma disciplina:

89

Em Português Estruturado: se média do aluno >= 6.0 então situação do aluno = “Aprovado” fimse Em Java: if (aluno.media >= 6) aluno.situacao = “Aprovado”;

Leia mais em:

JANDL JÚNIOR, Peter. Java 5: guia de consulta rápida. São Paulo : Novatec, 2006. 136 p, il. pg. 19.

9.2. SELEÇÃO ENCADEADA (IF – ELSE)

As estruturas de seleção encadeadas apresentam alternativas de ação diferentes de

acordo com a situação avaliada.

Exemplos: Se está chovendo então vou de carro senão vou de ônibus Se gosto de limonada com açúcar então coloco açúcar na limonada senão se gosto da limonada com adoçante então coloco adoçante na limonada

Sintaxe em Português Estruturado

se <expressão-lógica> então <seqüência-de-comandos-expressão-verdadeira> senão <seqüência-de-comandos-expressão-falsa> fimse

Sintaxe em Java

if (expressão-lógica) { <seqüência-de-comandos-expressão-verdadeira> } else { <seqüência-de-comandos-expressão-falsa> }

Um exemplo simplificado para informar se um aluno está aprovado ou reprovado em uma

disciplina é representado no quadro a seguir:

90

Em Português Estruturado: se nota do aluno >= 6.0 entao situação do aluno = “aprovado” senão situação do aluno = “reprovado” fimse Em Java: if (aluno.nota >= 6) aluno.situacao = “aprovado”; else

aluno.situacao = “reprovado”;

Leia mais em:

JANDL JÚNIOR, Peter. Java 5: guia de consulta rápida. São Paulo : Novatec, 2006. 136

p, il. pg. 19.

9.3. SELEÇÃO COMPOSTA

As estruturas de seleção compostas apresentam mais de uma condição e podem ser

classificadas em : simples ou encadeadas.

Devem ser utilizadas com os operadores lógicos E ou OU.

Exemplos: Se está com sede e tem dinheiro então compre uma garrafa de água Se o computador está ligado e tem browser então acesse a internet Se está calor ou a água está quente então mergulhe na piscina Se está chovendo e está fazendo frio e você está em casa então coma uma pipoca tome um chá quente Se é final de semana e o tempo está bom então vou à praia Senão fico em casa

Um exemplo de Sintaxe em Português Estruturado usando o operador lógico E é

apresentado no quadro a seguir.

se expressão-lógica1 e expressão-lógica2 então <seqüência-de-comandos-expressão-verdadeira> senão <seqüência-de-comandos-expressão-falsa> fimse

91

Em Java o operador lógico E é representado por && e o operador lógico OU é

representado por ||.

Exemplo de Sintaxe em Java usando o operador lógico E.

if (expressão-lógica1 && expressão-lógica2) { <seqüência-de-comandos-expressão-verdadeira> } else { <seqüência-de-comandos-expressão-falsa> }

Exemplo simplificado de um algoritmo para verificar se uma pessoa pode nadar em uma

piscina:

Exemplo em Português Estruturado: se (temperatura da água > 25) e (água está limpa) então pessoa pode nadar fimse Exemplo em Java: if (agua.temperatura>25) && (agua.situacao==‘L’)

pessoa.nadar = true;

Leia mais em:

JANDL JÚNIOR, Peter. Java 5: guia de consulta rápida. São Paulo : Novatec, 2006. 136

p, il. pg. 19.

9.4. SELEÇÃO MÚLTIPLA (SWITCH - CASE)

As estruturas de seleção múltipla permitem avaliar uma entre diversas alternativas.

Escolha o tempo sol : vou à praia chuva : fico em casa Escolha a cor verde : tenho esperança vermelho : estou apaixonado azul : está tudo tranquilo

Sintaxe em Português Estruturado:

escolha <expressão-de-seleção> opção 1 : <seqüência-de-comandos-1> opção 2 : <seqüência-de-comandos-2> . . senão <seqüência-de-comandos-extra> fimescolha

A opção senão indica que nenhuma das opções anteriores foi validada.

A sintaxe em Java é:

92

switch <expressão> { case 1 : <seqüência-de-comandos-1> break; case 2 : <seqüência-de-comandos-2> break; . . default : <seqüência-de-comandos-extra> }

Em Java a expressão só pode ter como resultado um valor numérico inteiro, caractere ou

enumeração. Em Java a opção senão é denominada de default e é opcional. O break é

utilizado para finalizar o switch e deve ser usado em cada condição.

Exemplo simplificado de um algoritmo para escrever por extenso o sexo de uma pessoa

dada a digitação de F ou M:

Exemplo em Português Estruturado: escolha sexo da pessoa "F" : escreva ("Feminino") "M" : escreva ("Masculino") senão escreva ("Sexo não informado") fimescolha Exemplo em Java: switch (pessoa.sexo) {

case 'F' : System.out.println("Feminino"); break;

case 'M' : System.out.println("Masculino"); break;

default : System.out.println("Não Informado"); }

Leia mais em:

JANDL JÚNIOR, Peter. Java 5: guia de consulta rápida. São Paulo : Novatec, 2006. 136 p, il. pg. 20.

9.5. ATRIBUIÇÃO CONDICIONAL

Existem situações em que se utiliza a estrutura encadeada, apenas para atribuir valor a

uma variável. Nestes casos pode-se utilizar o operador ?.

Quando o resultado da expressão lógica for verdadeira a variável representada pelo

identificador receberá o resultado da expressão_verdadeira. caso contrário receberá o

resultado da expressão_falsa.

Um exemplo para somar ou diminuir um valor a uma variável se ele for par ou ímpar é

apresentado a seguir:

93

Exemplo em Português Estruturado: num = (x é par)? x + 1 : x - 1 Exemplo em Java: int num = (x % 2 == 0) ? x++ : x--;

No exemplo se o valor x for par num receberá o valor de x acrescido de uma unidade.

Caso contrário receberá o valor de x diminuído de uma unidade.

Leia mais em:

JANDL JÚNIOR, Peter. Java 5: guia de consulta rápida. São Paulo : Novatec, 2006. 136

p, il. pg. 15.

9.5.1. EXERCÍCIOS PROPOSTOS:

1. Para a pessoa definida no exercício da lista anterior foram estabelecidos novos atributos: sexo, altura e peso. Assim, descreva uma solução baseada na metodologia para calcular o IMC (Índice de Massa Corporal) da pessoa. O IMC indica se um adulto está acima do peso, se está obeso ou abaixo do peso ideal considerado saudável. A fórmula para calcular o Índice de Massa Corporal é: IMC = peso / (altura)2. Considerando a tabela abaixo, informe o IMC da pessoa.

Condição IMC em Mulheres IMC em Homens abaixo do peso < 19,1 < 20,7 no peso normal 19,1 - 25,8 20,7 - 26,4 acima do peso ideal 25,9 - 32,3 26,5 - 31,1 obeso > 32,3 > 31,1

2. Para a conta corrente criada no exercício da lista anterior, o banco solicitou a inclusão de uma rotina para informar se o saldo do cliente é credor ou devedor. Baseado nisto, construa este método e a cada atualização do saldo informe se o cliente é credor ou devedor.

3. Um pai decidiu ensinar seu filho a fazer as operações aritméticas elementares (‘+’, ‘-’, ‘*’, ‘/’). Para isto, ele pedia que o filho fizesse as contas à mão e depois conferisse em um programa que ele pediu para que você desenvolvesse no computador. Baseado nisto, construa uma solução baseada na metodologia proposta onde dados dois valores e o operador, informe o resultado da operação. A classe a ser criada deve ter o nome de Matemática.

4. Na classe Matemática definida no exercício 3, insira métodos para: informar o maior entre dois números e informar o menor entre dois números. Usando apenas estes métodos criados, informe o maior e o menor valor entre três números.

94

5. Um matemático deseja verificar se determinados valores podem ser lados de um triângulo. Em caso afirmativo, ele deseja saber qual é o tipo do triângulo: eqüilátero (todos os lados iguais), isósceles (pelo menos dois lados iguais), ou escaleno (nenhum lado igual)). Ele lembra que para ser um triângulo, a soma do valor de dois lados tem que ser maior que a do terceiro lado.

6. Na classe criada no exercício da lista anterior insira um método para informar se o triângulo é ou não retângulo (h2= a2 + b2). Considere também a possibilidade de não ser triângulo, considerando as mesmas condições apresentadas naquele exercício.

7. Considerando duas pessoas da classe Pessoa criada no exercício da lista anterior, informe a mais alta.

9.6. PARA – FAÇA (FOR)

As estruturas de repetição com contador permitem a execução de um grupo de comandos

num determinado número conhecido de vezes.

Exemplos: Para 10 carros faça lave o carro Para 5 bombons faça coma o bombom Para 40 alunos faça calcule a média do aluno

Sintaxe

Em Português Estruturado Para contador de inicio a fim faça Bloco de comandos Fim para Em Java for (expressão 1; expressão 2; expressão 3)

bloco de comandos ;

IMPORTANTE:

� expressão 1: é a expressão que define o valor de inic ialização de uma variável de controle. Esta expressão é uma instrução de atribuiç ão executada uma única vez antes de o laço ser iniciado;

� expressão 2: é a expressão que define a condição de teste da variável de controle. Ela é avaliada como verdadeira ou falsa no i nício de cada execução do laço. Se a expressão for verdadeira, o bloco de comando s do laço é executado. Se for falsa o laço é encerrado e o controle passa para a instrução seguinte;

� expressão 3: é a expressão que define a forma de atua lização da variável de controle a cada vez que o laço for repetido. Ela é exe cutada ao final de cada repetição do laço.

95

Exemplo simplificado para ler e escrever 10 números:

Em Português Estruturado para contador de 1 a 10 faca leia (numero) escreva (numero) fimpara Em Java //declara a variável para ler e escrever o número int numero; //inicializa um objeto para leitura Scanner sc = new Scanner(System.in); //faz a repetição for (int cont = 1; cont <=10; cont++) { System.out.println("Digite um número"); //lê o número do teclado numero = sc.nextInt(); //escreve o número no monitor de vídeo System.out.println(numero); }

Leia mais em:

JANDL JÚNIOR, Peter. Java 5: guia de consulta rápida. São Paulo : Novatec, 2006. 136

p, il. pg. 17.

9.7. ENQUANTO – FAÇA (WHILE / DO - WHILE)

As estruturas de repetição condicionais avaliam uma determinada condição lógica para

fazer a execução do laço de repetição. Uma condição sempre será avaliada como

verdadeira ou falsa.

A estrutura condicional mais comum é o enquanto-faça. Esta estrutura executa um

conjunto de instruções enquanto a expressão lógica for avaliada como verdadeira.A

condição pode estar no início ou no final do bloco de execução.

Exemplos: Enquanto tem carros para lavar faça lave o carro Enquanto tem bombons para comer faça coma o bombom Enquanto não encontrei o livro na biblioteca faça procure em outra estante Faça calcule a média do aluno Enquanto tem alunos

96

A sintaxe é:

Em Português Estruturado enquanto <expressão-lógica> faça <seqüência-de-comandos> fim enquanto ou faça <seqüência-de-comandos> enquanto <expressão-lógica> Em Java while (expressão-lógica) { <seqüência-de-comandos> } ou do { <seqüência-de-comandos> } while (expressão-lógica);

IMPORTANTE:

� expressão-lógica: é a expressão avaliada antes de cada repetição do laço. Quando seu resultado for VERDADEIRO, <seqüência-de-comandos> é executada. Na expressão lógica podem ser usados os operadores lógicos NAO, E ou OU.

Exemplo simplificado para ler e escrever um número inteiro:

Em Português Estruturado leia(numero) enquanto numero <> 0 faca escreva (numero) leia (numero) fimenquanto Em Java //declara a variável para ler e escrever o número int numero; //inicializa um objeto para leitura Scanner sc = new Scanner(System.in); //lê o número do teclado System.out.println("Digite um número"); numero = sc.nextInt(); //enquanto o número digitado não for zero continua a repetição while (numero <> 0) { //escreve o número no monitor de vídeo System.out.println(numero); //lê outro número do teclado System.out.println("Digite um número"); numero = sc.nextInt(); }

No exemplo apresentado pode ser observado o uso de um flag (0). O flag indica o fim de

um determinado conjunto de dados.

Leia mais em:

97

JANDL JÚNIOR, Peter. Java 5: guia de consulta rápida. São Paulo : Novatec, 2006. 136

p, il. pgs. 18 e 19.

9.7.1. EXERCÍCIOS PROPOSTOS:

1. Um matemático está necessitando de várias funções relacionadas a um número inteiro positivo. Suponha a definição de uma classe InteiroPositivo que apresenta o seguinte atributo: um número X. Implemente os seguintes métodos: a) um método setValor , que realiza a consistência necessária para garantir que X

seja um inteiro positivo; b) um método para retornar o número X multiplicado por outro objeto de

InteiroPositivo (este outro objeto é o objeto encontrado imediatamente antes deste);

c) um método para definir o fatorial de X; Fatorial (X) = X * (X-1) * (X-2) * (X-3) * … * 2 * 1

d) um método para imprimir a série de Fibonacci formada por X elementos; Fibonacci = 1, 1, 2, 3, 5, 8, 13, …

e) um método para imprimir os divisores inteiros de X e a quantidade de divisores. Exemplo: para o número 12, os divisores são 1, 2, 3, 4, 6, 12 e a quantidade de divisores é 6;

f) um método para retornar o valor de H, baseado na fórmula:

X

1...

4

1

3

1

2

1 1 = H +++++ , também expresso por ∑

=

X

d d1

1

g) um método para retornar o valor de I, baseado na fórmula:

1

X

2

1-X...

2X

3

1-X

2

X

1 = I +++

−++

h) um método para retornar o valor de S, baseado na fórmula:

20!

x

!19

x

!18

x

!17

x

!16

x...

!5

x

!4

x

3!

x

2!

x x= S

23451617181920 ++++++++++

i) um método para retornar o valor de P, baseado na fórmula:

!12

6

!10

5

!8

4

!6

3

4!

2 -

2!

1 = P −+−+ , considerando X termos.

Você deverá desenvolver uma interface ao usuário que permita digitar o valor desejado e criar um objeto de InteiroPositivo , colocando-o numa das células do mundo (aleatoriamente). Dica: implemente a classe InteiroPositivo como subclasse de br.furb.furbot.Numero.

O matemático (robô) deve percorrer o mundo e ao encontrar um objeto deve passar todas as mensagens de InteiroPositivo, exibindo seus resultados. Ele continua seu caminho até que todos os objetos tenham sido encontrados.

2. Variação sobre o exercício anterior: Além da funcionalidade já desenvolvida no exercício 1, agora o matemático também tem a possibilidade de não mais passar

98

todas as mensagens, mas sim sortear uma delas e exibir o resultado, a cada objeto encontrado.

3. Variação sobre o exercício anterior: Além da funcionalidade acrescida no exercício 2, o matemático poderá também apenas passar uma mensagem selecionada pelo usuário. A seleção ocorre através da interface gráfica, antes de começar a execução.

4. Digitar uma frase na janela, separar em palavras, distribuir aleatoriamente no mundo e fazer o robô percorrer e remontar a frase. Crie uma caixa de texto (para digitação da frase), um botão (para separar a frase e distribuir as palavras no mundo), além dos botões de executar, parar e da console. O robô deve falar a frase inteira na console no final da execução.

5. Pegar 5 palavras (de no mínimo 3 letras e no máximo 10), em um mundo 15x15 e

montar uma palavra cruzada. Crie uma janela com cinco caixas de texto (para digitar cada uma das palavras) e um botão (para distribuí-las no mundo). A palavra deve ser desmontada em letras, para em seguida distribuir sequencialmente essas letras no mundo. Se a palavra é horizontal ou vertical, quem determina é o seu algoritmo. Porém, as cinco palavras devem se cruzar, ou seja, não pode existir uma palavra órfã.

6. Considere uma classe chamada TemperaturasDaSemana , a qual armazena as temperaturas máxima e mínima de cada um dos sete dias da semana. Sua aplicação deve permitir entrar com as temperaturas e depois oferecer ao usuário a possibilidade de consultar: a) a temperatura média de um determinado dia; b) a temperatura máxima ocorrida na semana, indicando o dia; c) a temperatura mínima ocorrida na semana, indicando o dia.

7. Considere uma matriz quadrada de inteiros de ordem N (visualizada no mundo). Crie um botão para popular esse mundo com NxN objetos Numero , com valores aleatórios. Crie uma classe de robô que passeie pelo mundo, e cada Numero deve ser armazenado numa matriz de inteiros. Na janela adicione um botão para executar e parar, e dois botões que: a) pergunta ao robô a soma dos elementos da diagonal principal da matriz e mostra

numa JOptionPane o resultado. O cálculo não pode ser feito previamente; b) [ergunta ao robô o menor valor par da matriz e mostra numa JOptionPane o

resultado. Adicione duas caixas de texto para solicitar as coordenadas x e y ao usuário e um botão que pergunta ao robô valor do elemento [x , y] digitado pelo usuário.

Adicione um último botão para que o robô volte à célula [0,0], ele monte uma nova matriz de ordem N, porém transposta, e altere os valores dos objetos Numero para refletir essa nova matriz.

8. Você está trabalhando em um projeto de automação de uma estação ferroviária. Uma das classes identificadas é PassageirosHora , que foi definida como sendo uma matriz

Ex.: ISTO É UM TESTE

ISTO 1

É 2

99

tridimensional de inteiros que em cada posição guarda a quantidade de passageiros transportados por hora, de determinado dia, de determinado mês. Assim a matriz é de ordem 12 meses x 30 dias x 24 horas. Crie esta classe, que deve ter as seguintes funcionalidades:

FUNCIONALIDADE Código de teste PassageirosHora ph = new PassageirosHora();

a) adicione mais um passageiro em determinada hora;

ph.adiciona(1,1,13); // 13 horas de 1o de Janeiro

b) retorne a quantidade de passageiros transportados em determinado dia;

int qtde = ph.quantosPassageiros(25,12); // Natal

c) retorne o mês em que houve o menor fluxo de passageiros.

int mês = ph.mesMenorFluxo();

d) retorne o dia, mês e hora em que houve a maior quantidade transportada de passageiros;

int[ ] momento = ph.picoTransporte();

9. Na classe Matemática, criada no exercício anterior insira um método para informar o Máximo Divisor Comum entre dois números.

10. RECURSOS NO FURBOT PARA DESENVOLVIMENTO DE JOGOS

Esta seção apresenta os recursos que o Furbot disponível para desenvolver jogos

simples. Todos os recursos aqui apresentados estão disponíveis a partir da versão 0.15.

A Figura 38 apresenta um exemplo de jogo do tipo PacMan desenvolvido utilizando os

recursos do FURBOT.

FIGURA 38 - MODELO DE MUNDO DO JOGO PACMAN.

10.1. USANDO O TECLADO

Através do método getUltimaTeclaPress() é possível obter do sistema o código da última

tecla pressionada. Cada tecla corresponde a um código diferente. Para você descobrir os

códigos das teclas que pretende usar no jogo, construa as seguintes linhas de código em

um robô do Furbot:

while (true) { int tecla = getUltimaTeclaPress(); diga(tecla); }

Ao executar o robô, você vai reparar que o sistema vai imprimindo o código “0” enquanto

nenhuma tecla for pressionada. Quando pressionar uma tecla o código dela é mostrado

na console, e em seguida volta a imprimir o código “0”. Esse exemplo mostra que ao

chamar o método ele tira o código que estava guardado, ou seja, se chamar duas vezes

101

seguidas, na segunda vez provavelmente não virá o mesmo código, e mais provável

ainda, deve vir o código “0”.

Já existem algumas teclas mapeadas no Furbot: TECLACIMA, TECLABAIXO,

TECLAESQUERDA, TECLADIREITA e TECLAESPACO. Com isso, o código retornado

pelo método getUltimaTeclaPress() pode ser comparado com essas constantes. Por

exemplo:

while (true) { int tecla = getUltimaTeclaPress(); if (tecla == TECLACIMA) { andarAcima(); } else { if (tecla == TECLABAIXO) { andarAbaixo(); } } diga(tecla); }

10.2. ADICIONANDO NOVOS OBJETOS AO MUNDO E REMOVENDO

OBJETOS DO MUNDO

Até agora você viu que a única forma de adicionar objetos no mundo é mexendo no XML.

Existe outra forma que é através de métodos do Furbot:

adicionarObjetoNoMundo(ObjetoDoMundo,Direcao) ou

adicionarObjetoNoMundoXY(ObjetoDoMundo, int, int). A utilização desses métodos é

muito útil quando o robô precisa disparar um tiro, por exemplo.

O código abaixo apresenta o uso desses dois métodos: cria dois novos Aliens (observe a

sintaxe usando a palavra reservada new) e adiciona-os no Mundo.

Alien alien1 = new Alien(); adicionarObjetoNoMundo(alien1, DIREITA); Alien alien2 = new Alien(); adicionarObjetoNoMundoXY(alien2, 3, 4); // x = 3, y = 4

Atenção: a execução do sistema pára se tentar incluir o mesmo objeto duas vezes. Por

exemplo, o código abaixo faz parar o sistema.

Alien alien1 = new Alien(); adicionarObjetoNoMundo(alien1, DIREITA); adicionarObjetoNoMundo(alien1, ESQUERDA); adicionarObjetoNoMundoXY(alien1, 3, 4); // x = 3, y = 4

102

Também é possível remover um objeto do mundo (esse é um recurso muito útil quando

algum elemento precisa sumir). O código abaixo apresenta o exemplo de como remover

um objeto que o robô encontrou.

ObjetoDoMundo obj = getObjeto(AQUIMESMO); removerObjetoDoMundo(obj);

10.3. FAZENDO SEUS PRÓPRIOS TIPOS DE OBJETOS DO MUNDO

O Furbot tem uma grande flexibilidade que permite que você faça seus próprios tipos de

objetos do mundo, permitindo atribuir uma imagem a ele e programar um comportamento

para esse objeto. Assim como até agora você programava cada novo robô através de

uma classe, é o mesmo que vai acontecer para criar esses novos objetos. Entretanto,

existem algumas diferenças que você precisa prestar muita atenção. Nos quadros abaixo

estão parte do código de um robô e de um objeto do mundo.

public class MeuRobo extends Furbot { public void inteligencia() throws Exception { } public static void main(String[] args) { MundoVisual.iniciar("MeuRobo.xml"); } }

public class Inimigo extends ObjetoDoMundoAdapter { public void executar() throws Exception { } }

Primeira observação: o robô estende de Furbot, e o inimigo estende

ObjetoDoMundoAdapter. Essa é a regra básica para criar novos tipos de objetos do

mundo: estender da classe ObjetoDoMundoAdapter.

Segunda observação: a lógica do robô fica no método inteligencia() e a lógica do inimigo

fica no método executar(). Essa é a segunda regra básica para implementar novos tipos

de objetos do mundo: a lógica dos objetos ficam no método executar(). Nessa lógica você

pode usar todos os recursos que já vinha usando para o robô: os métodos de movimento

(andarDireita(), andarAcima(), etc), para visão (getObjeto(), ehFim(), etc), para manter um

103

registro de atividades (diga()) e para adicionar e remover objetos (como visto nas seções

anteriores).

Terceira observação: normalmente colocaremos o método main() somente na classe do

robô. Se colocarmos em algum tipo de objeto, e quisermos executar um programa,

precisamos mandar a executar a classe do tipo do objeto. Como normalmente montamos

um robô para resolver o problema de um mundo, então a melhor posição para o método

main() é no próprio robô.

Os objetos dessa classe podem ser adicionados durante a execução do robô, através dos

métodos adicionarObjetoNoMundo(...) ou adicionarObjetoNoMundoXY(...) ou mapeá-los

no XML. Para isso, basta usar o elemento <objeto> e no atributo class colocar o nome da

classe. Veja um exemplo no quadro abaixo. Aqui é criado um objeto com a classe Inimigo

numa posição aleatória.

<objeto class = “Inimigo”> <random/> </objeto>

Agora veremos como atribuir uma imagem a qualquer objeto do mundo (inclusive o robô:

você poderá atribuir uma imagem personalizada para seu robô). Para isso será

necessário implementar o método buildImage(). Veja como fazer esse método no quadro

abaixo.

public ImageIcon buildImage() { return LoadImage.getInstance().getIcon("inimigo.png"); }

Observa como é bastante simples atribuir imagens aos objetos: basta informar o novo do

arquivo contendo a imagem. São aceitos arquivos no formato PNG, GIF e JPG. As

imagens precisam ter de preferência o tamanho de 50X50, que é a dimensão de cada

célula no mundo. O arquivo precisa estar na pasta do projeto (o mesmo local aonde você

vinha colocando os arquivos XML).

Lembre-se: é possível implementar esse método nos seus robôs.

10.4. CONFIGURANDO VELOCIDADES DIFERENTES PARA OS OBJETOS

Num jogo normalmente temos vários objetos animados com velocidades independentes.

Você sabe que a velocidade no Furbot é baseada numa barra de rolagem presente na

104

janela. Mas também é possível que se especifiquem velocidades diferentes para cada

objeto no mundo. Para isso utilizamos o método setVelocidade() conforme o exemplo no

quadro abaixo.

Alien1 alien = new Alien(); alien.setVelocidade(100); adicionarObjetoNoMundo(alien, ACIMA); .... setVelocidade(0);

A velocidade no Furbot é baseada num temporizador. Na verdade quando você atribui

uma velocidade ao objeto vai precisar pensar no tempo que o objeto vai levar entre

executar um comando e outro. No código acima foi criado um alien e atribuído uma

velocidade de 100. A unidade da velocidade é milisegundos. No caso desse alien, ele foi

configurado para ter um tempo de espera de 100ms entre executar um comando e outro.

A última linha atribui velocidade 0 ao robô, ou seja, cada comando é executado

instantaneamente sem existir um tempo de espera adicional. Novamente: quanto maior o

valor que você informa nesse método, menor será a sua velocidade.

10.5. SORTEIO

Para deixar um jogo interessante, existem momentos em que os objetos precisam sortear

algo, por exemplo, uma direção ou a velocidade do tiro. Para isso, você utilizará o método

sortear(). Esse método retorna um int. Por exemplo, o código abaixo sorteia um número e

faz o resto da divisão por quatro. De acordo com o resultado, que fica entre 0 e 3, o robô

toma uma decisão.

int sorteio = sortear() % 4; switch(sorteio) { case 0 : andarAcima(); break; case 1 : andarAbaixo(); break; case 2 : andarEsquerda(); break; case 3 : andarDireita(); break; }

10.6. TROCA DE MUNDO EM TEMPO DE EXECUÇÃO

Você saberia responder quando se encerra a execução do robô? .... Existem duas formas:

a primeira clicando no botão [Stop] da janela do mundo; a segunda é quando termina a

inteligência do robô. Se você deseja implementar que em algum momento do jogo, o

cenário do mundo troque, é preciso que saia do método inteligencia(). Mas saindo desse

105

método termina a execução do robô!!! Como poderíamos implementar a troca de

mundos?

A partir da versão 0.15 tem uma nova forma de iniciar o MundoVisual. Observe o código

no quadro abaixo.

public static void main(String[] args) { MundoVisual.iniciarSequencia(RoboJogavel.class , "PrimFase.xml", "SegFase.xml"); }

O novo método iniciarSequencia() recebe como parâmetro a classe de um robô e uma

lista de mundos (nesse exemplo tem somente dois, mas o limite é a memória). O primeiro

mundo a ser carregado é PrimFase. Se nada de novo for feito na inteligência do robô, a

execução simplesmente termina.

Para programar a troca de mundos durante a execução você precisará utilizar o método

proxMundo(int) da classe MundoVisual. Esse método sinaliza ao mundo para carregar

uma nova configuração automaticamente quando acabar a inteligência do robô. O

parâmetro indica o código do mundo a ser carregado, de acordo com os parâmetros

passados no método iniciarSequencia(). O primeiro mundo é de código 0, o segundo de

código 1 e assim por diante.

O quadro abaixo faz um teste comparando se o mundo atual (getMundo()) é de código 0,

ou seja, se é o primeiro mundo da lista. Se isso for verdadeiro então sinaliza o mundo

visual para utilizar o mundo de código 1 quando acabar a inteligência do robô.

if (MundoVisual.getMundo() == 0) { MundoVisual.proxMundo(1); }

O gerenciamento de fases, ou troca de cenários, acontece automaticamente, de acordo

com o mundo indicado no método proxMundo(int).

É importante chamar a atenção de que toda vez que um novo mundo é criado, todos os

objetos desse mundo são recriados, inclusive o robô. Existem situações em que

precisamos transferir dados de uma fase para outra, e infelizmente não tem como guardar

no robô. Uma alternativa criada para resolver esse problema é fazer com que o

MundoVisual mantenha esses dados. Existem três métodos que você utilizará para isso.

Vamos explicar esses métodos através do código abaixo. O método setAtributo() guarda

um valor de qualquer tipo (int, boolean, String, Alien, etc) e associa ele com um nome.

106

Esse nome deve ser único. Se você utilizar duas vezes, o valor que tinha antes é perdido.

O método temAtributo() verifica se existe um valor guardado com o nome passado por

parâmetro. E o método getAtributo() retorna o valor guardado com o nome passado como

parâmetro.

MundoVisual.setAtributo("x", getX()); MundoVisual.setAtributo("y", getY()); ... if (MundoVisual.temAtributo("x")) { int x = MundoVisual.getAtributo("x"); int y = MundoVisual.getAtributo("y"); }

10.7. CONTROLANDO PROBLEMAS DE CONCORRÊNCIA

Em jogos geralmente existem várias entidades movimentando-se no mundo do jogo (ex:

no PacMan existem os fantasmas e o pacman). Como o FURBOT originalmente não foi

concebido para tratar os problemas associados com aspectos de threads concorrentes, é

possível que vocês encontrem problemas relacionados ao disparo de exceções.

Para tentar minimizar (e não corrigir!!) o impacto destes problemas, utilizem a solução a

seguir. Em cada entidade que se movimenta declarar um atributo:

private boolean estouVivo = true;

No laço de repetição do método inteligencia (ou do método executar) teste o atributo

estouVivo. Exemplo:

... Direcao direcao = sortearDirecao(); boolean continuar = true; while (continuar == true && estouVivo ==true ) { if (!ehFim(direcao)) { if (!ehObjetoDoMundoTipo("Parede", direcao)) { andar(direcao); } } direcao = sortearDirecao(); }//while if (estouVivo == false) { diga ("MORRI"); } .....

Em cada entidade que se movimenta declarar um método que permite sinalizar que a

mesma não deve continuar a execução. Exemplo:

107

public void entidadeMorreu() { estouVivo = false; } .....

O método que realiza o controle de colisões deve apresentar o comportamento similar a

este:

public boolean ocorreuColisao(Direcao direcao) { ObjetoDoMundo obj = getObjeto(direcao); //primeiro “tenta pegar” o objeto if (obj != null) { //verifica se conseguiu pegar o objeto na posicao String tipo = obj.getSouDoTipo(); //testa o tipo do objeto if (tipo.equals("AlienPacManExemplo")) { AlienPacManExemplo al = (AlienPacManExemplo) obj; //mapeia o objeto para o tipo da classe // AlienPacManExemplo al.entidadeMorreu(); //envia uma mensagem para o objeto que deve parar diga("ALIENS COLIDIRAM"); return true; } else { if (tipo.equals("MeuPacMan")) { diga ("vou remover o pacMan"); MeuPacMan mp = (MeuPacMan) obj;//converte o objeto para o tipo // da classe MeuPacMan mp.pacManMorreu(); return true; } } } return false; }

Ao ser executado o método entidadeMorreu() da classe PacMan (por exemplo), será

atualizado o valor do atributo estouVivo para false e com isto o laço de repetição do

método inteligencia encerra sua execução.

O efeito desta solução é que a entidade “viva” continuará executando até retornar ao teste

do comando while. Neste momento ela pára de executar. Dependendo da complexidade

da lógica a ser executada, é possível que o comportamento da entidade fique errôneo por

um tempo equivalente ao tempo necessário para executar os comandos restantes até o

final do comando while.

Como a entidade encerra o método inteligencia() ou executar(), não ocorrem as exceções

decorrentes dos aspectos de concorrência.

108

10.8. CONSIDERAÇÕES FINAIS

É importante chamar a atenção de que o Furbot não é uma engine de jogos, mas um

conjunto de classes para facilitar o aprendizado de programação Java. Os problemas de

desempenho e alguns de apresentação são inevitáveis para garantir um ambiente fácil de

programar. Na medida do possível estaremos resolvendo esses problemas.

Aconselho que você destrinche esse documento: entenda todos os parágrafos e todos os

códigos. Programe para testá-los. Anote as dúvidas e procure pelos professores,

monitores ou alunos mais experientes.

10.9. EXEMPLO

import javax.swing.ImageIcon; import br.furb.furbot.Direcao; import br.furb.furbot.ObjetoDoMundoAdapter; import br.furb.furbot.suporte.LoadImage; public class SeguidorDeRobo extends ObjetoDoMundoAdapter{ private boolean fim = false; public ImageIcon buildImage() { return LoadImage.getInstance().getIcon("imagens/alienmovel.png"); } public SeguidorDeRobo() { setVelocidade(0); } public void executar() throws Exception { Direcao direcao = descobrirDirecao(); while (ehFim(direcao) == false) { obterLetra(); andar(direcao); }//while passoNaExtremidade(direcao); diga(palavra); fim = true; } private String palavra = ""; private void obterLetra() { Letra letra = getObjeto(AQUIMESMO); palavra += letra.getLetra(); } private void passoNaExtremidade(Direcao direcao){ if (direcao == ABAIXO || direcao == ACIMA) { andarEsquerda(); } else { andarAbaixo(); } private void andar(Direcao direcao) { switch (direcao) { case ABAIXO: andarAbaixo(); break; case ACIMA: andarAcima(); break; case DIREITA: andarDireita(); break; default : andarEsquerda(); }//switch }

109

private Direcao descobrirDirecao() { if (ehVazio(ABAIXO) == false) return ABAIXO; if (ehVazio(ACIMA) == false) return ACIMA; if (ehVazio(ESQUERDA) == false) return ESQUERDA; return DIREITA; } public boolean finalizou() { return this.fim ; } }//class }//SeguidorDeRobo

110

11. INSTALAÇÃO DO AMBIENTE DE DESENVOLVIMENTO: JDK E NETBEANS

O primeiro passo antes de utilizar o FURBOT é a instalação e configuração do ambiente

de desenvolvimento. Esta seção deste documento descreve os passos para baixar e

configurar o software necessário para o desenvolvimento de aplicações utilizando o

FURBOT. Para complementar o processo de instalação, acesse o link:

http://www.inf.furb.br/poo/furbot/index.html.

O material desta seção foi desenvolvido pelo Prof. Mauricio Capobianco Lopes e pela

monitora Fernanda Gums e tem por objetivo descrever os procedimentos para instalação

do ambiente de programação orientada a objetos: JDK e IDE Netbeans.

11.1. EXPLICAÇÃO INICIAL

Nas disciplinas de programação orientada a objetos iremos utilizar um conjunto de

ferramentas formado pelo ambiente de desenvolvimento Java da Sun – Java

Development Kit (JDK) 1.5 (ou superior). Contudo, este conjunto de ferramentas não

fornece um ambiente de desenvolvimento ou de edição dos programas-fonte.

Assim sendo, para criar as aplicações Java, poderemos utilizar a ferramenta Netbeans. A

ferramenta permite a edição dos programas em Java e proporciona um ambiente de

desenvolvimento que facilita o aprendizado da linguagem e dos conceitos associados.

11.2. DOWNLOAD DOS INSTALADORES

Você vai precisar do aplicativo de instalação de cada uma das ferramentas que serão

utilizadas.

Há duas formas de obtê-las:

1. Emprestando o CD disponível na biblioteca da universidade;

2. Fazendo o download diretamente da página dos fornecedores das ferramentas: IDE NetBeans e JDK.

11.2.1. FAZENDO O DOWNLOAD DO SOFTWARE JDK

Acesse o link: http://java.sun.com/javase/downloads/index.jsp. Você encontrará uma página

semelhante à mostrada na Figura 39:

FIGURA 39- TELA PARA A ESCOLHA DA VERSÃO DO JDK.

Clique no link “Get the JDK download” e você será remetido para uma página similar à

página abaixo (Figura 40):

FIGURA 40- DOWNLOAD CENTER.

Clique no link “Review License Agreement” e você será remetido para a página do acordo

de Licenciamento do software (Figura 41):

FIGURA 41- ACORDO DE LICENCIAMENTO DO SOFTWARE.

Leia o acordo de licenciamento do software e clique no botão “Accept License Agreement”

e você será remetido para uma página que você deverá escolher a plataforma e o

instalador a ser baixado (Figura 42):

FIGURA 42- SELECIONAR A PLATAFORMA E O INSTALADOR DO JDK.

Selecione uma das opções 1 ou 2 (para Windows) ou 3 ou 4 (para Linux) e clique no

botão “Download selected with Sun Download Manager” (opção 5). No Windows será

apresentada a janela para abrir um arquivo (Figura 43):

FIGURA 43- ABRIR O ARQUIVO PARA INICIAR O DOWNLOAD.

Clique no botão “Open” e será iniciado o processo de download do software Sun

Download Manager. Ao ser apresentada a janela abaixo (Figura 44) clique no botão

“Run”.

FIGURA 44- EXECUÇÃO DO GERENCIADOR DE DOWNLOAD.

Será apresentada a janela (Figura 45) que contém os termos de licença de uso do

software Sun Download Manager. Clique no botão “Accept”.

FIGURA 45- TERMOS DE LICENÇA DO SOFTWARE.

Na janela de opções (Figura 46) configure as opções de funcionamento do software Sun

Download Manager selecionando a opção “Browse” (1) para indicar em que pasta você

deseja armazenar o software JDK a ser baixado. Selecione também as demais opções (2)

conforme a sua preferência e clique no botão “OK”.

FIGURA 46- OPÇÕES PARA O DOWNLOAD.

Neste momento será apresentada uma janela (Figura 47) contendo as informações sobre

o processo de download do software selecionado. Como geralmente os arquivos a serem

baixados são relativamente grandes, o tempo para download vai depender da velocidade

de conexão com a internet que você possui. A qualquer momento você pode selecionar a

opção “Pause” para suspender temporariamente o download ou “Parar” para parar o

processo.

FIGURA 47- ANDAMENTO DO DOWNLOAD.

Depois que o arquivo tenha sido baixado com sucesso, inicie a instalação.

11.2.2. FAZENDO O DOWNLOAD DO SOFTWARE NETBEANS

Acesse o link: http://www.netbeans.info/downloads/index.php. Você encontrará uma página

semelhante a da Figura 48.

FIGURA 48- SITE DO NETBEANS > DOWNLOAD.

Se você vai executar o NetBeans em uma máquina com sistema operacional Windows,

clique no botão “Download NetBeans IDE”, baixe o arquivo e execute-o. Se você vai

executar o NetBeans em uma máquina com outro sistema operacional (Linux, MacOS,

Solaris) clique no link “Other Systems & Languages”, escolha o instalador, baixe o arquivo

e siga as instruções da seção 11.2.4.

11.2.3. INSTALANDO O AMBIENTE JDK

Para proceder à instalação do JDK, dê um duplo clique sobre o aplicativo e siga as

instruções de instalação. Inicialmente será apresentada a tela a seguir contendo o acordo

de licença de uso do software. Clique no botão “Accept”.

FIGURA 49-LICENÇA DE USO DO SOFTWARE.

Concordando com a licença de uso, aparecerá a tela de configuração da instalação

conforme a Figura 50:

FIGURA 50- CONFIGURAÇÃO DA INSTALAÇÃO.

No caso da instalação da versão 6 do ambiente de desenvolvimento (JDK), será instalado

também o ambiente de RunTime necessário para a execução de applets e aplicações em

geral na sua máquina. Esta solicitação será realizada como mostra a Figura 51. Clique no

botão “Next” e aguarde a finalização da instalação.

FIGURA 51- CONFIGURAÇÃO DA INSTALAÇÃO.

Ao término do processo de instalação do ambiente JDK, será apresentada a tela (Figura

52) indicando o sucesso dos procedimentos. O próximo passo é instalar o editor de

aplicações IDE Netbeans.

FIGURA 52- INSTALAÇÃO COMPLETA.

11.2.4. INSTALANDO O AMBIENTE NETBEANS

As informações a seguir foram obtidas a partir do link:

http://www.netbeans.org/community/releases/55/install_pt_BR.html#standalone.

118

11.2.4.1. WINDOWS

Em computadores com o Microsoft Windows, usar o instalador compactado auto-extraível

apresenta um método preferencial de instalar o NetBeans IDE.

Para instalar o NetBeans IDE:

1. Depois de fazer o download do arquivo instalador, clique duas vezes no ícone para abrir o instalador.

2. No assistente de instalação, escolha uma resposta para o Contrato de licença e clique em Próximo.

3. Especifique um diretório vazio dentro do qual será instalado o NetBeans IDE.

Observação: Esta instalação do NetBeans IDE não desorganizará as configurações de

outras instalações do NetBeans, porque o IDE cria automaticamente um novo diretório de

usuário quando é aberto (${HOME}/.netbeans/5.5).

1. Escolha o JDK que o IDE usará na lista de JDKs compatíveis e clique em Próximo. 2. Verifique se o local de instalação está correto e se há espaço disponível no sistema

para a instalação. 3. Clique em Próximo para iniciar a instalação.

Observação: Caso haja problemas durante a instalação do software, consulte a seção

Solução de problemas para obter as descrições completas e as soluções alternativas

sugeridas para problemas não resolvidos que podem afetar o processo de instalação.

11.2.4.2. LINUX

Em computadores com Linux, o método de preferência para instalar o NetBeans IDE é

usar o instalador binário.

Para instalar o NetBeans IDE:

1. Vá até o diretório que contém o instalador. 2. Se necessário, altere as permissões do arquivo instalador para tornar o binário

executável. Para tanto, digite em um prompt de comando:

$ chmod +x seu_binário_executável

Observação: Certifique-se de substituir seu_binário_executável pelo nome real do arquivo

do binário que foi baixado.

3. Abra o instalador executando em um prompt de comando:

$ ./seu_binário_executável

119

Observação: Verifique novamente se substituiu seu_binário_executável pelo nome real do

arquivo do binário que foi baixado.

4. No assistente de instalação, escolha uma resposta para o Contrato de Licença e clique em Próximo.

5. Especifique um diretório vazio dentro do qual será instalado o NetBeans IDE e clique em Próximo.

6. Escolha o JDK que o IDE usará na lista de JDKs compatíveis e clique em Próximo.

O instalador procura os JDKs instalados no sistema e pergunta se deseja especificar qual

será utilizado. É possível fazer isso na linha de comando. Por exemplo:

$ ./seu_binário_executável -is:javahome caminho_para_seu_jdk

7. Verifique se o local de instalação está correto e se há espaço disponível no sistema para a instalação.

8. Clique em Próximo para iniciar a instalação.

Observação: Caso haja problemas durante a instalação do software, consulte a seção

Solução de problemas para obter as descrições completas e as soluções alternativas

sugeridas para problemas não resolvidos que podem afetar o processo de instalação.

11.2.5. RESULTADOS

Você deve ter o Java e o IDE NetBeans instalados no seu sistema.

11.2.6. MAIS INFORMAÇÕES

• Site do IDE NetBeans • Documentação Java • Site do FURBOT

120

12. ANEXO 1 - LEIA MAIS EM ...

12.1. MODELAGEM DE PROBLEMAS

LARMAN, Craig. Utilizando UML e padrões : uma introdução à análise e ao projeto orientados a objetos. 2. ed. Porto Alegre : Bookman, 2004. 608 p, il

MELO, Ana Cristina. Desenvolvendo aplicações com UML 2.0 : do conceitual à implementação. 2. ed. atual. Rio de Janeiro : Brasport, 2005. 284 p, il.

MENEZES, Eduardo Diatahy Bezerra de. Princípios de análise e projeto de sistemas com UML . Rio de Janeiro : Campus, 2002. 286p, il.

SINTES, Anthony. Aprenda programação orientada a objetos em 21 dias. São Paulo : Pearson Education do Brasil, 2002. 693p, il.

Lógica de Programação e Algoritmos

CARBONI, Irenice de Fátima. Lógica de programação . São Paulo : Pioneira Thomson Learning, 2003. 240 p, il.

CORMEN, Thomas H. Algoritmos : teoria e prática. Rio de Janeiro : Campus, 2002. xvii, 916p, il. Tradução de: Introduction to algorithms.

MANZANO, Jose Augusto N. G; OLIVEIRA, Jayr Figueiredo de. Algoritmos : logica para desenvolvimento de programacao. Sao Paulo : Erica, 1996. 265p.

12.2. LINGUAGEM JAVA

DEITEL, P. J. Java : como programar.6. ed. Porto Alegre : Pearson, 2005. xl, 1110 p, il. Tradução de: Java how to program.

BARNES, David J; KOLLING, Michael. Programação orientada a objetos com Java . São Paulo : Pearson Education : Prentice Hall, 2004. xxviii, 368 p, il. , 1 CD-ROM. Tradução de: Objects first with Java : a practical introduction using Blue J. Acompanha CD que contém o JDK e o BlueJ para vários sistemas operacionais, Sites Web de suporte, além dos projetos de exemplo.

HORSTMANN, Cay S. Conceitos de computação com o essencial de Java . 3. ed. Porto Alegre : Bookman, 2005. x, 780 p, il. Tradução de: Computing concepts with Java essentials.

SANTOS, Rafael. Introdução à programação orientada a objetos usando JAV A. Rio de Janeiro : Campus, 2003. 319p, il. (Campus-SBC).

FURGERI, Santos. Java2 : ensino didático – desenvolvendo e implementando aplicações t. ed. São Paulo: Érica, 2006. 372p.