Curso Básico de Linguagem Java Prof. Marco Aurelio N. Esteves http://geocities.yahoo.com.br/marcoaurelionovaes JAVA • O Panorama da computação de alto desempenho • O crescimento do volume de dados e da complexidade dos processamentos atuais • Segundo Pfister, existem três alternativas: – Trabalhar mais arduamente – Trabalhar mais sabiamente – Pedir ajuda • A última década, e o avanço e a popularidade dos recursos tecnológicos • Motivação: grande disponibilidade e os altos custos dos supercomputadores • Ainda assim os grandes desafios ainda permanecem • A idéia dos Grids Computacionais 1 JAVA •PANORAMA DO CURSO •Por que devo aprender Java? •Objetivos x Tempo •Java é difícil? •O QUE É JAVA ? •Linguagem para construção de software de eletroeletrônicos remotos •Linguagem de programação pequena, confiável e portável •Linguagem de programação conveniente para a Internet •Linguagem de programação Orientada a Objetos •Linguagem de programação no formato Cliente-Servidor •FERRAMENTAS DE DESENVOLVIMENTO: •JDK/SDK 1.5 (JAVA 2) •NET BEANS •JBUILDER •ECLIPSE •JCREATOR LE (Freeware) 2 JAVA •INDEPENDÊNCIA DE PLATAFORMA: •PROGRAMAS TRADICIONAIS Compilador Windows EXE Windows Binário Compilador Linux EXE Linux Binário Compilador Solaris EXE Solaris Binário Código Fonte C, Delphi, VB •PROGRAMA JAVA Máquina virtual Windows Código Fonte JAVA Compilador JAVA •PORTABILIDADE X VELOCIDADE: Bytecode independente de plataforma Máquina virtual Linux Máquina virtual Solaris •Usar compiladores de código nativo (Asymetrix, Symantec e IBM) •Usar compiladores “Just in Time” H A R D W A R E •SEGURANÇA Prog1.java Prog1.class Byte Code Verifier RunTime 3 JAVA • SOFTWARES • DOWNLOADS •J2SE (Java 2 Standard Edition) – www.java.sun.com/j2se/downloads/index.html •J2SE v1.5 ( 72 Mb) •Documentação: J2SE V1.5 Documentation (45 Mb) •Jcreator – www.jcreator.com (2Mb) •BlueJ – www.bluj.org (2.3 Mb) •INSTALAÇÃO: •Instalar a documentação na raiz do JDK •Path (Path = ...;C:\J2SDK1.5\BIN) (FILE NOT FOUND !) • JCreator/BlueJ – Informar as pastas do J2SDK e documentação •VARIAÇÕES •APLICATIVOS DESKTOP (caractere e gráfico) •APLICATIVOS WEB: APPLETS, SERVLETS E JSP Classe •EJB métodos •NOÇÕES DE ORIENTAÇÃO A OBJETO •Motivação: Confiabilidade, Produtividade e Manutenibilidade •Estratégias: Encapsulamento, Herança e Polimorfismo •A Classe e o Encapsulamento propriedades 4 JAVA classe Carro1000 celta gol palio Instâncias (Objetos) classe Carr_1000_16V Nova classe derivada classe A método X() classe B método Y() classe C método Z() classe C1 Caso tenha outra definição do método X() teremos uma anulação. Caso tenha mais de uma definição do mesmo método na mesma classe teremos uma sobrecarga. classe C2 Chamada do método X() obj.X() 5 JAVA •Organização das classes em java •Hierarquia de Classes •Pacotes •O rt.jar e a documentação da API •Exemplos de Programas •Aplicativo Console import java.lang.*; //Não precisaria pois este pacote já é importado por default class Ex1 extends Object // Não precisaria pois estender Object é o default { public static void main(String args[]) { String frase = "Isto é um exemplo para saida em console"; System.out.println(frase); } } 6 JAVA // Aplicativo Gráfico import javax.swing.*; import java.awt.*; import java.awt.event.*; public class Ex2 { public static void main(String args[]) { JFrame Ex2 = new JFrame(); Font f = new Font("Arial",Font.BOLD,20); JLabel lab = new JLabel("Este é um programa com interface grafica"); Ex2.setTitle("Interface Grafica"); Ex2.setSize(400,200); Ex2.setFont(f); Ex2.getContentPane().add(lab); Ex2.setVisible(true); Ex2.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) {System.exit(0); }}); } } 7 JAVA // Programa Applet import java.awt.*; import javax.swing.*; import java.applet.*; public class Ex2 extends Applet { Font f = new Font("Arial",Font.BOLD,20); JLabel l = new JLabel("Este é um exemplo de Applet"); public void init() { l.setFont(f); add(l); } } ----------------------------------------------------------------------------------------------------------------------------- -------------<! Arquivo HTML para rodar o Applet > <HTML> <BODY BGCOLOR="#FFFACD"> <CENTER> <APPLET code = "Ex2.class" width = "300" height = "100" > </APPLET> </CENTER> </BODY> </HTML> 8 JAVA •Compilação e Execução: •O arquivo fonte (.java) deverá ter o mesmo nome da classe no programa caso esta classe seja descrita como public. Por convenção usar a primeira letra do nome da classe em maiúsculo •Para cada classe declarada no programa será criado um arquivo de classe (.class) após a compilação e apenas uma destas classes poderá conter o modificador public • Apenas a classe que será executada terá o método main obrigatoriamente declarado como: public static void main( String args[ ] ) •O procedimento para compilar e executar um aplicativo Java é: • javac MeuProg.java (Resultará, caso a classe também possua este nome, em MeuProg.class) • java MeuProg •Comentário e Documentação: •// -> Forma de comentar uma única linha • /* e */ -> Forma de comentar várias linhas •/** e */ -> Forma de criar um bloco de comentário para documentação com o utilitário javadoc. Tags de Documentação: @version, @author, @param, @return, @exception e @see •As tags @version e @author são apenas para descrição de classes e serão ignoradas a menos que se use as opções –author e –version como parâmetros para o javadoc 9 JAVA •/** Esta classe exibe uma string como exemplo •@version 1.0 •@author Marcos Esteves */ • public class TesteDoc { •/** Método para exibir uma string • @param texto é o parâmetro da classe <b>String</b> a ser recebido • @see #main */ • public void exibeString(String texto) { • System.out.println(texto); } • public static void main(String args[]) { • TesteDoc x = new TesteDoc(); • x.exibeString("String de teste !");} } javadoc –author –version TesteDoc.java •Literais Numéricos – Precedidos por 0 = octal e 0x = Hexa – Ex: 0377 = 3778 , 0x9876 = 987616 •Literais Booleanos – true e false (Não equivalem a 0 e 1) •Literais Caractere – Representado por um caractere isolado entre apóstrofos ou usando uma seqüência de escapes • Ex: ‘a’, ‘\\’, ‘\n’, ‘\u0041’, ‘1’, ‘\”’ •Literal String – São na realidade classes que se comportam como um tipo básico. São representados entre aspas inclusive as seqüências de escapes e caracteres unicode - Ex: “Uma linha\nDuas linhas\tTabulação” Ex: (“Doom II”, c:\games\doom) - implica em: “\”Doom II\”, c:\\games\\doom” 10 JAVA •Tipos de Dados – Os tipos de dados em Java são portáveis entre plataformas e portanto, invariáveis •Identificadores - Podem ter qualquer tamanho e caracter, a limitação vem do S.O com os nomes de classes e arquivos. Os tipos primitivos são: char(16), byte(8), short(16), int(32), long(64), float(32), double(64) e boolean(8) •Os tipos primitivos quando usados como variáveis de instância ou classe são inicializados por default, já como variáveis locais, devem ser inicializadas Ex: int x=10; float y = 3.141592F, double z = 1.35e+10, char sexo=‘M’, String texto = “\t\tIsto é\n\t\t um exemplo”, vazia = “”, branco = “ “ •Operadores •Aritméticos = +, -, *, /, % - unários +, -, ++, -• De Atribuição: +=, -=, *=, /= • Lógicos: &, && (AND), |, || (OR), ^(XOR), !(NOT) • Relacionais: = (atribuição), == (comparação), != (diferenciação), >, >=, <, <= Ex: int x=20 % 7, y=x / 2, x*=y, y=x++, z=++x, (x=?, y=?) , (if (i<=10) & (&&) (vet[i].equals(“João”)) (x=3) != (x==3), (if (i ==3) | (||) (i==5)) •Argumentos passados por linha de programa: •Ex: public static void main(String[ ] args){ ... } •java MeuProg Param1 Param2 (args[0] = param1 e args[1] = param2) class MeuProg { public static void main(String[] args){ System.out.println(“Nome= “+args[0]+”\nSobrenome= “+args[1]); } } • java MeuProg Jose Carlos - Saída : Nome= Jose e Sobrenome= Carlos (em linhas diferentes) 11 JAVA •Saída para dispositivo padrão: •Ex: System.out.println(String1+String2+...) – A conversão para String é automática devido a concatenação (+) (implicitamente usando o método toString() da superclasse Object) System.out.println(“Um ”+2+”Tres ”+4); •Coversão de Tipos: As conversões permitidas para tipos primitivos são no sentido do menor para o maior: byte -> short -> int -> long -> float -> double, e qualquer inversão neste sentido implica no uso de cast. Ex: double x= 9.997; int y = (int) x; •Principais formas de conversão de tipos: long x =10 -> int y = (int) x ; float x = 10 -> long y = (long) x ; String x = “10” -> int y = Integer.paseInt(x) String x = “20.54” -> float y = Float.parseFloat(x) ; String x = “20.54” -> double y = Double.parseDouble(x) ; int x = 10 -> String y = String.valueOf(x) ; float x = 10.35 -> String y = String.valueOf(x) ; double x = 254.34 -> String y = String.valueOf(x) Ex: java Conversao 2 4 3 class Conversao { public static void main(String args[]) { double nota1, nota2, nota3, media; nota1=Double.parseDouble(args[0]); nota2=Double.parseDouble(args[1]); nota3=Double.parseDouble(args[2]); media=(nota1+nota2+nota3)/3; System.out.println("A media e: "+media); } } // Saída = A media e: 3.0 12 JAVA •Constantes: Em Java as constantes somente podem ser declaradas para toda a classe e, por esta razão, é chamada de constante de classe. A declaração final indica a presença de uma constante. Ex: class UsandoConstantes { public static final double g = 32; // Definição deve vir antes do método public static void main(String[] args) {System.out.println(g + “ pes por segundo ao quadrado” } } Comandos Condicionais: .if ... else : a) As condições sempre devem estar entre parênteses b) Caso haja apenas uma instrução as chaves serão desnecessárias .Ex: if ( valor == 0 || valor == 1 ) fatorial =1; else { fatorial *=valor; valor--; } .O operador condicional ou ternário: Retorna sempre um valor pois é na verdade uma expressão .Ex: int maiorvalor = x > y ? x : y (Equivale a if (x>y) maiorvalor = x; else maiorvalor = y; .A estrutura switch-case: A variável de teste e os valores somente podem ser dos tipos primitivos simples byte, short, int e char .Ex: switch (oper) { case ‘+’ :a += 5; break; case ‘-’ : a -= 5; break; case ‘*’: a *= 5; break; case ‘/’: a /= 5; break; default: System.out.println(“Operador desconhecido !”); } 13 JAVA .Estruturas de repetição: .O laço for (inicialização; teste; incremento) a) todos os argumentos são opcionais b) É possível ter incrementos do tipo float .Ex: for (double x = 5; x<=10; x+=0.5){ ... } for (int parte = valor; parte > 1;) fatorial *= parte--; •O laço while (condição) e do { instruções } while (condição) a) É necessário parênteses para a condição e se houver apenas uma instrução não necessita de chaves b) while (condição) 1º Testa e depois executa do { instruções } while (condição) 1º executa depois testa Ex: while ( i < 10 ) { System.out.println(i + ” “); i++; } do { System.out.println(i + ” “); i++; } while ( i < 10 ) ; •Prática: Fazer a lista de exercícios nº 1 14 JAVA •Uso do teclado para entrada de dados usando Streams (JDK 1.4): •import java.io.*; - Informa que será importado o pacote (conjunto de classes) io com todas as suas classes além do pacote default java.lang.* •InputStreamReader obj1 = new InputStreamReader (System.in); - Cria um objeto (obj1) de fluxo de dados para receber da entrada padrão (System.in) um conjunto de bytes e convertelos em caracteres •BufferedReader obj2 = new BufferedReader (obj1); - Cria um buffer a partir do fluxo de entrada de caracteres a fim de armazená-los. Isto evita sucessivas leituras de bytes e conversões para caracteres (atua como um cache). •obj2.readLine(); - Método da classe BufferedReader para ler uma linha de texto e retornar um objeto String com o conteúdo da linha. •try {...} catch (tipo exceção) {...}: Instruções para se controlar os possíveis erros durante a execução do programa •getMessage() – Método da classe Exception que permite capturar a string geradora da exceção •printStackTrace() – Método da classe Exception que mostra o tipo de exceção gerado e onde ocorreu no programa •exit(1) – Método da classe System que interrompe a execução da JVM e o valor 1 é um indicador de anormalidade 15 JAVA •Ex: import java.io.*; class Dobro { public static void main ( String args[] ) { InputStreamReader entrada = new InputStreamReader(System.in); BufferedReader br = new BufferedReader (entrada ); String valorstr; int valornum; System.out.println(“Entre com um valor inteiro: “); try { valorstr = br.readLine(); valornum = Integer.parseInt(valorstr); System.out.println(“O dobro de “ + valorstr + ” e: “ + (valornum * 2)); } catch (Exception e) { System.out.println(“ Erro : “+e.getMessage()); e.printStackTrace(); System.exit(1); } }} •Exceções em Java: É a forma em Java de se escrever programas robustos (que possam tratar os possíveis erros sem abortar ). •A hierarquia de exceção: Throwable Exceções Explícitas Error Exception Exceções Implícitas Não Run time Exception RuntimeException 16 JAVA • Capturar ou Declarar a possibilidade de ocorrência de uma exceção (levantar a exceção)? •Tratar: Proteger o código do método que contém erro em potencial e tratá-lo usando try- catch {...} •Levantar: Divulgar com a cláusula throws que seu método, ou usa métodos que informam que podem gerar erros, ou levanta ele próprio exceções não tratadas dentro do seu método. • try {...} catch (exceção) {...} – Após a cláusula try, as linhas entre os blocos {...} terão a execução desviada para a cláusula catch predefinida ou genérica (Exception e). Quando um erro ocorre é gerado uma exceção que pode ser tratada. O tipo da exceção gerado depende da classe e método que se esta usando e variam desde erros de entrada e saída até erro de formatação •Ex: try { conjunto de instruções } catch (nome da exceção) { tratamento deste tipo de erro } catch (nome da exceção) { tratamento deste tipo de erro }... • finally – Opcional, mas para todo try deverá existir pelo menos um catch, a não ser que se utilize o finally. Consiste em um conjunto de código que será sempre executado independente de haver ou não erro. Normalmente usado para liberar recursos ou tratar erros desconhecidos. • O uso de throw(s): Instrução utilizada para declarar que determinada exceção pode ocorrer em um método e também é usada para provocar uma exceção em um método. Ex: import java.io.*; class ExemploException { public static void main(String args[]) { int limite; double nota, media, soma=0; InputStreamReader entrada = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(entrada); try { System.out.print("\nEntre com o numero de notas: "); limite = Integer.parseInt(br.readLine()); 17 JAVA for ( int i=1; i<=limite; i++) { System.out.print("\nEntre com uma nota: "); nota = Double.parseDouble(br.readLine()); if (nota < 0 || nota > 10) throw new Exception("Valor da nota < 0 ou >10 !"); soma += nota; } media = soma / limite; System.out.print("\nA media e: "+ media); System.out.println(); } catch(NumberFormatException e) { System.out.println("Valor digitado invalido !"); } catch(IOException e) { System.out.println("Erro na entrada de dados! "); System.exit(0); } catch (Exception e) { System.out.println(e.getMessage()); System.exit(0); } } } 18 JAVA • Uso do teclado para entrada de dados usando a classe Scanner (JDK 1.5) Classe Scanner: Utilizada para ler dados de forma mais facilitada. Esta classe está disponível a partir da versão 1.5 do JDK e pertence ao pacote java.util. Ex: import java.util.Scanner; ... Scanner in = new Scanner(System.in); System.out.println(“Entre com o seu nome: “); String nome = in.nextLine(); // Foi usado o nextLine() pois o nome poderia conter brancos Para ler um dado delimitado por branco: String primeiroNome = in.next(); // a leitura inicia no primeiro caractere diferente de espaço e termina // no primeiro igual a espaço Para ler dados numéricos: int idade = in.nextInt(); double salario = in.nextDouble(); Os métodos nextInt() e nextDouble() disparam Exceptions caso o dado não possa ser convertido para os seu respectivo tipo. Para evitar isso existem os métodos hasNextInt() e hasNextDouble() que retornam true caso a próxima seqüência seja válida. Obs: Sempre que tiver alguma leitura antes do nextLine(), seja com nextInt, nextDouble ou next, usar uma leitura nextLine() . Scanner in = new Scanner(System.in); System.out.println("Entre com a idade: "); idade = in.nextInt(); in.nextLine(); // Se não for colocada esta linha a próxima leitura será pulada System.out.println("Entre com o nome: "); nome = in.nextLine(); 19 JAVA •Funções Matemáticas: Estas funções em Java são provenientes de métodos da classe Math do pacote default java.lang definidos como static. •Sintaxe : Math.<nome do método>(<lista de argumentos>); - Possui duas constantes PI e E. •Método ceil(<valor double>): Calcula o próximo inteiro de um valor double retornando um double. Ex: Math.ceil(5.2); retornará 6.0 •Método floor(<valor double>): Calcula o inteiro anterior de um valor double retornando um double. Ex: Math.floor(5.9); retornará 5.0 •Método max(<valor1>,<valor2>): Calcula o maior entre <valor1> e <valor2> retornando o maior tipo encontrado. Ex Math.max(10,3.5); -> 10.0 •Método min(<valor1>,<valor2>): Calcula o menor entre <valor1> e <valor2> retornando o menor tipo encontrado. Ex Math.min(10,3.5); -> 3.5 •Método sqrt(<valor1 double>): Calcula a raiz quadrada de <valor1> retornando um double. Ex Math.sqrt(900); -> 30.0 (Negativo = NaN) •Método pow(<base>,<pot>): Calcula a potência de <base> por <pot> retornando um double. Ex Math.pow(25,0.5); -> 5.0 •Método round(<valor double>): Calcula o arredondamento do valor retornando um long. Ex. Math.round(30.5); -> 31 •Método random(): Retorna um valor double aleatório entre [0.0 e 1.0[ Ex. Para sortear um nº entre 0 e 99 -> (int) (Math.random() * 100) 20 JAVA • Funções de String: Em Java, String é uma classe que possui métodos para manipulação e que pode ser utilizada como uma variável. • Sintaxe: (Declaração) String s = “Linguagem Java”; (Utilização) s.<método>(argumento/s) “Os literais String deverão estar entre aspas”. • Método length(): Retorna um inteiro equivalente ao tamanho da string. Ex. int tamanho = s.length(); (tamanho = 14) • Método charAt(<índice>): Retorna um char correspondendo a posição relativa [0...(n-1)] do caracter na string. Ex. char c = s.charAt(5); (c = ‘a’) • Métodos toUpperCase() e toLowerCase(): Estes métodos convertem os caracteres de uma string para maiúsculo e minúsculo respectivamente retornando um string. Ex. String x = s.toUpperCase() ( x = “LINGUAGEM JAVA” ) – String x = s.toLowerCase() ( x = “linguagem java” ) • Método substring(<índice1>,]<índice2>[): Retorna um String com os caracteres a partir de <índice1> até ]<índice2>[. Se <índice2> não for especificado, será até o final da string. Ex. String x = s.substring(0,9); (x = “Linguagem”) • Método trim(): Remove todos os espaços antes e depois da string retornando uma String. String x = “ Espaços “; x = x.trim(); ( x = “Espaços” ) • Método replace(<char1>,<char2>): Substitui todas as ocorrências de <char1> por <char2> na string retornando um String. Se nenhuma ocorrência de <char1> for encontrada, a string original é retornada. Ex. String x = s.replace(‘a’,’ ‘); (x = “Lingu gem J v “) • Método valueOf(<nomevar>): Converte vários tipos de dados em String. Ex. String x = String.valueOf(45.74); (x = “45.74”) 21 JAVA • Formatação da saída: Ao se imprimir um número no console, o default é utilizar o número máximo de dígitos não zero do tipo em questão. Ex: x = 10000 / 3.0; System.out.println(x); Será exibido 3333.3333333333335 • Formatando com a classe NumberFormat do pacote java.text: (JDK 1.4) – Valores Numéricos: NumberFormat.getNumberInstance(); – Valores Monetários: NumberFormat.getCurrencyInstance(); – Valores Percentuais: NumberFormat.getPercentInstance(); • Cada um destes métodos obtém um formatador que é uma instância da classe NumberFormat, para a localização padrão. Em seguida utiliza-se o método format() desta classe para se obter uma String equivalente ao número formatado. Ex: NumberFormat nf = NumberFormat.getNumberInstance(); System.out.println(“Numero formatado:”+nf.format(x)); Numero Formatado: 3.333,333 • Para ajustar o tamanho utiliza-se os métodos setMaximumIntegerDigits(), setMinimumIntegerDigits(), setMaximumFractionDigits(), setMinimumFractionDigits(). Ex: nf.setMaximumFractionDigits(2); nf.setMaximumIntegerDigits(2); System.out.println("Numero formatado:"+nf.format(x)); 33,33 • Trocando a localidade padrão: Locale.xxxxxx, onde xxxxxx é o objeto que contém informações sobre a localidade. Ex: NumberFormat nf = NumberFormat.getNumberInstance(Locale.GERMANY); • Formatando a saída com a classe DecimalFormat(string_formatacao) Ex: Decimalformat df = new Decimalformat(#.###,##); System.out.println("Numero formatado:"+df.format(x)); 3.333,33 22 JAVA • Formatando com printf: A versão 1.5 do JDK trouxe de volta o printf que permite a formatação dos campos. A formatação ocorre de modo que cada um dos especificadores de formato que começam com o caractere % é substituídos pelo argumento correspondente. O caractere de conversão que finaliza o especificador de formato (%) indica o tipo a ser formatado. Ex: System.out.printf (“Olá, %s. no próximo ano o Sr. fará %d anos”, nome, idade); double x = 10000.0 / 3.0; System.out.println(x); // Exibe 3333.33333333333335 System.out.printf ( “%8.2f”,x); // Exibe 3333.33 Principais conversores para printf d -> Número inteiro decimal Ex: 159 f -> Ponto flutuante Ex: 15.9 s -> String Ex: “Hello” c -> Caractere Ex: ‘H’ b -> Lógico Ex: true tx -> Data e Hora (onde x representa o que se deseja da data e/ou hora) Ex: tD -> Data no formato EUA (mës;dia;ano) – 03/20/2006 ty -> Últimos dois dígitos do ano – 06 tm -> Mês com dois dígitos (com zeros iniciais) - 03 td -> Dia com dois dígitos (com zeros iniciais) - 20 Além disso é possível especificar sinalizadores que controlam a aparência do resultado formatado. Alguns exemplos: – + : Exibe o sinal para números positivos e negativos -> +3333.33 – Espaço : Adiciona um espaço antes de números positivos -> 3333.33 – - : Justifica campos à esquerda -> 3333.33 – ( : Insere números negativos entre parênteses -> (3333.33) – , : adiciona separadores de milhares -> 3,333.33 Ex: System.out.printf ( “%,.2f”, 10000.0 / 3.0); // Exibe 3,333.33 System.out.printf ( “%1$s %2$tB %2$te ,2$tY”, “Data Atual: “, new Date() ); 23 Data atual: Febuary 9, 2004 – Usando índice: %índice$ Prática: Fazer a lista de exercícios nº 2 JAVA Como definir Classes: Uma classe em java é sempre definida com a palavra class em minúsculo e o nome da classe com a primeira letra em maiúsculo. Em seguida normalmente se descreve os membros da classe, ou seja, os elementos que definem a classe. Ex: class Data { int dia; // Os tipos primitivos alocam espaço em memória, int mês; // já os tipos classe não pois são referências ! int ano; } dia = 0 mes= 0 null Data hoje; // Aloca espaço apenas para a referência : hoje ano= 0 hoje = new Data(); hoje 0x01abcd O operador new cria uma instância, aloca memória e chama o construtor da classe; •O acesso a qualquer membro da classe sem a devida instanciação provoca uma Exception do tipo NullPointerException. Ex: Data hoje; hoje.dia = 5; // ERRO ! Pois é necessário primeiro a instanciação hoje = new Data(); Ex: String nome1 = “Joao”; String nome2 = new String(“Joao”); if (nome1 == nome2) System.out.println(“São iguais”); else System.out.println(“São diferentes”); •Métodos em Java: São sub-rotinas que podem ser invocadas todas as vezes que se fizer necessário. qualificador tipo-do-retorno nome-do-método(tipo_parâmetro parâmetro){...} Qualificador: São os especificadores de acesso informando quem tem direito de acesso ao método, além da presença ou não da cláusula static. Esta cláusula informa se o método é de classe ou de instância. Tipo-do-retorno: Pode ser void indicando que nada será retornado, ou um tipo de dado ou classe informando o tipo do 24 retorno. Caso tenha algum retorno este deverá ser retornado através da cláusula return. JAVA Propriedades ou Variáveis: Existem 3 tipos de variáveis em java: de classe, de instância e local. Variáveis Locais: São as variáveis definidas dentro de algum método. Estas variáveis devem ser inicializadas antes de serem utilizadas. Variáveis de Instância: São as variáveis declaradas no corpo da classe e que pertencem a instância, ou seja, pertencem ao objeto e portanto cada objeto terá sua cópia com valores possivelmente diferentes. Variáveis de Classe: São variáveis também declaradas no corpo da classe mas que pertencem a classe como um todo, qualificando todas as instâncias da classe. Estas variáveis são declaradas com o qualificador static. Existe apenas uma cópia de cada variável de classe para todos os objetos da classe e estas residem em uma dimensão diferente da dos objetos. Tipos de Métodos: Existem dois tipos de métodos em Java: Métodos de Classe ou Estáticos e de Instância Métodos de classe: São os métodos definidos com o qualificador static e que operam apenas sobre as variáveis de classe. Estes métodos não precisam de uma instância para serem invocados pois podem ser chamados a partir do próprio nome da classe seguido do método. Ex: Integer.parseInt(), Math.max(), String.valueOf() Métodos de Instância: São os métodos declarados sem o qualificados static e que operam sobre as instâncias embora possam operar sobre as classes. Ex: classe Automovel { static int contaObj; // Variável de classe String modelo, marca; // Variáveis de instância public static void main(String args[]) // Método de classe { int x; ... // Variável local} String setModelo(String modeloAux) {...} } // Método de Instância 25 JAVA Variáveis e Métodos de classe e instância: As variáveis e métodos de classe (com o modificador static) ocupam dimensões distintas das variáveis e métodos de instância e são criadas uma única vez na instanciação do primeiro objeto da classe. Instância Dados da classe (Class) Ex: class Data { dia = 0 static int tipoCalendario; tipoCalendario = 0 mes = 0 trocaTipoCalendario() int dia, mes, ano; ano = 0 static void trocaTipoCalendario(int novo_tipo) { ... } incrementaDia() void incrementaDia( int num_dias) { ... } } Instância ... dia = 0 Data hoje = new Data(); mes = 0 Data amanha = new Data() 1º) hoje ano = 0 incrementaDia() 2º) amanha Invocando Variáveis e Métodos de classe e instância: As variáveis e os métodos de instância necessitam de uma instância para serem chamados. Já as variáveis e os métodos de classe podem e devem ser chamados pelo nome da classe. Ex: Data hoje = new Data(); hoje.dia = 5; hoje.incrementaDia(3); Data.tipoCalendario = 3; Data.trocaTipoCalendario(3); Integer.parseInt(),String.valueOf(), Math.max(), ... Métodos de Acesso: Seguindo os padrões da Orientação a Objetos de encapsulamento, os membros da classe não devem ter acesso externo a não ser por intermédio de métodos. Para isso as variáveis devem ser declaradas com o modificador private e os métodos que dão acesso as variáveis com o modificador public Os modificadores são: 1) private 2) public 3) protected 4)default (package) Ex: class Data { private int dia, mes, ano; public void setDia( int dia_aux) { dia = dia_aux }; public int getDia() { return dia }; ... // Para todas as demais variáveis } 26 Prática: Faça a Lista de exercícios Usando Classes até o número 5. JAVA •Manipulação de Data (classe Date): Esta classe do pacote java.util representa um determinado tempo decorrido a partir de determinada data arbitrária do calendário gregoriano 01 de Jan de 1970 00:00:00. Esta classe possui vários métodos de instância para data e hora. Ex: Date data = new Date(); •Os métodos mais comuns para manipulação de Datas são: data.getDate() – Retorna o dia do mês; getDay() – Retorna o dia da semana (0 domingo – 6 sábado); getMonth() - Retorna o mês ( 0 até 11); getYear() – Retorna o ano (para anos superiores a 2000 retornará 3 dígitos Ex. para 2000 retornará 100, para 2001 retornará 101, ...); data.setDate(dia) – Define o dia para o objeto data (o mesmo ocorre para setMonth() e setYear()). Os métodos mais comuns para manipular Hora são: data.getHours() – Retorna a hora de 0 – 23; getMinutes() - Retorna os minutos de 0 – 59; getSeconds() – Retorna os segundos de 0 – 59; setHours(horas), setMinutes(minutos) e setSeconds(segundos) definem a hora, os minutos e os segundos do objeto data; data.toLocaleString() – Retorna uma String contendo a data e hora do objeto data. •A classe GregorianCalendar: Esta classe é mais atual e recomendada para manipular datas e horas. Ex: GregorianCalendar diaDeHoje = new GregorianCalendar(). diaDeHoje = data do Sistema Oper. GregorianCalendar diaDeHoje = new GregorianCalendar(1999, 11, 31, 23, 59, 30). Meses de 0 a 11 Métodos mais utilizados: int get(int valor) – Onde valor pode ser qualquer uma das constantes definidas em Calendar como: YEAR, MONTH, DAY_OF_MONTH, DAY_OF_WEEK, DATE, HOUR, MINUTE, SECOND, AM_PM void set( int ano, int mes, int dia) ou void set(int ano, int mes, int dia, int hora, int minuto, int segundo) boolean equals(Object quando) – Compara o objeto corrente com quando retornando true se representam o mesmo ponto no tempo. boolean before(Object quando) – Retorna true se objeto corrente vier antes de quando boolean after(Object quando) - Retorna true se objeto corrente vier depois de quando 27 JAVA Ex: GregorianCalendar diaDeHoje = new GregorianCalendar(). int dia = diaDeHoje.get(Calendar.DAY_OF_MONTH); int mes = diaDeHoje.get(Calendar.MONTH); int ano = diaDeHoje.get(Calendar.YEAR); Alterando: diaDeHoje.set(Calendar.YEAR, 2007) diaDeHoje.set(Calendar.MONTH, Calendar.DECEMBER) OBS: A classe abstrata Calendar possui constantes para os meses de 0 a 11 Ex. DECEMBER = 11, APRIL = 3, ... •Construtores: São métodos que possuem o mesmo nome da classe, não possuem tipo de retorno e que tem por finalidade executar as tarefas básicas quando da criação de um objeto. Somente pode ser invocado com o construtor new. Esses métodos quando não são declarados, Java chama um default automaticamente. Ex: class Empregado { int mat; String nome; public Empregado(int mat_aux, String nome_aux) { mat = mat_aux; nome = nome_aux } public static void main (String args[ ] ) { Empregado emp = new Empregado( 123, “João Carlos”); System.out.println(“ Mat: “ + emp.mat + “Nome : “ + emp.nome ); } } OBS: Caso seja declarado algum construtor, o construtor default deixará de ser fornecido automaticamente ! •this e escopo: this dentro de uma definição de método de instância é usado para fazer referência ao objeto a partir do qual o método foi chamado. É uma referência para as variáveis de instância deste objeto, ao invés das variáveis locais, ou passar o objeto corrente como argumento para outro método. 28 Ex: Uma função tradicional : umaData = amanha( Data d ); Uma chamada em Java: Data d = new Data(); d.amanha(); // O método amanha irá operar sobre o objeto d JAVA Ex: public class Data { private int dia, mês, ano; public void amanha() { this.dia = this.dia + 1; } } // O this é desnecessário pois java já associa as variáveis e métodos ao objeto Ex: class TestaEscopo { int teste = 10; void imprimeTeste() { int teste = 20; System.out.println(“Teste = “+ teste); } // this.teste; public static void main(String args[]) { TestaEscopo st = new TestaEscopo(); st.imprimeTeste(); } } •Chamando outro construtor da mesma classe: A utilização de this como primeiro comando em um construtor indica a chamada de outro construtor sobrecarregado da classe. Ex: class Cliente { public Cliente (String n, int c ) { nome = n; numConta = c; } public Cliente ( String n) { this (n,numConta + 1); } Conta.cadastrarConta(this); } } // o this usado para passar a referência como parâmetro Exercício: Criar uma classe MeuCirculo com coordenadas de centro x, y e raio r. Defina dois construtores onde no 1º valor de x, y e r seja passado como argumento e, um segundo onde caso não se passe o valor do raio r assume-se o valor 1 como default. •Destrutores: Em Java a remoção dos objetos criados é feita automaticamente quando o objeto perde a referência ou não está mas sendo usado. Esta técnica chama-se Garbage Collection e ocorre quando o 29 sistema esta ocioso nas referências já marcadas. Prática: Faça a Lista de exercícios Usando Classes do ex. 6 ao 10. JAVA • Arrays: Em Java os vetores são tratados como objetos, ou seja, são referências e precisam dos passos necessários a criação de qualquer objeto em java (declaração e instanciação). Para diferenciar da declaração de tipos primitivos de dados usa-se [ ] depois do nome do vetor ou do tipo. Ex: String frase[]; ou String[] frase; int coordenadas[]; ou int[] coordenadas; A criação de objetos de array é feita após a sua declaração ou em conjunto com a declaração: Ex: frase = new String[10]; // String frase[] = new String[20]; coordenadas = new int[50]; // int[] coordenadas = new int[50]; Os elementos em um vetor são criados com os seguintes valores default – 0 para arrays numéricos, ‘ ‘ para caracteres, false para arrays boolean e null para objetos. Os arrays também podem ser criados a partir da inicialização: Ex. String nomes[] = {“João”, “Pedro”, “Mario”}; isto seria o mesmo que : String nomes[] = new String[3]; nomes[0] = “João”; nomes[1] = “Pedro”; nomes[2] = “Mario”; Os vetores sempre iniciam em zero e para se saber o tamanho de um vetor utiliza-se a variável de instância length. Ex: System.out.println(nomes.length); A cópia de vetores pode ser feita de duas formas: 1) Movendo-se um objeto array para outro o que faz com que ambas façam referência ao mesmo vetor. Ex: int[ ] vet1, vet2; vet1 = new int[10]; vet2 = vet1; vet1[5] = 15; System.out.println(vet2[5]) // também será 15; 2) Duplicando efetivamente os elementos do vetor com o método arraycopy(vetOrigem, posOrigem, vetDestino, posDestino, qtd) da classe System. 30 JAVA Ex: vet1={2, 3, 5, 7, 11, 13}; vet2 = {1001, 1002, 1003, 1004, 1005, 1006, 1007}; System.arraycopy( vet1, 2, vet2, 3, 4); for (int i = 0; i <vet2.length; i++) System.out.println(“Elemento “+ i +”: “+vet2[i]); vet2 1001 1002 1003 5 7 11 13 A utilização de arrays com mais dimensões é semelhante a anterior porém estes necessitam de mais índices. Os arrays multidimensionais em java são montados como arrays de arrays. int espaco[] [] [] = new int [10] [5] [5]; MeuObjeto matObj[] [] = new MeuObjeto[5] [5]; espaco[1] [2] [2] = 10; matObj[2] [5] = new matObj(); Existe uma classe Arrays do pacote java.util que possui alguns métodos de classe bastante úteis como: • static void sort( a ) -> Ordena o array a de um dos tipos int, long, short, char, byte, float ou double usando quicksort; • static int binarySerach( a , v) -> Busca um elemento v no array a ordenado usando pesquisa binária. Retorna o índice onde foi encontrado ou um valor negativo r indicando a posição onde deveria ser inserido. • static void fill ( a, b) -> Preenche todo o array a com o elemento b do mesmo tipo do array a. • static boolean equals( a, b) -> Compara os arrays a e b retornando true se forem do mesmo tipo, tiverem o mesmo comprimento e os elementos nos índices correspondentes coincidirem. Prática: Faça a Lista de exercícios Usando Vetores. 31 JAVA •Introdução ao Polimorfismo Estático: Implemente uma classe que tenha três métodos capazes de receber valores de tipos diferentes ( int, float e double) e imprimi-los. Instancie um objeto desta classe no método main e chame os métodos com os argumentos correspondentes. •Sobrecarga ou Polimorfismo Estático: É um tipo de polimorfismo onde vários métodos possuem o mesmo nome em uma classe e são diferenciados apenas pela quantidade, tipo ou ordem dos parâmetros. Esta técnica evita que métodos com funcionalidades semelhantes tenham nomes distintos facilitando o reaproveitamento de código. Desta forma métodos com mesmo nome se comportam de maneira diferente, pois possuem códigos diferentes de acordo com os argumentos passados. Ex String.valueOf( .... ) class Exemplo { public static void main(String args[]) { System.out.println(“Area do quadrado: “+area(3) ); System.out.println(“Area do retangulo: “+area(3,2) ); } public static int area(int x) { return x * x }; public static int area(int x, int y) { return x * y }; } Exercício: Implemente o exemplo acima em duas classes, uma que irá ler o número de argumentos passados e chamar o método area() e outra que irá conter apenas os métodos sobrecarregados area() para o cálculo da área. •A seguir um exemplo completo de uma classe Empregado e utilização de overloading: 32 JAVA // CLASSE EMPREGADO import java.util.*; class Empregado { private String nome; private double salario; private GregorianCalendar dataContratacao; public Empregado (String n, double s, GregorianCalendar d) { nome = n; salario = s; dataContratacao = d; } public void aumentaSalario(double percentualDeAumento) { salario = salario + salario * percentualDeAumento / 100; } public void alteraDataContratacao(int ano, int mes, int dia) { dataContratacao.set(Calendar.YEAR, ano); dataContratacao.set(Calendar.MONTH, mes); dataContratacao.set(Calendar.DATE, dia); } 33 JAVA // CONTINUAÇÃO public int anoContratacao() { return dataContratacao.get(Calendar.YEAR); } public String getNome() { return nome; } public double getSalario() { return salario; } public void print() { System.out.printf(“%s %7.2f %d “,nome, anoContratacao(), salario); } public void print(int i) { System.out.println(i); } public void print(String s) { System.out.println(s); } public void print(double d) { System.out.printf(“7.2f”,d); } } 34 JAVA // CLASSE QUE IMPLEMENTA O OVERLOADING import java.util.*; // Devido a classe GregorianCalendar public class TestaEmpregados { public static void main(String args[]) { Empregado vetEmpregados[] = new Empregado[3]; vetEmpregados[0] = new Empregado("Luiz Claudio", 3500, new GregorianCalendar(1989, 10, 1)); vetEmpregados[1] = new Empregado("Vinicius Aguiar", 4500, new GregorianCalendar(1989, 12, 6)); vetEmpregados[2] = new Empregado("Luciana Arruda", 2500, new GregorianCalendar(1993, 1, 12)); for (int i = 0; i < 3; i++) { vetEmpregados[i].print(vetEmpregados[i].getNome()); // passa um String vetEmpregados[i].print(vetEmpregados[i].getSalario()); // passa um double vetEmpregados[i].print(vetEmpregados[i].anoContratacao()); // passa um int } } } 35 JAVA Pacotes (package): É o modo empregado pela Sun para organizar e agrupar classes. Os pacotes são organizados por níveis de hierarquia de modo a garantir unicidade nas classes. A cláusula package: A cláusula package deve ser a primeira em um arquivo de classe e informa a que pacote a classe pertencerá, por exemplo: package faturamento. A ausência da cláusula package faz com que a classe pertença a um pacote default, que é o diretório corrente. Os pacotes especificados na cláusula package são mapeados para subdiretórios no sistema de arquivos do SO, sendo criada uma estrutura de subdiretórios similar ao pacote. Ex: Seja a classe ClasseUtil definida com: package sistemas.comuns e alocada no diretório c:\diretorioSistemas. Ao compilar, com –d, será criado um diretório sistemas abaixo do diretório atual e um subdiretório comuns abaixo do diretório sistemas com ClasseUtil.class: c:\diretorioSistemas\sistemas\comuns\ClasseUtil.class. Como o compilador localiza os pacotes: Para a localização do pacote é necessário informar ao classpath o diretório a partir do qual se encontra tal pacote, pois os caminhos são relativos a uma ou mais raízes especificadas no classpath. Os pacotes também podem ser oferecidos em arquivos .zip ou .jar, onde internamente existirá a hierarquia dos pacotes e arquivos. Ex: seja um classpath definido assim: CLASSPATH=.;c:\diretorioSistemas, e uma classe Exemplo que utiliza ClasseUtil definida assim: import sistemas.comuns.ClasseUtil; class Exemplo { ... }. A procura se daria: 1) 2) 3) 4) 5) 6) por ClasseUtil.class no pacote padrão em JAVA_HOME\jre\lib\rt.jar por ClasseUtil.class no classpath especificado: c:\diretorioSistemas por ClasseUtil.class no diretório local da classe Exemplo ( .) por sistemas\comuns\ClassUtil.class em JAVA_HOME\jre\lib\rt.jar por sistemas\comuns\ClassUtil.class em c:\diretorioSistemas // Onde deveria estar ! por sistemas\comuns\ClassUtil.class no diretório local da classe Exemplo O comando import: Quando em uma classe se utiliza um recurso de outra classe pública, que não pertença ao mesmo pacote, é necessário utilizar o comando import informado o pacote ao qual pertence a classe que 36 oferece o recurso desejado. Ex: import sistemas.comuns.ClasseUtil; ou import sistemas.comuns.*; JAVA Herança: É a peça chave da OO para o reaproveitamento de código e consiste em derivar uma classe a partir de outra herdando seus atributos e métodos. Em java só é possível estender uma única classe. Uma subclasse, quando criada, tende a incorporar novos atributos e/ou métodos tornando-se mais específica (especialização) que a classe original (generalização). Ex: classe Empregado (slide 33) package testes; import java.util.*; class Gerente extends Empregado { private String nomeDaSecretaria; public Gerente ( String n, double s, GregorianCalendar d ) { super (n, s, d); // super(...) chama o construtor da superclasse de parâmetros equivalentes nomeDaSecretaria = ""; // e deve ser o 1º comando no construtor da subclasse } public void aumentaSalario ( double percentualDeAumento ) // Método aumentaSalario reescrito { GregorianCalendar hoje = new GregorianCalendar( ); double bonus = 0.5 * ( hoje.get(Calendar.YEAR) - anoContratacao( ) ); // Não há acesso direto a super.aumentaSalario( percentualDeAumento + bonus ); // variáveis de Empregado pois são private } // super.metodo() chama o método de mesma assinatura na superclasse para não repetir o código public String getNomeDaSecretaria( ) { return nomeDaSecretaria; } public void setNomeDaSecretaria( String nome ) { nomeDaSecretaria = nome; } } 37 JAVA package testes; import java.util.*; public class TestaEmpregadoGerente { public static void main( String args[]) { Gerente mandaChuva = new Gerente ("Ricardo", 7500, new GregorianCalendar(1987,11,15)); mandaChuva.setNomeDaSecretaria("Claudia"); Empregado vetEmpregado[] = new Empregado[3]; vetEmpregado[0] = mandaChuva; // Em tempo de compilação vetEmpregado[0] é um Empregado vetEmpregado[1] = new Empregado("Claudia",2000,new GregorianCalendar(1999, 11, 6)); vetEmpregado[2] = new Empregado("Luciana",2500,new GregorianCalendar(1993, 1, 12)); System.out.println("Empregados e salarios antes do aumento"); for (int i = 0; i < 3; i++) { vetEmpregado[i].print(); } System.out.println(); for (int i = 0; i < 3; i++) { vetEmpregado[i].aumentaSalario(5); } // Em tempo de execução vetEmpregado[0] é um Gerente System.out.println("Empregados e salarios apos o aumento"); for (int i = 0; i < 3; i++) { vetEmpregado[i].print(); } // A classe Gerente não tem método print e usa o da classe Empregado System.out.println("\nA secretaria do departamento se chama: "+mandaChuva.getNomeDaSecretaria()); } } 38 JAVA •Encapsulamento: Com exceção dos modificadores final, static e abstract os demais public, protected, private e package são usados para controlar o acesso as variáveis, métodos e classes e são os primeiros a serem declarados. •Acesso padrão (pakage): Variável ou método declarado desta forma esta disponível para qualquer outra classe do mesmo pacote •Acesso private: Variáveis e métodos private são acessíveis apenas dentro da classe onde foram declaradas, ou através de métodos não private da classe. Nem os métodos nem as variáveis são passados por herança. •Acesso public: Variáveis e métodos públicos são acessíveis para qualquer classe. Aas variáveis de classe normalmente são públicas para poderem ser acessadas de qualquer lugar. •Acesso protected: Variáveis e métodos protected são acessíveis por qualquer classe do mesmo pacote ou por subclasse desta classe (Ex. Applet é subclasse de Panel mas estão em pacotes diferentes java.awt.Panel e java.applet.Applet) •Polimorfismo Dinâmico: Quando um método é invocado, o compilador tenta localizá-lo na classe a qual pertence o objeto e, caso não encontre, procura sucessivamente nas classes ancestrais até encontrar ou gerar erro. Polimorfismo dinâmico ou late binding consiste na utilização de objetos de classes distintas , porém relacionadas por hierarquia e que possuem a mesma assinatura (nome e lista de parâmetros) mas com códigos diferentes. Ex: Empregado vetEmpregado[ ] = new Empregado[2]; vetEmpregado[0] = new Gerente(“Ricardo Silva”, 7500, new GregorianCalendar(1987, 12, 15) ); vetEmpregado[1] = new Empregado(“Luiz Alberto”, 2500, new GregorianCalendar(1988, 10, 11) ); vetEmpregado[0].aumentaSalario(5); // Aumentos diferenciados para métodos de mesma assinatura vetEmpregado[1].aumentaSalario(5); // A seleção do método a carregar é realizada na hora da execução 39 JAVA •Impedindo a Herança: Java permite que se utilize a palavra-chave final juntamente com as classes impedindo assim que essa classe seja estendida (a classe String ). Também é possível aplicar final aos métodos de modo que estes não possam ser sobrepostos em outras classes. Todos os métodos de uma classe final também são final. Os principais motivos para se utilizar final são eficiência e segurança. •Ex: final class Vendedor { ... } •A cláusula instanceof: Utilizado para se saber a classe real a que pertence um objeto. •Ex: public void atualizaEmpregado( Empregado e ) { if ( e instanceof Gerente ) // atualiza Gerente else if ( e instanceof Vendedor ) // atualiza Vendedor else // atualiza Empregado comum; • Conversão entre objetos ( Casting ) : É possível se atribuir a referência de um objeto de uma subclasse para outro de uma superclasse diretamente, sempre no sentido de baixo para cima na árvore de hierarquia. Posteriormente, caso se queira recuperar toda a potencialidade do objeto da subclasse é só se fazer um cast na referência. Em OO há sempre dois tempos, o de compilação e o de execução. •Ex: public void atualizaEmpregado( Empregado e ) { if ( e instanceof Gerente ) { e.getNomeDaSecretaria(); // Erro ! Em tempo de compilação e é do tipo Empregado ( (Gerente) e). e.getNomeDaSecretaria(); // Ok o método é da classe Gerente para o compilador 40 JAVA •Ex: Empregado e = new Empregado(); Gerente g = new Gerente(); e = g; // Ok, Gerente tem tudo de Empregado e mais alguma coisa g = e; // Erro ! Certamente Empregado não tem tudo que deveria ter um Gerente g = (Gerente) e; // Ok, para o compilador mas em tempo de execução e tem que ser Gerente ! Ex: Faça uma classe onde sejam criados Empregados e Gerentes em um array de Empregados e imprima seus nomes e os nomes de suas secretárias quando for o caso a partir do vetor. import java.util.*; class ListaEmpregadosGerentes { public static void main(String args[]) { Empregado vetEmpregado[] = new Empregado[4]; Gerente mandaChuva1 = new Gerente ("Ricardo", 7500, new GregorianCalendar(1987,11,15)); mandaChuva1.setNomeDaSecretaria("Claudia"); Gerente mandaChuva2 = new Gerente ("Pedro", 5500, new GregorianCalendar(1980,06,28)); mandaChuva2.setNomeDaSecretaria("Luciana"); vetEmpregado[0] = mandaChuva1; vetEmpregado[1] = new Empregado("Claudia",2000,new GregorianCalendar(1999, 11, 6)); vetEmpregado[2] = new Empregado("Luciana",2500,new GregorianCalendar(1993, 1, 12)); vetEmpregado[3] = mandaChuva2; for (int i = 0; i < 4; i++) { if (vetEmpregado[i] instanceof Gerente) { System.out.println("Nome Gerente: "+ vetEmpregado[i].getNome()); System.out.println("Nome Secretária: "+ ((Gerente) vetEmpregado[i]).getNomeDaSecretaria()); } else System.out.println("Nome Empregado: "+ vetEmpregado[i].getNome()); } } 41 Prática: Faça o exercício usando herança e Polimorfismo JAVA •Classes Abstratas: É uma classe que define uma hierarquia para outras classes, porém é tão abstrata que seus métodos apenas dizem o que deve ser realizado pelos descendentes sem contudo implementar particularmente os códigos( métodos abstratos). Estas classes, definidas com o modificador abstract, não podem ser instanciadas diretamente apenas através de subclasses. Além disso, podem ter métodos e variáveis concretos e até não possuírem nenhum método abstrato, contudo se houver algum método abstrato a classe deverá ser declarada como abstrata. •Ex: public abstract class PassaroCanoro { private String origem; // variável concreta PassaroCanoro public abstratct void cantar() ; // método abstrato, sem implementação public String getOrigem() { return origem; } } // método concreto public class Curio extends PassaroCanoro Curió TrincaFerro { public void cantar() { ... } } public class TrincaFerro extends PassaroCanoro // Uma classe que estenda outra que seja abstrata deve { public void cantar() { ... } } Criando um objeto: // prover implementação a todos os métodos abstratos // ou também será abstrata PassaroCanoro pc; // Se pode declarar objeto de classe abstrata pc = new PassaroCanoro(); // Erro ! Porém não se pode instanciar PassaroCanoro pc = new Curio(); // Instância da subclasse 42 JAVA • A superclasse Object: Esta classe é a superclasse a partir da qual todas as classes derivam, ou seja todas as classes são filhas de Object. Normalmente se utiliza um objeto desta classe como armazenador genérico pois pode fazer referência a qualquer objeto. Esta classe também define alguns métodos úteis como: equals() e toString() que devem ser anulados em outras classes para trabalhar de forma customizada. •Método equals(): Na classe Object apenas compara se dois objetos apontam para a mesma área. Para saber se dois objetos distintos possuem o mesmo conteúdo deve-se anulá-lo. Ex: class Empregado { ... public boolean equals (Object obj) { // Testa-se um objeto qualquer é igual a um dado Empregado if ( ! (obj instanceof Empregado) ) return false; Empregado e = (Empregado) obj; return nome.equals(e.nome) && salario == e.salario && dataContratacao.equals(e.DataContratacao); •Método toString: Retorna uma String que representa o valor do objeto. De um geral as classes anulam este método a fim de dar uma representação impressa do estado do objeto. Ex: class Empregado { ... public String toString() { return nome + “\n” + salario + “\n” + dataContratacao; } // Chama toString() das classes // String e GregorianCalendar •Todos os arrays são classes que derivam da classe Object e todo array de objetos pode ser convertido em um array de Object: •Object vet = new int[10[; // Ok pois qualquer array é um Object; •Object vetObj[] = new Empregado[10]; // Se o array fosse de tipo básico daria erro ! 43 JAVA Ex. Um método para localizar um objeto de qualquer classe em um array de objetos também de qualquer classe. public int localizar (Object[] a, Object b) { for ( int i = 0; i < a.length; i++) if ( a[i].equals(b) ) return i; // O método equals chamado é o da classe real do objeto a[i] else return -1; • A classe Vector: É uma classe definida no pacote java.util que armazena elementos do tipo Object, sendo assim, para se recuperar o tipo real do objeto será necessário usar o cast. A classe Vector oferece vários métodos para trabalhar com vetor como se fosse uma lista encadeada, ou seja, aumentando e reduzindo o tamanho dinamicamente. • Criando: Vector vet = new Vector(3); Um Vector vazio com potencial de até 3 elementos. Ao se inserir o quarto elemento o Vector dobrará de tamanho automaticamente. Para se evitar o crescimento exponencial pode-se passar o tamanho do incremento no 2º argumento do construtor. Ex: new Vector(3,5); • Adicionando: Os métodos add() e add(int index, Object obj) adicionam um elemento ao final do Vector ou na posição index deslocando os elementos >= index. Ex: vet.add(new Empregado()) ou vet.add(3,novoFunc); • Removendo: O método remove(int index) remove o elemento na posicão = index no Vector. Ex: vet.remove(3); // Remove o elemento na quarta posição retornando-o como um Object • Obtendo o tamanho do Vector: Com o método size() é possível se obter o tamanho corrente do vetor. Ex int tam = vet.size(); • Acessando o Vector: Com o método get(int index) é possível acessar um elemento que esteja na posição index porém é bom lembrar que ele virá como um Object. Os elementos somente podem ser acessados após se ter inserido elementos com o método add(). Ex Item x = (Item) vet.get(3); • Alterando uma posição: Com set (int index, Object obj) é possível se alterar a posição index do Vector para o conteúdo obj. Também é necessário que a posição index já exista no Vector. 44 JAVA • Ajustando o tamanho real: É possível ajustar o tamanho do Vector sem adicionar todos os elementos um a um usando setSize(int n). Isto faz com que o Vector passe a ter n elementos null. Ex Vector v = new Vector(10); // capacidade 10 tamanho 0 v.set( 0, x ); // Erro ! Posição 0 ainda não existe. v.add(x); // v.size() passa a ser = 1 v.setSize(10); // v.size() passa a ser igual a 10 • Performance: As operações com Vector não são tão eficientes como com arrays. Desta forma é comum ao se saber que o array não mudará mais de tamanho, copiar os elementos do Vector para o array. Ex String nomes[] = new String[ vet.size() ]; vet.copyInto[nomes]; Um exemplo completo: import java.util.*; class Departamento { private String nome; private Vector empregados = new Vector(10); public Departamento ( String n ) { nome = n; } public void print() { System.out.println( nome ); } public void adicionarEmpregado ( Empregado e ) { empregados.add(e); } public Empregado removerEmpregado (Empregado e ) { int n encontrarEmpregado (empregados, e); if (n == -1 ) return null; else return (Empregado) empregados.remove(n); } 45 JAVA public void listarEmpregados() { for ( int i = 0 ; i < empregados.size() ; i++ ) { System.out.println( ( ( Empregado) empregados.get(i) ).getNome() ); } private static int encontrarEmpregado( Vector v, Empregado b ) { for ( int i = 0 ; i < v.size() ; i++ ) { if ( ( ( Empregado) v.get(i) ) . equals(b) ) return i; else return -1; } } import java.util.*; class TestaEmpregado { public static void main(String args[ ]) { Departamento umEmpregado = new Departamento(“Compras”); Empregado vinicius = new Empregado (“Vinicius Aguiar”, 4500, new GregorianCalendar(1992,6,13); umDepartamento.adicionaEmpregado(vinicius); Empregado carlos= new Empregado (“Carlos Ribeiro”, 5500, new GregorianCalendar(1993,7,14); umDepartamento.adicionaEmpregado(carlos); System.out.println(“Lista de Empregados”); umDepartamento.listarEmpregados(); Empregado empRemovido = umDepartamento.removerEmpregado(carlos); if ( ! (empRemovido == null) ) System.out.println(“Empregado removido = “+empRemovido.getNome()); else System.out.println(“Empregado Inexistente. Nome = ”+carlos.getNome() ); System.out.println(“Lista de Empregados”); umDepartamento.listarEmpregados(); empRemovido = umDepartamento.removerEmpregado(carlos); if ( ! (empRemovido == null) ) System.out.println(“Empregado removido = “+empRemovido.getNome()); else System.out.println(“Empregado Inexistente. Nome = ”+carlos.getNome() ); } } 46 JAVA • Objetos Empacotadores (classes Wrappers): Ocasionalmente é preciso converter um tipo básico em objeto e para isso todos os tipos básicos possuem uma classe com esse fim. As classes são Integer, Long, Float, Double, Character e Boolean. Todas essas classes são do tipo final, não podendo portando ser herdada, e também formam objetos imutáveis, ou seja, não se pode alterar o valor contido em objetos destas classes. Para se criar objetos a partir de tipos básicos utiliza-se os construtores das classes. Por exemplo, new Integer( 5 ) ou new Float( 35.4 ) cria objetos das classes Integer e Float com os valores 5 e 35.4 respectivamente Ex. Criar um Vector com valores do tipo double Vector v = new Vector(); v.add( 3.14 ); // Erro ! Método add() de Vector só permite objetos v.add(new Double(3.14) ); // Cria um objeto do tipo Double que armazena o valor 3.14 double x = ( (Double) v.get( n ) ). doubleValue(); // Método doubleValue() para recuperar o valor Outra Forma de converter String em tipo básico podendo conter separadores de milhares. try { x = new DecimalFormat().parse( s.trim( ) ).doubleValue(); } catch( ParseException e) { x = 0; } • A classe Class: A classe Class representa a identificação de tipo do objeto criado em tempo de execução. Desta forma a JVM sabe a que classe o objeto pertence e os métodos corretos. No entanto essas informações podem ser obtidas através do método getClass da classe Object que retorna um objeto da classe Class. Ex. Empregado e; ... Class c1 = e.getClass(); System.out.println(“Nome da classe = “+ e.getClass().getName() ); // Retorna o nome da classe for (int i = 0 ; i < 3 ; i++) // Pode retornar um Gerente ou um Empregado como nome de classe System.out.println( vetEmpregados[ i ].getClass().getName() + “ “+ vetEmpregados[ i ].getNome()); •Existem outras formas de se obter um objeto Class como Class.forName() e .class de um tipo 47 JAVA • Interfaces: É a forma usada por Java para fazer herança múltipla, ou seja, um filho herdar de mais de um pai como em C++. Como exemplo, suponha que desejamos escrever uma classe genérica para ordenação de qualquer tipo de objeto java. Começamos então com uma classe abstrata Sortable que possua um método abstrato copareTo() capaz de informar se um objeto é maior, menor ou igual a outro. Em seguida criamos uma classe OrdenaObjetos qualquer que possua um método de classe ordnedar( Sortable a[ ] ) que receba um array de objetos Sortable e os ordene a partir de seus métodos compareTo(). Para isso será necessário que as classses dos objetos estendam Sortable anulando o método compareTo(). Ex. class Empregados extends Sortable { ... // Estendendo Sortable public int compareTo( Sortable b ) // codificando o método compareTo() de Sortable { Empregado emp = (Empregado) b; if ( salario < emp.salario ) return -1; if ( salario > emp.salario ) return 1; return 0; } public class TestaOrdenacao { public static void main(String args [ ]) { Empregado vetEmpregados = new Empregado[ 3 ]; vetEmpregado[0] = new Empregado (“Vinicius Aguiar”, 4500, new GregorianCalendar(1992,6,13); vetEmpregado[1] =new Empregado (“Carlos Ribeiro”, 5500, new GregorianCalendar(1993,7,14); vetEmpregado[2] =new Empregado (“Marco Aurelio”, 3500, new GregorianCalendar(1990,4,30); OrdenaObjetos.ordenar(vetEmpregados); ... } // passando array de Empregados (Sortable) for ( int i = 0; i < vetEmpregados.length; i++ ) System.out.println( vetEmpregados[ i ] ); } } abstract class Sortable { public abstract int compareTo( Sortable b ); } // método que todo Sortable deve codificar 48 JAVA import java.util.*; class OrdenaObjetos { public static void ordenar( Sortable a[ ] ) { // recebe um array de Sortable int n = a.length; boolean troca = true; while ( troca ) { troca = false; for ( int i = 0; i < n – 1; i++ ) { Sortable temp = a[ i ]; if ( temp.compareTo( a[ i + 1 ] ) > 0 ) { // chama o compareTo() do Sortable correspondente a[ i ] = a[ i + 1 ]; a[ i + 1 ] = temp; troca = true; } } } } } • Existe um problema em se usar classe abstrata para expressar propriedade genérica: suponha uma classe que já estenda diretamente uma outra, neste caso não seria possível estender Sortable pois em java uma classe só pode ter um pai. Ex: class ClasseFilho extends ClassePai, Sortable; ERRO ! • A interface soluciona isso e é um compromisso de que sua classe irá implementar certos métodos com a mesma assinatura definida. Inclusive utiliza-se até a palavra implements para indicar esse compromisso. Ex. public interface Comparable // java.lang.Comparable { pubic int compareTo(Object b); } class ClasseFilho extends ClassePai implements Comparable, ... • Interfaces, assim como classes abstratas, também não podem ser instanciadas com new, mas podem fazer referência a objetos de classes que a implementem como se fosse uma superclasse. Ex. class Empregado implements Comparable { . . . } Comparable x = new Empregado( . . . ); if ( y instanceof Comparable ) { . . . } 49 JAVA • Uma Interface pode estender outra criando uma cadeia de interfaces e, embora não seja permitido campos de instância e nem métodos de classe, é possível se ter constantes. • Ex. public interface Y extends X { • { public static final int CONSTANTE = 10; • public int umMetodo(); } • É possível se implementar várias interfaces para maior flexibilidade. Como exemplo uma classe na qual se possa clonar e comparar objetos. • Ex. public Gerente extends Empregado implements Clonable, Comparable; Prática: Faça o Exercício Classes Abstratas e Interfaces • Classes Internas: São classes definidas dentro de outras classes. A motivação para o uso são as seguintes: –Os métodos da classe interna podem acessar os membros da classe externa diretamente; –As classes internas podem ser escondidas de outras classes no mesmo pacote; –As classes internas anônimas poupam muito código quando utilizadas; import java.awt.*; import java.awt.event; import java.util.*; import javax.swing.*; import javax.swing.Timer; public class InnerClassTest { public static void main(String args[ ]) { TalkingClock clock = new TalkingClock(1000, true); JOptionPane.showMessageDialog(null, “Sair do programa ? “); System.exit(0); } } 50 JAVA class TalkingClock { private int interval; private boolean beep; public TalkingClock ( int interval, boolean beep) { this.interval = interval; this.beep = beep; } public void start() { ActionLintener listener = new TimePrinter(); // Internamente new TimePrinter(this); Timer t = new Timer ( interval, listener); t.start(); } private class TimePrinter implements ActionListener { // Classe Interna private // Aqui existe uma referência do tipo TimeClock outer; public void actionPerformed(ActionEvent e) { Date now = new Date(); System.out.println(“ Agora são: “+ now); if (beep) // Variável da classe externa – Internamente (outer.beep) Toolkit.getDefaultTookit().beep(); } } } Obs: É gerado internamente um construtor do tipo : public TimePrinter( TalkingClock clock) { outer = clock; } 51 JAVA •Classe Interna Anônima: Quando se tem que criar uma classe interna para se usar somente um objeto dessa classe, é possível se criar o obj sem sequer dar nome a classe que além de ser interna passa a ser também anônima. public void start() { ActionLintener listener = new ActionListener() // new no supertipo da classe (com ou sem argumentos) ou interface // Cria o obj listener, de uma classe sem nome que implementa ActionListener, e possui a descrição abaixo { // Abre chaves depois dos parênteses indica a presença de classe anônima public void actionPerformed(ActionEvent e) { Date now = new Date(); System.out.println(“ Agora são: “+ now); if (beep) // Variável da classe externa – Internamente (outer.beep) Toolkit.getDefaultTookit().beep(); } }; // Fim da declaração da classe interna anônima Timer t = new Timer ( interval, listener); t.start(); } Significado: Crie um objeto de uma classe que implementa ActionListener e tem como método o actionPerformed. classe Interna anônima não pode ter construtores mas, caso seja necessário, pode-se passar parâmetros aos construtores da superclasse caso a classe anônima esteja estendendo uma classe e não uma interface. 52 JAVA • Interfaces gráficas com Swing: O pacote Swing não é um substituto do AWT ( Abstract Window Toolkit ), o pacote gráfico utilizado nas primeiras versões de java. Em vez disso, o Swing é visto como uma camada disposta sobre o AWT e que utiliza internamente os componentes da AWT. Diferentemente da AWT, onde alguns componentes gráficos utilizavam a capacidade de renderização da interfaces gráficas em que o aplicativo estava sendo executado, os componentes do Swing são todos escritos em puro java. • A idéia da AWT de utilizar a API nativa para a construção de GUI trouxe os seguintes problemas: •Diferenças nos comportamentos dos componentes em diferentes sistemas operacionais •Alguns sistemas operacionais possuem conjuntos limitados de componentes GUI •Erros na biblioteca de interface AWT para diferentes plataformas •A abordagem Swing derivada da Internet Fundation Classes, adotou a filosofia de manter o tratamento de eventos da AWT e obter da plataforma apenas a janela gráfica (Frame) e os demais componentes são renderizados sobre ela pelo próprio Java. •Desenhar os componentes de uma única forma trouxe diferentes aparências o que foi contornado em Java criando-se diferentes “look and feel” nos padrões Windows, Motif e Metal. Component List Button Container Label CheckBox Window Frame JComponent Hierarquia Parcial dos componentes da AWT 53 JAVA • Um componente do pacote Swing é reconhecido pela letra J antecedendo o nome do mesmo componente no pacote AWT. • A classe JFrame: Consiste na classe que representa a janela principal de um aplicativo de interface gráfica usando Swing. Esta classe estende diretamente a classe Frame do AWT. import javax.swing.*; // importa o pacote javax.swing public class PrimeiraJanela extends JFrame // estende JFrame { public PrimeiraJanela() { super (“Nossa primeira Janela”); // chama o construtor de JFrame especificando um título setSize(300, 150); // Ajusta o tamanho da janela (largura x altura) em pixel setVisible(true); // Exibe a janela } public static void main (String args[ ]) { PrimeiraJanela pj = new PrimeiraJanela(); // Cria uma instância de PrimeiraJanela pj.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Informa o que fazer ao fechar a janela } } • Embora a janela criada possa ter o comportamento esperado de uma janela Window o seu fechamento não faz com que a aplicação pare a execução, mas apenas feche a janela. Para que isto aconteça é necessário existir a última instrução pj.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE). 54 JAVA • Existe uma outra forma de fechar a janela e a aplicação, e está relacionada aos possíveis eventos gerados a partir de uma janela. Para isto basta importar o pacote java.awt.event.* e trocar a instrução anterior pela instrução abaixo, pois as novas classes utilizadas pertencem a este pacote. Ex: Pj.addWindowListener ( new WindowAdapter( ) // obj de Classe Interna anônima que estende uma classe Adaptadora { public void windowClosing ( WindowEvent e) // Sobre escreve este método dos sete oferecidos { System.exit( 0 ); } } ); • Especificando um título para a Janela: É possível se especificar um título para a janela durante a execução do programa usando o método setTitle( String titulo) da classe JFrame. Ex: JFrame janela = new MinhaJanela(); janela.setTitle(“ Texto da minha janela” ); • Definindo um ícone para a janela do aplicativo: É possível se definir um ícone para a janela em tempo de execução com as seguintes instruções: Ex: ImageIcon icone = new ImageIcon(“box.gif”); // A localização do arquivo é transformada em URL janela.setIconImage( icone.getImage() ); • Definindo o modo de exibição de uma janela: Para definir o modo de exibição de uma janela utiliza-se o método setExtendedState( int modo ) herdado da classe Frame; onde modo pode ser uma das três constantes: NORMAL, ICONFIED, MAXIMIZED_BOTH, ou seja, padrão, minimizada ou maximizada. •Ex: janela.setExtendedState( ICONFIED ); • Fixando as dimensões de uma janela: Para habilitar ou desabilitar o redimensionamento de uma janela utiliza-se o método setResizable( boolean valor) herdado de Frame. Ex: janela.setResizable(false); // Impossibilita o seu redimensionamento. • Especificando as dimensões de uma janela: Para especificar o tamanho de uma janela utiliza-se o método setSize( largura, altura ); Ex: janela.setSize(300, 200); 55 JAVA // Um Exemplo de utilização dos métodos da classe JFrame construindo uma Janela padrão import javax.swing.*; public class Janela extends JFrame{ protected int largura = 300, altura = 150; protected String titulo = "Sem título"; protected String icone = "padrão"; protected boolean redimensionavel = true; protected String modo = "normal"; public void mostrar() { this.setSize(largura, altura); this.setTitle(titulo); if(icone != "padrão") { ImageIcon iconeImg = new ImageIcon(icone); setIconImage(iconeImg.getImage()); } this.setResizable(redimensionavel); this.setVisible(true); if(modo == "normal") setExtendedState(NORMAL); else if(modo == "minimizada") setExtendedState(ICONIFIED); else setExtendedState(MAXIMIZED_BOTH); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } } 56 JAVA // Exemplo de uma classe que utiliza a classe Janela como padrão import javax.swing.*; public class MinhaJanela extends Janela { public MinhaJanela() { titulo = "Esta é uma classe personalizada"; altura = 600; largura = 800; redimensionavel = true; icone = "box.gif"; modo = "maximizada"; mostrar(); } public static void main(String args[]) { MinhaJanela app = new MinhaJanela(); } } . Anexando controles a janela: De uma forma geral são necessários três passos para se anexar controles nas janelas: 1) Obter uma referência ao objeto Container da janela. A classe JFrame é composta de 4 painéis dos quais o painel de conteúdo é o que nos interessa pois os demais são para controle interno da aparência; Ex: Container tela = janela.getContentPane(); 2) Definir a forma como os componentes serão dispostos no Container usando um gerenciador de janelas. Inicialmente usaremos a classe FlowLayout que aloca os componentes da esquerda para a direita de forma centralizada por default até atingirem a borda da direita, e então passam para a próxima linha. Ex: FlowLayout layout = new FlowLayout(); tela.setLayout ( layout ); Os componentes são dispostos por default a 5 pixels de distância na largura e na altura da borda da janela e entre eles. É possível alterar o alinhamento dos componentes usando as constantes: ( CENTER , LEFT e RIGHT) e o distanciamento passando os novos valores no construtor. 57 Ex: tela.setLayout( new FlowLayout( FlowLayout.LEFT, 20, 10); JAVA 3) Efetuar a chamada ao método add() da classe Container para adicionar os componentes ao Container. Ex: JButton btn = new JButton( “Clique aqui” ); tela.add( btn); • Um exemplo usando um label, um botão e uma caixa de texto import javax.swing.*; import java.awt.*; public class Controles2 extends JFrame { public Controles2() { super("Adicionando controles à janela"); Container tela = getContentPane(); // Obtendo o Container de JFrame (painel de conteúdo) FlowLayout layout = new FlowLayout(); // Obtendo um gerenciador de lay-out layout.setAlignment(FlowLayout.LEFT); // Ajustando a posição dos componentes a esquerda tela.setLayout(layout); // Informando ao Container para usar o lay-out criado JLabel rotulo = new JLabel("Seu Nome:"); // Cria um label com o texto “Seu nome” JTextField nome = new JTextField(10); // Cria uma caixa de texto com tamanho de 10 caracteres JButton btn = new JButton("OK!"); // Cria um botão com o rótulo “OK” tela.add(rotulo); tela.add(nome); // Adiciona os componentes criados ao Container tela.add(btn); setSize(300, 100); // Ajusta o tamanho da janela setVisible(true); // Exibe a janela } public static void main(String args[]) { Controles2 app = new Controles2(); app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } } 58 JAVA • Definindo a cor de fundo da janela: A cor de fundo da janela pode ser alterada com o método setBackground() do painel de conteúdo, ou seja, do objeto Container de JFrame. As cores podem ser estabelecidas através de constantes da classe Color ou através de valores do padrão RGB (Red-Green-Blue) que definen as tonalidades de vermelho, verde e azul variando de 0 a 255. Ex: Container tela = janela.getContentPane( ); tela.setBackground( Color.white); ou tela.setBackground( new Color(220, 220, 220) ); • Introdução a Manipulação de Eventos: Java fornece muita flexibilidade na manipulação de eventos podendo-se determinar qual objeto responderá a que evento. A manipulação na AWT em geral funciona da seguinte forma: • Um objeto ouvinte é uma instância de uma classe que implementa uma interface listner como ActionListener ou WindowListener; • Uma origem do evento é um objeto que pode reconhecer eventos, criar objetos que representem estes eventos e informar aos objetos ouvintes registrados a ocorrência destes eventos passando o objeto evento criado. Objetos eventos são derivações da classe java.util.EventObject como ActionEvent e WindowEvent; • A origem do evento envia o objeto evento a todos os objetos ouvintes registrados quando estes ocorrem; •Os objetos ouvintes então irão usar a informação do objeto evento recebido para determinar sua reação ao evento. • Eventos Semânticos: São os eventos que expressam o que o usuário está fazendo como clicar um botão, alterar uma caixa de texto e outros. Estes eventos são representados por quatro interfaces: • ActionEvent: clique em botão, seleção em menu, duplo clique em lista ou enter em caixa de texto; • AjustmentEvent: ajuste na barra de rolagem; • ItemEvent: Seleção em caixas de seleção ou itens de um listBox; • TextEvent: Alteração em uma caixa de texto ou área de texto. •Eventos de baixo nível: São os eventos que tornam o reconhecimento dos eventos semânticos possível. Há seis classes para representar esses eventos: •ComponentEvent: O componente foi redimensionado, movido ou ocultado; •KeyEvent: Uma tecla foi pressionada ou liberada; 59 JAVA • MouseEvent: O botão do mouse foi pressionado, liberado movido ou arrastado; • FocusEvent: Um componente recebeu ou perdeu o foco; • WindowEvent: Uma janela foi ativada, desativada, minimizada, restaurada ou fechada; • ContainerEvent: Um componente foi adicionado ou removido • Assim como existem diversas classes de eventos também existem diversas classes de ouvintes para estes eventos. O pacote básico de eventos java.awt.event disponibiliza 11 interfaces para este fim. São elas: ActionListener, AdjustmentListener,ComponentListener, ContainerListener, FocusListener, ItemListener, KeyListener, MouseListener, MouseMotionListener, TextListener e WindowListener. Sete dessas interfaces possuem classes adaptadoras por possuírem mais de um método. Estas classes visam facilitar a utilização: ComponentAdapter, ContainerAdapter, FocusAdapter, KeyAdapter, MouseAdapter, MouseMotionAdapter e WindowAdapter. . Respondendo aos eventos ActionEvents: Para responder a estes eventos são necessários os seguintes passos: 1) Criar um objeto origem que é um componente capaz de gerar um ActionEvent, como um botão ou uma caixa de texto por exemplo. Ex: JButton btn = new JButton(“Clique aqui”); 2) Criar um objeto ouvinte que é uma instância de uma classe que implemente a interface ActionListener, e fornecer código ao seu único método actionPerformed( ActionEvent e) que recebe o objeto evento. Ex: class TrataEventos implements ActionListener // Criação da classe ouvinte { public void actionPerformed( ActionEvent e ) { . . . // A reação ao clique do botão vem aqui ! } } TrataEventos trat = new TrataEventos( ) ; // Criação do objeto ouvinte 3) Adicionar o objeto ouvinte ao objeto origem para que este saiba a quem passar o objeto evento quando um ActionEvent ocorrer. Ex: btn.addActionListener(trat) 60 JAVA // Um Exemplo de tratamento de eventos import javax.swing.*; import java.awt.*; import java.awt.event.*; public class Eventos extends JFrame{ JTextField texto; public Eventos(){ super("Introdução ao uso de eventos"); Container tela = getContentPane(); FlowLayout layout = new FlowLayout(FlowLayout.LEFT); // Ajusta a exibição dos componentes tela.setLayout(layout); JLabel rotulo = new JLabel("Texto:"); // Criação de um Label texto = new JTextField(10); // Criação de uma caixa de texto com tamanho 10 JButton btn = new JButton("Exibir!"); // Criação de um botão TratEventos trat = new TratEventos(); // Criação do objeto ouvinte btn.addActionListener(trat); // Ligação do objeto origem (botão) ao objeto ouvinte tela.add(rotulo); tela.add(texto); // Adicionando componentes tela.add(btn); setSize(300, 100); setVisible(true); } public static void main(String args[]) { Eventos app = new Eventos(); app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } private class TratEventos implements ActionListener{ // Classe ouvinte definida como Interna para facilitar public void actionPerformed(ActionEvent evento){ // Método que trata o evento String txt = "Você digitou: " + texto.getText(); // Acessando a variável texto da classe externa JOptionPane.showMessageDialog(null, txt); } } } // Caixa de diálogo tipo mensagem 61 JAVA • Capturando o Objeto Evento: O objeto evento passado ao método actionPerformed( ) é do tipo ActionEvent, e esta classe permite saber qual o objeto origem gerou o evento através do método getSource() que retorna um Object. Ex: public void actionPerformed( ActionEvent e ) { Object source = e.getSource( ); String nomeClasse = source.getClass().getName(); // Capturando o nome da classe if ( source == blueButton ) ... // Identificando o objeto origem •Inclusão de Textos e Imagens: Para a inclusão de textos é necessária a utilização da classe JLabel. É possível controlar várias propriedades do texto como alinhamento, tipo de letra, tamanho, cor e etc. Uma Imagem também pode ser incluída a partir da classe ImageIcon que representa a imagem. De posse do objeto ImageIcon é possível exibi-lo em um JLabel exclusivamente ou em conjunto com um texto. Ex: import java.awt.*; import java.awt.event.*; import javax.swing.*; class TextosImagens extends JFrame { JLabel L1, L2, L3, L4; ImageIcon icone = new ImageIcon("C:/Teste/Imagem.gif"); TextosImagens() { setTitle("Inserindo Labels e Imagens na Janela"); setSize(350,120); setLocation(50,50); // Posicionamento em relação ao Container getContentPane().setBackground(new Color(220,220,220)); // Cor de fundo da janela // Continua página seguinte 62 JAVA L1 = new JLabel("Aprendendo",JLabel.LEFT); // Alinhamento do texto a esquerda L1.setForeground(Color.red); // Cor da Fonte do Label L2 = new JLabel(icone); L3 = new JLabel("Inserir ",JLabel.RIGHT); L3.setForeground(Color.blue); L4 = new JLabel("Labels e Imagens",icone,JLabel.CENTER); L4.setFont(new Font("Serif",Font.BOLD,20)); L4.setForeground(Color.black); getContentPane().setLayout(new GridLayout(4,1)); // Divide a Janela em um Grid (linhas,colunas) getContentPane().add(L1); getContentPane().add(L2); getContentPane().add(L3); getContentPane().add(L4); } public static void main(String args[]) { JFrame Janela=new TextosImagens(); Janela.show(); WindowListener x = new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }; Janela.addWindowListener(x); } } • O método setPreferredSize( Dimension preferredSize ) permite que se defina o tamanho de um componente, ou seja, a área que ele ocupará na janela. A classe Dimension encapsula largura e altura de um componente. •Ex. label1.setPreferredSize ( new Dimension ( 300, 200 ) ); // Ajusta o tamanho do label1 para 300 x 200. 63 JAVA •Inserindo Botões: Para adicionar Botões utiliza-se a classe JButton. Assim como o JLabel, JButton possui muitas propriedades que podem ser manipuladas. import java.awt.*; import java.awt.event.*; import javax.swing.*; public class TesteBotao extends JFrame implements ActionListener { // O JFrame é o obj ouvinte de ActionEvents JButton b1,b2; ImageIcon icone = new ImageIcon("tomcat.gif"); public TesteBotao() { setTitle("Inserindo botoes na janela"); setSize(350,100); setLocation(50,50); getContentPane().setBackground(new Color(180,180,180)); b1 = new JButton("Busca",icone); b1.setHorizontalTextPosition(AbstractButton.LEFT); // Posicao do texto em relação a imagem (default e direita) // b1.setVerticalTextPosition(AbstractButton.TOP); // Posicao do vertical do texto em relação a imagem (botton) b1.setBackground(new Color(100,180,180)); // Cor de fundo do botão b1.setForeground(Color.black); // Cor do texto do botão b1.setFont(new Font("ScriptS",Font.BOLD,20)); // Define a fonte do botão b1.setEnabled(true); // Habilita/Desabilita o botão b1.addActionListener(this); b1.setToolTipText("Pressione aqui para realizar uma busca"); // Coloca uma dica da funcionalidade do botão b1.setMnemonic(KeyEvent.VK_B); // Permite acionar o botão com a combinação ALT+B 64 JAVA b2 = new JButton("Cancelar"); b2.addActionListener(this); b2.setMnemonic(KeyEvent.VK_C); b2.setToolTipText("Pressione aqui para cancelar"); getContentPane().setLayout(new FlowLayout()); // gerenciador de layout FlowLayout getContentPane().add(b1); getContentPane().add(b2); } public void actionPerformed(ActionEvent e) // metodo definido na Interface ActionListener { if (e.getSource() == b1) { System.out.println("Botao 1 pressionado"); } if (e.getSource() == b2) { System.out.println("Botao 2 pressionado"); } } public static void main(String args[]) { JFrame Janela = new TesteBotao(); Janela.show(); WindowListener x = new WindowAdapter() //para fechar a janela { public void windowClosing(WindowEvent e) { System.exit(0); } }; Janela.addWindowListener(x); } } 65 JAVA • Incluindo Caixas de Texto: Para inclusão de caixas de texto utiliza-se a classe JTextField que também possui várias propriedades que podem ser modificadas. O exemplo abaixo exemplifica o seu uso com uma simples calculadora onde o usuário digita dois números em JTextFields e clica em um dos quatro botões de operação. import java.awt.*; import java.awt.event.*; import javax.swing.*; class TesteJTextField extends JFrame implements ActionListener { JLabel L1,L2,L3; JButton B1, B2, B3, B4, B5; JTextField T1,T2,T3; public static void main(String args[]) { JFrame Janela=new TesteJTextField(); Janela.setVisible(true); WindowListener x = new WindowAdapter() // Para fechar a janela { public void windowClosing(WindowEvent e) { System.exit(0); } }; Janela.addWindowListener(x); } 66 JAVA TesteJTextField() { setTitle("Calculadora"); setSize(350,90); setLocation(50,50); getContentPane().setBackground(new Color(150,150,150)); // Cor de Fundo getContentPane().setLayout(new GridLayout(3,4)); // Define o layout com 3 linhas e 4 colunas L1 = new JLabel("Num.1"); L1.setForeground(Color.black); // Cor da fonte do Label L1 L1.setFont(new Font("",Font.BOLD,14)); // Tipo da fonte do Label L1 L2 = new JLabel("Num.2"); L2.setForeground(Color.black); L2.setFont(new Font("",Font.BOLD,14)); L3 = new JLabel("Total"); L3.setFont(new Font("",Font.BOLD,14)); B1 = new JButton ("+"); B1.addActionListener(this); //Adiciona o obj JFrame que esta sendo construído B2 = new JButton ("-"); B2.addActionListener(this); // para que seja o objeto ouvinte dos botões para B3 = new JButton ("x"); B3.addActionListener(this); // ActionEvents B4 = new JButton ("/"); B4.addActionListener(this); B5 = new JButton ("Limpar"); B5.addActionListener(this); B5.setBackground(Color.black); // Cor de fundo do botão B5.setForeground(Color.white); // Cor do texto do botão T1 = new JTextField(); // Cria os JTextFields T2 = new JTextField(); T3 = new JTextField(); T3.setEditable(false); // Define que o textField é somente para leitura 67 JAVA getContentPane().add(L1); // Adiciona os botões, labels e getContentPane().add(T1); // textFields ao ContentPane() 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); } public void actionPerformed(ActionEvent e) // Para tratar ActionEvents gerados { float N1=0, N2=0, result=0; if (e.getSource()==B5) // Se objeto origem do evento for o botão B5 { T1.setText(""); T2.setText(""); T3.setText(""); return; } try { N1 = Float.parseFloat(T1.getText()); N2 = Float.parseFloat(T2.getText()); } catch (NumberFormatException erro) { T3.setText("Erro"); return; } 68 JAVA if (e.getSource() == B1) { result = N1 + N2; } if (e.getSource() == B2) { result = N1 - N2; } if (e.getSource() == B3) { result = N1 * N2; } if (e.getSource() == B4) { result = N1 / N2; } T3.setText(""+result); // Ajusta o resultado } } • Para o uso de password utiliza-se a classe JPasswordField que substitui os caracteres digitados por “*” por default. Entretanto é possível especificar o caractere de eco através do método setEchoChar(); ... JPasswordField P1 = new JPasswordField(); P1.setEchoChar('?'); P1.addActionListener(this); // Adiciona o objeto corrente como objeto ouvinte para ActionEvents como um // <enter> em um JTextField ou click em botões public void actionPerformed(ActionEvent e) { if (P1.getText().equals("JAVA")) // Está depreciado método getText(), melhor trocá-lo por getPassword() String texto = new String(P1.getPassword()); if (texto == “java”) T1.setText("Senha Valida"); else T1.setText("Senha Invalida"); } 69 JAVA •Listas de Seleção: As listas de seleção são objetos que possibilitam a escolha de um ou vários valores armazenados em uma lista de opções. Esta lista é representada pela classe JList e para sua utilização deve-se seguir os seguintes passos: 1. Declarar um objeto JList; 2. Declarar um objeto que conterá uma lista de opções ( DefaultListModel ) e adicionar a ele todas as opções 3. Instanciar um objeto do item 1 passando um objeto do item 2; 4. Criar um painel de rolagem ( JScrolPane ); 5. Adicionar o objeto do item 1 ao painel de rolagem. O exemplo a seguir demonstra o uso dos principais métodos em uma lista de seleção, onde se pode adicionar e remover itens da lista. import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; // Devido ao ListSelectionListener public class TesteJList extends JFrame implements ListSelectionListener, ActionListener { JLabel L1; JTextField T1; JList lista; // Declaração do JList JButton bquant, bindice, bclear; DefaultListModel listModel; // Declaração do objeto que conterá uma lista de opções public static void main(String args[]) { JFrame Janela = new TesteJList(); Janela.setVisible(true); 70 JAVA WindowListener x = new WindowAdapter() // Classe Interna para o evento WindowListener { public void windowClosing(WindowEvent e) { System.exit(0); } }; Janela.addWindowListener(x); } TesteJList() { setLocation(300,100); setTitle("Uso do JList"); setSize(200,250); T1 = new JTextField(); T1.addActionListener(this); // Adiciona o JFrame como ouvinte para ActionEvents de T1 L1 = new JLabel("Sem selecao"); L1.setForeground(Color.black); bquant = new JButton("Quantidade de itens"); bquant.addActionListener(this); // Idem acima para bquant bindice = new JButton("Indice selecionado"); bindice.addActionListener(this); // Idem acima para bindice bclear = new JButton("Remove item"); bclear.addActionListener(this); // Idem acima para bclear listModel = new DefaultListModel(); // Criação do objeto que conterá a lista de opções listModel.addElement("Banana"); // Adição das opções da lista listModel.addElement("Pera"); listModel.addElement("Maça"); listModel.addElement("Uva"); lista = new JList(listModel); // Criação do JList com as opções da lista no objeto listModel 71 JAVA lista.addListSelectionListener(this); // Adiciona o JFrame como objeto ouvinte para seleções na lista JScrollPane Painel = new JScrollPane(lista); // Adiciona o JList lista ao Painel com barra de Rolagem (JScrollPane) getContentPane().setLayout(new GridLayout(6,1)); // Adiciona o gerenciador GridLayout com 6 linhas e 1 coluna getContentPane().add(L1); getContentPane().add(T1); getContentPane().add(Painel); getContentPane().add(bquant); getContentPane().add(bindice); getContentPane().add(bclear); } public void actionPerformed(ActionEvent e) // Método do JFrame para tratar ActionEvents { if (e.getSource()==T1) { listModel.addElement(T1.getText()); //adiciona itens a lista T1.setText(""); } if (e.getSource() == bquant) T1.setText("Quantidade: " + listModel.getSize()); if (e.getSource() == bindice) T1.setText("Indice selecionado: " + lista.getSelectedIndex()); if (e.getSource() == bclear) { int index = lista.getSelectedIndex(); L1.setText("Removido : "+ lista.getSelectedValue()); listModel.remove(index); } } public void valueChanged(ListSelectionEvent e) // Método do JFrame para tratar alterações na lista de seleção { L1.setText("Selecionado : "+ lista.getSelectedValue()); } } Ex: Ao remover um item não selecionado no exemplo acima provoca erro, corrija de modo a verificar se há algum 72 item selecionado antes de removê-lo. JAVA •Incluindo Caixas de Seleção (ComboBox): Criadas a partir da classe JComboBox funciona praticamente igual ao JList porém há diferenças entre os métodos para a manipulação de suas propriedades. Um Exemplo: import java.awt.*; import java.awt.event.*; import javax.swing.*; public class TesteComboBox extends JFrame implements ActionListener, ItemListener // Trata ItemEvents { JLabel L1; JTextField T1,T2,T3; JComboBox combo; // Declara os ComboBox JButton B1,B2,B3,B4,B5,B6,B7,B8; public static void main(String args[]) { JFrame Janela = new TesteComboBox(); Janela.setVisible(true); WindowListener x = new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }; Janela.addWindowListener(x); } 73 JAVA TesteComboBox() { setTitle("Uso do JComboBox"); setSize(400,170); getContentPane().setBackground(new Color(190,190,190)); L1 = new JLabel("Conteudo"); L1.setForeground(Color.blue); L1.setFont(new Font("Arial", Font.BOLD, 15)); B1 = new JButton("Mostra Texto"); B1.addActionListener(this); B2 = new JButton("Mostra Indice"); B2.addActionListener(this); B3 = new JButton("Adiciona Item"); B3.addActionListener(this); B4 = new JButton("Remove Item"); B4.addActionListener(this); B5 = new JButton("Remove Todos"); B5.addActionListener(this); B6 = new JButton("Quant. Itens"); B6.addActionListener(this); T1 = new JTextField(); T2 = new JTextField(); String[] cores = {"Branco","Vermelho","Azul","Verde"}; // Cria um vetor com estas opções combo = new JComboBox(cores); // Cria um JComboBox com as opções do vetor cores combo.addItemListener(this); // Informa que o objeto ouvinte para ItemEvents do Combo é o JFrame getContentPane().setLayout(new GridLayout(5,2)); getContentPane().add(L1); getContentPane().add(combo); getContentPane().add(B1); getContentPane().add(B4); getContentPane().add(B2); getContentPane().add(B5); getContentPane().add(B3); getContentPane().add(T1); getContentPane().add(B6); getContentPane().add(T2); } 74 JAVA public void actionPerformed(ActionEvent e) // Trata os ActionsEvents dos botões { if (e.getSource()==B1) // mostra texto L1.setText("Texto: "+combo.getSelectedItem()); if (e.getSource()==B2) // mostra indice L1.setText("Indice: " + combo.getSelectedIndex()); if (e.getSource()==B3) // adiciona item if (T1.getText().length() != 0) { combo.addItem(T1.getText()); T1.setText(""); } if (e.getSource()==B4) // remove item a partir do índice do item selecionado combo.removeItemAt(combo.getSelectedIndex()); if (e.getSource()==B5) // remove todos os itens combo.removeAllItems(); if (e.getSource()==B6) //quantidade de itens no combo T2.setText(""+combo.getItemCount()); } public void itemStateChanged(ItemEvent e) // Se ocorrer alterações(ItemEvents) no Combo ... { T1.setText(""+combo.getSelectedItem()); } } 75 JAVA •Incluindo Caixas de Opção (CheckBox): Criadas a partir de JCheckBox permitem apresentar vária opções como caixas nas quais o usuário pode marcar nenhuma, uma ou várias delas. Exemplo: import java.awt.*; import java.awt.event.*; import javax.swing.*; public class TestaCheckBox extends JFrame implements ItemListener // JFrame como ouvinte de ItemEvent { JLabel L1; JCheckBox C1, C2; // Declara os CheckBox static int negrito=0, italico=0; public static void main(String args[]) { JFrame Janela = new TestaCheckBox(); Janela.ssetVisible(true); WindowListener x = new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }; Janela.addWindowListener(x); } TestaCheckBox() { getContentPane().setBackground(new Color(180,180,180)); setTitle("Uso do JCheckBox"); setSize(300,70); getContentPane().setLayout(new FlowLayout(FlowLayout.CENTER)); 76 JAVA L1 = new JLabel("Java"); L1.setFont(new Font("Arial",Font.PLAIN,20)); L1.setForeground(Color.black); C1 = new JCheckBox("Negrito"); // Cria o checkbox sem marcação. Poderia ser (“Negrito”,true). C1.setBackground(new Color(180,180,180)); C1.addItemListener(this); // Adiciona o JFrame para ser o objeto ouvinte de ItemEvents do C1 C2 = new JCheckBox("Italico"); C2.setBackground(new Color(180,180,180)); C2.addItemListener(this); // Adiciona o JFrame para o objeto ouvinte de ItemEvents do C2 getContentPane().add(L1); getContentPane().add(C1); getContentPane().add(C2); } public void itemStateChanged(ItemEvent e) // Método do JFrame que trata o ItemEvent ocorrido { if(e.getSource()==C1) { // Testa se foi do checkbox C1 if(e.getStateChange() == ItemEvent.SELECTED) // Poderia ser DESELECTED negrito=Font.BOLD; else negrito=Font.PLAIN; } if(e.getSource()==C2) { if(e.getStateChange() == ItemEvent.SELECTED) italico=Font.ITALIC; else italico=Font.PLAIN; } L1.setFont(new Font("Arial",negrito+italico,20)); } } 77 JAVA •Incluindo Painéis e Botões de Radio: Os painéis são criados a partir da classe JPainel e são utilizados como containers. Os botões de radio são criados a partir da classe JRadioButton e, diferentemente dos checkboxes, permitem que apenas uma entre várias opções seja marcada pelo usuário. Estes devem sempre ser agrupados em um ButtonGroup para cada conjunto de botões de rádio no Frame. Um exemplo completo: import java.awt.*; import java.awt.event.*; import javax.swing.*; class TestePainel_RadioButton extends JFrame implements ItemListener // O JFrame é Ouvinte de ItemEvents { JLabel L1,L2; float N1=0,result=0; JTextField T1, T2; JPanel P1, P2; // Declara os painéis JRadioButton radio1,radio2,radio3; // Declara os RadioButtons ButtonGroup radiogroup; // Declara o RadioGroup public static void main(String args[]) { JFrame Janela = new TestePainel_RadioButton(); Janela.setVisible(true); WindowListener x = new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }; Janela.addWindowListener(x); 78 } JAVA TestePainel_RadioButton() { setTitle("Uso de botoes de Radio "); setSize(340,120); getContentPane().setLayout(new FlowLayout(FlowLayout.CENTER)); L1 = new JLabel("Digite um valor"); L1.setForeground(Color.blue); L2 = new JLabel("% do Valor :"); L2.setForeground(Color.blue); T1 = new JTextField(5); T2 = new JTextField(5); P1 = new JPanel(); P2 = new JPanel(); T2.setEditable(false); radio1 = new JRadioButton("10% do valor"); radio2 = new JRadioButton("20% do valor"); radio3 = new JRadioButton("30% do valor"); radio1.setMnemonic(KeyEvent.VK_1); // Cria Teclas de Atalho para acionar os RadioButtons radio2.setMnemonic(KeyEvent.VK_2); radio3.setMnemonic(KeyEvent.VK_3); radiogroup = new ButtonGroup(); radiogroup.add(radio1); radiogroup.add(radio2); radiogroup.add(radio3); radio1.addItemListener(this); radio2.addItemListener(this); radio3.addItemListener(this); P1.setLayout(new FlowLayout(FlowLayout.CENTER)); P1.setBackground(new Color(200,200,200)); 79 JAVA P2.setLayout(new GridLayout(2,3)); P2.setBackground(new Color(200,200,200)); P1.add(L1); P1.add(T1); P2.add(radio1); P2.add(radio2); P2.add(radio3); P2.add(L2); P2.add(T2); getContentPane().add(P1); getContentPane().add(P2); } public void itemStateChanged(ItemEvent e) { if (T1.getText().length()==0) return; try { N1 = Float.parseFloat(T1.getText()); if (e.getSource()==radio1) result = (N1 * 10)/100; if (e.getSource()==radio2) result = (N1 * 20)/100; if(e.getSource()==radio3) result = (N1 * 30)/100; } catch(NumberFormatException erro) { T2.setText("Erro"); return; } T2.setText(""+result); } } Prática: Fazer os exercícios Usando Swing 80