Professional Documents
Culture Documents
PROGRAMAÇÃO MODULAR
volume I
A Linguagem Java
Roberto
S.
Bigonha
PROGRAMAÇÃO MODULAR
Volume I
A Linguagem Java
Quarta Edição
Roberto S. Bigonha
Belo Horizonte, MG
15 de Fevereiro de 2017
Roberto S. Bigonha: Pequisador Independente. PhD em
Ciência da Computação pela Universidade da Califórnia, Los An-
geles. Professor Titular Emérito da Universidade Federal Minas
Gerais. Membro da Sociedade Brasileira de Computação. Áreas
de interesse: Linguagens de Programação, Programação Modular,
Estruturas de Dados, Compiladores, Semântica Formal.
COPYRIGHT
c 2006, 2015, 2016, 2017 - Roberto S. Bigonha
Prefácio ix
Agradecimentos xi
1 Estruturas Básicas 1
1.1 Identificadores . . . . . . . . . . . . . . . . . . . . 1
1.2 Programas . . . . . . . . . . . . . . . . . . . . . . 3
1.3 Tipos de dados . . . . . . . . . . . . . . . . . . . . 3
1.4 Tipo boolean . . . . . . . . . . . . . . . . . . . . . 4
1.5 Tipos numéricos . . . . . . . . . . . . . . . . . . . 4
1.6 Constantes simbólicas . . . . . . . . . . . . . . . . 10
1.7 Expressões . . . . . . . . . . . . . . . . . . . . . . 11
1.8 Arranjos . . . . . . . . . . . . . . . . . . . . . . . 16
1.9 Comandos . . . . . . . . . . . . . . . . . . . . . . 23
1.10 Entrada e saı́da básicas . . . . . . . . . . . . . . . 36
1.11 Ambientes e escopo de nomes . . . . . . . . . . . . 45
1.12 Exercı́cios . . . . . . . . . . . . . . . . . . . . . . . 46
1.13 Notas bibliográficas . . . . . . . . . . . . . . . . . 47
2 Classes e Objetos 49
2.1 Criação de novos tipos . . . . . . . . . . . . . . . . 51
2.2 Criação de objetos . . . . . . . . . . . . . . . . . . 53
2.3 Controle de visibilidade . . . . . . . . . . . . . . . 58
2.4 Métodos . . . . . . . . . . . . . . . . . . . . . . . 61
iii
iv SUMÁRIO
3 Hierarquia 91
3.1 Interfaces . . . . . . . . . . . . . . . . . . . . . . . 92
3.2 Hierarquia de interfaces . . . . . . . . . . . . . . . 99
3.3 Implementação dual . . . . . . . . . . . . . . . . . 103
3.4 Hierarquia de classes . . . . . . . . . . . . . . . . . 111
3.5 Tipo estático e tipo dinâmico . . . . . . . . . . . . 116
3.6 Execução de construtoras . . . . . . . . . . . . . . 119
3.7 Iniciação de membros de dados . . . . . . . . . . . 122
3.8 Atribuição de referências . . . . . . . . . . . . . . 125
3.9 Especialização de comportamento . . . . . . . . . . 128
3.10 Ligação dinâmica . . . . . . . . . . . . . . . . . . . 131
3.11 Redefinição de métodos estáticos . . . . . . . . . . 136
3.12 Redefinição de métodos finais . . . . . . . . . . . . 137
3.13 Redefinição de membros de dados . . . . . . . . . . 137
3.14 Modificadores de acesso . . . . . . . . . . . . . . . 139
3.15 Comparação de objetos . . . . . . . . . . . . . . . 141
3.16 Classe Object . . . . . . . . . . . . . . . . . . . . . 142
3.17 Clonagem de objetos . . . . . . . . . . . . . . . . . 143
3.18 Classes abstratas . . . . . . . . . . . . . . . . . . . 147
3.19 Hierarquia múltipla . . . . . . . . . . . . . . . . . 150
SUMÁRIO v
4 Polimorfismo 157
4.1 Polimorfismo referencial . . . . . . . . . . . . . . . 158
4.2 Polimorfismo funcional . . . . . . . . . . . . . . . . 159
4.3 Resolução de sobrecarga estática . . . . . . . . . . 163
4.4 Resolução de sobrecarga dinâmica . . . . . . . . . . 167
4.5 Reúso de funções . . . . . . . . . . . . . . . . . . . 169
4.6 Paradoxo da herança . . . . . . . . . . . . . . . . . 179
4.7 Exercı́cios . . . . . . . . . . . . . . . . . . . . . . . 183
4.8 Notas bibliográficas . . . . . . . . . . . . . . . . . 184
8 Pacotes 263
8.1 Importação de pacotes . . . . . . . . . . . . . . . . 265
8.2 Resolução de conflitos . . . . . . . . . . . . . . . . 267
8.3 Visibilidade . . . . . . . . . . . . . . . . . . . . . . 268
8.4 Compilação com pacotes . . . . . . . . . . . . . . . 270
8.5 Exercı́cios . . . . . . . . . . . . . . . . . . . . . . . 275
10 Genericidade 293
10.1 Métodos genéricos . . . . . . . . . . . . . . . . . . 294
10.2 Classes genéricas . . . . . . . . . . . . . . . . . . . 296
10.3 Criação de objetos de tipo . . . . . . . . . . . . . . 299
10.4 Tipos primitivos e referências . . . . . . . . . . . . 300
SUMÁRIO vii
11 Coleções 313
11.1 Introdução . . . . . . . . . . . . . . . . . . . . . . 313
11.2 Exercı́cios . . . . . . . . . . . . . . . . . . . . . . . 313
11.3 Notas bibliográficas . . . . . . . . . . . . . . . . . 313
13 Threads 417
13.1 Criação de Thread . . . . . . . . . . . . . . . . . . 417
13.2 Classe Thread . . . . . . . . . . . . . . . . . . . . 421
13.3 Ciclo de vida de Threads . . . . . . . . . . . . . . 424
13.4 Prioridades de Threads . . . . . . . . . . . . . . . 426
13.5 Sincronização de Threads . . . . . . . . . . . . . . 428
13.6 Threads sincronizadas . . . . . . . . . . . . . . . . 435
13.7 Encerramento de Threads . . . . . . . . . . . . . . 438
13.8 Exercı́cios . . . . . . . . . . . . . . . . . . . . . . . 444
13.9 Notas bibliográficas . . . . . . . . . . . . . . . . . 444
15 Applets 453
15.1 Introdução . . . . . . . . . . . . . . . . . . . . . . 453
15.2 Criação de applets . . . . . . . . . . . . . . . . . . 453
15.3 Ciclo de vida de applets . . . . . . . . . . . . . . . 457
15.4 Exemplos de applets . . . . . . . . . . . . . . . . . 458
15.5 Exercı́cios . . . . . . . . . . . . . . . . . . . . . . . 467
15.6 Notas bibliográficas . . . . . . . . . . . . . . . . . 467
xi
Capı́tulo 1
Estruturas Básicas
1.1 Identificadores
1.2 Programas
Os tipos numéricos inteiros são byte, char, short, int e long. Todos
esses tipos possuem as operações de atribuição (=) e de comparação
1.5. TIPOS NUMÉRICOS 5
Tipo int
Tipo long
Tipo byte
int x = 1;
byte b1 = 1, b2 = 2;
byte b3 = b1 + b2 ; // Erro de compilaç~
ao
byte b4 = (byte) (b1 + b2);
byte b5 = (byte) (512 + 3); // b5 recebe 3
byte b6 = x; // Erro de compilaç~
ao
byte b7 = (byte) x;
1.5. TIPOS NUMÉRICOS 7
Tipo short
Tipo char
Tipo float
Tipo double
1.7 Expressões
Operador Operação
-e troca sinal do operando e do tipo numérico
!e nega logicamente o resultado de e do tipo boolean
~e inteiro resultado da inversão dos bits do inteiro e
++v valor de v após incrementar o seu conteúdo
v++ valor de v antes incrementar o seu conteúdo
--v valor de v após decrementar o seu conteúdo
v-- valor de v antes de decrementar o seu conteúdo
new t aloca objeto do tipo t e informa seu endereço
(t)e converte, se possı́vel, e para o tipo t
1.8 Arranjos
1.9 Comandos
Atribuição
Bloco
5 i += j;
6 }
7 j = i*10;
8 }
Todavia, como o escopo de uma declaração em Java inicia-se
somente no ponto em que ocorre, estendendo-se até o fim do bloco,
a função main do programa seguinte é válida:
1 public static void main(String[] args){
2 int i = 10;
3 if (i == 10){ int j = 100; i += 10;}
4 int j;
5 j = i*10;
6 }
Comando if
Comando switch
Comando while
Comando for
Rótulos de Comandos
Comando continue
Comando break
Comando return
Comando throw
Comando try
Comando Synchronized
Classe JOptionPane
Classe Kbd
Classe InText
Classe Screen
Classe OutText
Fim de arquivo
1.12 Exercı́cios
Classes e Objetos
na classe.
1 public class PontoA{
2 private int x, y;
3 public PontoA(int a,int b){this.x=a; this.y=b;}
4 public PontoA( ){this(0,0);}
5 public set(int a,int b){this.x=a; this.y=b;}
6 public int getX( ){return this.x;}
7 public int getY( ){return this.y;}
8 public void clear( ){this.x = 0; this.y = 0;}
9 public String display( ){
10 return "(" + this.x + "," + this.y + ")";
11 }
12 }
A classe PontoA pode então ser usada como molde para cons-
truir objetos, os quais compartilham o mesmo leiaute para os seus
campos, conforme ilustra a Figura 2.1.
2.4 Métodos
11 }
12 }
A operação de chamar uma das funções de uma classe qualificada
por um dado objeto, por exemplo, p.clear(), é interpretada como
enviar a mensagem, no caso clear, ao objeto receptor, nesse exem-
plo p. O objeto receptor é aquele que recebe e trata a mensagem.
Tratar uma mensagem é executar a função membro que corres-
ponde à mensagem recebida. Essa visão é importante, pois pode
haver mais de uma função correspondendo a uma mesma men-
sagem, cabendo ao sistema de execução selecionar aquela que for
aplicável em cada caso. Esse processo, que é denominado ligação
dinâmica, implementa um importante tipo de polimorfismo.
Objetos são alocados no heap pelo operador new e seus campos são
automaticamente zerados, conforme seus respectivos tipos. Cam-
pos numéricos recebem valor 0, booleanos, false, e as referências
a objeto são iniciados com o valor null. Ainda durante a execução
do operador new, as iniciações indicadas nas declarações dos atri-
butos da classe são processadas, e, por último, o corpo de uma das
funções construtoras declaradas na classe, selecionadas conforme
os tipos dos parâmetros, é executada.
Uma função construtora distingue-se dos demais métodos de
uma mesma classe por ter o nome da classe e não possuir espe-
cificação de tipo de retorno. A presença de funções construtoras
em uma classe não é obrigatória. Muitas classes não têm função
construtora explicitamente especificada. Por outro lado, pode-se
especificar mais de uma função construtora em uma mesma classe,
desde que elas sejam distinguı́veis uma das outras pelo número de
parâmetros ou pelos tipos de seus parâmetros.
64 CAPÍTULO 2. CLASSES E OBJETOS
um objeto para que ele libere os recursos mantidos sob seu controle
pode não ser fácil de ser tomada.
Para contornar essa dificuldade, Java possibilita a definição de
uma função membro especial, de nome finalize, que é executada
automaticamente quando a área do objeto da classe que a contém
estiver para ser liberada pelo coletor de lixo. Por exemplo, na
classe ProcessaArquivo abaixo, a função finalize, quando chamada
pelo coletor de lixo, providenciará o fechamento do arquivo que foi
aberto na respectiva função construtora do objeto:
1 public class ProcessaArquivo{
2 private Stream arquivo;
3 public ProcessaArquivo(String nomeDoarquivo){
4 arquivo = new Stream(nomeDoArquivo);
5 }
6 public void fechaArquivo(){
7 if (arquivo != null){
8 arquivo.close(); arquivo.null();
9 }
10 }
11 protected void finalize() throws Throwable{
12 super.finalize(); fechaArquivo();
13 }
14 }
O método finalize é um método protected definido na classe
Object, e que pode ser redefinido pelo programador em sua classe.
Toda classe Java é uma extensão direta ou indireta de Object, cujos
métodos podem ser redefinidos em subclasses ou classes estendidas,
obedecendo certas regras. Em particular, de acordo com sua as-
sinatura em Object, finalize, a menos que sua visibilidade seja
ampliada em uma subclasse, não lhe é permitido ser chamada di-
retamente pelo cliente da classe que o contém. Outros detalhes, por
exemplo, o significado de super, que aparece na linha 12, podem
ser encontrados no Capı́tulo 3.
68 CAPÍTULO 2. CLASSES E OBJETOS
Programa G3 produz
Saı́da: Finalize foi chamada
mostrando que a chamada explı́cita do coletor de lixo garante a
execução da função finalize dos objetos liberados até o ponto
dessa chamada.
1 public class G3{
2 public static void main(String[ ] args){
3 A a = new A(); a = new A ( );
4 System.gc ();
5 //for (int i=1; i <1000000; i++);
6 //System.out.print("Acabou!");
7 }
8 }
9 class A{
10 protected void finalize( ) throws Throwable{
11 super.finalize();
12 System.out.print("Finalize foi chamada. ");
13 }
14 }
via a operação
referência-ao-objeto instanceof nome-de-uma-classe
que retorna true ou false.
Note que todo objeto do tipo Conta1 tem seu próprio saldo
mı́nimo. Em situações nas quais os valores de saldo mı́nimo va-
76 CAPÍTULO 2. CLASSES E OBJETOS
13 class C{
14 public static int t = X.f(’C’), z = X.f(’C’);
15 static{t = 100; System.out.print(" t = " + t);}
16 {t = 1000; System.out.print(" t = " + t);}
17 public C(){t = 10000; System.out.print(" t = " + t);}
18 }
19 class D{
20 public static int u = X.f(’D’), k = X.f(’D’);
21 static{u = 100; System.out.print(" u = " + u);}
22 {u = 1000; System.out.print(" u = " + u);}
23 public D(){u = 10000; System.out.print(" u = " + u);}
24 }
P3 r = 1000 r = 10000
P4
P5 B B s = 100
P6
P7 s = 1000 s = 10000
P8 C C t = 100 t = 1000 t = 10000
Acabou
2.13 Exercı́cios
Hierarquia
3.1 Interfaces
da interface.
Mais de uma classe pode implementar uma mesma interface, e
objetos dessas classes têm o tipo definido pela interface.
Para ilustrar as vantagens do uso de interfaces no lugar de classes
concretas, considere as declarações a seguir.
1 public class Bolo{
2 private double calorias, gorduras;
3 public Bolo(double c, double g){
4 calorias = c; gorduras = g;
5 }
6 public String identidade( ){return "Bolo" ;}
7 public double calorias( ){return this.calorias;}
8 private double gorduras( ){return this.gorduras;}
9 }
10 public class Torta{
11 private double calorias, gorduras;
12 public Bolo(double c, double g){
13 calorias = c; gorduras = g;
14 }
15 public String identidade( ){return this.calorias;}
16 private double gorduras( ){return this.gorduras;}
17 }
Compartilhamento de implementação
1 class Usuário3{
2 private String f(Sobremesa x){x.calorias();}
3 private double g(Comestivel y){
4 return y.gorduras( );
5 }
6 public void testeUsuário (){
7 Fruta a = new Fruta(50.0,3.0);
8 Bolo b = new Bolo(150.0,19.0);
9 double z = g(a) + g(b);
10 System.out.println(a.identidade() + " : " + f(a));
11 System.out.println(b.identidade() + " : " + f(b));
12 System.out.println("Total de gorduras " + z);
13 }
14 }
Uma classe pode implementar zero ou mais interfaces, mas deve
estender sempre uma outra classe. Se nenhuma extensão for espe-
cificada, a classe, por default, estende Object. Assim, os métodos
definidos nas interfaces podem ser implementados diretamente na
classe ou então herdados de outra classe.
O formato geral da declaração de uma classe é:
[public] class NomeDaClasse [extends Superclasse]
[implements Interface1, Interface2, ...]{
declaraç~
oes de métodos e atributos
• Coordenadas Polares:
– Soma: ρ1 eiθ1 + ρ2 eiθ2 = (ρ1 ∗ cos θ1 + ρ2 ∗ cos θ2)
+i(ρ1 ∗ sin θ1 + ρ2 ∗ sin θ2)
– Subtração: ρ1 eiθ1 + ρ2 eiθ2 = (ρ1 ∗ cos θ1 − ρ2 ∗ cos θ2)
+i(ρ1 ∗ sin θ1 − ρ2 ∗ sin θ2)
– Multiplicação: ρ1 eiθ1 · ρ2 eiθ2 = ρ1 ρ2 ei(θ1+θ2)
ρ1 eiθ1 ρ1
– Divisão: ρ2 eiθ2
= ρ2 ei(θ1−θ2).
1 public interface C{
2 public static int x = 100;
3 public static void g( ){ x = 10;} // Errado
4 }
Figura 3.9
112 CAPÍTULO 3. HIERARQUIA
Reúso de implementação
Comecei na C
Passei na A( )
Passei na B(a,b)
Passei na B( )
Voltei na C
Passei na A( )
Passei na B(a,b)
Terminei na C
122 CAPÍTULO 3. HIERARQUIA
7 class B extends A{
8 private C y = new C( );
9 public B( ){super(y);}
10 }
Note que a tentativa abaixo de enganar o compilador também
não funciona.
1 class B extends A{
2 private C y;
3 public B( ){super(y = new C( ));}
4 }
Nesse exemplo, compilador Java sabiamente protesta com a
mensagem:
Teste.java:3:cannot reference y before supertype
constructor has been called.
3.8. ATRIBUIÇÃO DE REFERÊNCIAS 125
8 class D{
9 A f(C1 x1, C2 x2, ..., Cn xn){ ... }
10 A g(C1 y1, C2 y2, ..., Ck yk){ ... }
11 }
12 class E extends D{
13 A f(C1 z1, C2 z2, ..., Cn zn){ ... }
14 B g(C1 t1, C2 t2, ..., Ck tk){ ... }
15 }
O programa RedefineFunç~oes abaixo mostra a flexibilidade e as
restrições oferecidas pelo mecanismo de redefinição.
Note que embora a redefinição de g na classe E retorne um objeto
do tipo B, o valor retornado por x.g() é sempre suposto ser do tipo
A, pois o tipo estático de x é D, e o compilador não pode garantir
que o tipo dinâmico de x seja E. Adota-se sempre a solução mais
conservadora, que é usar o tipo estático de uma referência para
130 CAPÍTULO 3. HIERARQUIA
1 class C extends B{
2 private int c;
3 public void h (int z){...} // void Hc(C this,int z)
4 }
O descritor de C, mostrado na Figura 3.24, herda a vmt do
descritor de B e a ela acrescenta uma nova entrada, de ı́ndice 3
(terceira entrada), para o novo método, h, declarado em C. Essa
nova entrada é devidamente iniciada como o endereço de primeira
instrução de Hc, que representa código bytecode de h.
Métodos declarados finais têm uma restrição ainda maior: eles não
podem ser redefinidos nem redeclarados nas classes estendidas. As
tentativas que vão de encontro a essa regra serão apontadas como
erro pelo compilador, como no programa a seguir, onde a definição
de f na classe B é rejeitada.
1 public class A{
2 private int x;
3 final public void f(int x){this.x = x;}
4 }
5 public class B extends A{
6 private int x;
7 public void f(int x){this.x = x*x;} // <== Erro
8 }
Note que um método declarado final força que ele seja o último
de uma cadeia de suas redefinições dentro da hierarquia. Um
método final é normalmente inserido na vmt de sua classe, mas
o valor de sua entrada nessa tabela não pode ser alterado quando
subclasses forem criadas.
1 class A{
2 public String s = "A";
3 public void h( ){ System.out.print(" A: " + s);}
4 }
5 class B extends A{
6 public String s = "B";
7 public void h( ){ System.out.print(" B: " + s);}
8 }
3.20 Conclusão
3.21 Exercı́cios
Polimorfismo
(
universal
referencial
ad-hoc
(
paramétrico
polimorfismo universal
inclusão
funcional
(
sobrecarga
ad-hoc
coerção
diferentes tipos.
Ressalte-se que o polimorfismo de funções pode manifestar-se
simultaneamente nas duas dimensões, i.e., funções podem ser ao
mesmo tempo polissêmicas e polivalentes.
O último tipo de polimorfismo da classificação original de Car-
delli & Wagner, e preservada na Figura 4.2, o funcional ad-hoc de
coerção, é o que decorre da possibilidade de conversão automática
de tipo, comum em muitas linguagens de programação para sim-
plificar a escrita de programas.
O exemplo mais comum são funções definidas com parâmetros
formais de tipo numérico, e.g., float sin(float x), e que aceitam
automaticamente parâmetros de chamada outros tipos de numé-
ricos, como int. Nesses casos, os parâmetros de chamadas são
automaticamente convertidos para o tipo esperado. A esse tipo de
conversão automática de valores dá-se o nome de coerção.
11 public UsoDeSobreCarga1{
12 public static void main(String[ ] args){
13 T t = new T( ); U u = new U( ); W c; R m;
14 A a = new A( ); A b = new B( );
15 a.f(t); // funç~
ao f da linha 2
16 c = a.f(t,u); // funç~
ao f da linha 3
17 m = a.f( ); // funç~
ao f da linha 4
18 b.f(t); // funç~
ao f da linha 7
19 c = b.f(t,u); // funç~
ao f da linha 8
20 m = b.f( ); // funç~
ao f da linha 9
21 }
22 }
Em Java, o tipo de retorno de métodos não é usado para di-
ferenciar operações polissêmicas, mas o tipo do objeto receptor é
devidamente utilizado nesse processo, como ilustram as chamadas
de f das linhas 17 e 18.
Na presença de hierarquia de classes, o mecanismo de resolução
estática de sobrecarga de funções torna-se mais elaborado. A iden-
tificação da implementação do método polissêmico a ser executada
ainda é determinada a partir dos tipos dos parâmetros de chamada,
mas pode haver mais de um candidato que satisfaça o critério de
identificação.
Nesses casos, a relação hierárquica entre o tipo de cada parâmetro
formal e o tipo do argumento correspondente deve ser também
usada para desambiguar, dando-se preferência à função cujo tipo
de parâmetro formal em análise seja mais próximo hieraquicamente
do tipo do parâmetro de chamada correspondente. Para ilustrar
essas novas regras, considere a seguinte hierarquia de classes.
1 public class A{int x; ... }
2 public class B extends A{int y; ... }
3 public class C extends B{int z; ... }
O programa Teste1, apresentado a seguir, imprime o texto "f(A)",
pois, embora o tipo dinâmico de x seja C, o seu tipo estático é A,
4.3. RESOLUÇÃO DE SOBRECARGA ESTÁTICA 165
1 class SobreCarga2{
2 public static void main(String[ ] args){
3 T t = new T(); U u = new U();
4 A a = new A(); A b = new B(); A c = new C();
5 a.f(t); // funç~
ao f da linha 2
6 a.g(u); // funç~
ao g da linha 2
7 b.f(t); // funç~
ao f da linha 6
8 b.g(u); // funç~
ao g da linha 2
9 c.f(t); // funç~
ao f da linha 9
10 c.g(u); // funç~
ao g da linha 10
11 }
12 }
Observe que a identificação da versão do método a ser invocado
é feito em três etapas:
1. Inicialmente, a referência ao objeto receptor de cada invocação
de um método é considerada como um parâmetro adicional
cujo tipo é o tipo estático da referência ao objeto receptor.
2. A seguir, o compilador usa os tipos estáticos dos argumentos
especificados, incluindo o da referência ao objeto receptor, para
determinar o conjunto dos métodos candidatos.
3. Depois o compilador gera um código para, durante a execução,
seja feita a escolha do método, dentre os candidatos, a ser
ativado, com base no tipo dinâmico do objeto receptor.
Enfatiza-se que tipos estáticos são determináveis pelo compila-
dor, mas a resolução da sobrecarga de métodos pelo tipo dinâmico
somente pode ser feita durante a execução.
Uso de interfaces
linguagem.
Sem herança múltipla, certas funções podem ter que ser dupli-
cadas para cobrir toda a funcionalidade associada aos seus nomes.
Entretanto, essa perda de poder de expressão pode ser compensada
pelo uso de interfaces.
Para ilustrar como essa perda de poder de expressão ocorre e
como ela é solucionada, suponha que herança múltipla de classe
seja permitida em Java, e considere a modelagem apresentada nas
declarações abaixo e resumida na hierarquia mostrada na Figura
4.3, na qual os diagramas apresentam no seu lado esquerdo os
atributos privados da classe representada, e do lado direito, as
suas operações públicas.
As classes que aparecem no diagrama da Figura 4.3 são definas a
172 CAPÍTULO 4. POLIMORFISMO
4.7 Exercı́cios
Tratamento de Falhas
6 class A {
7 void g( ) throws E{int k; ... ; throw new E(k); ....}
8 ...
9 }
O programa B abaixo inicia-se com a execução dos comandos a
partir da linha 3, e, ao atingir a linha 5, inicia a execução do bloco
associado ao try. A chamada a.g() leva à execução da linha 7 da
190 CAPÍTULO 5. TRATAMENTO DE FALHAS
1 class MeuVetor{
2 private int [ ] p;
3 private int tamanho;
4 public void MeuVetor(int n){
5 p = new int[n]; tamanho = n;
6 }
7 public int elemento(int i) throws Indice{
8 if ( 0 <= i && i < tamanho )
9 return p[i] ;
10 throw new Indice(i);
11 }
12 public void atribui(int i, int v) throws Indice{
13 if ( 0 <= i && i < tamanho )
14 p[i] = v ;
15 throw new Indice(i);
16 }
17 }
1 public class C{
2 void f( ){
3 MeuVetor x = new MeuVetor(5);
4 int k;
5 try{
6 System.out.print("Ponto A");
7 k = g(x);
8 System.out.print("Ponto B");
9 }
10 catch(Indice x){
11 System.out.print("Indice Errado = " + x.i);
12 k = 0;
13 }
14 System.out.println("Valor de k = " + k);
15 }
16 int g(MeuVetor v) throws Indice{
17 return v.elemento(10);
18 }
19 public static void main(String[] args){
20 C c = new C( );
21 c.f();
22 System.out.println("Chegou aqui");
23 }
24 }
8 class Final{
9 public void f( ){
10 int x = 10;
11 System.out.print("x = " + x);
12 try{ x = 11;
13 System.out.print("x = " + x);
14 throw new Exception();
15 }
16 catch(Exception e){
17 x = 12;
18 System.out.print("x = " + x);
19 }
20 finally{
21 x = 13;
22 System.out.print("x = " + x);
23 }
24 }
25 }
A ativação de main de Finally1 causa o seguinte fluxo de execu-
ção, linha a linha:
• Executa-se linha 4 de main, chamando a função f.
• Executam-se linhas 10, 11 (imprime x = 10), 12, 13 (imprime
x = 11), 14 (exceção lançada).
8 class Final{
9 int x = 10;
10 public int f( ){
11 try{return x;}
12 catch(Exception e){x = 100; return x;}
13 finally{x = 1000;}
14 }
15 }
O mesmo ocorre quando o return está dentro de catch. O pro-
grama Finally abaixo imprime x = 107, a.y = 1100.
1 public class Finally6{
2 static public void main(String[ ] args){
3 Final a = new Final( ); int x = a.f();
4 System.out.println("x = " + x + ", a.y = " + a.y);
5 }
6 }
7
8 class Final{
9 public int x = 0, y = 0;
10 public int f( ){
11 try{x = 1; throw new Exception( );}
12 catch(Exception e) {x = 100; return x+7;}
13 finally{ x = x + 1000; y = x;}
14 }
15 }
Por outro lado, comando return que ocorre na cláusula finally
prevale sobre o do corpo do try ou de catch, sendo obedecido ime-
diatamente. Por exemplo, no programa abaixo, o valor impresso é
x = 1000 e não x = 10.
1 public class Finally7{
2 static public void main(String[ ] args){
3 Final a = new Final(); int x = a.f();
4 System.out.print("x = " + x);
5 }
6 }
5.4. OBJETO DE EXCEÇÃO 199
7 class Final{
8 public int f( ){
9 int x = 10;
10 try{return x; }
11 catch(Exception e){x = 100;}
12 finally {x = 1000; return x;}
13 }
14 }
não é livre. A ordem, de cima para baixo, deve ser de uma classe
mais especı́fica para a mais geral da hierarquia. Isso porque a busca
pelo catch é feita de cima para baixo, sendo concluı́da quando for
encontrado o primeiro que satisfizer o teste é-um relativo ao tipo
do seu parâmetro.
A correção da ordem é automaticamente verificada pelo compi-
lador, que, por exemplo, não aceita a ordenação de catches usada
no método errado do programa abaixo, porque o primeiro catch iria
capturar todas as exceções de sua hierarquia, e, consequentemente,
as cláusulas que o seguem seriam inúteis.
1 class A extends Exception{ }
2 class B extends A{ }
3 class OrdemErrada{
4 public void errado( ){
5 try {... throw new B( ); ...}
6 catch (Exception e ){ ... }
7 catch (A s){ ... }
8 catch (B s){ ... }
9 }
10 }
5.7 Exercı́cios
Biblioteca Básica
207
208 CAPÍTULO 6. BIBLIOTECA BÁSICA
é equivalente a
String s = "Onde pode acolher-se um fraco " + x.toString( );
6.3. CLASSE STRING 213
Construtoras de String
• public String( ):
contrói novo objeto String vazio.
String s = new String( );
• public String(String t):
constrói um novo objeto String contendo uma cópia da sequên-
cia de caracteres t.
String s = new String("abcde");
• public String(char v[ ]):
constrói um novo objeto String a partir de um vetor de char.
char[ ] c = {‘A’, ‘B’, ‘C’, ‘D’};
String s = new String(c);
• public String(StringBuffer b):
constrói um objeto String a partir de um objeto do tipo StringBuffer
passado como parâmetro.
Inspeção de caracteres
Localização de caracteres
Localização de subsequências
String s1 = "abc-dfg-hjk-dfg-gmn-opq-dfg-mhj-klm";
String s2 = new String("dfg");
int k = s1.lastIndexOf(s2); // k recebe 24
• public int lastIndexOf(String s, int p):
retorna posição ≤ p da última ocorrência de s em this. O
valor de k no fim do código abaixo é 12:
String s1 = "abc-dfg-hjk-dfg-gmn-opq-dfg-mhj-klm";
String s2 = new String("dfg");
int k = s1.indexOf(s2, 15); // k recebe 12
Particionamento de sequências
Construtoras de StringBuffer
Inclusão de caracteres
pelos métodos:
Controle de capacidade
Remoção de caracteres
Recuperação de subsequências
Substituição de caracteres
Uso de StringBuffer
Construtoras de StringTokenizer
Operações de Tokenizer
Classe Boolean
Classe Character
Classe Number
Classe Integer
Classe Long
Classe Float
Classe Double
6.7 Exercı́cios
Classes Aninhadas
seus campos.
O exemplo a seguir é uma cópia ligeiramente modificada da
classe Conta anteriormente apresentada. As modificações são a
declaração da classe Permiss~oes como aninhada não-estática, em
vez de estática, e pelas mudanças decorrentes, especialmente na
forma de criação de objetos de classe interna:
1 public class Conta{
2 private long número; private long saldo;
3 public class Permiss~oes{
4 public boolean podeDepositar,
5 podeSacar, podeEncerrar;
6 void verifiquePermiss~ ao(Conta c){
7 ... c.número ... // OK
8 ... this.número ... // OK
9 }
10 }
11 public Permiss~oes obtémPermiss~
ao( ){
12 return new Permiss~oes( );
13 }
14 }
15
16 class Banco{
17 Conta c = new Conta( );
18 Conta.Permiss~
oes p1 = c.new Permiss~
oes( );
19 void f(){
20 Conta.Permiss~oes p2;
21 p2 = c.obtémPermiss~
ao( );
22 if (p1.podeDepositar && p2.podeSacar) ...
23 }
24 }
Destaca-se que nessa nova versão de Conta, a referência ao atri-
buto número da classe envolvente, ocorrida na linha 8 de Conta está
correta, e que, na linha 18, o operador new apresenta-se com uma
sintaxe e uma semântica especiais, na qual o objeto envolvente é
especificado.
250 CAPÍTULO 7. CLASSES ANINHADAS
1 class X{
2 int a, d;
3 class Y{
4 int b, d;
5 class Z{
6 int c, d;
7 ... a ... // X.this.a = a de X
8 ... b ... // Y.this.b = b de Y
9 ... c ... // Z.this.c = c de Z
10 ... X.this.d ... // d de X
11 ... Y.this.d ... // d de Y
12 ... d ... // Z.this.d = d de Z
13 }
14 }
15 }
1 public class X{
2 int a, d;
3 public class Y{
4 int b, d;
5 public class Z{
6 int c, d;
7 void g( ){
8 ... a ... b ... c ...
9 X.this.d ... Y.this.d ... this.d ...
10 }
11 }
12 }
13 public static void main(String[ ] args){
14 A x = new X ( );
15 X.Y y = x.new Y( );
16 X.Y.Z z = y.new Z( );
17 }
18 }
7.3. EXEMPLO DE CLASSES ANINHADAS 253
29 public class Z{
30 int c;
31 public Z(int c){ this.c = c; }
32 void mostraRefer^
encias(String s){
33 o.println(" imprime a = " + a);
34 o.println(" imprime X.this.a = " + X.this.a);
35 o.println(" imprime b = " + b );
36 o.println(" imprime c = " + c );
37 }
38 }
39 }
40 }
imprime 0 1 2 3 4 5 6 7 8 9:
Se uma classe for declarada para ser usada uma única vez no
próprio local onde foi declarada, seu nome pode ser omitido, de-
clarando-se a classe diretamente como operando do operador new.
Por exemplo, considere a classe CorpoDiscente do exemplo anterior,
repetida a seguir, que contém a classe Enumeraç~aoLocal, declarada
dentro do método elementos:
1 class CorpoDiscente{
2 private final Object[ ] objetos;
3 public CorpoDiscente(Object[] objetos){
4 this.objetos = objetos;
5 }
6 public Enumeraç~
ao elementos( ){
7 final int tamanho = objetos.length;
8 class Enumeraç~
aoLocal implements Enumeraç~
ao{
9 private int posiç~ao = 0;
10 public boolean aindaHá( ){
11 return (posiç~
ao < tamanho);
12 }
13 public Object próximo()throws FaltaElemento{
14 if (posiç~
ao >= tamanho)
15 throw new FaltaElemento();
16 return objetos[posiç~ao++];
17 }
18 public void reInicia( ){ posiç~ao = 0; }
19 }
20 return new Enumeraç~
aoLocal( );
21 }
22 }
A classe local Enumeraç~aoLocal tem garantidamente um único
uso, que é o da linha 20. Seu nome adiciona muito pouco à clareza
do programa e pode ser eliminado do código, substituindo a cons-
trutora do new por uma declaração anônima, como mostra a nova
versão de CorpoDiscente:
260 CAPÍTULO 7. CLASSES ANINHADAS
1 public Enumeraç~
ao elementos( ){
2 final int tamanho = objetos.length;
3 return new Enumeraç~
ao{
4 private int posiç~ao = 0;
5 public boolean aindaHá( ){
6 return (posiç~
ao < tamanho);
7 }
8 public Object próximo( ) throws FaltaElemento{
9 if (posiç~
ao >= tamanho)
10 throw new FaltaElemento();
11 return objetos[posiç~ao++];
12 }
13 public void reInicia( ){ posiç~ao = 0; }
14 }
15 }
16 }
1 class A{
2 class B{ }
3 }
4 class D extends A.B{
5 D(A a){ a.super() }
6 }
7 public class Main{
8 public static void main(String[ ] args){
9 A a = new A();
10 A.B b = a.new B();
11 C c = new C();
12 D d = new D(a);
13 }
14 }
7.7 Exercı́cios
Pacotes
263
264 CAPÍTULO 8. PACOTES
8.3 Visibilidade
1 package BibliotecaA;
2 public class F{
3 public static void main(String[] args){
4 int x;
5 A a = new A( ); // OK
6 B b = new B( ); // OK
7 x = 1 + a.pub + b.pub; // OK
8 x = x + a.pro + b.pro; // OK
9 x = x + a.pac + b.pac; // OK
10 System.out.println("X = " + x);
11 }
12 }
• A partir de X:
X>javac -classpath Y Y\P\C.java
Nesse caso, a partir de X, pode-se encontrar A.class e B.class
no subdiretório Y, informado pelo -classpath, e o arquivo C.java
encontra-se no subdiretório P que está dentro de Y, conforme
especificado na linha de comando. A localização do arquivo-
fonte a ser compilado não depende do -classpath.
O comando para executar o main da classe P.C a partir da pasta
X é:
X>java -classpath Y P.C
onde -classpath Y indica onde, a partir de X, os arquivos A.class,
B.class e C.class estão armazenados. Note que a localização da
classe principal, P.C, é dada pela diretiva -classpath. Assim, no
comando java somente seu nome completo, P.C, precisa ser forne-
cido.
Para ilustrar a compilação de mais de um pacote, considere a hie-
rarquia de diretórios mostrada na Figura 8.2, contendo os arquivos-
fonte:
• Arquivos A.java:
package P;
public class A{ ... }
274 CAPÍTULO 8. PACOTES
• Arquivos B.java:
package P;
public class B{ ... }
• Arquivos C.java:
package Q;
public class C{ ... A ... B ... }
Os comandos para disparar a compilação, dependendo de sua
localização no sistema de arquivos, são:
P>javac A.java
P>javac B.java
Q>javac -classpath .. C.java
X>javac -classpath Y Y\Q\C.java
Observe que a partir de X, na quarta linha acima, Y dá a localização
de P.A e P.B e que o caminho desde X a P.C deve ser explı́cito.
O nome de um pacote pode ser repetido, da mesma forma que
um subdiretório pode ter o mesmo nome de um outro que não seja
seu irmão na hierarquia, conforme exemplificado na Figura 8.3,
onde há duas pastas de nome P, que definem uma única biblioteca
de nome P, contendo as classes A, B e M.
Suponha que os arquivos-fonte que aparecem na Figura 8.3 se-
jam:
• Arquivo A.java:
package P;
class A{ int x; ... }
8.5. EXERCÍCIOS 275
8.5 Exercı́cios
Entrada e Saı́da
277
278 CAPÍTULO 9. ENTRADA E SAÍDA
Classe InputStream
Classe OutputStream
Classe FilterOutputStream
Class PrintStream
Classe System
A classe System dá acesso aos arquivos de fluxo in, out e err, au-
tomaticamente criados para leitura de teclado, escrita na tela do
monitor e no arquivo de erro, respectivamente. Esses campos da
classe System são definidos da forma:
• public static InputStream in
• public static PrintStream out
• public static PrintStream err
O uso direto arquivo in é limitado por ser de fluxo de bytes,
tornando muito trabalhosa, por exemplo, a leitura de um inteiro
digitado na entrada padrão. Cada byte do inteiro teria que ser
lido, e seu valor devidamente construı́do. Em geral, o arquivo in é
280 CAPÍTULO 9. ENTRADA E SAÍDA
Interface DataInput
• boolean readBoolean( ):
lê de um byte e retorna true se for diferente de zero, false,
caso contrário.
• byte readByte( ):
lê e retorna um byte.
• char readChar( ):
lê dois bytes e retorna um valor do tipo char
• double readDouble( ):
lê oito bytes e retorna um valor do tipo double.
• float readFloat( ):
lê quatro bytes e retorna um valor do tipo float.
• int readInt( ):
lê quatro bytes e retorna um valor do tipo int.
• String readLine( ):
lê a próxima linha de texto do fluxo de entrada.
• long readLong( ):
lê oito bytes e retorna um valor do tipo long.
• short readShort( ):
lê dois bytes e retorna um valor do tipo short.
9.1. FLUXOS DE BYTES E CARACTERES 281
Classe FileInputStream
Classe DataInputStream
• byte readByte( ) :
conforme DataInput.
• char readChar( ) :
conforme DataInput.
• double readDouble( ):
conforme DataInput.
• float readFloat( ):
conforme DataInput.
• int readInt( ) :
conforme DataInput.
• String readLine( ):
conforme DataInput.
• void close( ):
fecha o arquivo de fluxo e libera os recursos associados ao fluxo.
O protocolo de uso de DataInputStream é ilustrado pelo trecho
de código:
1 FileInputStream f = new FileInputStream("arq.dat");
2 DataInputStream g = new DataInputStream(f);
3 int k = g.readInt( );
4 double s = g.readDouble( );
que destaca a necessidade de inicialmente se criar, na linha 1, o
objeto de acesso ao arquivo, no caso o de nome "arquivo.dat", e
utilizá-lo na construtora de g.
Para mostrar o funcionamento da classe DataInputStream e do
método String.split, muito usados para manipular dados lidos
de arquivo de fluxo, suponha que seja dado o arquivo de fluxo
meusdados.txt contendo a sequência de caracteres:
"ab1c cd2ef,ghi jk3mnop,qrs4tuvz !@#$5%^&*() ZZZ\naaaaa"
onde \n é o caractere de mudança de linha.
O programa Io a seguir faz a leitura de uma linha do arquivo
de fluxo meusdados.txt, a particiona nas maiores subsequências que
9.1. FLUXOS DE BYTES E CARACTERES 283
Classe Reader
Classe InputStreamReader
protocolo:
BufferedReader in
= new BufferedReader(new InputStreamReader(System.in));
Classe BufferedReader
Objetos BufferedReader lê um texto a partir de um fluxo de
caracteres e o armazena em um buffer interno, do qual porções são
retiradas à medida que comandos de leitura de caracteres, arranjos
ou de linhas são emitidos. Os comandos de leitura causam pedidos
de leitura correspondentes ao fluxo de dados subjacente.
Normalmente BufferedReader opera sobre fluxos mais básicos
da famı́lia Reader, e.g., InputStreamReader. As principais operações
são:
• BufferedReader(Reader in):
abre para leitura o fluxo de caracteres definido pelo parâmetro
e usa um buffer de um tamanho default.
• void close( ):
fecha o arquivo de fluxo representado pelo objeto corrente.
• int read( ):
lê um caractere.
• int read(char[ ] c, int p, int t):
lê uma sequência de t caracteres e a armazena a partir da
posição p do arranjo c.
• String readLine( ):
lê uma sequência de caracteres até encontrar o fim de linha.
O programa abaixo obtém informações do operador, via o ar-
quivo padrão de entrada System.in. O programa TestaConsole es-
9.2. IMPLEMENTAÇÃO DE MYIO 285
Classe Kbd.java
1 package myio;
2 import java.io.*; import java.util.*;
3 public class Kbd{
4 private static DataInputStream infile =
5 new DataInputStream(System.in);
6 private static StringTokenizer st;
7 final static public boolean readBoolean( )
8 throws IOException{
9 if (st == null || !st.hasMoreTokens( ))
10 st = new StringTokenizer(infile.readLine( ));
11 return new Boolean(st.nextToken( )).booleanValue( );
12 }
13 final static public int readInt( )throws IOException{
14 if (st == null || !st.hasMoreTokens( ))
15 st = new StringTokenizer(infile.readLine( ));
16 return Integer.parseInt(st.nextToken( ));
17 }
18 final static public long readLong( )throws IOException{
19 if (st == null || !st.hasMoreTokens( ))
20 st = new StringTokenizer(infile.readLine( ));
21 return Long.parseLong(st.nextToken( ));
22 }
23 final static public float readFloat()throws IOException{
24 if (st == null || !st.hasMoreTokens( ))
25 st = new StringTokenizer(infile.readLine( ));
26 return new Float(st.nextToken( )).floatValue( );
27 }
28 final static public double readDouble( )
29 throws IOException{
30 if (st == null || !st.hasMoreTokens( ))
31 st = new StringTokenizer(infile.readLine( ));
32 return new Double(st.nextToken( )).doubleValue( );
33 }
9.2. IMPLEMENTAÇÃO DE MYIO 287
Classe Screen.java
1 package myio;
2 public class Screen{
3 final static public void println( ){
4 System.out.println( );
5 }
6 final static public void print(String s){
7 System.out.print(s);
8 }
9 final static public void println(String s){
10 System.out.println(s);
11 }
12 final static public void print(char c){
13 System.out.print(c);
14 }
15 final static public void print(int i){
16 System.out.print(i);
17 }
18 final static public void print(boolean b){
19 System.out.print(b);
20 }
21 final static public void println(boolean b){
22 System.out.println(b);
23 }
24 final static public void print(byte b){
25 System.out.print(b);
26 }
27 final static public void println(byte b){
28 System.out.println(b);
288 CAPÍTULO 9. ENTRADA E SAÍDA
29 }
30 final static public void print(char c){
31 System.out.print(c);
32 }
33 final static public void println(char c){
34 System.out.println(c);
35 }
36 final static public void print(int i){
37 System.out.print(i);
38 }
39 final static public void println(int i){
40 System.out.println(i);
41 }
42 final static public void print(long n){
43 System.out.print(n);
44 }
45 final static public void println(long n){
46 System.out.println(n);
47 }
48 final static public void print(float f){
49 System.out.print(f);
50 }
51 final static public void println(float f){
52 System.out.println(f);
53 }
54 final static public void print(double d){
55 System.out.print(d);
56 }
57 final static public void println(double d){
58 System.out.println(d);
59 }
60 }
Classe InText.java
1 package myio;
2 import java.io.*; import java.util.*;
3 public class InText{
9.2. IMPLEMENTAÇÃO DE MYIO 289
Classe OutText.java
1 package myio;
2 import java.io.*;
3 public class OutText{
4 private PrintStream o;
5 public OutText(String fileName) throws IOException{
6 OutputStream fout = new FileOutputStream(fileName);
7 o = new PrintStream(fout);
8 }
9 final public void println( ){
10 o.println( );
11 }
12 final public void print(String s){
13 o.print(s);
14 }
15 final public void println(String s){
16 o.println(s);
17 }
18 final public void print(byte i){
19 o.print(String.valueOf(i));
20 }
21 final public void println(byte i){
22 o.println(String.valueOf(i));
23 }
24 final public void print(int i){
25 o.print(String.valueOf(i));
26 }
27 final public void println(int i){
28 o.println(String.valueOf(i));
29 }
30 final public void print(boolean b){
9.3. EXERCÍCIOS 291
31 o.print(String.valueOf(b));
32 }
33 final public void println(boolean b){
34 o.println(b + "");
35 }
36 final public void print(short i){
37 o.print(String.valueOf(i));
38 }
39 final public void println(short i){
40 o.println(String.valueOf(i));
41 }
42 final public void print(long n){
43 o.print(String.valueOf(n));
44 }
45 final public void println(long n){
46 o.println(String.valueOf(n));
47 }
48 final public void print(float f){
49 o.print(String.valueOf(f));
50 }
51 final public void println(float f){
52 o.println(String.valueOf(f));
53 }
54 final public void print(double d){
55 o.print(String.valueOf(d));
56 }
57 final public void println(double d){
58 o.println(String.valueOf(d));
59 }
60 }
9.3 Exercı́cios
Genericidade
11 }
A expressão A<Integer> designa um novo tipo, resultado da in-
vocação da classe A com o parâmetro Integer, tal que as ocorrências
do tipo T no corpo de A são interpretadas como Integer. Especi-
ficamente, o método s da classe A<T>, para o caso de A<Integer>,
espera um argumento do tipo Integer, e o método irmão g retorna
um objeto do tipo Integer.
O programa a seguir ilustra a criação de dois novos tipos a partir
classe genérica A, a qual é invocada duas vezes, linhas 3 e 7, para
construir os tipos A<Integer> e A<Double>, respectivamente.
1 public class Genérico2{
2 public static void main(String[ ] args){
3 A<Integer> m = new A<Integer>( );
4 int k, i = 10;
5 m.s(i); k = m.g( );
6 System.out.print("Valor de i = " + k + ", ");
7 A<Double> q = new A<Double>( ) ;
8 double w, t = 100.0;
9 q.s(t); w = q.g( );
10 System.out.print("Valor de t = " + w);
11 }
12 }
T x = new T( );
onde T é um tipo parâmetro, é rejeitada pelo compilador. Para se
obter o efeito desejado de criar um objeto do tipo designado por
T, deve-se escrever:
T x = (T) new Object( );
que aloca corretamente o objeto desejado.
Essa diferença na sintaxe da operação de criação de objetos su-
gere que o código gerado em cada caso seja especı́fico e particular.
A declaração abaixo mostra a definição da classe genérica A<T>,
onde T especifica seu tipo parâmetro:
1 class A<T>{
2 private T x ;
3 public A( ){x = (T) new Object( );}
4 public void s(T y){x = y;}
5 public T g( ){return x;}
6 }
O parâmetro formal ou variável de tipo T é usado na classe A
para declarar o atributo x, o parâmetro y do método s e o tipo do
valor de retorno de g.
10 q.s(t);
11 w = q.g( );
12 System.out.print("Valor de t = " + w);
13 }
14 }
Quando uma classe genérica é estendida ou especializada, seus
parâmetros devem ser supridos adequadamente. Caso a subclasse
desejada seja genérica, suas variáveis de tipo podem ser usadas
para instanciar a superclasse genérica, com mostram os seguintes
exemplos de especialização:
1 class C<H> extends A<H>{ }
2 class D<T,R> extends A<T>{
3 private R z;
4 public D(R v){super( ); z = v;}
5 public R g( ){return z;}
6 }
7 class E extends A<Integer>{ }
Note que os parâmetros da classe genérica derivada, e.g., H de
C, T e R de D, são usados para definir a instância das classes base
especificadas.
O programa Genérico6, que ilustra o uso das classes genéricas A
e D, imprime i = 10, b = 100, c = 1000.0.
1 public class Genérico6{
2 public static void main(String[ ] args){
3 A<Integer> m = new A<Integer>( );
4 int k,i = 10;
5 m.s(i); k = m.g( );
6 System.out.print("i = " + k + ", ");
7 double c = 1000.0;
8 D<Integer,Double> q = new D<Integer,Double>(c);
9 int a, b = 100;
10 double t;
11 q.s(b); a = q.g( );
12 System.out.print("b = " + a + ", ");
304 CAPÍTULO 10. GENERICIDADE
13 t = q.h( );
14 System.out.print("c = " + t);
15 }
16 }
Por garantir a compilação de programas de versões de Java mais
antigas pelos novos compiladores de Java, permite-se estender clas-
ses genéricas sem especificação de seus argumentos, como em:
class B extends A
que tem a interpretação de
class B extends A<Object>
Essa convenção permite que programas escritos em versões de Java
anteriores a 5.0 e que usam, por exemplo, a classe LinkedList, con-
tinuem a funcionar em ambientes Java de versão 5.0 ou maior,
nos quais as classes da famı́lia Collection, como LinkedList, foram
substituı́das por versões parametrizadas do tipo LinkedList<T>.
Por outro lado, a declaração
class F extends A<T>
está sintaticamente errada pela indefinição do tipo T, usado para
instanciar A.
7 public class R{
8 public int f( ){return 1; }
9 }
10
11 class R2 implements R{
12 public int f( ){return 1000; }
13 }
O programa Genérico8, onde M pode ser qualquer uma das im-
plementações acima, imprime k = 100, j = 1000:
1 public class Genérico8{
2 public static void main(String[ ] args){
3 M<R1> m = new M<R1>( );
4 M<R2> r = new M<R2>( );
5 R1 a = new R1( );
6 R2 b = new R2( );
7 int j, k;
8 m.s(a);
9 r.s(b);
10 k = m.g( );
11 j = r.g( );
12 System.out.print("k = "+ k + ", j = "+ j);
13 }
14 }
Tentativas de se instanciar a classe M definida acima com tipos
fora da famı́lia de R serão apontadas como erro de compilação,
como ocorre no programa abaixo:
1 public class Genérico9{
2 public static void main(String[ ] args){
3 M<Integer> m = new M<Integer>( ); // ERRO
4 int j,k = 1;
5 m.s(k);
6 j = r.g( );
7 System.out.print("k = "+ k + ", j = " + j);
8 }
9 }
Na definição de tipos vinculados, a palavra-chave extends pode
significar tanto estende como implementa, dependendo do nome
que segue a palavra extends. No caso de se desejar vincular o
308 CAPÍTULO 10. GENERICIDADE
14 }
15 }
A execução do programa Somador1 produz:
Números: [1, 2.0, 3, 4.0, 5]
Soma: 15.0
Considere agora que se tenha trabalhar com listas de int e de
double separadamente. Assim, seria necessário somar numéricos
do tipo int e do tipo double usando o mesmo método sum. A
solução óbvia, embora equivocada, seria criar as listas de Integer
e de Double, denominadas list1 e list2, e definidas abaixo:
1 import java.util.ArrayList;
2 public class Somador2{
3 public void static main(String[ ] args){
4 Integer [] integers = {1, 2, 3, 4, 5}
5 Double [] doubles = {1.0, 2.0, 3.0, 4.0, 5.0}
6 Arraylist<Integer> list1 = new Arraylist<Integer>();
7 System.out.println("Inteiros: " + list1);
8 System.out.printlh("Soma inteiros: " + sum(list1));
9 Arraylist<double> list2 = new Arraylist<Double>();
10 System.out.println("Duplos: " + list2);
11 System.out.println("Soma duplos: " + sum(list2));
12 }
13 public static double sum(Arraylist<Number> list){
14 double t = 0.0;
15 for(Number e : list) t += e.doubleValue( );
16 return t;
17 }
18 }
10.10 Exercı́cios
Coleções
11.1 Introdução
11.2 Exercı́cios
313
314 PROGRAMAÇÃO MODULAR A Linguagem Java
Capı́tulo 12
GLOSSÁRIO
315
316 CAPÍTULO 12. INTERFACE GRÁFICA DO USUÁRIO
(0, 0)
+x
eixo x
(x, y)
+y
eixo y
12.1 Janelas
java.lang.Object
|
+--java.awt.Component
|
+--java.awt.Container
| |
| +--java.awt.Window
| |
| +--java.awt.Frame
| |
| +--javax.swing.JFrame
+--javax.swing.JComponent
|
+--- javax.swing.JPanel
• setTitle(String t):
define tı́tulo da janela
• setSize(int largura, int altura):
define dimensões da janela
• setSize(Dimension d):
define dimensões da janela
• show( ):
coloca janela visı́vel e por cima das demais
• setVisible(boolean b):
controla visibilidade da janela
• setLocation(int x, int y) ou
setLocation(Point p):
posiciona a janela na tela
318 CAPÍTULO 12. INTERFACE GRÁFICA DO USUÁRIO
1 import javax.swing.*;
2
• paint(Graphics g):
– Desenha informações gráficas na janela.
– É chamado automaticamente, por exemplo, em resposta a
um evento, como click de mouse ou abertura de janela.
– Deve ser redefinido pelo programa do usuário
– Não deve ser chamado diretamente
– paint(Graphics g) é da classe Container
• repaint():
– Limpa o fundo do componente gráfico corrente de qualquer
desenho anterior e chama o método paint para redesenhar
12.1. JANELAS 321
SAÍDA DE Vitral
>java UsaVitral
• dispose ( ):
fecha janela e recupera os recursos do sistema utilizados
• setIconImage(Image imagem):
define a imagem da janela iconizada ou minimizada
• setBounds(intx, int y, int largura, int altura):
posiciona janela na tela e define suas dimensões
12.1. JANELAS 323
• Point getLocation( ):
devolve coordenadas do vértice esquerdo superior da janela
324 CAPÍTULO 12. INTERFACE GRÁFICA DO USUÁRIO
CLASSE Graphics
Métodos
• public void drawLine(int x1, int y1, int x2, int y2):
g.drawLine(x1,x2,y1,y2) desenha no objeto g do tipo Graphics
uma linha entre os pontos (x1, y1) e (x2, y2).
• public void drawRect(int x, int y, int width, int height):
Desenha um retângulo com a largura (width) e a altura (height)
especificadas.
• public void fillRect(int x, int y, int width, int height):
Desenha um retângulo sólido com a largura e altura especifi-
cadas, com canto superior esquerdo no ponto (x, y).
• public void clearRect(int x, int y, int width, int height):
Desenha um retângulo transparente, ou seja, com a cor da
borda e a cor de fundo igual a cor do componente sobre o qual
será desenhado. Usado para separar componentes.
• public drawRoundRect (int x, int y, int width,
12.2. DESENHOS GEOMÉTRICOS 325
Largura (width)
CONTROLE DE CORES
DESENHO DE ARCOS
DESENHO DE POLÍGONOS
Controle de cores
Classe Polygon
• public Polygon():
– Constrói um novo objeto do tipo polı́gono. O polı́gono
recém contruı́do não contém nenhum ponto.
• public Polygon(int xValues[], int yValues[], int npts):
– Constrói um novo objeto do tipo polı́gono com npts vértices,
sendo cada vértice é formado por uma coordenada x do ar-
ray xValues e uma coordenada y do array yValues.
• addPoint(int x, int y):
Adiciona um novo ponto ao polı́gono
Polygon p = new Polygon ( );
p.addPoint(10,10);
p.addPoint(10,30);
p.addPoint(20,30);
g.drawPolygon(p);
Classe Font
1 import java.awt.*;
2 import javax.swing.*;
3
5 g.setFont(new Font("Monospaced",Font.ITALIC,24));
6 g.drawString("Monospaced 24 point italic.",20,70);
7 }
Classe Color
MÉTODOS DE Color
CONSTANTES DE COR
Constante Color Cor Valor RGB
public final static Color orange laranja 255,200,0
public final static Color pink cor-de-rosa 255,175,175
public final static Color cyan ciano 0,255,255
public final static Color magenta magenta 255,0,255
public final static Color yellow amarelo 255,255,0
public final static Color black preto 0,0,0
public final static Color white branco 255,255,255
public final static Color gray cinza 128,128,128
public final static Color lightGray cinza-claro 192,192,192
public final static Color darkGray cinza-escuro 64,64,64
public final static Color red vermelho 255,0,0
public final static Color green verde 0,255,0
public final static Color blue azul 0,0,255
USO DE Color
1 import java.awt.*; import javax.swing.*;
2 public class RectColorido extends JFrame {
3 public RectColorido() {
4 super ("Ret^
angulos coloridos");
5 setSize (150, 80);
6 setVisible(true);
7 }
8 public void paint (Graphics g) {
9 g.setColor(new Color (255,0,0)); // vermelho
10 g.fillRect(25, 25, 100, 20);
11 g.setColor(new Color(0.0f,1.0f,0.0f ));// verde
12 g.fillRect(25, 50, 100, 20);
13 }
14 }
13 }
>java UsaRectColorido
12.4. COMPONENTES BÁSICOS DE INTERFACE 335
COMPONENTES BÁSICOS
COMPONENTE JLabel
• JLabel (rótulo):
– Uma área em que podem ser exibidos textos não-editáveis
ou ı́cones.
– Labels ou rótulos são utilizados para mostrar um pequeno
texto que não pode ser alterado.
– Rótulos comuns são vistos nomeando botões e caixas de
texto.
• Métodos de JLabel:
– JLabel( ): rótulo sem identificação
– JLabel(String t): cria rótulo com identificação t
– void setText(String t): define a identificação do rótulo
– String getText( ): devolve a identificação do rótulo
336 CAPÍTULO 12. INTERFACE GRÁFICA DO USUÁRIO
COMPONENTE JButton
• JButton (botão):
Uma área que aciona um evento quando recebe um click de
mouse.
• Métodos de JButton:
– JButton( ): cria botão sem identificação
– JButton(Icon icon): cria botão com o ı́cone
– JButton(String text): cria botão com o texto
COMPONENTE JTextField
• JList (lista):
Uma área em que uma lista de itens é exibida a partir da qual o
usuário pode fazer uma seleção clicando uma vez em qualquer
elemento na lista.
Um clique duplo em um elemento na lista gera um evento de
ação. Múltiplos elementos podem ser selecionados.
• JPanel (painel):
Um contêiner em que os componentes podem ser colocados.
HIERARQUIA DE JComponent
java.lang.Object
|
+--java.awt.Component
|
+--java.awt.Container
| |
| +--java.awt.Window
| |
| +--java.awt.Frame
| |
338 CAPÍTULO 12. INTERFACE GRÁFICA DO USUÁRIO
| +--javax.swing.JFrame
+--javax.swing.JComponent
|
...
javax.swing.JComponent
| | ... | | | |
| | | | | +--- JPanel
| | | | +-- JComboBox
| | | +--- Jlist
| | +--- JLabel
| |
| +--- AbstractButton
| |
| +--- JButton, JToggleButton, JMenuItem
+-- JTextComponent |
| + JRadioButton, JCheckBox
+--- JTextField, JTextArea
CLASSE Container
MÉTODOS DE Container I
• add(Component c):
adiciona o componente c no fim do contêiner
• add(Component c, int posicao):
adiciona o componente c na posição indicada do contêiner
• setLayout(LayoutManager leiaute):
define o leiaute a ser usado para posicionamento de compo-
12.4. COMPONENTES BÁSICOS DE INTERFACE 339
nentes no contêiner.
Leiaute definido por objeto do tipo:
– FlowLayout
– BorderLayout
– GridLayout
• setFont(Font f):
define o fonte do contêiner
340 CAPÍTULO 12. INTERFACE GRÁFICA DO USUÁRIO
• Posicionamento Absoluto:
Sob o total controle pelo programador
• Gerente de Layout:
Posicionamento automático
• Programação Visual com IDE:
Caixa de ferramenta + arrastar e colar
POSICIONAMENTO ABSOLUTO
GERÊNCIA DE LEIAUTES
CLASSE FlowLayout
1 ...
2 JFrame f = new MinhaFrame();
3 FlowLayout layout = new FlowLayout();
4 Container c = f.getContentPane();
5 c.setLayout(layout);
6 c.add(meuComponente)
7 ...
CLASSE BorderLayout
CLASSE GridLayout
INTERFACE ActionListener
– getSource( ):
retorna a referência do objeto originador do evento
– String getActionCommand( ) :
retorna o string do comando associado com a ação, por
exemplo, o rótulo de um botão
12.6. MODELO DE EVENTOS 345
EVENTOS E OUVINTES I
Interface MétodosPar^
ametro/ Origem
Acessadores
ActionListener action- ActionEvent Button
Performed getSource List
getAction- MenuItem
Command TextField
JLabel e JTextField
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
>java UsaEntradaDeTexto
12.6. MODELO DE EVENTOS 347
2 ActionListener {
3 public void actionPerformed (ActionEvent e) {
4 String s = "";
5 if (e.getSource() == text)
6 s = "Ola " + e.getActionCommand() + "!";
7 JOptionPane.showMessageDialog (null, s);
8 }
9 }
1 public class UsaEntradaDeTexto {
2 public static void main (String args[]) {
3 EntradaDeTexto j = new EntradaDeTexto();
4 j.addWindowListener (
5 new WindowAdapter (){
6 public void windowClosing(WindowEvent e){
7 System.exit(0);
8 }
9 });
10 }
11 }
EVENTOS E OUVINTES II
Interface Métodos Par^
ametro/ Origem
Acessadores
WindowListener windowClosing WindowEvent Window
windowOpened getWindow
windowIconified
windowDeiconified
windowClosed
windowActivated
windowDeactivated
Eventos de Janela ocorrem quando a janela:
• é fechada com clique no X ou aberta;
• torna-se ativa com clique na janela ou torna-se inativa
• é minimizada (iconizada) com clique no Box
• é restaurada (desiconizada) com clique no ı́cone
12.6. MODELO DE EVENTOS 349
CLASSES ADAPTADORAS
BOTÕES
BOTÕES DE COMANDOS
>java UsaExemploBotao
12.7. BOTÕES DE COMANDO 351
BOTÕES DE COMANDO
1 import java.awt.*;
2 import java.awt.event.*;
3 import javax.swing.*;
4 public class ExemploBotao extends JFrame {
5 private class TratadorDeEventosDeBotao
6 implements ActionListener{ ... }
7 private JButton botao =
8 new JButton ("Lugar de clicar com o mouse");
9 public ExemploBotao() {
10 super ("botoes de comando");
11 Container c = getContentPane();
12 c.setLayout (new FlowLayout() );
13 c.add (botao);
14 botao.addActionListener
15 (new TratadorDeEventosDeBotao());
16 setSize (275, 100); setVisible(true);
17 }
18 }
1 private class TratadorDeEventosDeBotao
2 implements ActionListener {
3 public void actionPerformed (ActionEvent e){
4 JOptionPane.showMessageDialog (null,
5 "Voce clicou sobre o " +
352 CAPÍTULO 12. INTERFACE GRÁFICA DO USUÁRIO
6 e.getActionCommand() );
7 }
8 }
BOTÕES DE ESTADO
– JCheckBox
– JRadioButton
Uso de JCheckBox
>java UsaDiversasOpcoes
JCheckBox
1 import java.awt.*;
2 import java.awt.event.*;
3 import javax.swing.*;
4 public class DiversasOpcoes extends JFrame {
354 CAPÍTULO 12. INTERFACE GRÁFICA DO USUÁRIO
1 import java.awt.*;
2 import java.awt.event.*;
3 import javax.swing.*;
4 public class UsaDiversasOpcoes {
5 public static void main (String args[]) {
6 DiversasOpcoes j = new DiversasOpcoes();
7 j.addWindowListener(
8 new WindowAdapter( ) {
9 public void windowClosing(WindowEvent e){
10 System.exit(0);
11 }
12 }
13 );
14 }
15 }
Botões de rádio
USO DE JRadioButton
>java UsaUmaOpcao
356 CAPÍTULO 12. INTERFACE GRÁFICA DO USUÁRIO
JRadioButton
1 import java.awt.*;
2 import java.awt.event.*;
3 import javax.swing.*;
4
6 red.addItemListener (controlador);
7 green.addItemListener (controlador);
8
9 radioGroup.add(red);
10 radioGroup.add(green);
11
2 implements ItemListener {
3 public void itemStateChanged (ItemEvent e) {
4 if (e.getSource() == red)
5 c.setBackground (Color.red);
6 else if (e.getSource() == green)
7 c.setBackground (Color.green);
8 }
9 }
1 import java.awt.*; import java.awt.event.*;
2 import javax.swing.*;
3 public class UsaUmaOpcao {
4 public static void main (String args[]) {
5 UmaOpcao j = new UmaOpcao();
6 j.addWindowListener (
7 new WindowAdapter () {
8 public void windowClosing(WindowEvent e){
9 System.exit(0);
10 }
11 }
12 );
13 }
14 }
358 CAPÍTULO 12. INTERFACE GRÁFICA DO USUÁRIO
OPERAÇÕES DE JComboBox
• JComboBox(String[ ] names ):
12.8. CAIXAS DE COMBINAÇÃO 359
• setMaximumRowCount( int n ):
define número de linhas visı́veis da caixa de combinação. Se
necessário barras de rolagem serão automaticamente incluı́das
• int getSelectedIndex( ):
ı́ndice dos itens inicia-se com 0
JComboBoxFame
1 import javax.swing.JFrame;
2
JComboBoxFrame
3 import java.awt.event.ItemEvent;
4 import javax.swing.JFrame;
5 import javax.swing.JLabel;
6 import javax.swing.JComboBox;
7 import javax.swing.Icon;
8 import javax.swing.ImageIcon;
Classe ComboBoxFrame
1 public class ComboBoxFrame extends JFrame {
2 private JComboBox comboBox;
3 private JLabel label;
4 private String names[] = {
5 "bug1.gif","bug2.gif","travelbug.gif",
6 "buganim.gif"
7 };
8 private Icon icons[] = {
9 new ImageIcon( names[ 0 ]),
10 new ImageIcon( names[ 1 ]),
11 new ImageIcon( names[ 2 ]),
12 new ImageIcon( names[ 3 ])
13 };
14 public ComboBoxFrame( ){ ... }
15 }
Construtora de ComboBoxFrame
1 public ComboBoxFrame( ){
2 super("Testing JComboBox");
3 setLayout( new FlowLayout( ) );
4
10 add(comboBox );
11 label = new JLabel(icons[0]);//exibe primeiro ı́cone
12.8. CAIXAS DE COMBINAÇÃO 361
12 add(label);
13 }
12.9 Listas
OPERAÇÕES DE JList
• JList(Object[ ] itemNames):
mostra na lista os elementos de itemNames, normalmente con-
vertidos com toString.
• setVisibleRowCount(int n)
• int setSelectionMode(int mode):
define o modo de seleção de itens, que pode ser
SINGLE SELECTION,
SINGLE INTERVAL SELECTION ou
MULTIPLE INTERVAL SELECTION
• setListData(Object[ ] itens ):
configura os itens dados, por default convertidos com toString,
no Jlist corrente
• setCellRenderer(ListCellRenderer renderer):
delega ao método
renderer.getListCellRendererComponent(...),
no lugar de toString, a produção de cada um dos itens da
JList
• int getSelectedIndex( ) :
• int[ ] getSelectedIndices( ) :
• Object getSelectedValue( ):
retorna o rótulo do item selecionado
• Object[ ] getSelectedValues( ):
retorna os rótulos dos itens selecionados
• setFixedCellWidth( int w )
• setFixedCellHeight( int h )
12.9. LISTAS 363
VALORES DO SelectionMode
1 import java.awt.FlowLayout;
2 import java.awt.Color;
3 import javax.swing.JFrame;
4 import javax.swing.JList;
5 import javax.swing.JScrollPane;
6 import javax.swing.event.ListSelectionListener;
7 import javax.swing.event.ListSelectionEvent;
8 import javax.swing.ListSelectionModel;
1 public class ListFrame extends JFrame {
2 private JList colorJList;
364 CAPÍTULO 12. INTERFACE GRÁFICA DO USUÁRIO
CONSTRUTORA DE ListFrame
1 public ListFrame() {
2 super( "List Test" ); setLayout(new FlowLayout( ));
3
7 // n~
ao permite múltiplas seleç~
oes
8 colorJList.setSelectionMode(
9 ListSelectionModel.SINGLE_SELECTION);
10
7 }
8 );
9
1 import java.awt.FlowLayout;
2 import java.awt.event.ActionListener;
3 import java.awt.event.ActionEvent;
4 import javax.swing.JFrame;
5 import javax.swing.JList;
6 import javax.swing.JButton;
7 import javax.swing.JScrollPane;
8 import javax.swing.ListSelectionModel;
CLASSE MultipleSelectionFrame
1 public class MultipleSelectionFrame {
2 private JList colorJList;
3 private JList copyJList;
4 private JButton copyJButton;
5
CONSTRUTORA DE MultipleSelectionFrame
1 public MultipleSelectionFrame() {
2 super( "Multiple Selection Lists" );
3 setLayout( new FlowLayout() );
4
3 colorJList.setVisibleRowCount( 5 );
4
5 colorJList.setSelectionMode(
6 ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
6 }
7 }
8 );
3 copyJList.setVisibleRowCount( 5 );
4
5 copyJList.setFixedCellWidth( 100 );
6
7 copyJList.setFixedCellHeight( 15 );
8
9 copyJList.setSelectionMode(
10 ListSelectionModel.SINGLE_INTERVAL_SELECTION);
1 import java.awt.FlowLayout;
2 import java.awt.event.ActionListener;
3 import java.awt.event.ActionEvent;
4 import java.awt.Color;
5 import javax.swing.JFrame;
368 CAPÍTULO 12. INTERFACE GRÁFICA DO USUÁRIO
6 import javax.swing.JList;
7 import javax.swing.JButton;
8 import javax.swing.JScrollPane;
9 import javax.swing.ListSelectionModel;
10 import javax.swing.ListCellRenderer
CLASSE MultipleSelectionFrame
1 public class MultipleSelectionFrame {
2 private JList colorJList, JList copyJList;
3 private JButton copyJButton;
4 private final String colorNames[] = { "Black", "Blue",
5 "Cyan", "Dark Gray", "Gray", "Green", "Light Gray",
6 "Magenta", "Orange", "Pink", "Red", "White", "Yellow"
7 };
8 private final Color colors[] = {Color.black, Color.blue,
9 Color.cyan, Color.darkGray, Color.gray, Color.green,
10 Color.lightGray, Color.magenta, Color.orange,
11 Color.pink,Color.red, Color.white, Color.yellow
12 };
13 public MultipleSelectionFrame() { ... }
14 }
CONSTRUTORA DE MultipleSelectionFrame
1 public MultipleSelectionFrame() {
2 super( "Multiple Selection Lists" );
3 setLayout( new FlowLayout() );
4
14 }
3 colorJList.setVisibleRowCount( 5 );
4
5 colorJList.setSelectionMode(
6 ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
3 copyJList.setVisibleRowCount( 5 );
4
5 copyJList.setFixedCellWidth( 100 );
6
7 copyJList.setFixedCellHeight( 15 );
8
9 copyJList.setSelectionMode(
10 ListSelectionModel.SINGLE_INTERVAL_SELECTION);
11
12 copyJList.setCellRenderer(new MyRenderer(colors));
5 }
6 class MyRenderer extends implements ListCellRenderer {
7 private Color[ ] colors;
8 public MyCellRenderer(Color[ ] colors) {
9 this.colors = colors;
10 }
11 public Component getListCellRendererComponent(
12 JList list, Object value, int index,
13 boolean isSelected, boolean cellHasFocus){...}
14 }
12.10 Painéis
CLASSE Jpanel
• JPanel( ):
cria painel com FlowLayout
• void setLayout(LayoutManager layout):
associa leiaute ao painel
• JPanel(LayoutManager layout):
cria painel com o leiaute indicado
• add(Component c):
Adiciona o componente gráfico c no painel.
USANDO PAINÉIS
>java UsaPanelDemo
12.10. PAINÉIS 373
1 import java.awt.*;
2 import java.awt.event.*;
3 import javax.swing.*;
4
11 }
1 public PanelDemo ()
2 super ("Demonstrando Paineis");
3 Container c = getContentPane();
4 buttonPanel.setLayout(new GridLayout (2,3));
5 for (int i = 0; i < buttons.length; i++) {
6 buttons[i] = new JButton ("Button " + (i + 1));
7 buttonPanel.add (buttons[i]);
8
JPanel PERSONALIZADO
>java UsaPainelPersonalizado
ESTENDENDO JPanel
1 import java.awt.*; import java.swing.event.*;
2 import javax.swing.*;
3
>java UsaRemoveComponente
376 CAPÍTULO 12. INTERFACE GRÁFICA DO USUÁRIO
1 import java.awt.*;
2 import java.awt.event.*;
3 import javax.swing.*;
4 public class UsaRemoveComponente{
5 public static void main (String args[]){
6 RemoveComponente j = new RemoveComponente();
7 j.addWindowListener (
8 new WindowAdapter() {
9 public void windowClosing (WindowEvent e) {
10 System.exit(0);
11 }
12 }
13 );
14 }
15 }
1 import java.awt.*;
2 import java.awt.event.*;
3 import javax.swing.*;
4 public class RemoveComponente extends JFrame
5 implements ActionListener{
6 private JPanel buttonPanel = new JPanel();
7 private JButton buttons[ ] = new JButton[6];
8 private JButton remocao2 = new JButton("remove 2");
9 private JButton remocao4 = new JButton("remove 4");
10 private JButton adicao2 = new JButton("adicao 2");
11 private JButton adicao4 = new JButton("adicao 4");
12 public RemoveComponente( )...
13 public void actionPerformed(ActionEvent e) ...
14 }
12.10. PAINÉIS 377
1 public RemoveComponente( ) {
2 super ("Adiç~
ao e Remoç~
ao de Componentes");
3 buttonPanel.setLayout(new GridLayout (2,3));
4 for (int i = 0; i < buttons.length; i++) {
5 buttons[i] = new JButton ("Button " + i);
6 buttonPanel.add(buttons[i]);
7 buttonPanel.add(buttons[i]); //somente um inserido
8 }
9 "Adiciona Componentes na Janela";
10 "Associa Ouvinte a Bot~ oes";
11 setSize (425, 150);
12 show();
13 }
• "Adiciona Componentes na Janela":
1 Container c = getContentPane();
2 c.add(remocao2,BorderLayout.WEST);
3 c.add(remocao4,BorderLayout.EAST);
4 c.add(adicao2,BorderLayout.NORTH);
5 c.add(adicao4,BorderLayout.CENTER);
6 c.add(buttonPanel, BorderLayout.SOUTH);
• "Associa Ouvinte a Bot~
oes":
1 remocao2.addActionListener(this);
2 remocao4.addActionListener(this);
3 adicao2.addActionListener(this);
4 adicao4.addActionListener(this);
1 public void actionPerformed(ActionEvent e) {
2 if (e.getSource()== remocao2)
3 buttonPanel.remove(buttons[2]);
4 else if (e.getSource()== remocao4)
5 buttonPanel.remove(buttons[4]);
6 else if (e.getSource()== adicao2)
7 buttonPanel.add(buttons[2]);
8 else if (e.getSource()== adicao4)
9 buttonPanel.add(buttons[4]);
10
11 buttonPanel.repaint();
12 }
378 CAPÍTULO 12. INTERFACE GRÁFICA DO USUÁRIO
EVENTOS DE MOUSE
EVENTOS E OUVINTES IV
CLASSE MouseEvent
• int getClickCount( ):
retorna número de cliques rápidos e consecutivos
• int getX( ), int getY( ) e Point getPoint( ):
retornam coordenadas (x,y), relativas ao componente, do mouse
onde evento ocorreu
• int getButton( ):
retorna qual botão do mouse mudou de estado. Valor retor-
nado é uma das constantes: NOBUTTON, BUTTON1, BUTTON2,
BUTTON3
• int getModifier():
retorna um int descrevendo as teclas modificadoras, e.g., (Shift,
Ctl+Shift) ativas durante evento
• String getMouseModifierText(int):
retorna um String descrevendo as teclas modificadoras (Shift,
380 CAPÍTULO 12. INTERFACE GRÁFICA DO USUÁRIO
MÉTODOS DE MouseListener
MÉTODOS DE MouseMotionListener
>java UsaEvtMouse
1 import java.awt.*;
2 import java.awt.event.*;
3 import javax.swing.*;
4 public class EvtMouseDemo extends JFrame
5 implements MouseListener, MouseMotionListener {
6 private JLabel status1 = new JLabel();
7 private JLabel status2 = new JLabel();
8 private JLabel status3 = new JLabel();
9
12 "CONSTRUTORA DE EvtMouseDemo";
13
14 "Operaç~
oes de tratamento de evento";
15 }
CONSTRUTORA DE EvtMouseDemo
1 public EvtMouseDemo () {
2 super ("Demonstrando Eventos de Mouse");
3
4 c.add(status1,BorderLayout.SOUTH);
5 c.add(status2,BorderLayout.NORTH);
6 c.add(status3,BorderLayout.EAST);
7
8 addMouseListener (this);
382 CAPÍTULO 12. INTERFACE GRÁFICA DO USUÁRIO
9 addMouseMotionListener (this);
10
5 j.addWindowListener (
6 new WindowAdapter() {
7 public void windowClosing (WindowEvent e){
8 System.exit(0);
9 }
10 }
11 );
12 }
13 }
UM PROGRAMA DE PINTURA
>java Painter
10 }
11 public void paint (Graphics g){ g.fillOval(x,y,4,4); }
12 public static void main (String args[]){...}
13 }
1 addMouseMotionListener (
2 new MouseMotionAdapter() {
3 public void mouseDragged (MouseEvent e) {
4 x = e.getX();
5 y = e.getY();
6 repaint();
7 }
8 }
9 );
1 public static void main (String args[]){
2 Painter j = new Painter ();
3 j.addWindowListener (
4 new WindowAdapter() {
5 public void windowClosing (WindowEvent e){
6 System.exit(0);
7 }
8 }
9 );
10 }
12.12. EVENTOS DE TECLADO 385
EVENTOS DE TECLADO
3. Digitada "A":
chamado keyTyped com "A"
4. Liberada a tecla A:
chamado keyReleased com VK_A
5. Liberada a tecla SHIFT:
chamado keyReleased com VK_SHIFT
1. Pressionada a tecla A:
chamado keyPressed com VK_A
2. Digitada "a":
chamado keyTyped com "a"
3. Liberada a tecla A:
chamado keyReleased com VK_A
EVENTOS E OUVINTES V
MÉTODOS DE KeyEvent
• char getKeyChar():
devolve o caractere digitado
12.12. EVENTOS DE TECLADO 387
• int getKeyCode():
devolve o código virtual do caractere digitado
• String getKeyText(int codTecla):
devolve texto descrevendo o código virtual da tecla.
Ex: getKeyText(KeyEvent.VK_END) devolve "END"
• int getKeyModifiers( ):
devolve a máscara do modificador associado ao evento
• String getKeyModifiersText(int modificadores):
devolve descrição das tecla modificadoras
(SHIFT, CTRL, CTRL+SHIFT)
Parâmetro obtido pelo método getModifiers()
• boolean isAltDown():
idem para tecla ALT
• boolean isControlDown():
idem para tecla CONTROL
• boolean isShiftDown():
idem para tecla SHIFT
>java UsaTecladoDemo
388 CAPÍTULO 12. INTERFACE GRÁFICA DO USUÁRIO
9 textArea.setText(line1+"\n"+line2+"\n"+line3+"\n");
10 }
1 public static void main (String args[]){
2 UsaTecladoDemo j = new UsaTecladoDemo();
3 j.addWindowListener (
4 new WindowAdapter() {
5 public void windowClosing (WindowEvent e) {
6 System.exit(0);
7 }
8 }
9 );
10 }
MULTIDIFUSÃO DE EVENTOS
>java MulticastTest
390 CAPÍTULO 12. INTERFACE GRÁFICA DO USUÁRIO
>java MulticastTest
8 public MulticastPanel( ){
9 JButton newButton = new JButton("New");
10 add(newButton);
11 newButton.addActionListener(this);
12 closeAllButton = new JButton("Close all");
13 add(closeAllButton);
14 }
15 public void actionPerformed(ActionEvent evt) ...
16 }
1 public void actionPerformed(ActionEvent evt){
2 SimpleFrame f = new SimpleFrame();
3 f.setTitle("Window " + counter);
4 f.setSize(200, 150);
5 f.setLocation(30 * counter, 30 * counter);
6 f.show();
7 closeAllButton.addActionListener(f);
8 }
9 class SimpleFrame extends JFrame implements ActionListener{
10 public void actionPerformed(ActionEvent evt){
11 MulticastPanel.setCounter(0);
12 dispose();
13 }
14 }
1 class MulticastFrame extends JFrame
2 public MulticastFrame() {
3 setTitle("MulticastTest"); setSize(300, 200);
4 addWindowListener(new WindowAdapter( ){
5 public void windowClosing(WindowEvent e){
6 System.exit(0);
7 }
8 );
9 Container contentPane = getContentPane();
10 contentPane.add(new MulticastPanel());
11 }
12 }
13 public class UsaMulticast {
14 public static void main(String[] args) {
392 CAPÍTULO 12. INTERFACE GRÁFICA DO USUÁRIO
COMPONENTE JTextArea
– setEditable(boolean b)
>java UsaTextAreaDemo
12.13. ÁREAS DE TEXTO 393
9 tArea.setEditable (false);
10 c.add (new JScrollPane(tArea));
11 setSize(200, 200);
12 setVisible(true);
13 }
1 import java.awt.*; import java.awt.event.*;
2 import javax.swing.*;
3 public class UsaTextAreaDemo {
4 public static void main (String args[]) {
5 TextAreaDemo j = new TextAreaDemo();
6 j.addWindowListener (
7 new WindowAdapter () {
8 public void windowClosing (WindowEvent e) {
9 System.exit(0);
10 }
11 }
12 );
13 }
14 }
>java UsaJanelaComScrollBar
12.13. ÁREAS DE TEXTO 395
COMPONENTE JSlider
MÉTODOS DE JSlider
EVENTOS E OUVINTES VI
DEMONSTRADOR DE JSlider
>java UsaSliderDemo
MENU DE OPÇÕES
CLASSES DE MENU
>java UsaMenu
12.15. BARRAS DE MENUS, MENUS E SUBMENUS 401
1 import javax.swing.*;
2 import java.awt.event.*;
3 import java.awt.*;
4
CONSTRUTOR DE MenuTest
1 public MenuTest() {
2 super( "Uso de Menus" );
3 JMenuBar bar = new JMenuBar(); setJMenuBar( bar );
4
8 Container c = getContentPane();
9 c.setBackground( Color.cyan );
10 "CONSTRÓI RÓTULO display";
11 c.add( display, BorderLayout.CENTER );
12
4 aboutItem.addActionListener(
5 new ActionListener() {
6 public void actionPerformed( ActionEvent e ) {
7 JOptionPane.showMessageDialog( MenuTest.this,
8 "Este é um exemplo de uso de Barra de Menus,\n" +
9 "Menus e SubMenus","O Que é",
10 JOptionPane.PLAIN_MESSAGE);
12.15. BARRAS DE MENUS, MENUS E SUBMENUS 403
11 }
12 }
13 );
4 exitItem.addActionListener(
5 new ActionListener() {
6 public void actionPerformed(ActionEvent e){
7 System.exit( 0 );
8 }
9 }
10 );
8 formatMenu.addSeparator();
9
6 fontMenu.addSeparator( );
7
11 }
12 }
12.16. MENUS SENSÍVEIS AO CONTEXTO 407
UTILIZANDO JPopupMenus
1 class UsaPopupMenu {
2 private JPopupMenu menu = new JPopupMenu( );
3
10 addMouseListener (...);
11 ...
12 }
1 addMouseListener (
2 new MouseAdapter() {
3 public void mousePressed (MouseEvent e) {
408 CAPÍTULO 12. INTERFACE GRÁFICA DO USUÁRIO
4 checkForTriggerEvent (e);
5 }
6 public void mouseReleased (MouseEvent e){
7 checkForTriggerEvent (e);
8 }
9 private void checkForTriggerEvent (MouseEvent e){
10 if (e.isPopupTrigger( ) )
11 menu.show(e.getComponent(),e.getX(),e.getY());
12 }
13 }
14 );
12.17. JANELAS MÚLTIPLAS 409
JDesktopPane e JInternalFrame
11 }
1 public InternalFrame() {
2 super("Document #" + (++openFrameCount),
3 true, //a frame pode ter seu tamanho modificado
4 true, //a frame pode ser fechada.
5 true, //a frame pode ser maximizada.
6 true);//a frame pode ser minimizada.
7 // Define o tamanho inicial da frame.
8 setSize(300,300);
9 // Define a localizacao inicial da nova frame.
10 setLocation(xOffset*openFrameCount,
11 yOffset*openFrameCount);
12 }
1 import javax.swing.JInternalFrame;
2 import javax.swing.JDesktopPane;
3 import javax.swing.JMenu;
4 import javax.swing.JMenuItem;
5 import javax.swing.JMenuBar;
6 import javax.swing.JFrame;
7 import java.awt.event.*; import java.awt.*;
8 public class ExtenalFrame extends JFrame {
9 JDesktopPane desktop;
10 public ExternalFrame {...}
11 protected JMenuBar createMenuBar( ) {...}
12 protected void createFrame( ) {...}
13 }
12.17. JANELAS MÚLTIPLAS 411
1 public ExternalFrame() {
2 super("InternalFrameDemo");
3 // Make the big window be indented 50 pixels
4 // from each edge of the screen.
5 int inset = 50;
6 Dimension screenSize =
7 Toolkit.getDefaultToolkit().getScreenSize();
8 setBounds(inset, inset, screenSize.width - inset*2,
9 screenSize.height-inset*2);
10 "Adiciona ouvinte para fechar janela";
11 "Set up the GUI";
12 }
8 menu.add(menuItem);
9 menuBar.add(menu);
10 return menuBar;
11 }
1 menuItem.addActionListener(
2 new ActionListener() {
3 public void actionPerformed(ActionEvent e) {
4 createFrame();
5 }
6 }
7 );
1 protected void createFrame() {
2 InternalFrame frame = new InternalFrame();
3 frame.setVisible(true); //necessary as of kestrel
4 desktop.add(frame);
5 try {
6 frame.setSelected(true);
7 } catch (java.beans.PropertyVetoException e)
8 }
12.18. APARÊNCIA E COMPORTAMENTO 413
APARÊNCIA E COMPORTAMENTO
• LookAndFeelInfo[ ] UIManager.getInstaledLookAndFeels():
retorna a lista de look and feel instalados no sistema.
• UIManager.setLookAndFeel(String lfClassname):
faz o look and feel de nome lfClassName ser o corrente no
414 CAPÍTULO 12. INTERFACE GRÁFICA DO USUÁRIO
sistema.
UIManager.setLookAndFeel(
"com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
UIManager.setLookAndFeel(
"");
12.19. EXERCÍCIOS 415
UIManager.setLookAndFeel(
"com.sun.java.swing.plaf.motif.MotifLookAndFeel");
UIManager.setLookAndFeel(
"javax.swing.plaf.metal.MetalLookAndFeel");
12.19 Exercı́cios
Threads
1 public class B {
2 public static void main(String[] a) {
3 T linha1 = new T(); // cria linha
4 T linha2 = new T(); // cria outra linha
5 linha1.start(); // dispara linha1
6 ...
7 linha2.start(); // dispara linha 2
8 ....
9 }
10 }
13
1 class Jogo
2
9
13.1. CRIAÇÃO DE THREAD 419
(RE)DEFINIÇÃO DE run()
1 class Exemplo {
2 public static void main(String[] a) {
3 ExtnOfThread t1 = new ExtnOfThread();
4 t1.start();
5 Thread t2 = new Thread (new ImplOfRunnable());
6 t2.start();
7 }
8 }
1 class ExtnOfThread extends Thread {
2 public void run() {
3 System.out.println("extension of Thread running");
4 setPriority( getPriority() +1 );
5 try {sleep(1000);}
6 catch (InterruptedException ie) return;
7 }
8 }
9 class ImplOfRunnable implements Runnable {
10 public void run() { ... }
11 }
A CLASSE java.lang.Thread
• NOVO:
Estado inicial após a criação da linha com o operador new.
• EXECUTÁVEL:
Estado após a execução do método start().
– A linha pode estar rodando ou não.
– Em alguns sistemas uma linha executa até que outra de
maior prioridade tome-lhe o controle.
13.3. CICLO DE VIDA DE THREADS 425
PRIORIDADES DE LINHAS
USO DE yield
POR EXEMPLO:
1 >java Babel false 3 Sim Nao
2 >Sim Sim Sim Nao Nao Nao
3 >java Babel true 3 Sim Nao
4 >Sim Nao Sim Nao Sim Nao
1 class Babel extends Thread {
2 static boolean deveCeder;
3 static int vezes;
4 String palavra;
5 Babel(String oQue) { palavra = oQue; }
6 public void run() {
7 for (int i = 0; i < vezes; i++) {
8 System.out.print(palavra + " ");
9 if (deveCeder) yield();
10 }
11 }
12 public static void main(String[] args) {
13 vezes = Integer.parseInt(args[1]);
14 deveCeder = new Boolean(args[0]).booleanValue();
15 Thread corrente = currentThread();
16 corrente.setPriority(Thread.MAX_PRIORITY);
17 for (int i=2; i<args.length; i++) {
18 new Babel(args[i]).start();
19 }
428 CAPÍTULO 13. THREADS
20 }
21 }
22 >java Babel false 3 Sim Nao
23 >Sim Sim Sim Nao Nao Nao
24 >java Babel true 3 Sim Nao
25 >Sim Nao Sim Nao Sim Nao
7 if (argFrom==0) {
8 from = 2;
9 } else from = argFrom;
10 to = argFrom + 99;
11 }
12 public void run() {...}
13 }
1 public void run() {
2 for (long i=from; i<=to && i<n; i++) {
3 if (n%i == 0) {
4 System.out.println("Factor " + i +
5 " found by thread " + getName());
6 break;
7 }
8 yield();
9 }
10 }
9 }
10 try{ for(int i=0;i<10;i++) p[i].join();}
11 catch(Exception e)
12 System.out.println("gauge reads " +
13 gauge + ", safe limit is " + Limit);
14 }
15 }
COMANDO synchronized
• O comando
synchronized(obj) {cmds}
bloqueia o objeto obj durante a execução de cmds.
• Outras linhas que executarem o comando synchronized (obj)
para o mesmo objeto ficarão em espera até que o objeto seja
desbloqueado.
1 class L1 extends Thread {
2 Object lock;
3 public L1(Object obj){lock = obj; }
4 ...
5 public void run(){... synchronized(lock){...r1...} ...}
6 }
7 class L2 extends Thread {
8 Object lock;
9 public L2(Object obj){lock = obj;}
10 ...
432 CAPÍTULO 13. THREADS
Figura 13.1
é equivalente a
void RaisePressure() { synchronized(this) { corpo }
• synchronized somente sincroniza métodos de um mesmo ob-
jeto.
MÉTODOS SINCRONIZADOS
OPERAÇÕES DE SINCRONIZAÇÃO
DETALHES DE wait
DETALHES DE notify
DEFINIÇÃO DO BUFFER
1 public class Buffer {
2 private int size;
3 private int [ ] contents;
4 private int in, out;
5 private int total =0;
6 Buffer(int size) {
7 this.size = size; contents = new int[size];
8 }
9 public synchronized void put(int item){ ...}
10 public synchronized int get() {... }
11 }
1 public synchronized void put(int item){
2 while(total >= size) {
3 try {this.wait();}
4 catch(InterruptedException e){ }
5 }
6 contents[in] = item;
7 System.out.println
8 ("Buffer:write at "+ in + "item" + item);
9 if(++in == size) in = 0;
10 total++;
11 this.notifyAll();
12 }
1 public synchronized int get() {
2 int temp;
3 while(total <= 0)
4 try this.wait();
5 catch(InterruptedException e){ }
6 temp = contents[out];
7 System.out.println
8 ("Buffer:read from "+out+ "item" + temp);
9 if(++out == size) out=0;
10 total--;
11 this.notifyAll();
12 return temp;
13 }
438 CAPÍTULO 13. THREADS
• Toda aplicação começa com uma linha que executa seu método
main.
• Uma aplicação que não cria outras linhas termina quando seu
main termina.
• Linhas podem ser user ou daemon.
• Por default, toda linha é do tipo user.
• No caso de haver outras linhas, a aplicação somente termina
quando todas as linhas do tipo user terminarem.
• Aplicação não espera por linhas do tipo daemon, isto é, todas
linhas deste tipo morrem junto com a aplicação.
• Criam-se linhas daemon com o comando:
setDaemon(true)
11 }
12 SAIDA: M1. Begin
13 T1. Begin
14 M3. End
3 T1. Begin
4 T2. Post-Mortem Sigh
5 T3. Resurrection
6 M5. End
4 T1. Begin
5 M4. Continues
6 M6. End
3 M2. Continues
4 T1. Begin
5 M4. Continues
6 M5. End
7 T2. Interrupted
8 T4. End
13.8 Exercı́cios
Reflexão Computacional
CLASSE java.lang.Class
• String getName():
c.getname() retorna o nome da class descrita por c
• Class getSuperClass():
c.getSuperClass() retorna a superclasse de c.
• Class[ ] getInterfaces():
c.getInterfaces() retorna um arranjo de objetos Class que
informa as interfaces implementadas por c.
• boolean isInterface()
• String toString()(:
445
446 CAPÍTULO 14. REFLEXÃO COMPUTACIONAL
• Method[ ] getMethods():
retorna um arranjo contendo os objetos Method dos métodos
públicos.
• Method[ ] getDeclaredMethods:
retorna um arranjo contendo os objetos Methods de todos os
métodos.
• Constructor[ ] getConstructors():
retorna um arranjo contendo os objetos Construtor que fornece
os construtores públicos.
• Constructor[ ] getDeclaredConstructors:
retorna um arranjo contendo os objetos Constructor que for-
nece todos os construtores;
14.1. CLASSE CLASS 447
• Uso de getClass():
1 Empregado e;
2 Class c = e.getClass();
3 ...
4 Methods [ ] m = c.getMethods();
5
• Uso de forName(String):
1 String nome = "Empregado";
2 Class c = Class.forName(nome);
3 ...
4 Methods [ ] m = c.getMethods();
5 Object x = c.newInstance();
6
• O trecho de programa
1 Empregado e = new Empregado("José da Silva",data);
2 Class c = e.getclass();
3 System.out.println(c.getName() + " " + e.getname());
• IMPRIME Empregado José da Silva
CLASSE java.lang.reflect.Modifier
TESTE DA REFLEXÃO
1 import java.lang.reflect.*;
2 import CoreJava.*;
3 public class ReflectionTest {
4 public static void printConstructors(Class cl) {...}
5 public static void printMethods(Class cl){ ... }
6 public static void printFields(Class cl){ ... }
14.1. CLASSE CLASS 449
14.2 Exercı́cios
Applets
15.1 Introdução
APPLETS
CLASSE Applet
java.lang.Object
|
+--java.awt.Component
|
+--java.awt.Container
|
+--java.awt.Panel
|
453
454 CAPÍTULO 15. APPLETS
+--java.applet.Applet
CLASSE JApplet
java.lang.Object
|
+--java.awt.Component
|
+--java.awt.Container
|
+--java.awt.Panel
|
+--java.applet.Applet
|
+--javax.swing.JApplet
EXECUÇÃO DE APPLETS
CRIAÇÃO DE APPLETS
• Arquivo Mensagem.java:
1 import java.awt.Graphics; import java.applet.Applet;
2 public class Mensagem extends Applet {
3 public void paint(Graphics g) {
4 g.drawString("Sim!", 15, 25);
5 }
6 }
• Arquivo Mensagem.java:
1 import java.awt.Graphics; import javax.swing;
2 public class Mensagem extends JApplet {
3 public void paint(Graphics g) {
4 g.drawString("Sim!", 15, 25);
5 }
6 }
• Arquivo Pagina1.html:
1 <title> Applet muito simples</title>
2 <applet code="Mensagem.class" width=200 height=100>
3 </applet>
• Arquivo Pagina2.html:
1 <title> Applet muito simples</title>
2 <object codetype=application/java"
3 classid = "Mensagem.class" width=200 height=100>
4 </object>
Z:\>appletviewer Pagina1.html:
456 CAPÍTULO 15. APPLETS
Arquivo Teste.html:
1 <HTML>
2 <APPLET Code="Teste.class",width=300 height=40></APPLET>
3 </HTML>
Arquivo Teste.java:
1 import java.applet.Applet; import java.awt.Graphics;
2 public class Teste extends Applet {
3 public void init() { repaint(); }
4 public void paint(Graphics g) {
5 g.drawRect(0,0,size().width - 1,size().height - 1);
6 g.drawString("Texto dentro do retangulo", 5, 15);
7 }
8 }
• void init():
Chamado automaticamente quando a applet for carregada a
primeira vez.
Se a applet usa threads, init deve tipicamente criar essas th-
reads.
• void start():
Chamado automaticamente sempre que o browser visitar a
página que contém a applet.
Isto é, chamado em resposta à pressão dos botões Back e
Forward do navegador.
• void stop():
Chamado automaticamente sempre que o navegador sair da
página que contém a applet.
Isto é, chamado em resposta à pressão dos botões Back e
Forward do navegador.
• void destroy():
Chamado quando a página não for mais alcançável.
É usado para liberar recursos não mais necessários.
• void paint(Graphics g):
chamado automaticamente pelo sistema de janela quando o
componente tiver que ser (re)exibido.
APPLET SOMADOR(AddtionApplet.html)
1 <html>
2 <hr>
3 <h2>Applet ilustra entrada e saida de
4 dados via browser</h2>
5
APPLET SOMADOR(AddtionApplet.java)
1 import java.awt.Graphics;
2 import javax.swing.*;
3 public class AdditionApplet extends JApplet {
4 double sum; // sum of values entered by user
5
TRANSFERINDO PARÂMETROS
• No arquivo anagrama.html:
462 CAPÍTULO 15. APPLETS
1 ...
2 <applet code="Anagrama.class" width=500 height=500>
3 <param name="objetivo" value="surfando na rede">
4 <param name="palavras" value="palavra.txt">
5 <param name="tamanho" value="2">
6 <param name="valor" value="3.14">
7 </applet>
8 ...
• No arquivo Anagrama.java:
1 String s1 = getParameter("tamanho");
2 int k = Integer.parseInt(s1);
3 String s2 = getParameter("objetivo");
4 String s3 = getParameter("valor");
5 double d = Double.valueOf(s3).doubleValue();
QUADRO DA CALCULADORA
1 class CalculatorFrame extends JFrame {
2 public CalculatorFrame() {
3 setTitle("Calculator");
4 setSize(200, 200);
5 addWindowListener(new WindowAdapter( ) {
6 public void windowClosing(WindowEvent e){
7 System.exit(0);
8 }
15.4. EXEMPLOS DE APPLETS 463
9 } );
10
CONSTRUTOR DE CalculatorPanel
1 public CalculatorPanel() {
2 setLayout(new BorderLayout());
3 display = new JTextField("0");
464 CAPÍTULO 15. APPLETS
4 display.setEditable(false);
5 add(display, "North");
6 JPanel p = new JPanel();
7 p.setLayout(new GridLayout(4, 4));
8 String buttons = "789/456*123-0.=+";
9 for (int i = 0; i < buttons.length(); i++)
10 addButton(p, buttons.substring(i, i + 1));
11 add(p, "Center");
12 }
MÉTODO addButton
1 private void addButton(Container c, String s) {
2 JButton b = new JButton(s);
3 c.add(b);
4 b.addActionListener(this);
5 }
MÉTODO actionPerformed
1 public void actionPerformed(ActionEvent evt) {
2 String s = evt.getActionCommand();
3 if (’0’<=s.charAt(0)&&s.charAt(0)<=’9’||s.equals(".")){
4 if (start) display.setText(s);
5 else display.setText(display.getText() + s);
6 start = false;
7 } else {
8 if (start) {
9 if (s.equals("-")){
10 display.setText(s); start = false;
11 }
12 else op = s;
13 } else {
14 double x = Double.parseDouble(display.getText());
15 calculate(x); op = s; start = true;
16 }
17 }
18 }
15.4. EXEMPLOS DE APPLETS 465
MÉTODO Calculate
1 public void calculate(double n) {
2 if (op.equals("+")) arg += n;
3 else if (op.equals("-")) arg -= n;
4 else if (op.equals("*")) arg *= n;
5 else if (op.equals("/")) arg /= n;
6 else if (op.equals("=")) arg = n;
7 display.setText("" + arg);
8 }
A PÁGINA DA CALCULADORA
1 <HTML>
2 <TITLE> Uma Calculadora </TITLE>
3 <BODY>
4 Eis aqui uma calculadora.
5 <HR>
6
10 <HR>
11
12 </BODY>
13 </HTML>
CAlCULADORA APPLET
7 }
8 }
APPLETS X SEGURANÇA
15.5 Exercı́cios
Considerações Finais
469
470 PROGRAMAÇÃO MODULAR A Linguagem Java
Bibliografia
Rótulos, 32 Exceção
Repetição, 23 Não-Verificada, 186
do-while, 23 Verificada, 186
for, 23, 29 Expressão, 11
for Aprimorado, 23, 31 Aritmética, 11
while, 23, 28 Booleana, 13
Retorno, 23 Condicional, 11, 13
return, 23, 35 Curto-Circuito, 4
Constante Lógica, 11
Decimal, 5 Regular, 225
Hexadecimal, 6
Octal, 6 Genericidade, 293
Simbólica, 10, 99 Classe Genérica, 296
Conversão de Tipos, 9 Interface Genérica, 304
casting, 10 Limite Superior, 305
Desempacotar, 241, 301 Método Genérico, 294
Empacotar, 241, 301 Herança, 50, 111
Numéricos, 10 Especialização, 112
Coordenadas Generalização, 112
Cartesianas, 104 Múltipla, 171, 177
Polares, 104 Simples, 170, 176
Delegação, 177 Subtipos, 112
Hierarquia
Efeito Colateral, 24
de Genéricos, 302
efeito colateral, 4
de Tipos, 91
Encapsulação, 50
Interfaces, 99
Escopo
Subclasses, 111
de Declaração, 25
Subtipos, 92
de Declarações, 46
Supertipos, 92
de Nome, 45
Ocultação de nomes, 24 IEEE 754, 5, 9
ÍNDICE REMISSIVO 481
Visibilidade
Controle, 58
Modificador de Acesso
private, 245, 269
protected, 245, 269
public, 245, 269
pacote, 245