A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

Linguagem de Programação IV. Ementa da Disciplina Fundamentos do paradigma orientado a objetos em Java. Bibliotecas de suporte, componentes gráficos,

Apresentações semelhantes


Apresentação em tema: "Linguagem de Programação IV. Ementa da Disciplina Fundamentos do paradigma orientado a objetos em Java. Bibliotecas de suporte, componentes gráficos,"— Transcrição da apresentação:

1 Linguagem de Programação IV

2 Ementa da Disciplina Fundamentos do paradigma orientado a objetos em Java. Bibliotecas de suporte, componentes gráficos, interfaces e estruturas de dados, classes coletivas. Tratamento de exceção. Gerência de memória. Multithreading (concorrência). Applets Java.

3 Bibliografia LIVRO TEXTO: DEITEL, H.M., DEITEL, P.J. Java, Como Programar. 4ª Edição. Porto Alegre: Bookman, 2003. LEMAY, L. e CADENHEAD, R. Aprenda em 21 Dias Java 2: Professional Reference. 3a. Ed. São Paulo: Campus, 2003. OBRAS DE REFERÊNCIA: HORSTMANN, Cay. Big Java. Porto Alegre: Bookman, 2004. HORSTMANN, Cay, et al. Core Java 2, Volume 1: Fundamentos. S. Paulo: Makron Books, 2001. HORSTMANN, Cay, et al. Core Java 2, Volume 2: Recursos Avançados. S. Paulo: Makron Books, 2001. FURGERI, Sérgio. Java 2 Ensino Didático. São Paulo: Editora Érica, 2002. CAMARÃO, C. e FIGUEIREDO, L. Programação de Computadores em Java. Rio de Janeiro: LTC, 2003 SANTOS, R. Introdução à Programação Orientada a Objetos usando Java. Rio de Janeiro: Campus, 2003. MECENAS, I. Java 2 Fundamentos, Swing e JDBC. Rio de Janeiro: Alta Books, 2003. OLIVEIRA, Alcione P. Notas de Aula DPI-UFV. Viçosa, 2001. CHAN, Mark C. et al. Java: 1001 Dicas de Programação. São Paulo: Makron Books, 1999. ECKEL, Bruce. Thinking in Java, 3rd Edition. (e-book). DAVIS, Stephen R. Aprenda Java Agora. Rio de Janeiro: Campus, 1997. LALANI, Suleiman S. e JAMSA, Kris. Java: Biblioteca do Programador. São Paulo: Makron Books, 1997. NEWMAN, A. et al. Usando Java: O Guia de Referência Mais Completo. Rio de Janeiro: Campus, 1997. WUTKA, Mark. Java: Técnicas Profissionais. São Paulo: Berkeley, 1997. DAMASCENO JR., Américo. Aprendendo Java: Programação na Internet. São Paulo: Érica, 1996. JEPSON, Brian. Programando Banco de Dados em Java. São Paulo: Makron Books, 1997. RITCHEY, Tim. Java! Indianápolis, EUA: New Riders, 1995. FLANAGAN, David. Java in a Nutshell. OReilley & Associates, 1997.

4 A história de Java Origem: projeto de pesquisa da Sun Microsystems, iniciado em 1991, destinado a desenvolver uma linguagem para a programação de dispositivos eletrônicos em geral (pagers, celulares, PDAs, TV a cabo, etc). Baseada em C e C++. Seu criador, James Gosling, inicialmente a chamou de Oak, mas descobriu-se que, na época, já havia uma outra linguagem com este mesmo nome. Conta a lenda, que o nome Java foi escolhido em uma cafeteria, e refere-se a uma variedade de café, originário da ilha homônima, do Pacífico. Impulso ao uso de Java: a World Wide Web explode em popularidade a partir de 1993 e a Sun percebe o seu grande potencial para a construção de páginas com conteúdo dinâmico. Em 1995, Java é anunciada formalmente à comunidade mundial. Atualmente, a tecnologia Java divide-se em J2SE, J2EE e J2ME e está na versão 1.5.0 (o chamado Core Java Software, ou, J2SE 5.0)

5 Um ambiente Java típico Fase 1 Editor Disco O programa criado no editor é armazenado em disco. Fase 2Compilador Disco O compilador cria bytecodes e os armazena em disco Fase 3 Carregador de Classe Disco O carregador de classe coloca bytecodes na memória principal

6 Um ambiente Java típico (cont.) Fase 4 Verificador de Bytecodes O verificador de bytecodes confirma que todos os bytecodes são válidos e não violam restrições de segurança de Java Fase 5 Interpretador O interpretador lê os bytecodes e traduz para a linguagem de máquina do computador, e executa o programa

7 Um primeiro exemplo em Java Use o Edit ou qualquer outro editor e digite o seguinte programa Java: //Um primeiro programa em Java 2 public class AloMundo { public static void main(String args[]) { System.out.println("Alo, mundo!"); } Após digitá-lo, salve com o nome da classe, ou seja: AloMundo.java Java é uma linguagem case sensitive, ou seja, faz distinção entre letras maiúsculas e minúsculas em variáveis, comandos e arquivos.

8 Para compilar o programa, a partir da janela de comando, mude para o diretório onde o arquivo fonte foi armazenado e digite: javac AloMundo.java A compilação vai gerar um arquivo de bytecodes chamado AloMundo.class Para executar o programa, também a partir da janela de comando, digite: java AloMundo O comando java carrega o interpretador e indica que o arquivo AloMundo.class deve ser interpretado e executado. A execução sempre começa pelo método main. Obs.: o comando java deve omitir o sufixo do arquivo a ser interpretado. Ao fazer a instalação no seu computador, verifique se as seguintes alterações foram feitas no arquivo autoexec.bat (para o Windows 98): SET JAVA_HOME = C:\JDK1.4.1 (ou o nome que você usou) SET PATH = C:\JDK1.4.1\bin;%PATH%; ( idem ) SET CLASSPATH = C:\JDK1.4.1\LIB;.; ( idem )

9 Entendendo o programa AloMundo AloMundo apresenta vários recursos importantes de Java: // Um primeiro programa em Java 2 Comentário de linha. Um comentário de múltiplas linhas, de acordo com as especificações da ferramenta de documentação javadoc, segue a sintaxe: /** Um primeiro programa em Java 2 * Autor: Prof. Wander */ public class AloMundo Definição de classe para AloMundo. Todo programa java consiste de uma ou mais classes definidas pelo programador. As palavras reservadas de Java devem ser escritas sempre em minúsculas.

10 Os nomes de classes, por convenção, são escritos com todas as palavras iniciando com letras maiúsculas. Nomes de classes e quaisquer outros identificadores definidos pelo programador devem seguir as seguintes regras: pode conter letras, números, caractere de sublinhar e cifrão não pode começar com número não pode conter espaços em branco Uma chave esquerda { inicia o corpo de cada definição de classe. Uma chave direita } correspondente termina cada definição de classe. public static void main(String args[]) O método main é parte de todo aplicativo Java, que começa a execução a partir deste ponto. Um método pode ser definido como um bloco de construção de programa. Uma definição de classe em Java possui um ou mais métodos.

11 A palavra-chave void indica o tipo de retorno do método main. Isto significa que main não retorna valor algum. Uma chave esquerda { inicia o corpo de cada definição de método. Uma chave direita } correspondente termina cada definição de método. System.out.println("Alo, Mundo!"); System.out é o objeto de saída padrão. Permite exibir informações na janela de comando a partir da qual o aplicativo Java é executado. O método System.out.println exibe uma linha de texto na janela de comando. Ao final, o cursor é posicionado no início de uma nova linha. Um método alternativo é System.out.print cuja diferença consiste em manter o cursor imediatamente após o texto apresentado na janela de comando. Esta linha do programa Java constitui uma instrução. Toda instrução deve terminar com ponto-e-vírgula, chamado terminador de instrução.

12 "Alo, Mundo" é uma string de caracteres, e deve ser definida entre aspas duplas. Nem toda classe necessariamente deve possuir um método main e, portanto, ser um aplicativo Java. O exemplo a seguir ilustra isto: public class Teste { public static void main(String a[]){ AloMundo.Alo(); } class AloMundo { public static void Alo(){ System.out.println("Alo, mundo"); }

13 GUI em Java: pacote Swing Java possui dois pacotes de interfaces gráficas com o usuário. O mais antigo é a AWT (Abstract Windowing Toolkit), que utiliza os componentes gráficos nativos do sistema operacional. O exemplo abaixo emprega o pacote Swing ( javax.swing ), que emprega componentes gráficos Java. //AloMundo com interface grafica import javax.swing.JOptionPane; public class AloMundo2 { public static void main(String args[]) { JOptionPane.showMessageDialog( null,"Alô, Mundo!"); System.exit(0); } Após digitá-lo, salve com o nome da classe, ou seja: AloMundo2.java

14 Java possui uma extensa biblioteca de classes pré-definidas disponíveis para o programador. Estas classes são agrupadas em categorias de classes relacionadas, chamadas de pacotes. O conjunto de pacotes Java é denominado biblioteca de classes Java ou Java Application Programming Interface – API. O pacote javax.swing ajuda o programador a definir interfaces gráficas com o usuário (Graphical User Interfaces – GUIs) import javax.swing.JOptionPane; O comando import indica a localização da classe JoptionPane, presente no pacote de classes javax.swing Saída do programa AloMundo2.java :

15 JOptionPane.showMessageDialog(null,"Alô, Mundo!"); O método showMessageDialog requer dois argumentos, separados por vírgulas. O segundo argumento deve ser do tipo String. System.exit(0); O método exit() da classe System termina o programa. É obrigatório em todo programa que usa interface gráfica. O argumento 0 indica que o aplicativo terminou com sucesso. A classe System é parte do pacote java.lang, que é importado automatica- mente em todo programa Java. O método exit() termina a JVM após o encerramento da aplicação gráfica.

16 Variáveis Em Java, é necessário definir formalmente uma variável antes de utilizá-la. Isto implica em declarar o seu nome e tipo de informação que irá armazenar. int numero; String nome; double preco; boolean flag; É uma boa prática de programação definir uma variável por linha. Existem três tipos de variáveis em Java: locais, de instância e de classe. As variáveis locais podem ser declaradas em qualquer lugar dentro de um método. Uma boa prática de programação consiste em defini-las imediata- mente após a chave de abertura do método. Atenção: todas as variáveis locais precisam ser inicializadas antes de serem utilizadas, caso contrário, o compilador acusará erro!

17 As variáveis de instância podem ser declaradas em qualquer lugar dentro de uma classe. Uma boa prática de programação consiste em defini-las imediata- mente após a chave de abertura da classe. As definições de variáveis de instância, ao contrário das variáveis locais, rece- bem automaticamente um valor inicial padrão, especificado pelo compilador. Variáveis numéricas recebem 0, de caracteres, '\0', lógicas, false, objetos, null. class Teste { int numero; public static void main(String args[]) { Teste teste = new Teste(); System.out.println(teste.numero); } Uma variável de instância só pode ser referenciada em uma instância da classe.

18 As variáveis de classe, definidas pelo modificador static, podem ser declaradas em qualquer lugar dentro de uma classe. As definições de variáveis de classe, da mesma forma que as variáveis de instância, recebem automaticamente um valor inicial padrão, especificado pelo compilador. Variáveis numéricas recebem 0, de caracteres, '\0', lógicas, false, objetos, null. class Teste { static int numero; public static void main(String args[]) { System.out.println(numero); } Uma variável de classe pertence à classe, independe de qualquer instanciação de objetos da classe.

19 Tipos de dados Existem oito tipos de dados primitivos em Java para o armazenamento de inteiros, números de ponto flutuante, caracteres e valores lógicos. Ao contrário do que acontece em outras linguagens de programação, em Java estes tipos primitivos têm o mesmo tamanho e características em qualquer plataforma de hardware e sistema operacional. boolean 08 bits true ou false char 16 bits '\u0000' a '\uFFFF' byte 08 bits -128 a 127 short 16 bits -32.768 a 32.767 int 32 bits -2.147.483.648 a 2.147.483.647 long 64 bits até 9.223.372.036.854.775.807 float 32 bits até 3.40292347E+38 double 64 bits até 1.7976931348623157E+308 Obs.: Os caracteres Unicode são usualmente expressos em termos de um esquema de codificação hexadecimal. O prefixo \u indica um valor Unicode.

20 import javax.swing.JOptionPane; public class Teste { public static void main(String[] args) { JOptionPane.showMessageDialog(null,""+Double.MAX_VALUE); System.exit(0); } O exemplo acima ilustra a utilização de uma variável de classe, MAX_VALUE, da classe Double. Esta classe é chamada empacotadora ou wrapper. Cada um dos tipos primitivos Java possui a sua correspondente classe empacotadora. A variável de classe MAX_VALUE retorna o valor máximo do tipo primitivo utilizado, no caso, double.

21 Se o valor de uma variável não deve ser alterado durante a execução do aplicativo Java, você poderá usar uma variável constante, que é definida através da palavra-chave final. final double PI = 3.141592; final char CODIGO = '&'; Por convenção, programadores Java utilizam maiúsculas para definir nomes de constantes. Um outro conceito importante em Java é o de literal, que consiste em qualquer número – no caso de tipos numéricos – que representam diretamente um valor. public class Teste { public static void main(String a[]){ float total; total = 5.5; //Erro!! System.out.println(total); }

22 public class Teste { public static void main(String a[]){ float total; total = 5.5F; System.out.println(total); } O erro acontece porque Java trata todas as operações de ponto flutuante em double e a conversão de double para float não é automática. Também é possível declarar literais de ponto flutuante com expoentes: public class Teste { public static void main(String a[]){ double total; total = 1.0e5; System.out.println(total); }

23 Literais de caracteres são expressos por meio de um único caracter delimitado por apóstrofos. Alguns literais de caracteres úteis são apresentados abaixo: \n nova linha \t tabulação \b retrocesso \\ barra \' apóstrofo \" aspas public class Teste { public static void main(String a[]){ System.out.println("Clube Atletico Mineiro: \n\"Galo forte e vingador!\""); }

24 Saída de dados com printf Um novo recurso, introduzido em J2SE 5.0, é o método System.out. printf, capaz de formatar mais adequadamente uma saída em Java, em uma forma semelhante à função printf da linguagem C. public class Teste { public static void main(String[] a) { String s = "Atlético"; System.out.printf( " Grandioso %s\n",s); } Grandioso Atlético O primeiro argumento de printf é a string de formatação, composta de constantes string e caracteres de formatação. No exemplo acima, o delimitador % seguido de s indica que o método deve ter um outro argumento do tipo String.

25 Os caracteres de formatação podem também ser usados para compor uma String, usando o método String.format, conforme no exemplo a seguir: public class Main { public static void main(String[] args) { int a = 65; String s = String.format("char: %c integer: %d hexa: %h octal: %o",a,a,a,a); System.out.println(s); } Para o exemplo acima, onde é usado o mesmo argumento para a formatação, existem alternativas para a codificação: String s = String.format("char: %c integer: %<d hexa: %<h octal: %<o",a); String s = String.format("char: %1$c integer: %1$d hexa: %1$h octal: %1$o",a);

26 Entrada de dados com Scanner A leitura de dados de entrada em aplicativos através da janela de comando do sistema operacional era surpreendentemente complexa até a versão 1.4.2 do J2SE. Isto não era problema para aplicativos com recursos GUI, mas tornava-se desconfortável para estudantes interessados em escrever programas simples com o propósito de aprender Java. J2SE 5.0 introduz a classe java.util.Scanner para a entrada de dados, inclusive através da entrada padrão, System.in. O exemplo a seguir apresenta uma aplicação Java para a entrada de dois números pelo teclado e a saída da soma na janela de comando do sistema operacional. É necessário criar uma instância da classe Scanner, passando como argumento o objeto padrão de entrada, System.in, que irá capturar as entradas de dados via o teclado. O método nextInt(), da instância da classe Scanner, lê o valor digitado e o armazena em uma variável do tipo int.

27 import java.util.Scanner; public class Teste { public static void main(String[] args) { Scanner entrada = new Scanner(System.in); int num1; int num2; int soma; System.out.print("Entre com o primeiro número: "); num1 = entrada.nextInt(); System.out.print("Entre com o segundo número: "); num2 = entrada.nextInt(); soma = num1 + num2; System.out.printf("A soma é: %d", soma); } Um exemplo de saída do aplicativo acima: Entre com o primeiro número: 34 Entre com o segundo número: 23 A soma é: 57

28 O exemplo seguinte calcula o seno de um valor fornecido em tempo de execução: import java.util.Scanner; public class Teste { public static void main(String[] args) { Scanner entrada = new Scanner(System.in); double angulo; double seno; System.out.print("Entre com o ângulo em graus: "); angulo = entrada.nextDouble(); seno = Math.sin(Math.toRadians(ângulo)); System.out.println("Seno: " + seno); } O método nextDouble(), da classe Scanner, captura um double da entrada padrão System.in e o armazerna em uma variável do tipo double. A classe Math do pacote java.lang define a constante PI através de uma variável de classe. O método estático Math.sin(double) retorna o seno de um ângulo em radianos passado como argumento.

29 Import Static A versão J2SE 5.0 incorporou o recurso import static, que permite importar os métodos e atributos estáticos, permitindo utilizá-los sem o prefixo de classe. O código anterior pode ser reescrito, a partir da versão 5.0, conforme abaixo: import java.util.Scanner; import static java.lang.Math.*; public class Teste { public static void main(String[] args) { Scanner entrada = new Scanner(System.in); double angulo; double seno; System.out.print("Entre com o ângulo em graus: "); angulo = entrada.nextDouble(); seno = sin(toRadians(ângulo)); System.out.println("Seno: " + seno); }

30 Entrada de dados com Swing import javax.swing.JOptionPane; import static javax.swing.JOptionPane.*; public class Adição { public static void main(String[] args){ String s1, s2; int num1, num2, soma; s1 = JOptionPane.showInputDialog ("Entre com o 1º número"); s2 = JOptionPane.showInputDialog ("Entre com o 2º número"); num1 = Integer.parseInt(s1); num2 = Integer.parseInt(s2); soma = num1 + num2; JOptionPane.showMessageDialog(null,"A soma é " + soma, "Resultado", PLAIN_MESSAGE); System.exit(0); } O próximo exemplo apresenta uma solução para a soma de dois números inteiros usando o pacote javax.swing de interface gráfica de Java.

31 Esta versão do método showInputDialog da classe JOptionPane requer quatro argumentos. O primeiro será null. O segundo é a mensagem a ser exibida na caixa de diálogo. O terceiro é o texto a ser exibido na barra de título. O quarto é um valor que indica o ícone do tipo de diálogo de mensagem a ser exibido. No programa Adição.java, trocando-se o quarto argumento de JOptionPane para INFORMATION_MESSAGE, temos a seguinte saída para a caixa de diálogo:

32 O método parseInt(String) da classe Integer recebe como argumento um valor String e retorna o valor convertido em inteiros. Se o argumento não puder ser convertido, a máquina virtual Java lançará uma exceção do tipo NumberFormatException. public class ParseInt { static int i; public static void main(String[] args) { i = Integer.parseInt("um"); System.out.println(i); } As classes empacotadoras Double e Float, dentre outras, possuem também seus métodos parse, para a conversão do valor de um objeto String em tipos primitivos float e double, respectivamente. public class ParseDouble { public static void main(String[] args) { double d = Double.parseDouble( " 25.4 " ); System.out.println(d); }

33 Autoboxing A versão J2SE 5.0 incorporou o recurso denominado autoboxing, que consiste na conversão automática entre tipos primitivos e seus wrappers (classes empacotadoras). public class AutoBoxing { public static void main(String[] args) { int meuInt = 25; Integer meuInteger = meuInt; System.out.printf( " Integer: %d\tint: %d ", meuInteger, meuInt); } public class Unboxing { public static void main(String[] args) { Integer meuInteger = new Integer( " 12 " ); int meuInt = meuInteger; System.out.println(meuInt); }

34 Comando if / else import javax.swing.JOptionPane; public class ParImpar{ public static void main(String args[]) { String s; String resp = "O número "; int i; s = JOptionPane.showInputDialog( "Entre com o\nnúmero inteiro"); i = Integer.parseInt(s); if((i % 2) == 0) resp = resp + s + " é par!"; else resp = resp + s + " é ímpar!"; JOptionPane.showMessageDialog(null, resp, "Par ou Ímpar", JOptionPane.INFORMATION_MESSAGE); System.exit(0); }

35 Os operadores aritméticos em Java são representados da seguinte forma: + (soma), - (subtração), * (multiplicação), / (divisão), % (resto da divisão inteira). Os operadores relacionais em Java são representados da seguinte forma: == (igual), != (diferente), >, = e <=. O exemplo anterior contêm apenas uma única instrução associada as cláusulas if e else. Para incluir várias instruções no corpo do comando é necessário chave de abertura { e fechamento } de bloco. public class Modulo { public static void main(String[] args) { System.out.print(5.5 % 2); }

36 O exemplo anterior faz uma comparação entre uma variável e um literal do tipo primitivo int. Cuidado com expressões relacionais para comparar objetos, ao invés de tipos primitivos. import java.util.Scanner; public class Teste { public static void main(String[] args) { Scanner entrada = new Scanner(System.in); String string; System.out.print("Digite Sim: "); string = entrada.nextLine(); if(string == "Sim") System.out.println("Iguais"); else System.out.println("Diferentes"); } O resultado impresso será Diferentes, uma vez que o objeto sim referencia uma posição de memória diferente do literal Sim.

37 Para comparar se o conteúdo de dois objetos String são idênticos, uma sugestão é empregar o método equals() da classe String. import java.util.Scanner; public class Teste { public static void main(String[] args) { Scanner entrada = new Scanner(System.in); String string; System.out.print("Digite Sim: "); string = entrada.nextLine(); if(string == "Sim") System.out.println("Iguais"); else System.out.println("Diferentes"); } Outros dois métodos da classe String são equalsIgnoreCase(), seme- lhante a equals() e charAt(), que obtém o tipo primitivo char corres- pondente a posição informada como argumento para o método.

38 Um applet Java simples import javax.swing.JApplet; import java.awt.Graphics; public class AloMundoApplet extends JApplet { public void paint(Graphics g){ g.drawString("Alô, Mundo!",25,25); } Para executar o programa acima em um browser, é necessário um arquivo html do tipo AloMundoApplet.html, que carrega a classe AloMundoApplet : Um applet Java é um tipo especial de programa que é executado em um navegador de páginas da World Wide Web.

39 A palavra-chave extends indica que a classe AloMundoApplet é uma subclasse (ou classe derivada) de JApplet (chamada superclasse ou classe básica). A classe JApplet faz parte do pacote javax.swing. Herança: AloMundoApplet herda to- dos os atributos (dados) e comportamen- tos (métodos) da classe JApplet. AloMundoApplet sobrescreve o método paint da classe JApplet. Este método requer como parâmetro um objeto da classe Graphics, por convenção nomeado por g, usado por paint para desenhar imagens no applet. A classe Graphics pertence ao pacote java.awt. O método drawString da classe Graphics desenha o string de caracteres Alô, Mundo! no applet, a partir da posição 25 pixels na horizontal e 25 pixels, na vertical. A origem das coordenadas é o canto superior esquerdo do applet.

40 Para executar um applet é necessário criar um arquivo de html. O utilitário appletviewer permite carregar o arquivo html e este, por sua vez, carrega o applet. Para executá-lo, use appletviewer AloMundoApplet.html Os componentes width e height do tag indicam respectiva- mente a largura e a altura do applet, em pixels, no navegador. Cuidado! Se você não definir os componentes de largura e altura adequadamente em html, seu applet pode não ser desenhado correta- mente na tela. Se você estiver utilizando o editor de programas TextPad ou o ambiente de desenvolvimento Eclipse, não será necessário criar o arquivo html, uma vez que ele o fará automaticamente e executará o seu applet no applet viewer da Sun. Ao utilizar o ambiente integrado BlueJ, você poderá ainda escolher se deseja executar o applet através do appletviewer ou do navegador instalado em seu computador.

41 import javax.swing.*; import java.awt.*; public class AloMundo2Applet extends JApplet { public void paint(Graphics g) { g.setColor(Color.red); g.drawLine(15,10,210,10); g.drawLine(15,30,210,30); g.drawString("Alô, Mundo!",25,25); } O método setColor(Color.red) de- fine a cor vermelha para a instância g da classe Graphics. red é uma constante da classe Color do pacote java.awt. O método drawLine da classe Graphics desenha linhas no applet. Os 4 argumentos referem-se as coordenadas x e y do pixel inicial e do pixel final da linha a ser desenhada.

42 public class Soma { public static void main(String[] args) { int i = 1; int soma = 0; while (i <= 100) { soma = soma + i; i = i + 1; } System.out.println(soma); } Estrutura de repetição while É necessário uma chave de abertura { e uma chave de fechamento } de bloco, delimitando o conjunto de instruções associadas a estrutura de repetição.

43 import java.text.DecimalFormat; import java.util.Scanner; public class Teste { public static void main(String args[]) { Scanner entrada = new Scanner(System.in); byte n = 0; //contador de notas int nota, soma = 0; double media; System.out.print("Nota do aluno, -1 termina: "); nota = entrada.nextInt(); while (nota != -1) { soma = soma + nota; n = (byte) (n + 1); System.out.print("Nota do aluno, -1 termina: "); nota = entrada.nextInt(); } DecimalFormat df = new DecimalFormat("0.00"); if (n != 0) { media = soma / n; System.out.println("Media igual a " + df.format(media)); } else System.out.println("Nenhuma nota foi digitada"); }

44 O pacote java.text disponibiliza classes para formatação de valores e expressões. A classe DecimalFormat é usada neste exemplo. O formato 0.00 especifica que a saída terá pelo menos um dígito à esquerda do ponto decimal e exatamente dois dígitos à direita do ponto decimal. O método format desta classe é usado para formatar uma variável do tipo primitivo double. Este exemplo apresenta um operador de coerção explícita (casting) para converter o resultado da expressão (n + 1) em um valor do tipo byte. Esta conversão é necessária porque o literal 1 é do tipo int o que implica que a expressão retornará um valor também do tipo int. public class CoercaoExplicita { public static void main(String[] args) { float f; f = (float) 5.5; System.out.print(Float.toString(f)); }

45 A partir de J2SE 5.0, a classe Formatter, através do método printf, também pode ser usada para a formatação da saída em System.out. import java.util.Scanner; import static java.lang.Math.*; public class Teste { public static void main(String args[]){ double raio; double area; Scanner entrada = new Scanner(System.in); System.out.print("Informe o raio do círculo: "); raio = entrada.nextDouble(); area = PI * pow(raio, 2); System.out.printf ("A area do circulo equivale a %6.2f", area); } O método estático Math.pow(base,exp) implementa a exponenciação. Este método recebe dois argumentos double e retorna um valor double.

46 A tabela a seguir apresenta alguns códigos de formatação da classe Formatter e usados em System.out.printf. f número de ponto flutuante em formato fixo e,E número de ponto flutuante em notação exponencial (formato científico) g,G número em ponto flutuante em formato genérico (fixo para números pequenos e exponencial para grandes) d inteiros em decimal. o número inteiro em octal x,X Número inteiro em hexadecimal s,S converte qualquer valor e apresenta em string t,T formato para data e hora (com códigos adicionais para dia, mês, ano, etc.)

47 import java.util.Date; public class Teste { public static void main(String args[]){ System.out.printf("Hoje: %1$td de %1$tB de %1$tY", new Date()); } A classe Date instancia um objeto contendo a data e hora do sistema operacional. Os caracteres de formatação d, B e Y exibem, respectivamente, o dia, com 2 caracteres, o mês, por estenso, e o ano, com 4 dígitos. A tabela de caracteres de formatação para data e hora contempla diversas outras possibilidades de apresentação. Hoje: 05 de Janeiro de 2005

48 Operadores de Atribuição Java herda de C/C++ a característica dos operadores de atribuição, usados para abreviar as expressões de atribuição. +=c += 7c = c + 7 -=d -= 4d = d – 4 *=e *= 5e = e * 5 /=f /= 3f = f / 3 %=g %= 2g = g % 2 OperadorExpressãoEquivalência Também estão disponíveis em Java o operador unário de incremento ++ e o operador unário de decremento --. ++ pré-fixado ++a ++ pós-fixado a++ -- pré-fixado --b -- pós-fixado b--

49 public class Incremento { public static void main(String args[]) { int i; i = 1; System.out.println(i); System.out.println(i++); System.out.println(i); i = 1; System.out.println(i); System.out.println(++i); System.out.println(i); } 112122112122 Os operadores de incremento e decremento ( ++ e -- ) incrementam e decrementam variáveis de tipo inteiro de uma unidade. Na forma pré-fixada o operador modifica o valor da variável antes que o valor seja usado na expressão. Na forma pós-fixada o operador modifica o valor da variável depois que o valor é usado na expressão onde está a variável.

50 Estrutura de repetição for Exemplo de Applet Java utilizando a estrutura de repetição for. Observe que não foi necessário definir chaves de abertura e fechamento para delimitar um bloco de comandos associados ao for, uma vez que só há uma linha de instrução. import java.awt.Graphics; import javax.swing.JApplet; public class TesteFor extends JApplet { public void paint(Graphics g) { for (int i = 1; i <= 10; i++) g.drawLine(10, 10, 250, i * 10); } A estrutura for em Java é constituída de um valor inicial, um teste e um passo, delimitados por ponto-e-vírgula.

51 import javax.swing.JOptionPane; import static javax.swing.JOptionPane.*; public class SomaPar { public static void main(String args[]) { int soma = 0; for (int i = 2; i <= 100; i += 2) soma += i; JOptionPane.showMessageDialog(null, "Valor da soma: " + soma, "Soma dos pares até 100", INFORMATION_MESSAGE); System.exit(0); } Exemplo: programa para somar os números pares entre 0 e 100, usando laço for.

52 import javax.swing.*; public class Potencia { public static void main(String args[]) { double potencia; JTextArea area = new JTextArea(); area.setText("Numero\tQuadrado\n"); for (int i = 1; i <= 10; i++) { potencia = Math.pow(i, 2); area.append("" + i + '\t' + potencia + '\n'); } JOptionPane.showMessageDialog(null, area, "Quadrado dos numeros de 1 a 10", JOptionPane.INFORMATION_MESSAGE); System.exit(0); } Exemplo: programa para calcular a potência de 2 dos números inteiros de 1 a 10. Java não possui um operador nativo para exponenciação.

53 Este exemplo utiliza a classe JTextArea do pacote javax.swing. Esta classe define um componente GUI capaz de armazenar e exibir múltiplas linhas de texto. Os métodos setText(String) e append (String) permitem, respectivamente, atribuir e acrescentar Strings na instância da classe JTextArea. public class TestaFor { static int i; public static void main(String[] args) { for( ; i < 10; ) System.out.print(i++ + " "); } Uma estrutura for pode ser construída sem um ou mais de seus componentes.

54 Estrutura de seleção múltipla switch import javax.swing.*; public class Calculadora { public static void main(String args[]) { String s1, s2, s3; float f1, f2, f3=0; char c; s1 = JOptionPane.showInputDialog("Primeiro operando: "); s2 = JOptionPane.showInputDialog("Segundo operando: "); s3 = JOptionPane.showInputDialog("Operador aritmético: "); f1 = Float.parseFloat(s1); f2 = Float.parseFloat(s2); c = s3.charAt(0); switch (c) { case '+' : f3 = f1 + f2; break; case '-' : f3 = f1 - f2; break; case '*' : case 'x' : f3 = f1 * f2; break; case '/' : f3 = f2 / f1; break; default: } JOptionPane.showMessageDialog(null, "Resultado: " + f3, "calculadora", JOptionPane.INFORMATION_MESSAGE); System.exit(0); }

55 A variável ou expressão de controle da estrutura de seleção switch deve assumir um valor inteiro, ou seja, do tipo byte, short, int ou char. O comando break é necessário para impedir que a execução do programa continue nas cláusulas case seguintes. A cláusula default não é obrigatória. O método charAt() da classe String permite selecionar o caracter cuja posição é especificada como parâmetro. A posição inicial corresponde a 0.

56 Estrutura de repetição do/while A estrutura do/while testa a condição de continuação do laço depois do corpo do laço ser executado. Portanto, o corpo do laço sempre é executado pelo menos uma vez. public class TestaDoWhile { public static void main(String args[]) { byte i; do { i = (byte) (Math.random() * 10); System.out.print(i + " "); } while (i != 0); } O método random() da classe Math gera um número aleatório do tipo double compreendido entre 0, inclusive, e 1, exclusive. Não é necessário o comando import para a classe Math, que pertence ao pacote java.lang.

57 Operadores Lógicos Java possui vários operadores lógicos que podem ser utilizados para obter combinações lógicas do tipo AND, OR, XOR e NOT. Para combinações AND, os operadores lógicos & e && são utilizados. Se & for empregado, as expressões em ambos os lados são avaliadas. Para combinações OR, os operadores lógicos | e || são utilizados. A combina- ção XOR possui o operador lógico ^. Isto resulta em um valor true se a expressão contiver um valor true e um false. A combinação NOT utiliza o operador lógico !. public class TestaOR1 { public static void main(String args[]) { int i = 2; int j = 3; if((j == i++) | (i < ++j)) System.out.println("i = " + i + " j = " + j); }

58 public class TestaOR2 { public static void main(String args[]) { int i = 2; int j = 3; if((j == i++) || (i < ++j)) System.out.println("i = " + i + " j = " + j); } Os dois exemplos retornam o mesmo resultado. Na prática, para avaliação de expressões lógicas, recomenda-se empregar os operadores && e ||. public class TestaXOR { public static void main(String args[]) { int i = 2; int j = 3; if((j == i++) ^ (i < ++j)) System.out.println("XOR OK"); else System.out.println("XOR not OK"); }

59 Métodos A maioria dos programas de computador usados profissionalmente são muito mais extensos do que os exemplos apresentados. A abordagem para grandes programas é construí-los a partir de pequenas partes ou módulos. Os módulos em Java são chamados métodos e classes. Os programas são escritos combinando novos métodos e classes do usuário com métodos e classes disponíveis na Java API e também com métodos e classes já disponibilizados por outros programadores. Cada método deve se limitar a executar uma única e bem definida tarefa e o nome do método deve efetivamente expressar isto. import java.util.Scanner; public class NomeUsuario { public static void main(String args[]) { Scanner ent = new Scanner(System.in); System.out.print("Digite seu nome: "); String nome = ent.nextLine(); System.out.println("Olá, %s", nome); }

60 Neste exemplo, a classe NomeUsuario, definida pelo programador, invoca o método readLine da classe Console. A definição desta classe encontra-se no pacote corejava. Esta classe não faz parte da Java API. Foi escrita por outros programadores Java e disponibilizada para uso em [Horstmann, 2001]. A classe do usuário Saudação abaixo, utiliza um método definido pelo usuário chamado imprime. Este método possui um argumento do tipo String e não retorna nenhum valor. É um método do tipo void. import java.util.Scanner; public class Saudação { public static void main(String args[]) { Scanner entrada = new Scanner(System.in); String nome = entrada.nextLine(); imprime(nome); } static void imprime(String s){ System.out.printf("Olá, %s", s); }

61 public class QuadInt { public static void main(String args[]) { int i; for(int x = 1; x <= 10; x++) { i = quadrado(x); System.out.printf ("Quadrado de %02d: %03d\n", x, i); } //Método quadrado public static int quadrado(int y){ return (int) Math.pow(y, 2); } A classe do usuário QuadInt utiliza um método definido pelo usuário chamado quadrado. Este método possui um argumento do tipo int e retorna um valor também do tipo int.

62 import javax.swing.*; import java.awt.*; public class Celsius extends JApplet { double c; double f; public void init() { String sc; sc = JOptionPane.showInputDialog ("Entre com a temperatura\nem graus Celsius"); c = Double.parseDouble(sc); f = ( 9 * c ) / 5 + 32; } public void paint(Graphics g) { g.drawString("A temperatura " + c + "°C equivale a " + f + "°F", 25, 25); } A classe do usuário Celsius sobrescreve os métodos init() e paint() de JApplet. Em um applet, o método paint() deve ser usado unicamente para formatar uma saída utilizando métodos da classe Graphics.

63 Regras de Escopo Todos os exemplos vistos até aqui utilizam identificadores para nomes de variáveis e de objetos. Identificadores também são usados para nomear classes e métodos definidos pelo usuário. Cada identificador tem como atributos a duração e o escopo. A duração ou tempo de vida é o período durante o qual o identificador existe na memória. O escopo diz respeito ao local onde o identificador pode ser referenciado no programa. public class Escopo { int x = 1; public static void main(String args[]) { Escopo escopo = new Escopo(); int x = 5; System.out.println("x vale " + x); escopo.metodoA(); escopo.metodoB(); escopo.metodoA(); escopo.metodoB(); System.out.println("x vale " + x); }

64 public void metodoA() { int x = 25; System.out.println("x em A vale " + x); x++; System.out.println("x em A vale " + x); } public void metodoB() { System.out.println("x em B vale " + x); x *= 10; System.out.println("x em B vale " + x); } x vale 5 x em A vale 25 x em A vale 26 x em B vale 1 x em B vale 10 x em A vale 25 x em A vale 26 x em B vale 10 x em B vale 100 x vale 5 Uma variável local só é visível no método onde foi criada, este é o seu escopo. Uma variável de instância é visível em todo o contexto da instância da classe, este é o seu escopo. Uma variável de classe é visível por todas as instâncias da classe. Duração: uma variável local existe apenas durante a execução do método. Uma variável de instância existe durante a existência da instância da classe.

65 Sobrecarga de Métodos Java permite que vários métodos com o mesmo nome sejam definidos, contanto que tais métodos tenham diferentes conjuntos de parâmetros. Esta característica é chamada sobrecarga de métodos. public class Sobreposicao { public static void main(String args[]) { Sobreposicao sobre = new Sobreposicao(); System.out.println("Quadrado de 3: " + sobre.quadrado(3)); System.out.println("Quadrado de 3.5: " + sobre.quadrado(3.5)); } public int quadrado(int i) { return i*i; } public double quadrado(double f) { return f*f; }

66 Métodos sobrecarregados são distinguidos por sua assinatura, ou seja, uma combinação do nome do método e seu tipo de parâmetro. public class Area { public static void main(String args[]) { Area area = new Area(); System.out.println("Área quadrado.:" + area.area(3)); System.out.println("Área retângulo:" + area.area(3,4)); System.out.println("Área cubo.....:" + area.area(3,2,3)); } public int area(int i) { return i * i; } public int area(int i, int j) { return i * j; } public int area(int i, int j, int k) { return i * j * k; }

67 Arrays Um array é um grupo de posições contíguas na memória que possuem o mesmo nome e o mesmo tipo. Em java, os arrays são tratados como objetos e, portanto, devem ser instanciados com o comando new. int[] array;//declara o array int array[];//declara o array array = new int[12]; //instancia o array Quando um array é instanciado, seus elementos são automaticamente inicializa- dos com zero para tipos de dados numéricos e null para referências a objetos. Em Java, o primeiro elemento de um array é sempre referenciado pelo índice 0. O array array acima, poderá ser referenciado pelos índices de 0 a 11. int[] array = new int[12]; // ou... int array[] = new int[12]; Que também pode ser escrito na forma:

68 import javax.swing.*; public class Array { public static void main(String args[]) { String saida = ""; int[] i; i = new int[10]; saida += "Índice - Valor\n"; for (int j = 0; j < i.length; j++) { i[j] = (int) (Math.random() * 10); saida += j + " - " + i[j] + "\n"; } JOptionPane.showMessageDialog(null, saida, "Inicializando um array", JOptionPane.INFORMATION_MESSAGE); System.exit(0); } A variável de instância length é a forma adequada de "percorrer" os elementos de um array em Java.

69 Os elementos de um array podem ser alocados e inicializados na sua própria declaração. O exemplo abaixo especifica um array instanciado implicitamente com 4 elementos. String nomes[] = {"Ana", "José", "Maria", "Rita"}; Os arrays, ao serem instanciados, sempre alocam valores iniciais para os seus elementos, mesmo que declarados como variáveis locais. public class TestaArray { public static void main(String[] args) { byte[] array; array = new byte[5]; for(byte i = 0; i < array.length; i++) System.out.println(array[i]); } Se você tentar acessar um elemento cujo índice seja inexistente, lança- rá uma exceção do tipo ArrayIndexOutOfBoundsException.

70 Passando arrays para métodos Existem duas maneiras de se passar argumentos para métodos: por valor e por referência. Em java, variáveis de tipo primitivo são sempre passadas por valor e objetos, incluindo arrays, são sempre passados por referência. public class Parametro { public static void main(String[] args) { int[] array = {1, 2, 3, 4, 5}; System.out.println("Valores originais do array:"); for(int i = 0; i < array.length; i++) System.out.print(array[i] + " "); Parametro p = new Parametro(); p.modificaArray(array); System.out.println("\nValores modificados no metodo:"); for(int i = 0; i< array.length; i++) System.out.print(array[i] + " "); System.out.println ("\nValor de a[3] antes da passagem: " + array[3]); p.modificaElemento(array[3]); System.out.println ("Valor de a[3] depois da passagem: " + array[3]); }

71 public void modificaArray(int[] a) { for(int j = 0; j < a.length; j++) a[j] *= 2; } public void modificaElemento(int e) { e *= 2; } Valores originais do array: 1 2 3 4 5 Valores modificados no metodo: 2 4 6 8 10 Valor de a[3] antes da passagem: 8 Valor de a[3] depois da passagem: 8 Para passar um array como argumento para um método, basta especi- ficar o nome da instância, sem colchetes.

72 Arrays multidimensionais Arrays com dois índices são utilizados normalmente para representar tabelas de valores consistindo de informações organizadas em linhas e colunas. Em java, um array bidimensional, do tipo m[2][2], pode ser declarado e inicializado com: int[][] m = {{1, 2}, {3, 4}}; O exemplo abaixo apresenta algumas das potencialidades de arrays em Java: public class Arrays { public static void main(String[] args) { String[][] s1 = new String[2][2]; s1[0][0] = "Rita"; String[] s2 = {"Julia", "Augusto"}; s1[1] = s2; for(int i = 0; i < s1.length; i++) for(int j = 0; j < s1[i].length; j++) System.out.println(s1[i][j]); } Rita null Julia Augusto

73 Estrutura for each J2SE 5.0 apresenta a estrutura for each, capaz de fazer a iteração de arrays (e também outras estruturas de dados avançadas de Java). public class TestaForEach { public static void main(String args[]) { int[] array = new int[10]; for(int i : array) { array[i] = (int) (Math.random() * 10); System.out.printf("%02d\n",array[i]); } A nova estrutura for each torna a iteração de arrays mais simples e elegante, e deve ser empregada sempre que possível pelo programador Java.

74 Parâmetros na linha de comando Os argumentos digitados na linha de comando são passados para o método main() da classe invocada por meio de um vetor de Strings. Por exemplo, se for executada a linha de comando java Teste um dois três o método main() da classe Teste receberá o seguinte vetor de Strings : args[0] = "um" args[1] = "dois" args[2] = "três" O espaço serve como separador de argumentos. Se for necessário tratar uma cadeia de caracteres com espaço como um único argumento será preciso delimitá- la com aspas duplas. Assim, o comando java teste um "dois três" resulta no seguinte vetor: args[0] = "um" args[1] = "dois três" O exemplo a seguir imprime a soma dos argumentos passados na linha de comando.

75 public class Argumentos { public static void main(String[] args) { int soma = 0; for(int i = 0; i < args.length; i++) soma += Integer.parseInt(args[i]); System.out.print("Soma dos argumentos: "); System.out.println(soma); } Para uma entrada do tipo java Argumentos 1 2 3 4 a saída será: Soma dos argumentos: 10

76 Strings Em Java, uma cadeia de caracteres é sempre um objeto da classe java.lang. String. Não existe um tipo primitivo para armazenar cadeias de caracteres. String s1; s1 = new String("abcdef"); String s2 = "ghijkl"; É possível instanciar um objeto da classe String usando o operador new ou atribuindo o valor diretamente, conforme acima. public class Strings { public static void main(String[] args) { String s1 = new String("abcdef"); String s2 = s1; if(s1 == s2) System.out.print("s1 igual a s2"); else System.out.print("s1 diferente de s2"); }

77 No exemplo anterior, a referência para a instância s2 é apontada para o mesmo endereço de memória da instância s1, logo a saída da aplicação será: s1 igual a s2 public class Strings2 { public static void main(String[] args) { String s1 = new String("abcdef"); String s2 = "abcdef"; if(s1 == s2) System.out.print("s1 igual a s2"); else System.out.print("s1 diferente de s2"); } s1 diferente de s2 Neste caso, a nova instância s2 criada referencia um endereço de memória diferente daquele apontado pela instância s1. Trata-se de objetos distintos!

78 Uma instância da classe String é um objeto imutável. public class Strings3 { public static void main(String[] args) { String s1 = "abc"; String s2 = s1; s1 = s1.concat("def"); if(s1 == s2) System.out.print("s1 igual a s2"); else System.out.print("s1 diferente de s2"); } s1 diferente de s2 Sendo um objeto String imutável, a linha s1 = s1.concat("def"); irá passar a referência ao objeto s1 para um outro endereço de memória. Assim, as instâncias s1 e s2 não mais referenciam à mesma posição de memória.

79 public class Strings4 { public static void main(String[] args) { for(int i = 0; i < args.length; i++) System.out.print(args[i].length()); } A classe String possui o método length(), que retorna o tamanho da cadeia de caracteres. Lembre-se que arrays possuem um atributo length que contém o tamanho do array. Para uma execução do tipo java Strings4 Clube Atlético Mineiro, a saída é: 587 Como regra geral, os métodos que modificam o conteúdo de instâncias da classe String, como concat(), visto na página anterior, passam a referenciar para uma nova posição de memória.

80 Classe StringBuffer A classe StringBuffer é uma alternativa mais adequada para a manipulação de cadeias de caracteres quando for necessário fazer muitas alterações nos valores armazenados. Ao contrário da classe String, objetos da classe StringBuffer podem ser alterados sem que a MVJ modifique a referência na memória. public class TestaStringBuffer { public static void main(String[] args) { StringBuffer sb1 = new StringBuffer("abc"); StringBuffer sb2 = sb1; sb1 = sb1.append("def"); if(sb1 == sb2) System.out.print("sb1 igual a sb2"); else System.out.print("sb1 diferente de sb2"); }

81 sb1 igual a sb2 O método append() da classe StringBuffer altera o valor da instância sb1, mantendo a referência a mesma posição de memória. Assim, sb2 e sb1 continuam apontando para o mesmo endereço. StringBuffer sb = new StringBuffer(); String s = "abcdef"; sb = s; Não é possível fazer uma conversão direta de String para StringBuffer, conforme visto abaixo: O método append() da classe StringBuffer pode ser usado para este fim: StringBuffer sb = new StringBuffer(); String s = "abcdef"; sb.append(s); Para converter um objeto StringBuffer em String, deve empregar o método toString() : s = sb.toString();

82 Enumerated Types J2SE 5.0 incorpora (finalmente!) o recurso de tipos enumerados, comum em C/C++. Um enum é um tipo especial de classe, definida em java.lang.Enum. public class TestaEnums { enum Times {ATLÉTICO, VASCO, GRÊMIO, CORITIBA, BAHIA}; public static void main(String[] args) { for(Times time : Times.values()) System.out.printf("%s\n", time); } ATLÉTICO VASCO GRÊMIO CORITIBA BAHIA Cada identificador (ex.: Times.ATLÉTICO ) é um objeto da classe Enum.

83 import java.util.EnumSet; public class Teste { enum Semana {DOMINGO, SEGUNDA, TERÇA, QUARTA, QUINTA, SEXTA, SÁBADO}; public static void main(String[] args){ for(Semana dia : EnumSet.range (Semana.SEGUNDA, Semana.SEXTA)) System.out.println(dia); } É possível percorrer parte de um enum usando o método java.util. EnumSet.range, conforme no exemplo que se segue. Uma outra situação recomendada para o uso de enums é em comandos de seleção múltipla switch, conforme exemplo que se segue.

84 import java.util.Scanner; public class Teste { enum Operador {MAIS, MENOS, VEZES, DIVIDIDO_POR}; public static void main(String[] args) { double x = Double.parseDouble(args[0]); double y = Double.parseDouble(args[1]); double res = 0; for (Operador op : Operador.values()) { switch(op) { case MAIS: res = x + y; break; case MENOS: res = x - y; break; case VEZES: res = x * y; break; case DIVIDIDO_POR:res = x / y; } System.out.printf("%2.2f %s %.2f = %2.2f\n", x, op, y, res); }

85 Programação baseada em objetos Em linguagens como Pascal e C, a programação é orientada à ação. Em Java, a programação é orientada a objetos. Os programadores Java concentram-se em escrever seus próprios tipos definidos pelo usuário, chamados classes. Cada classe contém dados (atributos) bem como o conjunto de métodos que manipulam os dados. class Produto extends Object { public int codigo; public String nome; public int quantidade; public double preco; public Produto(int c, String n, int q, double p){ codigo = c; nome = n; quantidade = q; preco = p; }

86 O exemplo anterior mostra a declaração de uma classe do usuário chamada Produto que contém quatro atributos: codigo, nome, quantidade e preco. public class Produto extends Object indica que a classe do usuário Produto estende a classe Object (do pacote Java.lang ). Na realidade, o usuário nunca cria uma classe a partir do zero. Neste exemplo, a classe Produto herda os atributos (dados) e comportamentos (métodos) da classe Object. A palavra-chave public é um modificadores de acesso aos membros da classe. O modificador public indica que o acesso é permitido a outras classes. A classe Produto possui um método chamado Produto. Este é o método construtor da classe. Um construtor é um método especial que inicializa as variáveis de instância de um objeto de classe. O método construtor somente pode ser invocado em um comando new, para instanciar um novo objeto da classe.

87 Utilize agora o BlueJ para instanciar alguns objetos da classe Produto. Você pode acessar os atributos de cada um dos objetos dando um duplo clique sobre o ícone das instâncias. Você pode criar uma nova instância da classe Produto clicando com o botão direito do mouse sobre o ícone da classe.

88 class TestaProd { public static void main(String a[]){ String s = " "; Produto produto; produto = new Produto(10, "Sabonete", 12, 1.20); System.out.println(produto.codigo + s + produto.nome); System.out.println(produto.quantidade + s + produto.preco); produto.quantidade = 100; System.out.println(produto.quantidade + s + produto.preco); produto.preco *= 1.10; System.out.println(produto.quantidade + s + produto.preco); } Inclua uma nova classe do usuário TestaProd em seu projeto no BlueJ. A classe TestaProd declara uma variável produto do tipo Produto e a instancia, através do comando new, que invoca o método construtor.

89 A linha tracejada indica que a classe TestaProd usa métodos e/ou atributos da classe Produto. Atente para o importante fato de que a classe TestaProd só conseguiu acessar diretamente os atributos da classe Produto porque estes foram declarados como public. O que aconteceria se eles fossem declarados como private ?

90 class Empregado { private String nome; private double salario; //Método Construtor public Empregado(String n, double s) { nome = n; salario = s; } public void print() { System.out.println(nome + " " + salario); } public void aumentaSalario(double percentual) { salario *= 1 + percentual / 100; } Os modificadores de acesso tem por objetivo definir a visibilidade de um membro de uma classe (atributo ou método) em relação à outras classes. O modificador private permite ao acesso apenas aos membros da própria classe.

91 public class TestaEmpregado { public static void main(String args[]) { Empregado[] empregado = new Empregado[3]; empregado[0] = new Empregado("Rita", 1000); empregado[1] = new Empregado("Maria", 1200); empregado[2] = new Empregado("Julia", 1500); for(int i = 0; i < empregado.length; i++) { empregado[i].aumentaSalario(5); empregado[i].print(); } Observe que empregado é um array de instâncias da classe Empregado, contendo 3 objetos desta classe. Rita 1050.0 Maria 1260.0 Julia 1575.0

92 Os modificadores de acesso disponíveis são apresentados na tabela abaixo: ModificadorDescrição default Somente classes do mesmo pacote possuem acesso public Todos possuem acesso private Apenas os membros da classe protected Idêntico a default, com uma exceção: O modificador protected, além de permitir o acesso a membros do mesmo pacote, permite o acesso a partir de subclasses, ainda que em outros pacotes. O modificador default é assumido, caso nenhum dos demais modificadores seja especificado. Não existe uma palavra reservada default em Java.

93 Sobrecarga de construtores Os métodos de uma classe podem ser sobrecarregados. Para sobrecarregar um método construtor, simplesmente forneça uma definição separada de cada um dos métodos sobrecarregados. Tais métodos devem possuir listas de parâme- tros diferentes. class Empregado { private String nome; private double salario; public Empregado(String n, double s) { nome = n; salario = s; } public Empregado(String n) { nome = n; salario = 500; }

94 Métodos set e get As variáveis de instância definidas como privadas só podem ser manipuladas através de métodos da própria classe. Todavia, as classes podem fornecer métodos public para permitir a clientes da classe atribuir valores ( set ) ou obter ( get ) variáveis de instância declarados como private. public class Cliente { private String nome; private String endereco; private String telefone; public Cliente(String n, String e, String t) { nome = n; endereco = e; telefone = t; } public void setNome(String n) {nome = n;} public void setEndereco(String e) {endereco = e;} public void setTelefone(String t) {telefone = t;} public String getNome() {return nome;} public String getEndereco() {return endereco;} public String getTelefone() {return telefone;} }

95 public class TestaCliente { public static void main(String args[]) { Cliente fulano = new Cliente ("Fulano", "Rua Halfeld", "3213-5000"); Cliente beltrano = new Cliente ("Beltrano", "Rua Marechal", "3224-1000"); System.out.println("Cliente 1: " + fulano.getNome()+ ", " + fulano.getEndereco() + ", " + fulano.getTelefone() + "\n"); System.out.println("Cliente 2: " + beltrano.getNome() + ", "+ beltrano.getEndereco() + ", " + beltrano.getTelefone() + "\n"); fulano.setNome("Ciclano"); beltrano.setEndereco("Rua Sao Joao"); fulano.setTelefone(beltrano.getTelefone()); System.out.println("Cliente 1: " + fulano.getNome()+ ", " + fulano.getEndereco() + ", " + fulano.getTelefone() + "\n"); System.out.println("Cliente 2: " + beltrano.getNome() + ", "+ beltrano.getEndereco() + ", " + beltrano.getTelefone() + "\n"); }

96 Os nomes dos métodos de para atribuir e obter valores das variáveis de instância das classes não tem que ser necessariamente set e get, mas esta é uma boa prática de programação em Java. Cliente 1: Fulano, Rua Halfeld, 3213-5000 Cliente 2: Beltrano, Rua Marechal, 3224-1000 Cliente 1: Ciclano, Rua Halfeld, 3224-1000 Cliente 2: Beltrano, Rua Sao Joao, 3224-1000

97 Varargs J2SE 5.0 apresenta um novo recurso denominado varargs, que permite passar um número variável de argumentos a um método, sem a necessidade de encapsulá-lo em um array, por exemplo. class VarOla { public static void printSaudação(String... nomes) { for(String n : nomes) { System.out.println("Olá " + n + ". "); } public static void main(String[] args) { printSaudação("Wander", "Rita", "Julia","Augusto"); } A declaração de um argumento como varargs é denotada pelo seu tipo seguido de reticências (...) e o nome.

98 Em tempo de compilação, um varargs é convertido para um array. Isto explica porque o código abaixo executa sem problemas, alterando a clássica assinatura do método main. class VarOla { public static void printSaudação(String... nomes) { for(String n : nomes) { System.out.println("Olá " + n + ". "); } public static void main(String... args) { printSaudação(args); } A Sun, inclusive, aconselha o uso de varargs em lugar de arrays na assinatura do método main.

99 Sobrecarga com Varargs O exemplo a seguir ilustra o comportamento do compilador Java no caso de haver métodos sobrecarregados com e sem varargs disputando a execução. public class QualMétodo { QualMétodo(Integer... size) { System.out.println("Versão com varargs"); } QualMétodo(int i, int j) { System.out.println("Versão com tipo int"); } QualMétodo(Integer i, Integer j) { System.out.println("Versão com Integer"); } public static void main(String[] args) { System.out.println("Chamada com tipo int"); new QualMétodo(2, 3); System.out.println("Chamada com Integer"); new QualMétodo(new Integer(2), new Integer(3)); }

100 Chamada com tipo int Versão com tipo int Chamada com Integer Versão com Integer Observa-se que a chamada com varargs não tem precedência, quando da existência de métodos com assinatura igual à chamada. Ainda usando o exemplo anterior, somente será chamado o método com varargs em situações como a apresentada abaixo, onde não há correspondência com um método específico. public static void main(String[] args) { System.out.println("Chamada com tipo int"); new QualMétodo(2, 3, 4); } Chamada com tipo int Versão com varargs

101 Referência this Em algumas situações é necessário referenciar o próprio objeto corrente. Por essa razão todo objeto possui um atributo especial identificado por this que é uma referência para o próprio objeto. O exemplo abaixo mostra um uso típico do atributo this. Ele mostra um método cujo parâmetro formal possui o mesmo nome de um atributo de instância. Para distingui-los é necessário qualificar o atributo da instância com o atributo this. import java.awt.Color; public class ObjGeo { private Color cor; private int larg; private int alt; public ObjGeo (Color cor, int larg, int alt) { this.cor = cor; this.larg = larg; this.alt = alt; } public Color getCor() {return cor;} public int getLarg() {return larg;} public int getAlt() {return alt;} }

102 import java.awt.Color; public class TestaObjGeo { public static void main(String args[]) { ObjGeo obj = new ObjGeo(Color.red,4,8); System.out.println("Cor: " + obj.getCor()); System.out.println("Largura: " + obj.getLarg()); System.out.println("Altura: " + obj.getAlt()); } A classe Color, do pacote java.awt, é responsável pela manipulação das cores em Java. A Color.red define a cor vermelha para a instância obj do objeto ObjGeo. Cor: java.awt.Color[r=255,g=0,b=0] Largura: 4 Altura: 8

103 Modificador static Cada instância de um objeto tem sua própria cópia de todas as variáveis de instância. Porém, em certas situações, pode ser útil usar uma variável de classe, estática, cujo valor é compartilhado por todas as instâncias da classe. public class Socio { private String nome; private String endereco; private static int numSocios; public Socio (String n, String e) { nome = n; endereco = e; numSocios++; } public String getNome() {return nome;} public String getEndereco() {return endereco;} public static int getNumSocios() {return numSocios;} }

104 public class TestaSocio { public static void main(String args[]) { Socio s1 = new Socio("Pedro","Rua Santa Rita"); Socio s2 = new Socio("Paulo","Av. dos Andradas"); Socio s3 = new Socio("Jose","Av. Rio Branco"); System.out.println("Socios do clube:\n"+ s1.getNome() + ", " + s1.getEndereco() + "\n" + s2.getNome() + ", " + s2.getEndereco() + "\n" + s3.getNome() + ", " + s3.getEndereco()); System.out.println("Numero de socios: "+ Socio.getNumSocios()); } Socios do clube: Pedro, Rua Santa Rita Paulo, Av. dos Andradas Jose, Av. Rio Branco Numero de socios: 3

105 Pacotes Pacotes é a solução proposta pela Sun para reunir interfaces e classes relacionadas formando uma biblioteca. Esta organização evita a colisão de nomes de classes. Veja a extensão do problema: sendo Java uma linguagem para atuar na internet, como evitar que classes obtidas por download não tenham os mesmos nomes de classes já existentes na máquina?! Toda classe pertence a um pacote. Apenas o pacote default, que refere-se as classes do diretório corrente e o pacote java.lang, que agrupa as classes do núcleo básico de Java, não precisam ser importados com o comando import. As classes de um pacote devem colocadas em um diretório obedecendo a estru- tura do nome do pacote, a partir de algum diretório presente na variável de ambiente classpath. Suponha que eu tenha criado um conjunto de classes de objetos geométricos. Poderia criar um pacote chamado wander para colocar as classes.

106 package wander; public class ObjGeo { Color cor; int x; int y; public ObjGeo (Color cor, int x, int y) { this.cor = cor; this.x = x; this.y = y; } A variável de ambiente classpath poderia ser definida como: set classpath =.;c:\...\jdk1.4.1\lib;c:\java; O arquivo ObjGeo.class deve ser colocado no diretório: c:\java\wander Os atributos da classe ObjGeo foram definidos com o modificador de acesso default. Isto significa que somente classes do pacote wander poderão acessar estes atributos.

107 import wander.ObjGeo; import java.awt.Color; public class TestaObjGeo { public static void main(String[] args) { ObjGeo obj = new ObjGeo(Color.CYAN, 10, 10); System.out.println(obj.cor); System.out.println(obj.x); System.out.println(obj.y); } Este programa apresentará erro de compilação, informando que os atributos obj.cor, obj.x e obj.y não são visíveis, mesmo declarando o comando import para importar a classe ObjGeo do pacote wander. Lembre-se, atributos definidos com o modificador de acesso default só são visíveis por classes dentro do mesmo pacote. A classe TestaObjeto não foi definida dentro do pacote wander.

108 package wander; import java.awt.Color; public class TestaObjGeo { public static void main(String[] args) { ObjGeo obj = new ObjGeo(Color.CYAN, 10, 10); System.out.println(obj.cor); System.out.println(obj.x); System.out.println(obj.y); } Redefinição da classe TestaObjGeo dentro do pacote wander : O programa compila normalmente. Qual seria o comportamento do compilador se os atributos da classe ObjGeo fossem definidos com o modificador de acesso protected ? E com private ?

109 Herança Por exemplo, podemos considerar que um objeto Circulo, Triangulo ou Retangulo é também um objeto FormaGeometrica. Neste contexto, FormaGeometrica é chamada uma superclasse e a classe Circulo é uma subclasse. Também é válido dizer que a classe Triangulo herda atributos e/ou métodos de FormaGeometrica. Herança é um mecanismo que permite que características comuns a diversas classes sejam especificadas em uma classe base, ou superclasse. A partir desta superclasse, outras classes podem ser especificadas. Cada classe derivada ou subclasse apresenta as características (atributos e métodos) da classe base e acrescenta a elas o que for definido de particularidade na subclasse. Para especificar que uma classe é subclasse de uma outra classe, Java emprega a palavra reservada extends.

110 import java.awt.Color; public class FormaGeo { protected Color cor; protected int x, y; public FormaGeo(Color c, int x, int y) { cor = C; this.x = x; this.y = y; } public Color getCor() { return cor; } public int getX() { return x; } public int getY() { return y; }

111 import java.awt.Color; public class Circulo extends FormaGeo { protected double raio; public Circulo(Color c, int x, int y, int r) { super(c, x, y); raio = r; } public double area() { return Math.PI * Math.pow(raio, 2); } A instrução super() é uma chamada explícita ao construtor da superclasse. Esta instrução é necessária para passar à superclasse os parâmetros recebidos pelo construtor da subclasse. Observe que a subclasse não define atributos correspondentes a estes atributos, que pertencem a superclasse. É um erro de sintaxe se uma chamada super por uma subclasse não for a primeira instrução no construtor da subclasse.

112 A linha contínua indica que a classe Circulo herda métodos e/ou atributos da classe Forma. Observe que você pode criar objetos (instâncias) da classe Forma e também da classe Circulo, utilizando o BlueJ.

113 import java.awt.Color; public class TestaHeranca { public static void main(String[] args) { FormaGeo fg = new FormaGeo(Color.red, 4, 8); Circulo circ = new Circul (Color.blue, 2, 5, 10); System.out.println ("Cor da Forma Geometrica: " + fg.getCor()); System.out.println ("Cor do Circulo: " + circ.getCor()); System.out.println ("Area do Circulo: " + circ.area()); System.out.println ("Coordenada X da Forma Geometrica: " + fg.getX()); System.out.println("Coordenada Y do Circulo: " + circ.getX()); }

114 Outro exemplo utilizando herança: public class Ponto extends Object { protected int x; protected int y; public Ponto(int a, int b) { x = a; y = b; System.out.println("Ponto - " + this); } public String toString() { return "Centro: [" + x + ", " + y + "]"; } O método toString() é definido originalmente na classe Object. Permite converter uma representação interna do objeto em uma string que pode ser apresentada ao usuário. Aqui, o método está sendo sobrescrito para formatar mais adequadamente os atributos da classe Ponto.

115 public class Circulo extends Ponto { protected double raio; public Circulo(double r, int a, int b) { super(a, b); raio = r; System.out.println("Circulo - " + this); } public String toString() { return super.toString() + ", Raio: " + raio; } public class TestaHeranca { public static void main(String[] args) { Ponto pt; Circulo circ1; Circulo circ2; pt = new Ponto(10, 5); circ1 = new Circulo(4.5, 72, 29); circ2 = new Circulo(10, 5, 5); }

116 As classes Ponto e Circulo apresentam uma nova utilização para this, usado para invocar implicitamente o método toString(). Ponto - Centro: [10, 6] Ponto - Centro: [72, 29], Raio: 0.0 Circulo - Centro: [72, 29], Raio: 4.5 Ponto - Centro: [5, 5], Raio: 0.0 Circulo - Centro: [5, 5], Raio: 10.0 O objeto corrente, referenciado por this, nas instâncias da classe Circulo, é sempre desta classe. O método toString() chamado, neste caso, é o da classe Circulo.

117 Classes abstratas Uma classe abstrata não pode ser instanciada, ou seja, não há objetos que possam ser construídos diretamente de sua definição. Por exemplo, a compilação do seguinte trecho de código dará erro: abstract class ClasseAbstrata { public static void main(String[] args) { ClasseAbstrata ca = new ClasseAbstrata(); } Somente classes concretas, ou seja, que não foram definidas como abstratas, é que podem ser instanciadas. As classes abstratas definem um conjunto de funcionalidades das quais pelo menos uma está especificada mas não está definida ou seja, contém pelo menos um método abstrato. abstract class ClasseAbstrata { public abstract int metodo(); }

118 Um método abstrato não cria uma definição, mas apenas uma declaração de um método que deverá ser implementado em uma classe derivada. Assim, para que uma classe derivada de uma classe abstrata possa instanciar objetos, os métodos abstratos devem ser definidos nestas classes derivadas. class ClasseConcreta extends ClasseAbstrata { public int metodo() { return 0; } public abstract class Time { abstract void meuTime(); public static void futebol() { System.out.println("Eu gosto de futebol"); } O exemplo a seguir ilustra um caso simples de uso de classe abstrata. A classe Time define o método abstrato meuTime(), que é sobrescrito em seguida por 3 classes concretas.

119 public class America extends Time { void meuTime() { System.out.println("Eu sou americano..."); } public class Atletico extends Time { void meuTime() { System.out.println("Eu sou ATLETICANO!"); } public class Cruzeiro extends Time { void meuTime() { System.out.println("Eu sou cruzeirense..."); } As classes America, Atletico e Cruzeiro redefinem o método abstrato meuTime(), de acordo com as particularidades de cada torcedor.

120 public class MeuTime { public static void main(String[] args) { America america = new America(); Atletico atletico = new Atletico(); Cruzeiro cruzeiro = new Cruzeiro(); Time.futebol(); america.meuTime(); atletico.meuTime(); cruzeiro.meuTime(); } Eu gosto de futebol. Eu sou americano... Eu sou ATLETICANO! Eu sou cruzeirense... O método futebol() é um método estático da classe Time, portanto, não necessita de uma instância de classe para ser referenciado. Observe que uma classe abstrata tanto pode ter métodos abstratos quanto métodos concretos.

121 Suponha uma classe abstrata FormaGeometrica. Como calcular a área de um objeto desta classe? Se as classes Retangulo, Elipse e Triangulo são classes concretas derivadas de FormaGeometrica, então é possível utilizar métodos específicos de cada uma dessas classes para calcular a área. A técnica de polimorfismo permite que uma chamada de método faça com que diferentes ações ocorram de acordo com o tipo de objeto chamado. public abstract class Forma { public double area() { return 0.0; } public abstract String getNome(); } A classe Forma é uma classe abstrata, com um método abstrato getNome().

122 public class Ponto extends Forma { protected int x, y; public Ponto() { x = 0; y = 0; } public Ponto(int a, int b) { x = a; y = b; } public int getX() { return x; } public int getY() { return y; } public String getNome() { return "Ponto"; } public String toString() { return "[" + x + ", " + y + "]"; }

123 public class Circulo extends Ponto { protected double raio; public Circulo() { raio = 0; } public Circulo(double r, int a, int b) { super(a, b); raio = r; } public double area() { return Math.PI * Math.pow(raio,2); } public String toString() { return "Centro: " + super.toString() + ", Raio: " + raio; } public String getNome() { return "Circulo"; }

124 public class Retangulo extends Ponto { protected int base; protected int altura; public Retangulo() { base = 0; altura = 0; } public Retangulo(int x, int y, int b, int h) { super(x, y); base = b; altura = h; } public double area() { return base * altura; } public String toString() { return "Centro: " + super.toString() + ", Base:" + base + ", Altura: " + altura; } public String getNome() { return "Retangulo"; }

125 As classes Circulo e Retângulo estendem Ponto e sobrescrevem os métodos area() e getNome() de Forma e também o método toString() de Ponto. public class Desenha { public static void main(String args[]) { Ponto pt = new Ponto(7, 11); Circulo circ = new Circulo(3.5, 22, 8); Retangulo ret = new Retangulo(10, 10, 5, 8); Forma[] forma = new Forma[3]; forma[0] = pt; forma[1] = circ; forma[2] = ret; for(int i = 0; i < forma.length; i++) System.out.println(forma[i].getNome() + ": " + forma[i].toString() + "\nArea = " + forma[i].area()); }

126 A figura apresenta todas as classes e os relacionamentos existentes entre elas em um projeto construído no BlueJ. Ponto: [7, 11] Area = 0.0 Circulo: Centro: [22, 8], Raio: 3.5 Area = 38.48451000647496 Retangulo: Centro: [10, 10], Base:5, Altura: 8 Area = 40.0

127 Interfaces Interfaces são classes abstratas completamente não implementadas, ou seja, todos os métodos são abstratos e devem ser sobrescritos por métodos das classes concretas que as implementam. A forma geral de uso de uma interface em Java é: class Identificador implements Interface1,Interface2... O conceito de interface permite a implementação de uma espécie de herança múltipla em Java, sobrepondo a regra de que uma subclasse somente pode ser herdada de uma única superclasse. Considerando que todos os métodos de uma interface são abstratos, quando uma classe implementa esta interface, deve escrever o código de todos esses métodos abstratos. Este é o chamado contrato entre a interface e a classe que a implementa. O exemplo a seguir define uma interface Radio e uma interface Relogio. A classe concreta RadioRelogio que herda os métodos destas interfaces.

128 public interface Radio { void setEstacao(double d); double getEstacao(); } import java.util.Date; public interface Relogio { void setHorario(Date d); Date getHorario(); } Todos os métodos definidos em uma interface são obrigatoriamente public e abstract, mesmo que isto não seja declarado esplicitamente. A interface Radio abaixo é idêntica a anterior. public interface Radio { public abstract void setEstacao(double d); public abstract double getEstacao(); }

129 import java.util.Date; public class RadioRelogio implements Radio, Relogio { private Date horario; private double estacao; public void setEstacao(double d) { estacao = d; } public double getEstacao() { return estacao; } public void setHorario(Date d) { horario = d; } public Date getHorario() { return horario; } public static void main(String[] args) { RadioRelogio rr = new RadioRelogio(); rr.setEstacao(1.5); rr.setHorario(new Date()); System.out.println(rr.getEstacao()); System.out.println(rr.getHorario()); }

130 Classes Internas Em Java é possível declarar uma classe dentro da declaração de outra classe. Tais classes são denominadas classes internas. public class Externa { private int x = 7; class Interna { public void imprimeExterna() { System.out.println("x vale " + x); } Neste exemplo, a classe interna está acessando um membro privado da classe externa. Isto está correto, afinal, a classe interna é também um membro da classe externa.

131 public class Externa { private int x = 7; public void instanciaInterna(){ Interna in = new Interna(); //instancia interna in.imprimeExterna(); //invoca método da interna } class Interna { public void imprimeExterna() { System.out.println("x vale " + x); } } //fim da classe interna public static void main(String[] args){ Externa ex = new Externa(); //instancia externa ex.instanciaInterna(); //invoca método da externa } Para instanciar uma classe interna, é necessário uma instância da classe externa. Acima, a instância ex é que instancia um objeto in da classe interna.

132 public class Externa { private int x = 7; class Interna { public void imprimeExterna() { System.out.println("x vale " + x); } public static void main(String[] args){ Externa ex = new Externa(); Externa.Interna in = ex.new Interna(); in.imprimeExterna(); } Voltando a classe Externa da página anterior, este exemplo ilustra como criar um objeto da classe interna fora do código da instância da classe externa. A instanciação de uma classe interna é o único cenário em Java em que se faz necessário chamar new a partir de uma instância.

133 Classes Internas Anônimas Java permite que se crie um objeto de uma classe interna sem nome, chamada classe interna anônima. class Externa { public void imprime(){ System.out.println("Eu sou a classe externa"); } public class TestaAnonima { Externa ex = new Externa() { public void imprime() { System.out.println ("Eu sou a classe interna anônima"); } }; public static void main(String[] args){ TestaAnonima ta = new TestaAnonima(); ta.ex.imprime(); }

134 Tratamento de exceções Um erro para o qual pode existir um tratamento é chamado, em computação, de exceção. Exemplos de exceções incluem divisão por zero, parâmetros de métodos inválidos, overflow e subscrito de arrays fora dos limites. Utilizar tratamento de exceções permite ao programador remover o código de tratamento de erros da linha principal de execução do programa. Isso melhora a clareza e a modificabilidade do código fonte. public class Excecao { public static void main(String[] args) { System.out.println("Antes do erro"); try { System.out.print(10 / 0); } catch(RuntimeException e){ System.out.println("Erro"); } System.out.println("Depois do erro"); }

135 Exceções são objetos que pertencem a classes organizadas em uma hierarquia. A classe que se encontra no topo desta hierarquia é a classe Throwable, que possui duas subclasses: Exception e Error. Exception e suas subclasses são usadas para indicar condições que podem ser recuperadas. Error e suas subclasses indicam condições que em geral não podem ser recuperadas, causando a terminação do programa. Todos os objetos da classes Exception devem ser capturados ou explicitamente relançados para um nível acima na pilha de chamadas. Isto só não é válido para os objetos das classes RuntimeException, que definem as exceções que podem ser lançadas durante a execução normal da máquina virtual, como divisão por zero ou indexação fora dos limites do array. O exemplo anterior, classe Excecao, captura uma exceção da classe RuntimeException, o que, portanto, não é exigido pela máquina virtual Java. Um método pode lançar mais de uma exceção, portanto, muitas vezes é preciso definir um bloco try / catch capaz de tratar mais de uma exceção. Neste caso, cada cláusula catch trata uma exceção.

136 class Matematica { public static void main(String[] args) { try { int op1 = Integer.parseInt(args[0]); int op2 = Integer.parseInt(args[1]); System.out.println("Soma = " + (op1 + op2)); System.out.println("Subtracao = " + (op1 - op2)); System.out.println("Produto = " + (op1 * op2)); System.out.println("Divisao = " + (op1 / op2)); } catch(ArithmeticException ae) { System.out.println("Erro de divisao por zero"); } catch(ArrayIndexOutOfBoundsException aie) { System.out.println("Numero de argumentos invalido"); } catch(NumberFormatException nfe) { System.out.println("Digite apenas numeros inteiros"); } Soma = 15 Subtracao = 5 Produto = 50 Divisao = 2 ArithmeticException, ArrayIndexOutOfBounds Exception e NumberFormatException são subclasses de RuntimeException e, portanto, o programador não é obrigado a capturar estas exceções.

137 import java.io.*; public class Adicao { public static void main(String[] args) { String s; int num1, num2, soma; try { System.out.println("Entre com o 1o. numero: "); InputStreamReader isr = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(isr); s = br.readLine(); num1 = Integer.parseInt(s); System.out.println("Entre com o 2o. numero: "); s = br.readLine(); num2 = Integer.parseInt(s); soma = num1 + num2; System.out.println("Soma = " + soma); } catch(IOException e) { System.out.println("Erro na entrada de dados"); }

138 As classes do pacote java.io podem lançar exceções do tipo IOException. O programador Java é obrigado a capturar estas exceções, usando blocos try / catch (ou relançá-las explicitamente para o nível acima). Não capturar ou lançar uma exceção causa um erro de compilação. Para indicar que um método pode lançar uma exceção, Java utiliza a palavra reservada throws, usada na declaração do método, e colocada antes da chave de abertura do corpo do método. A inclusão da cláusula throws à definição do do método simplesmente significa que o método poderá lançar uma exceção, em caso de ocorrer algum problema. A classe Adicao é reescrita a seguir, utilizando a cláusula throws, sem capturar e tratar uma possível exceção da classe IOException.

139 import java.io.*; public class Adicao { public static void main(String[] args) throws IOException { String s; int num1, num2, soma; System.out.println("Entre com o 1o. numero: "); InputStreamReader isr = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(isr); s = br.readLine(); num1 = Integer.parseInt(s); System.out.println("Entre com o 2o. numero: "); s = br.readLine(); num2 = Integer.parseInt(s); soma = num1 + num2; System.out.println("Soma = " + soma); }

140 Para lançar explicitamente uma exceção, utiliza-se o operador throw. O exemplo a seguir cria uma classe do usuário chamada NumeroPositivo, que lança uma exceção Exception se for passado um argumento inválido. class NumeroPositivo { private int num; public NumeroPositivo(int n) throws Exception { if (n < 1) throw new Exception("Número não positivo"); num = n; } A cláusula throws, na assinatura do método, especifica que pode ser lançada uma exceção da classe Exception. O comando throw cria um novo objeto da classe Exception e ainda acrescenta um argumento referente a esta exceção. A classe TestaExcecao, definida a seguir, instancia um novo objeto da classe NumeroPositivo, passando um valor como argumento. A exceção lançada por NumeroPositivo será capturada pelo bloco try-catch de TestaExcecao.

141 public class TestaExcecao { public static void main(String[] args) { try { NumeroPositivo np = new NumeroPositivo(Integer.parseInt(args[0])); } catch (Exception e) { System.out.println(e.getMessage()); } O método getMessage(), da classe Exception, retorna uma String correspondente ao argumento definido na definição do objeto da classe Exception (ou qualquer uma das suas subclasses). Para uma execução do tipo: java TestaExcecao 0, a saída será: Número não positivo

142 Exceções do programador Se o programador considerar que nenhuma exceção se encaixa no tipo de erro que pretende lançar, pode criar uma nova subclasse de Exception para representar essa exceção. class PosiviteNumberException extends Exception { public PosiviteNumberException(String s) { super(s); } A classe PosiviteNumberException estende a classe Exception. O argumento String s é passado para a superclasse. A classe do usuário NumeroPositivo foi reescrita para lançar Posivite NumberException ao invés de Exception. A execução de Testa Excecao obterá o mesmo resultado visto anteriormente.

143 class NumeroPositivo { private int num; public NumeroPositivo(int n) throws PosiviteNumberException { if (n < 1) throw new PosiviteNumberException ("Número não positivo"); num = n; } Existe ainda uma cláusula opcional do bloco try-catch chamada finally. Seu propósito é conter um trecho de código que deve ser executado independentemente de ocorrer ou não uma exceção. O exemplo seguinte é uma adaptação da classe Matematica (pág. 117), incluindo uma cláusula finally após o último catch. Para uma execução do tipo java Matematica 3 0 a saída é: Soma = 3 Subtracao = 3 Produto = 0 Erro de divisao por zero Obrigado por usar a calculadora

144 class Matematica { public static void main(String[] args) { try { int op1 = Integer.parseInt(args[0]); int op2 = Integer.parseInt(args[1]); System.out.println("Soma = " + (op1 + op2)); System.out.println("Subtracao = " + (op1 - op2)); System.out.println("Produto = " + (op1 * op2)); System.out.println("Divisao = " + (op1 / op2)); } catch (ArithmeticException e) { System.out.println("Erro de divisao por zero"); } catch (ArrayIndexOutOfBoundsException e) { System.out.println ("Numero de argumentos invalido"); } catch (NumberFormatException e) { System.out.println ("Digite apenas numeros inteiros"); } finally { System.out.println ("Obrigado por usar a calculadora"); }

145 GUIs AWT e Swing Java possui dois pacotes para manipulação de componentes GUI. O pacote java.awt (Abstract Windowing Toolkit) está diretamente associado com as capacidades de GUI da plataforma local. O pacote javax.swing surgiu na versão 1.2 (Java 2) e seus componentes GUI são chamados Java puros, por apresentarem o mesmo look&feel em qualquer plataforma. Frame é o componente do pacote AWT responsável pela criação de janelas no ambiente gráfico utilizado. Este componente gera uma janela com barra de título, bordas e pode ter outros componentes em seu interior, como caixas de texto, botões, caixas de rolamento, etc. Ao se utilizar o pacote swing, usamos o componente JFrame, que herda os atributos e comportamentos de Frame. O exemplo a seguir demonstra a criação de uma janela por intermédio da classe JFrame do pacote javax.swing.

146 import java.awt.*; import javax.swing.*; public class Janela extends JFrame { public Janela() { //método construtor da classe setTitle(Uma janela qualquer); setSize(400,50); setLocation(150,150); setResizable(false); getContentPane().setBackground(Color.red); } public static void main(String args[]) { Janela j = new Janela(); j.show(); //Exibe a Janela j.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE); }

147 Uma janela da classe JFrame ou qualquer subclasse só é exibida na tela quando o método show é invocado. Além disso, o tamanho de uma janela deve ser definido através do método setSize, herdado da classe java.awt.Component. A posição da janela é especificada com o método setLocation, também do pacote Component. A cor de fundo é atribuída através do método setBackground. O método setResizable determina se a janela pode ou não ser redimensionada. O método main do exemplo define uma ou mais instruções responsáveis pelo fechamento da janela. Isto é necessário para encerrar a janela DOS ao término da execução do aplicativo. O método setDefaultCloseOperation da classe JFrame é responsável por esta tarefa.

148 Os rótulos são definidos com a classe JLabel (uma subclasse de java.awt.Component ) e permitem exibir uma única linha de texto, com ou sem um arquivo de imagem anexado. O próximo exemplo ilustra a utilização de rótulos, incluindo um arquivo de imagem, no frame conforme apresentado ao lado. Componente JLabel É possível controlar várias propriedades dos rótulos, incluindo alinhamento, tipo de letra, tamanho e cor. ToolTipText (dica de ferramenta)

149 import javax.swing.*; import java.awt.*; import java.awt.event.*; public class TestaRotulo extends JFrame { private JLabel Rot1,Rot2; public TestaRotulo() { super("Teste de JLabel");//para setTitle() Container C = getContentPane(); C.setLayout(new FlowLayout()); Rot1 = new JLabel(" CES/JF sem logo"); Rot1.setToolTipText("Rótulo 1"); C.add(Rot1); Icon Ces = new ImageIcon("c:\\ceslogo.gif"); Rot2 = new JLabel(" CES/JF com logo"); Rot2.setIcon(Ces); Rot2.setHorizontalTextPosition (SwingConstants.CENTER); Rot2.setVerticalTextPosition (SwingConstants.BOTTOM); Rot2.setToolTipText("Rótulo 2"); C.add(Rot2); setSize(200,200); show(); }

150 public static void main(String args[]) { TestaRotulo T = new TestaRotulo(); T.setDefaultCloseOperation(JFrame. EXIT_ON_CLOSE); } O método setLayout da classe Container define o tipo do gerenciador de leiaute para a interface com o usuário do aplicativo Java. Se você vai usar mais de um componente gráfico em um Container, deverá usar também um gerenciador de leiaute para conter todos os componentes. FlowLayout é o gerenciador mais simples e que coloca os componentes GUI anexados da esquerda para a direita até o limite do Container. A classe TestaRotulo instancia dois componentes JLabel. O comando super, por herança, invoca o método setTitle de JTable. Lembre-se que TestaRotulo é uma subclasse de JTable.

151 A classe ImageIcon do pacote javax.swing permite definir um objeto gráfico a ser visualizado em componentes swing. Os arquivos de imagens suportados são GIF, JPEG e PNG. É importante não esquecer de especificar o caminho completo do arquivo de imagem na árvore de diretório. Caso contrário, o interpretador Java irá apresentar o frame sem a imagem (e não acusará nenhuma mensagem de erro!). Um objeto da classe ImageIcon é um objeto Icon, uma vez que a classe ImageIcon implementa a classe Icon. O método setToolTipText é herdado pela classe Jlabel da classe JComponent e é utilizado para especificar um componente GUI com uma dica de ferramenta. Os métodos setHorizontalTextPosition e setVerticalTextPosition do objeto Jlabe l permitem especificar o alinhamento do arquivo gráfico em relação ao texto do rótulo. Respectivamente, controlam o alinhamento horizontal e vertical do ícone. O argumento SwingConstants possui as opções LEFT, RIGHT e CENTER (horizontal) e TOP e BOTTOM (vertical).

152 As GUIs são baseadas em eventos, tais como mover o mouse, clicar um botão, selecionar um item de um menu, fechar uma janela, etc. Informações de eventos são armazenados em objetos de classes que estendem AWTEvent. Importante: Para processar um evento é necessário registrar um ouvinte de eventos e implementar um tratador de eventos. O ouvinte de eventos é um objeto de uma classe que implementa uma ou mais interfaces listener de eventos dos pacotes java.awt.event e javax.swing.event. Lembre-se: para cada evento ouvido deve haver um método tratador de eventos para tratá-lo. Tratamento de eventos Um objeto ouvinte de eventos detecta um determinado tipo de evento, como um clique do mouse em um programa. Um tratador de eventos é um método chamado em resposta ao evento detectado pelo ouvinte de eventos.

153 import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Classico extends JFrame{ private JButton Cruzeiro, Atletico; public Classico() { super("Classico mineiro"); Container C = getContentPane(); C.setLayout(new FlowLayout()); Cruzeiro = new JButton("Cruzeiro"); C.add(Cruzeiro); Atletico = new JButton("Atletico"); C.add(Atletico); TrataBotao B = new TrataBotao(); Cruzeiro.addActionListener(B); Atletico.addActionListener(B); setSize(250,100); show(); } Um evento com botões (Jbutton) Cria dois botões, Cruzeiro e Atlético Instancia os botões, definindo os rótulos Instancia a classe interna para tratamento de eventos dos botões

154 public static void main(String args[]) { Classico clas = new Classico(); clas.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); } //classe interna para tratamento de evento de botão: private class TrataBotao implements ActionListener { //método para tratamento de evento de botão: public void actionPerformed(ActionEvent e) { JOptionPane.showMessageDialog(null, "O melhor de Minas: "+e.getActionCommand()); } //Fim do método actionPerformed } //Fim da classe interna TrataBotao } //Fim da classe Classico Este exemplo apresenta o objeto botão, um componente gráfico em que o usuário clica sobre o objeto para acionar uma ação específica. Um Jbutton gera um ActionEvent que deve ser tratado pelo método actionPerfomed a partir da classe interna que implementa ActionListene r.

155 Este exemplo usa um tipo de botão chamado botão de comando, que gera um ActionEvent quando o usuário clica no botão com o mouse. Neste exemplo, o tratamento de eventos é feito na classe interna TrataBotao. O método actionPerformed define uma caixa de diálogo de mensagem contendo o rótulo do botão que foi pressionado pelo usuário. O rótulo é obtido através do método getActionCommand. Cada tipo de evento tem uma interface listener de eventos correspondente. Assim, ActionEvent é tratado por ActionListener ; MouseEvent, por MouseListener ; KeyEvent, por KeyListener, e assim por diante.

156 O exemplo a seguir, uma calculadora com as quatro operações aritméticas, ilustra a inclusão de caixas de texto JTextField e botões JButton em uma janela Jframe, com os respectivos tratamento de eventos. import java.awt.*; import java.awt.event.*; import javax.swing.*; class Calcula extends JFrame implements ActionListener { JLabel L1,L2,L3; //Cria 3 rótulos JButton B1,B2,B3,B4,B5; //Cria 5 botões JTextField T1,T2,T3; //Cria 3 caixas de texto Eventos com caixas de texto Caixas de texto ( JTextField ) Botões ( JButton )

157 public static void main(String args[]){ Calcula calc = new Calcula(); calc.show(); calc.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public Calcula() { setTitle("Calculadora"); setSize(350,150); setLocation(50,50); getContentPane().setLayout(new GridLayout(3,4)); L1 = new JLabel("Operando1"); L2 = new JLabel("Operando2"); L3 = new JLabel("Resultado"); B1 = new JButton("+"); B1.addActionListener(this); B2 = new JButton("-"); B2.addActionListener(this); B3 = new JButton("x"); B3.addActionListener(this); B4 = new JButton("/"); B4.addActionListener(this); B5 = new JButton("Limpar"); B5.addActionListener(this); Associa ouvintes de eventos para cada um dos botões criados

158 T1 = new JTextField(); T2 = new JTextField(); T3 = new JTextField(); T3.setEditable(false); getContentPane().add(L1); getContentPane().add(T1); getContentPane().add(B1); getContentPane().add(B2); getContentPane().add(L2); getContentPane().add(T2); getContentPane().add(B3); getContentPane().add(B4); getContentPane().add(L3); getContentPane().add(T3); getContentPane().add(B5); } Este aplicativo utiliza um novo tipo de gerenciador de leiaute, chamado GridLayout. Este gerenciador especifica, como argumentos, o número de linhas e o de colunas para o leiaute. As suas posições vão sendo alocadas sempre de cima para baixo e da esquerda para a direita. Aloca os objetos de rótulos, botões e caixas de texto ao gerenciador de leiaute. Torna a caixa de texto T3 não-editável pelo usuário

159 public void actionPerformed(ActionEvent e) { if(e.getSource()==B5) { T1.setText(""); T2.setText(""); T3.setText(""); return; } float op1=0,op2=0,res=0; try { op1 = Float.parseFloat(T1.getText()); op2 = Float.parseFloat(T2.getText());} catch(NumberFormatException erro) { T3.setText("Erro!!"); return;} if(e.getSource() == B1) res = op1 + op2; if(e.getSource() == B2) res = op1 - op2; if(e.getSource() == B3) res = op1 * op2; if(e.getSource() == B4) res = op1 / op2; T3.setText(""+res); } Limpa as caixas de texto

160 A cláusula this passada como argumento para o método addActionListener para cada um dos botões criados significa que o ouvinte de eventos está sendo associado ao próprio botão. O método tratador de eventos actionPerformed deve tratar todos os eventos associados a ouvintes no método calcula. Assim, se o evento disparado for associado ao botão B5, as caixas de texto devem ter seus valores limpados. O método setText de JTextField foi utilizado para este propósito. Os valores digitados nas caixas de texto devem ser convertidos em campos numéricos para sem processados. O método getText de JTextField obtém o valor atual da caixa de texto e o método parseFloat converte para valores do tipo básico float. Uma cláusula try-catch foi empregada para impedir que o programa seja interrompido caso o usuário informe um valor não numérico para os campos operando1 e operando2.

161 Listas de Seleção JList As listas de seleção são objetos swing que possibilitam a escolha de um ou vários valores armazenados em uma lista de opções. Esta lista é manipulada a partir da classe JList. O exemplo seguinte ilustra a utilização desta classe. import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; public class Quitanda extends JFrame implements ListSelectionListener { JTextField tf; JList lista; DefaultListModel dlm; double[] preco = {0.8, 4.0, 3.5, 5.0, 0.7};

162 public static void main(String args[]){ Quitanda q = new Quitanda(); q.show(); q.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } Quitanda() { setLocation(300,100); setTitle("Quitanda do Prof. Wander"); setSize(250,70); tf = new JTextField(); tf.setEditable(false); dlm = new DefaultListModel(); dlm.addElement("Banana"); dlm.addElement("Pera"); dlm.addElement("Maçã"); dlm.addElement("Uva"); dlm.addElement("Laranja"); lista = new JList(dlm); lista.addListSelectionListener(this); JScrollPane painel = new JScrollPane(lista); getContentPane().setLayout(new GridLayout(2,1)); getContentPane().add(painel); getContentPane().add(tf); } Os itens devem ser inseridos em um objeto da classe DefaultListModel

163 public void valueChanged(ListSelectionEvent e){ tf.setText("Fruta: " + lista.getSelectedValue() + " - Preço: R$ " + preco[lista.getSelectedIndex()]); } O pacote javax.swing.event é necessário para a manipulação de eventos de JList. Cada vez que o usuário escolhe um item da lista é gerado um evento a ser tratado pelo método valueChanged. É também necessário implementar a interface ListSelectionListener para que as opções de JList possam ser reconhecidas à medida que o usuário seleciona um item da lista. Os itens a serem colocados em um JList devem antes ser inseridos em objeto DefaultListModel para depois serem associados a uma lista JList. O método addListSelectionListener deve ser invocado para que a opção escolhida seja reconhecida no momento da ação do usuário. O método getSelectedValue() retorna o texto do elemento selecionado na lista. O método getSelectedIndex() retorna um número inteiro corres- pondente ao índice do elemento selecionado.

164 Caixas de seleção JComboBox As caixas de seleção JComboBox permitem que o usuário selecione apenas um único item de sua lista, e é uma opção ao componente gráfico JList. import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; public class Quitanda extends JFrame implements ItemListener { JTextField tf; JComboBox cb; double[] preco = {0.8, 4.0, 3.5, 5.0, 0.7}; public static void main(String args[]) { Quitanda q = new Quitanda(); q.show(); q.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); }

165 Quitanda() { setLocation(300,100); setTitle("Quitanda do Prof. Wander"); setSize(250,100); tf = new JTextField(); tf.setEditable(false); String frutas[] = {"Banana","Pera","Maçã","Uva","Laranja"}; cb = new JComboBox(frutas); cb.addItemListener(this); getContentPane().setLayout(new GridLayout(2,1)); getContentPane().add(cb); getContentPane().add(tf); } //fim do método Quitanda public void itemStateChanged(ItemEvent e) { tf.setText("Fruta: " + cb.getSelectedItem() + " - Preço: R$ " + preco[cb.getSelectedIndex()]); } //fim do método itemStateChanged } A interface ItemListener é responsável por reconhecer eventos relacionados ao componente JComboBox.

166 Na inicialização do objeto cb, sua lista passa a conter as Strings armazenadas em um array de itens: cb = new JComboBox(frutas); O método addItemListener registra o objeto cb para que as mudanças de seleção sejam reconhecidas e tratadas pelo método itemStateChanged. O método getSelectedItem retorna o conteúdo do texto selecionado. O método getSelectedIndex retorna um valor inteiro contendo o índice da opção selecionada.

167 Caixas de Opção JCheckBox As caixas de opção JCheckBox são objetos swing que permitem representar opções que podem ser ativadas e desativadas com um simples clique do mouse. import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Estilo extends JFrame implements ItemListener { JLabel jl; JCheckBox cb1,cb2; // cria dois objetos JCheckBox static int negrito=0,italico=0; public static void main(String args[]) { Estilo est = new Estilo(); est.show(); est.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } //fim do método main

168 Estilo() { getContentPane().setBackground (newColor(180,180,180)); setTitle("Estilo de letras"); setSize(300,70); getContentPane().setLayout (newFlowLayout(FlowLayout.CENTER)); jl = new JLabel("Tupi "); jl.setFont(new Font("Arial",Font.PLAIN,20)); jl.setForeground(Color.black); cb1 = new JCheckBox("Negrito"); cb1.setBackground(new Color(180,180,180)); cb1.addItemListener(this); cb2 = new JCheckBox("Italico"); cb2.setBackground(new Color(180,180,180)); cb2.addItemListener(this); getContentPane().add(jl); getContentPane().add(cb1); getContentPane().add(cb2); } Cria uma cor com os valores RGB 180, 180, 180 Cria um rótulo usando a fonte Arial, corpo 20

169 public void itemStateChanged(ItemEvent e) { if(e.getSource()==cb1) { if(e.getStateChange()==ItemEvent.SELECTED) negrito=Font.BOLD; else negrito=Font.PLAIN; } if(e.getSource()==cb2) { if(e.getStateChange()==ItemEvent.SELECTED) italico=Font.ITALIC; else italico=Font.PLAIN; } jl.setFont(new Font("Arial",negrito+italico,20)); } //fim do método itemStateChanged } Ao se utilizar o padrão RGB (red-green-blue) para definir uma nova cor para um objeto swing, os valores numéricos para estas três tonalidades devem variar entre 0 e 255.

170 Para que a seleção seja reconhecida pelo método itemStateChanged, é necessário invocar o método addItemListener para cada um dos objetos JCheckBox instanciados. O método addItemListener será executado sempre que o usuário clicar em um dos botões JCheckBox. A comparação e.getStateChange()==ItemEvent.SELECTED é utilizada para verificar se o componente JCheckBox está marcado ou não. As propriedades SELECTED e DESELECTED indicam que o objeto está, respectivamente, marcado e desmarcado. As constantes Font.PLAIN, Font.BOLD e Font.ITALIC são previamente definidas em Java e possuem como valor 0, 1 e 2, respectivamente e devem ser tratados como int. A combinação de seus valores gera estilos diferentes de letras para a instância jl de Jlabel em jl.setFont(new Font ("Arial",negrito + italico,20));. O argumento 20 significa que a fonte será exibida com 20 pontos de altura (ponto é uma unidade de medida comum em artes gráficas. Uma polegada possui 72 pontos).

171 Painéis e botões de rádio Os painéis JPanel são utilizados quando mais de um tipo de leiaute precisa ser inserido em uma janela. Desta forma, por exemplo, um painel pode ser FlowLayout e o outro GridLayout. Os botões de rádio JRadioButton permitem que uma entre várias opções seja escolhida pelo usuário. Os botões de rádio devem sempre ser agrupados em um ButtonGroup para cada conjunto de botões a serem inseridos no JFrame. import java.awt.*; import java.awt.event.*; import javax.swing.*; class Desconto extends JFrame implements ItemListener { JLabel l1,l2; float n=0,res=0; JTextField tf1,tf2; JPanel p1,p2; //cria dois painéis JRadioButton rb1,rb2,rb3; //cria três botões de rádio ButtonGroup rg; //cria um conjunto de botões

172 public static void main(String args[]) { JFrame d = new Desconto(); d.show(); d.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } Desconto() { setTitle("Cálculo do Desconto"); setSize(350,120); getContentPane().setLayout(new FlowLayout(FlowLayout.CENTER)); l1 = new JLabel("Digite o preço do produto"); l1.setForeground(Color.red); l2 = new JLabel("Valor do desconto: "); l2.setForeground(Color.red); tf1 = new JTextField(5); //campo de texto p/preço do produto tf2 = new JTextField(5); //campo de texto p/valor do desconto tf2.setEditable(false); p1 = new JPanel(); p2 = new JPanel(); rb1 = new JRadioButton("10%"); rb2 = new JRadioButton("20%"); rb3 = new JRadioButton("30%"); rg = new ButtonGroup(); rg.add(rb1); //adiciona rb1 ao grupo de botões de rádio rg.add(rb2); //adiciona rb2 ao grupo de botões de rádio rg.add(rb3); //adiciona rb3 ao grupo de botões de rádio

173 rb1.addItemListener(this); //registra o evento do botão rb1 rb2.addItemListener(this); //registra o evento do botão rb2 rb3.addItemListener(this); //registra o evento do botão rb3 p1.setLayout(new FlowLayout(FlowLayout.CENTER)); p2.setLayout(new GridLayout(2,3)); p1.add(l1); //adiciona o rótulo l1 ao painel p1 p1.add(tf1); //adiciona o campo de texto tf1 ao painel p1 p2.add(rb1); //adiciona o botão de rádio rb1 ao painel p2 p2.add(rb2); //adiciona o botão de rádio rb2 ao painel p2 p2.add(rb3); //adiciona o botão de rádio rb3 ao painel p2 p2.add(l2); //adiciona o rótulo l2 ao painel p2 p2.add(tf2); //adiciona o campo de texto tf2 ao painel p2 getContentPane().add(p1); //adiciona o painel p1 ao frame getContentPane().add(p2); //adiciona o painel p2 ao frame } public void itemStateChanged(ItemEvent e) { if (tf1.getText().length()==0) return; try { n = Float.parseFloat(tf1.getText()); if (e.getSource()==rb1) res = (n * 10)/100; if (e.getSource()==rb2) res = (n * 20)/100; if (e.getSource()==rb3) res = (n * 30)/100; } catch(NumberFormatException erro) { tf2.setText("Erro"); return; } tf2.setText(""+res); } //fim do método itemStateChanged }

174 O exemplo declara dois painéis JPanel p1 e p2 que podem ser encarados da mesma forma que as janelas JFrame, pois possuem as mesmas propriedades: cor de fundo, leiaute, objetos que contêm, etc. Depois de definidas as propriedades de um painel, ele é inserido em uma janela. Assim, uma janela pode conter vários painéis, cada qual com a sua própria formatação e leiaute. O painel p1 é definido como FlowLayout e contém um rótulo e um campo de texto. O painel p2 é definido como GridLayout contendo 2 linhas e 3 colunas e contém, além de um campo de texto e um rótulo, o agrupamento de botões de rádio.

175 Barras de rolagem JScrollBar As barras de rolagem JScrollBar permitem variar um valor numérico dentro de uma faixa estabelecida por um mínimo e um máximo. A sintaxe para criar uma barra de rolagem utilizando JScrollBar é: JScrollBar(orientação,valor inicial,intervalo do meio, valor mínimo,valor máximo) A orientação é um valor inteiro que define se a barra de rolagem é horizontal ( 0 ) ou vertical ( 1 ). A orientação também pode ser definida pelas constantes JScrollBar.HORIZONTAL e JScrollBar.VERTICAL. O intervalo do meio é um valor do tipo inteiro que define o incremento ou decremento do valor da barra de rolagem quando o usuário clicar nessa área. import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.text.DecimalFormat;

176 public class Conversao extends Jframe implements AdjustmentListener { JScrollBar sb1; JLabel l1,l2; DecimalFormat df; public static void main(String args[]) { JFrame c = new Conversao(); c.show(); c.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } Conversao() { setSize(250,100); setTitle("Conversão de Medidas"); getContentPane().setLayout(new GridLayout(3,1)); sb1 = new JScrollBar(JScrollBar.HORIZONTAL,0,5,0,105); sb1.addAdjustmentListener(this); l1 = new JLabel(Centímetros",JLabel.CENTER); l2 = new JLabel(Polegadas",JLabel.CENTER); getContentPane().add(sb1); getContentPane().add(l1); getContentPane().add(l2); }

177 public void adjustmentValueChanged(AdjustmentEvent e) { l1.setText(sb1.getValue() + " Centímetros"); DecimalFormat nf; df = new DecimalFormat(0.000); double pol = sb1.getValue() / 2.54; l2.setText(df.format(pol) +" Polegadas"); } A interface AdjustmentListener é utilizada para reconhecer a interação do usuário com um objeto JScrollBar. Os argumentos JScrollBar.HORIZONTAL,0,5,0,105 definem uma barra de rolagem horizontal, com valor inicial 0, com valor de incremento e decremento para o intervalo do meio 5, com valor mínimo 0 e valor máximo 105. Na realidade, o valor máximo exibido será 100, porém este argumento deve receber o valor máximo acrescido do intervalo do meio. O método addAdjustmentListener registra a barra de rolagem para que o evento seja gerado por ela.

178 Áreas de texto JTextArea As áreas de texto JTextArea já foram apresentadas anteriormente. Aqui são vistas algumas características deste componente Swing, cuja sintaxe é JTextArea(texto inicial, número de linhas iniciais, dimensão). texto inicial deve ser um objeto String e este argumento é opcional. número de linhas iniciais define o nº de linhas que a área de texto terá, sem o uso de uma barra de rolagem, que pode ser definida através do com- ponente JScrollPane.

179 import java.awt.*; import java.awt.event.*; import javax.swing.*; public class CopiaTexto extends JFrame implements ActionListener { JTextArea ta1,ta2; JButton b1,b2; public static void main(String args[]) { JFrame cp = new CopiaTexto(); cp.show(); cp.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } CopiaTexto() { setSize(480,280); setTitle("Copia Texto"); getContentPane().setLayout(new FlowLayout(FlowLayout.CENTER)); b1 = new JButton("Copia Tudo"); b1.addActionListener(this); b2 = new JButton("Copia Seleção"); dimensão deve ser um valor inteiro que especifica o número de caracteres W (o caracter mais largo do alfabeto) que cabem em uma linha na área de texto. Em razão desta definição, em geral cabem bem mais caracteres do que o número que for introduzido como argumento.

180 b2.addActionListener(this); ta1 = new JTextArea(5,40); ta2 = new JTextArea(5,40); JScrollPane p1 = new JScrollPane(ta1); JScrollPane p2 = new JScrollPane(ta2); getContentPane().add(p1); getContentPane().add(b1); getContentPane().add(b2); getContentPane().add(p2); } public void actionPerformed(ActionEvent e) { if (e.getSource()==b1) //copia o conteúdo de ta1 em ta2 ta2.setText(ta1.getText()); if (e.getSource()==b2) //copia a seleção de ta1 em ta2 ta2.setText(ta1.getSelectedText()); } Os métodos getText e getSelectedText da classe JTextArea obtêm, respectivamente, o texto do componente e o texto selecionado do componente.

181 Swing: menus O primeiro passo para se criar um menu em Java é definir uma barra de menus JMenuBar, que deverá conter o conjunto de menus que aparece na parte superior da janela gráfica. Além disso, é necessário definir a barra de menus padrão da janela, utilizando o método setJMenuBar. Em seguida, deve-se criar os menus JMenu a serem inseridos na barra de menus através do método.add( ). O passo seguinte é criar um novo item de menu JMenuItem e incluí-lo no seu menu através do método.add( ). Barra de Menus Menu Itens do Menu

182 import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Menus extends JFrame implements ActionListener { JMenuBar mb; JTextField tf; JMenu Cadastro, Relatorio; JMenuItem Ccliente, Cfornec, Csair, Rcliente, Rfornec; public static void main(String args[]) { JFrame m = new Menus(); m.show(); m.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } Menus() { setTitle("Exemplo com Menus"); setSize(270,130); setLocation(50,50); tf = new JTextField(); mb = new JMenuBar(); //cria a barra de menus Cadastro = new JMenu("Cadastro"); //cria um novo menu Relatorio = new JMenu("Relatórios"); //cria um novo menu Ccliente = new JMenuItem ("Cliente"); //cria um novo item Ccliente.addActionListener(this); //registra o evento Cfornec = new JMenuItem ("Fornecedor"); //cria um novo item Cfornec.addActionListener(this); //registra o evento Csair = new JMenuItem ("Sair do sistema"); //cria um novo item Csair.addActionListener(this); //registra o evento

183 Cadastro.add(Ccliente); //adiciona o item ao menu Cadastro.add(Cfornec); //adiciona o item ao menu Cadastro.add(Csair); Rcliente = new JMenuItem ("Relação de Clientes"); Rcliente.addActionListener(this); Rfornec = new JMenuItem ("Relação de Fornecedores"); Rfornec.addActionListener(this); Relatorio.add(Rcliente); //adiciona o item ao menu Relatorio.add(Rfornec); //adiciona o item ao menu mb.add(Cadastro); //adiciona o menu à barra mb.add(Relatorio); //adiciona o menu à barra setJMenuBar(mb); //define a barra de menus como padrão getContentPane().add(tf); } public void actionPerformed(ActionEvent e) { if (e.getSource() == Ccliente) tf.setText("Escolhido o item Cliente"); if (e.getSource() == Cfornec) tf.setText("Escolhido o item Fornecedor"); if (e.getSource() == Rcliente) tf.setText("Escolhido o item Relação de Clientes"); if (e.getSource() == Rfornec) tf.setText("Escolhido o item Relação de Fornecedores"); if (e.getSource() == Csair) System.exit(0); }

184 O exemplo a seguir apresenta um menu com um aspecto mais sofisticado, utilizando subitens, ícones, barra divisória e teclas de atalho para acessar os itens do menu. import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Profissa extends JFrame implements ActionListener { JMenuBar mb; JMenu Arquivo, Save; JMenuItem Novo, Abrir, Sair, Salvar, SalvarComo, SalvarTudo; public static void main(String args[]) { JFrame p = new Profissa(); p.show(); p.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); }

185 public Profissa() { setTitle("Menu Profissional"); setSize(250,150); mb = new JMenuBar(); //cria a barra de menus Arquivo = new JMenu("Arquivo"); //cria um novo menu Arquivo.setMnemonic(KeyEvent.VK_A); Arquivo.addActionListener(this); Save = new JMenu("Save"); //cria um novo menu Novo = new JMenuItem ("Novo",new ImageIcon("icon2.gif")); Novo.addActionListener(this); Novo.setAccelerator(KeyStroke.getKeyStroke (KeyEvent.VK_N, ActionEvent.ALT_MASK)); Novo.setMnemonic(KeyEvent.VK_N); Abrir = new JMenuItem ("Abrir",new ImageIcon("PASTA2.gif")); Abrir.addActionListener(this); Abrir.setAccelerator(KeyStroke.getKeyStroke (KeyEvent.VK_A, ActionEvent.ALT_MASK)); Abrir.setMnemonic(KeyEvent.VK_B); Salvar = new JMenuItem ("Salvar",new ImageIcon("disk_cat.gif")); Salvar.addActionListener(this); Salvar.setAccelerator(KeyStroke.getKeyStroke (KeyEvent.VK_S, ActionEvent.CTRL_MASK)); Salvar.setMnemonic(KeyEvent.VK_S); SalvarComo = new JMenuItem ("Salvar Como"); SalvarComo.setAccelerator(KeyStroke.getKeyStroke (KeyEvent.VK_C, ActionEvent.CTRL_MASK));

186 SalvarComo.addActionListener(this); SalvarComo.setMnemonic(KeyEvent.VK_C); SalvarTudo = new JMenuItem ("Salvar Tudo"); SalvarTudo.addActionListener(this); SalvarTudo.setAccelerator(KeyStroke.getKeyStroke (KeyEvent.VK_T, ActionEvent.CTRL_MASK)); SalvarTudo.setMnemonic(KeyEvent.VK_T); Sair = new JMenuItem ("Sair",new ImageIcon("DOOR_EXI.gif")); Sair.addActionListener(this); Sair.setAccelerator(KeyStroke.getKeyStroke (KeyEvent.VK_X, ActionEvent.ALT_MASK)); Sair.setMnemonic(KeyEvent.VK_A); Save.add(Salvar); //adiciona o item ao menu Save.add(SalvarComo); //adiciona o item ao menu Save.add(SalvarTudo); //adiciona o item ao menu Arquivo.add(Novo); //adiciona o item ao menu Arquivo.add(Abrir); //adiciona o item ao menu Arquivo.add(Save); //adiciona o item ao menu Arquivo.addSeparator(); //adiciona uma barra divisória Arquivo.add(Sair); //adiciona o item ao menu mb.add(Arquivo); //adiciona o menu à barra setJMenuBar(mb); //define a barra de menus como padrão }

187 public void actionPerformed(ActionEvent e) { if (e.getSource() == Novo) JOptionPane.showMessageDialog(null,"menu Novo.", "Usando menus",JOptionPane.INFORMATION_MESSAGE); if (e.getSource() == Abrir) JOptionPane.showMessageDialog(null,"menu Abrir.", "Usando menus",JOptionPane.INFORMATION_MESSAGE); if (e.getSource() == Salvar) JOptionPane.showMessageDialog(null,"Sub-menu Salvar.", "Usando menus",JOptionPane.INFORMATION_MESSAGE); if (e.getSource() == SalvarComo) JOptionPane.showMessageDialog(null,"Sub-menu Salvar Como.", "Usando menus",JOptionPane.INFORMATION_MESSAGE); if (e.getSource() == SalvarTudo) JOptionPane.showMessageDialog(null,"Sub-menu Salvar Tudo.", "Usando menus",JOptionPane.INFORMATION_MESSAGE); if (e.getSource() == Sair) System.exit(0); } Arquivo.setMnemonic(KeyEvent.VK_A) cria um sublinhado embaixo da letra especificada, neste caso, a letra A. Assim, os itens do menu Arquivo podem ser acessados via teclado, usando a combinação ALT + A.

188 O método setAccelerator é utilizado para criar um atalho para um item de menu. Duas constantes devem ser passadas para este método. Por exemplo, as constantes KeyEvent.VK_N e ActionEvent.ALT_MASK definem o atalho como ALT + N. O método addSeparator() cria uma barra divisória no menu. Outros objetos gráficos também podem ser inseridos em nenus, tais como botões de rádio JRadioButton ou caixas de marcação JCheckBox. Para inseri-los em um menu, basta utilizar o método add.

189 Eventos do mouse As classes receptoras de eventos relacionados ao uso do mouse em Java são MouseListener e MouseMotionListene r. MouseListener refere-se aos eventos gerados pelo mouse quando é clicado, entra na área de um componente, sai da área de um componente, etc. MouseMotionListener refere-se a eventos do mouse gerados pela sua movimentação sobre um componente. Os métodos para registrar os objetos usados em uma aplicação swing, no que se refere ao uso dos eventos do mouse são addMouseListener() e addMouseMotionListener(). Ao ser gerado um evento do mouse, é necessário declarar os respectivos métodos para tratamento do evento. Os métodos a serem declarados para um evento do tipo MouseEvent gerado pela classe MouseListener são mousePressed, mouseClicked, mouseEntered, mouseExited e mouseReleased. Observe que é obrigatório declarar todos estes métodos, mesmo que apenas um venha a ser realmente utilizado.

190 Existem ainda métodos que permitem verificar as características do evento do mouse. Por exemplo, é possível detectar se foi dado um clique ou um duplo clique no mouse. Veja alguns métodos associados aos eventos do mouse: int getClickCout() – retorna o número de vezes que o mouse foi clicado; int getX() – retorna a posição X do ponteiro do mouse sobre o componente swing; int getY() – retorna a posição Y do ponteiro do mouse; boolean isAltDown() – retorna true se a tecla ALT foi pressionada em conjunto com o mouse; boolean isControlDown() – retorna true se a tecla CRTL foi pressiona- da em conjunto com o mouse; boolean isShiftDown() – retorna true se a tecla SHIFT foi pressionada em conjunto com o mouse; O exemplo seguinte, EventoMouse, ilustra uma aplicação básica de tratamento de eventos do mouse.

191 import java.awt.*; import java.awt.event.*; import javax.swing.*; public class EventoMouse extends JFrame implements MouseListener { Container C1; JButton B1; JTextField T1; public static void main(String args[]) { JFrame Janela = new EventoMouse(); Janela.show(); Janela.setDefaultCloseOperation(EXIT_ON_CLOSE); } public EventoMouse() { setTitle("Trata evento do mouse"); setSize(250,100); C1 = getContentPane(); C1.setLayout(new FlowLayout()); B1 = new JButton("Galor forte e vingador"); B1.addMouseListener(this); T1 = new JTextField(20); C1.add(B1); C1.add(T1); } public void mousePressed(MouseEvent e) { T1.setText("O botão do mouse foi pressionado"); }

192 public void mouseClicked(MouseEvent e) { T1.setText("O botão do mouse foi solto"); } public void mouseReleased(MouseEvent e) { T1.setText("O ponteiro do mouse foi arrastado"); } public void mouseEntered(MouseEvent e) { T1.setBackground(Color.black); T1.setForeground(Color.white); T1.setText("O ponteiro do mouse entrou na área"); } public void mouseExited(MouseEvent e) { T1.setBackground(Color.gray); T1.setForeground(Color.black); T1.setText("O ponteiro do mouse saiu da área"); } A figura ao lado ilustra uma saída para a aplicação EventoMouse. Como já foi dito, é necessário declarar todos os métodos para tratamento de eventos do mouse, mesmo que apenas um venha a ser efetivamente usado.

193 Classes adaptadoras Algumas das interfaces ouvintes de eventos de Java, a exemplo de MouseListener, exigem do usuário a implementação de vários métodos, o que nem sempre é desejável. Para solucionar este inconveniente, os pacotes java.awt.event e java. swing.event fornecem classes adaptadoras de ouvintes de eventos. Uma classe adaptadora implementa uma interface e fornece uma implementação- padrão, com o corpo do método vazio, para cada um dos métodos. Por exemplo, a classe adaptadora MouseAdapter implementa a interface MouseListener e a classe adaptadora MouseMotionAdapter implementa a interface MouseMotionListener.


Carregar ppt "Linguagem de Programação IV. Ementa da Disciplina Fundamentos do paradigma orientado a objetos em Java. Bibliotecas de suporte, componentes gráficos,"

Apresentações semelhantes


Anúncios Google