Escolar Documentos
Profissional Documentos
Cultura Documentos
Versão: 1.0
Autor:
Ermínio Jasse
Colaboradores:
Elpídio Maúnde
Fevereiro de 2013
FUNDAMENTOS DE PROGRAMAÇÃO
Bibliografia
Caelum. 2005.Java e Orientação à Objectos. 2005.
1
Índice
Bibliografia ................................................................................... 1
1 Introdução a Linguagem de Programação Java ................................ 5
1.1 Origem ..................................................................................................................... 5
1.2 Porquê Java? ............................................................................................................. 6
1.3 Características da Linguagem Java ............................................................................ 6
1.4 Ambiente de Desenvolvimento Java .......................................................................... 8
1.4.1 Java IDE ( Java Integrated Development Environment ) .................................... 8
2
4.7 Pacote (package) ......................................................................................................54
4.8 Sugestão de desenho de classes ................................................................................55
3
7 Array de Objectos – Algoritmos de Ordenação e Pesquisa .............. 87
7.1 Ordenação de Array de tipos primitivos ...................................................................87
7.1.1 Ordenação por selecção ....................................................................................87
7.1.2 Ordenação de Array de Objectos ......................................................................90
7.2 Pesquisa...................................................................................................................96
7.2.1 Pesquisa Linear (linear Search) ........................................................................96
7.2.2 Pesquisa Binária (binary Search) ......................................................................99
8 Ficheiros .....................................................................................102
8.1 Fluxo de dados e Ficheiros .....................................................................................102
8.2 Excepção ...............................................................................................................103
8.2.1 Tratamento de Excepção ................................................................................104
8.2.2 Apanhar uma excepção ..................................................................................106
8.2.3 Utilização da palavra reservada throw ............................................................107
8.3 Ficheiro de Texto ...................................................................................................107
8.3.1 Ficheiro de Entrada ( input files) ....................................................................108
8.3.2 Ficheiro de Saída ( output files ) .....................................................................112
8.4 Análise de dados com StreamTokenizer .................................................................117
8.5 Ficheiros de Objectos.............................................................................................121
8.5.1 Serialização ....................................................................................................121
8.5.2 Ficheiro de saida ............................................................................................123
8.5.3 Ficheiro de entrada .........................................................................................125
4
Capítulo 2 – Estruturas Principais da Programação JAVA
1. Origem
2. Porquê Java?
3. Características
4. Ambiente de desenvolvimento
1.1 Origem
Em 1992 a Sun criou umaequipe (conhecida como Green Team) para desenvolver inovações
tecnológicas. A equipe foi liderada por James Gosling, considerado o pai do Java. A equipe voltou
com a idéia de criar um interpretador (já era uma máquina virtual, veremos o que é isso mais a
frente) para pequenos dispositivos, facilitando a reescrita de software para aparelhos electrônicos,
como vídeo cassete, televisão e aparelhos de TV a cabo.
A idéia não deu certo. Tentaram fechar diversos contractos com grandes fabricantes de aparelhos
eletrônicos, como a Panasonic, mas não houve êxito devido a conflitos de interesses e custos. Hoje,
o Java domina o mercado de aplicações para telefones celulares com mais de 2.5 bilhões de
dispositivos compatíveis, porém em 1994 ainda era muito cedo para isso.
Com o advento da web, a Sun percebeu que poderia utilizar a idéia criada em 1992 para rodar
pequenas aplicações dentro do browser. A semelhança era que na Internet havia uma grande
quantidade de sistemas operativos e browsers, e com isso seria uma grande vantagem poder pro-
gramar numa única linguagem, independente da plataforma. Foi aí que o Java 1.0 foi lançado:
focado em transformar o browser de apenas um cliente fino (thin client ou terminal burro) para
uma aplicação que possa também realizar operações, não apenas renderizar html.
Actualmente os applets realmente não são o foco da Sun. É curioso notar que a tecnologia Java
nasceu com um objetivo em mente, foi lançado com outro, mas, no final, decolou mesmo no
desenvolvimento de aplicações do lado do servidor. Sorte? Talvez!!!
Em 2009 a Oracle comprou a Sun, fortalecendo a marca. A Oracle sempre foi, junto com a IBM,
uma das empresas que mais investiram e fizeram negócios através do uso da plataforma Java
(Caelum, 2005).
5
Capítulo 2 – Estruturas Principais da Programação JAVA
Simple Simples
Robust Forte
Secure Seguro
Portable Portátil
Interpreted Interpretado
Dynamic Dinâmico
Orientada à Objectos
Java é uma linguagem voltada para a programação orientada a objectos e, por isso, todo o código
está contido dentro de classes.
Java suporta herança simples, mas não herança múltipla. A ausência de herança múltipla pode ser
compensada pelo uso de herança e interfaces, onde uma classe herda o comportamento de sua
superclasse além de oferecer uma implementação para uma ou mais interfaces.
Compilada e Interpretada
Todo programa Java é compilado e interpretado. Um programa em Java é compilado para um
código composto por instruções chamadas “bytecode”. O “bytecode” é um código de uma máquina
6
Capítulo 2 – Estruturas Principais da Programação JAVA
virtual, chamada Máquina Virtual Java (Java Virtual Machine - JVM), idealizada pelos criadores
da linguagem. Os bytecodes são independentes da plataforma e são interpretados pela JVM para
serem executados no computador.
Todo o interpretador Java ou browser que execute applets Java é uma implementação de uma
Máquina Virtual Java. A JVM também pode ser implementada em hardware.
Além da JVM, a plataforma Java é composta também pelo Java Application Programming
Interface (Java API). A API Java é uma grande colecção de componentes de software
disponibilizados que fornecem muitas capacidades interessantes e úteis, tais como, componentes
de interface gráfica, conexão via sockets, entre outros. A API Java é agrupada em bibliotecas
(packages ou pacotes ) de componentes relacionados.
O código Java é compilado (criação de bytecode) uma única vez, porém o programa (o bytecode
criado) é interpretado toda vez que for executado. Esse processo pode ser melhor visualizado na
figura a seguir:
PROGRAMA JAVA
public class HelloWorld {
System.out.println(“Helllo, World”);
HelloWorld.java
Compilador
HelloWorld.class
7
Capítulo 2 – Estruturas Principais da Programação JAVA
Nota: Tanto o JRE e o JDK podem ser descarregados do site http://java.sun.com, hoje gerido pela
Oracle. Para encontrá-los, acesse o link Java SE dentro dos top downloads.
• JVM = apenas a Virtual Machine, esse download não existe, ela sempre vem
acompanhada.
• JRE = Java Runtime Environment, ambiente de execução Java, formado pela JVM e
bibliotecas, tudo que é necessário para executar uma aplicação Java. Mas nós precisamos
de mais.
• JDK = Java Development Kit: Nós, desenvolvedores, faremos o download do JDK do Java
SE (Standard Edition). Ele é formado pela JRE somado a ferramentas, como o compilador.
Após instalar o necessário, podemos escrever os nossos programas em qualquer editor de texto,
como Notepad, Wordpad, etc., e salvar o ficheiro com a extensão (.java), e de seguida compilar
os programas e interpretá-los.Tudo isso é possível através da linha de comando porém, para
facilitar o desenvolvimento dos programas, utilizaremos uma IDE (Integrated Development
Environment).
A resposta para a questão acima é Não. Podemos usar qualquer outro editor de texto que possua
syntax highlighting ou outros recursos.
Obs: É sempre bom começar por correr os programas de forma “tradicional”, pois, devemos nos
acostumar com os erros de compilação para melhor aprendermos o Java.
Hoje em dia existem muitos IDE’s gratuítos para o Java. Um dos mais utilizados e que
recomendamos actualmente é o Netbeans (http://netbeans.org/downloads/), mas pode também usar
o eclipse (http://www.eclipse.org/downloads/) que é bastante semelhante.
8
Capítulo 2 – Estruturas Principais da Programação JAVA
Os passos iniciais para desenvolver um programa em java com o Netbeans IDE, podem ser vistos
no seguinte endereço: http://netbeans.org/kb/docs/java/quickstart.html
Hello, World!
9
Capítulo 2 – Estruturas Principais da Programação JAVA
De forma resumida podemos afirmar que Java é multiplataforma ou seja, os programas nele
escritos são executados independentemente do sistema operativo instalado na máquina.
1. Espaço em Branco
10
Capítulo 2 – Estruturas Principais da Programação JAVA
Java é uma linguagem de formato livre. Não é necessário indentar para que ela funcione
correctamente. Por exemplo, o nosso programa HelloWorld poderia ser escrito da seguinte
maneira:
Devemos, porém, tomar cuidado para que haja pelo menos um espaço, Tab ou uma nova linha
entre palavras que não estejam separadas por um operador ou separador. Como boa prática de
programação, é sempre bom manter espaços entre os métodos, variáveis, intruções, etc. de modo
a ter um código mais organizado e legível.
2. Comentários em Java
Os comentários em código-fonte Java podem ser de 3 tipos:
O comentário de várias linhas é usado para comentários mais longos que uma linha, e é iniciado
com “/*” (barra-asterísco) e finalizado com “*/” (asterísco-barra). Tudo que estiver entre “/*” e
“*/” é considerado como sendo comentário e, portanto, ignorado pelo compilador.
11
Capítulo 2 – Estruturas Principais da Programação JAVA
2.2 Identificadores
Identificadores são palavras usadas para nomes de classes, métodos e variáveis. Um identificador
pode ser qualquer sequência de caracteres de letras maiúsculas e minúsculas, números e caractere
de sublinhado e símbolo de cifrão. Mas, tome os seguintes cuidados:
• Eles não podem começar com números para não serem identificados como literais
numéricos;
• Java é sensível a maiúsculas/minúsculas. Assim, o identificador Valor é diferente de valor.
b) Constantes
As constantes (variáveis finais), são declaradas usando letras maiúsculas (todo o nome). Para as
constantes formadas por mais de um termo, usa-se underscore para separá-los. Os nomes de
constantes Java são formados por substantivos e adjectivos.
c) Classes
12
Capítulo 2 – Estruturas Principais da Programação JAVA
Nomes de classes são escritos em minúsculo com a primeira letra em maiúscula. Para os nomes
compostos por mais de um termo, usa-se underscore para separá-los e cada novo termo deve
começar com letra maiúscula. Os nomes de classes são formados por substantivos e adjectivos.
Exemplos: InterfaceSimples, Interface.
13
Capítulo 2 – Estruturas Principais da Programação JAVA
As variáveis globais não inicializadas recebem por default o valor 0 (zero). As variáveis locais
(dentro de métodos) não são inicializadas por default e, por isso, é gerado um erro de compilação
quando não é atribuído nenhum valor inicial a elas e essas são acessadas.
O seguinte programa cria variáveis de cada tipo primitivo e exibe seus valores:
public class SimpleTypes {
byte b = 5;
short s = 5;
int i = 334;
long l = 34567l;
float f = 35.76f;
double d = 35.76;
System.out.println("byte b = " + b);
}
}
2.5 Constantes
Em Java não podem ser definidas constantes locais para um determinado método como, por
exemplo, para o main. Ao invés disso, pode haver somente constantes para todos os métodos na
classe. Elas são chamadas usualmente de constantes da classe. As constantes são sempre definidas
através dos modificadores static final. Por exemplo:
2.6 Operadores
Os operadores aritméticos só podem ser usados para operandos do tipo numérico. Esses operadores
não podem ser usados para os tipos boolean, mas podem para char, uma vez que char é um
subconjunto do tipo int.
15
Capítulo 2 – Estruturas Principais da Programação JAVA
Operador Operação
== Igual a
!= Diferente de
> Maior que
< Menor que
>= Maior ou igual que
<= Menor ou igual que
Os operadores relacionais sempre retornam um valor boolean (true ou false) como resultado. Por
exemplo:
int a = 4;
int b = 1;
boolean c = a < b;
O trecho de código acima mostra duas variáveis (a e b) sendo comparadas e a variável c recebendo
como resultado o valor booleano, no caso, false.
Operador Resultado
&& AND lógico
|| OR lógico
! Negação
Prioridade Operadores
Mais alta Casting
++, --, (prefixa)
16
Capítulo 2 – Estruturas Principais da Programação JAVA
*, /, %
+, -
<, <=, >, >=
==, !=
&&
||
=, +=, -=, *=, /=, %=
Mais baixa ++, --(postfixa)
Em java, a classe Math fornece um conjunto de funções e constantes. A sintaxe da utilização dessas
é escrevendo o nome da função ou constante prefixado com o nome da classe, isto é, Math. Por
exemplo:
Nota: A classe Math tem duas constantes Math.PI e Math.E ( número π e o número e )
17
Capítulo 2 – Estruturas Principais da Programação JAVA
Mas em alguns casos pode ser necessário converter, por exemplo, um double em um inteiro. Toda
conversão numérica em Java é possível, mas informações podem ser perdidas. Estas conversões
podem ser realizadas com o uso de casting. A sintaxe do casting é colocar o tipo desejado entre
parêntesis antes do nome da variável. Por exemplo:
double x = 9,997;
int nx = (int) x;
Java permite ainda que certas conversões sejam feitas pela atribuição de valores de um tipo para
outro sem que seja necessário o uso de casting. As conversões permitidas de forma automática
pelo compilador são:
Você pode atribuir o valor de uma variável que está à esquerda para aquela do tipo que está à
direita.
Muito embora os chars não sejam usados como inteiros, você pode operá-los como se fossem
inteiros. Desta maneira, é necessário o uso de casting para converter inteiros em caracteres.
Caracteres podem ser considerados inteiros sem o uso de casting. Por exemplo:
int tres = 3;
char um = '1';
char quatro = (char) (tres+um);
18
Capítulo 2 – Estruturas Principais da Programação JAVA
A variável quatro finaliza com o valor ‘4’ armazenado nela. Observe que um foi promovido para
int na expressão, exigindo a definição de tipo de char antes da atribuição para a variável quatro.
Se você deseja que uma variável inteira receba o valor inteiro que um determinado caractere
representa, você pode usar o método digit (char c, int i) da classe Character, onde passamos como
parâmetro o caractere e a base de conversão (binária,decimal, etc). Para o contrário, converter um
inteiro para um caractere que represente aquele inteiro, utilize o método forDigit (int i, int j) onde
o primeiro parâmetro representa o valor inteiro a ser convertido e o segundo parâmetro a base de
conversão. O exemplo abaixo ilustra essas conversões:
No Java, a partir do Java 1.5 ou J2SE 5, que recebeu o codinome "Tiger", está disponível a classe
Scanner do pacote java.util. Essa classe implementa as operações de entrada de dados pelo
teclado no console.
Para utilizar a classe Scanner em uma aplicação Java deve-se proceder da seguinte maneira:
19
Capítulo 2 – Estruturas Principais da Programação JAVA
20
Capítulo 2 – Estruturas Principais da Programação JAVA
import javax.swing.JOptionPane;
/* NOTA
* Aqui, nós ainda não tratamos Excepções e Thread, portanto podem
ocorrer erros.
* por exemplo, se o utilizador não introduzir o nome (clicar OK sem
ter escrito nada),
* ou clicar em CANCEL. outro erro que pode ocorrer é se o utilizador
introduzir no campo age
* com erro, ou seja, escrever 19 years (no campo age só se quer o
valor númerico, 19 no caso)
*
* O tratamento de Excepções e Threads está na Programação Orientada
a Objectos
*/
public class LeituraDados {
public static void main(String[] args) {
21
Capítulo 2 – Estruturas Principais da Programação JAVA
}
}
O programa apresenta 2 vezes a caixa de diálogo sendo que pela 1ª vez, pergunta o nome, e pela
2ª, a idade. O utilizador deverá introduzir correctamente os dados e clicar em OK.
Se o utilizador introduz FILZA AZIZE como nome e 22 como idade, obteremos como output do
programa a seguinte informação:
Dica: teste o programa várias vezes, com dados diferentes, e também com dados incorrectos para
ver a saída.
Passo a passo:
2. Declare um String para receber o que o utilizador escreve na caixa de texto, por exemplo:
String name = JOptionPane.showInputDialog("What is your name?");
3. Se os dados forem String (name, por exemplo) utilizamos directamente esse input.
Mas se os dados representam um valor numérico, devemos converter o input (sempre é String)
para o valor numérico. Concretamente se o valor for:
22
Capítulo 2 – Estruturas Principais da Programação JAVA
2. Formatação de Saída[opcional]
Java imprime o valor double com até 15 dígitos significativos. Em alguns casos uma
representação de muitos dígitos na parte da fracção é redundante. Para limitar o número de
dígitos na parte da fracção podemos utilizar a classe java.text.NumberFormat como é ilustrado
no seguinte exemplo:
import java.text.NumberFormat;
---------------------------
double x = 1000.0/3.0;
NumberFormat formatter = NumberFormat.getNumberInstance();
formatter.setMaximumFractionDigits(4); //no máx 4 dígitos da parte
fracc.
formatter.setMinimumFractionDigits(4); //no mim 4 dígitos da parte
fracc.
String s = formatter.format(x);
System.out.println("X before
formatting:"+x);//333.33333333333333333333333333
System.out.println("X after formatting:"+s);//333.3333
------------------
23
Capítulo 3 – Estruturas de Controle do JAVA
1. Blocos de Instruções;
2. Instruções Condicionais;
3. Multiselecções Switch;
4. Estruturas de Repetição - Ciclos
5. Array
6. String
3.1 Blocos
Um bloco de instruções, ou ainda, uma instrução composta, é um conjunto de instruções que fica
dentro de um par de chavetas { e };
//um bloco
{
Instrução1;
Instrução2;
………………………
}
Os blocos podem ser encaixados. Um fica totalmente dentro do outro.
1. Primeira forma
if (condição) instrução;
24
Capítulo 3 – Estruturas de Controle do JAVA
if ( x >= 0 ) y = Math.sqrt( x );
//assim, se x < 0, não se faz NADA!
2. Segunda forma
if ( condição ) instrução1; else instrução2;
Execução: se a condição for verdadeira, executa a instrução1, caso contrário executa a instrução2.
Na posição de cada instrução pode conter um bloco ou vazio. Antes do else há símbolo de ponto e
vírgula (; else), diferentemente da Programação em Pascal.
Exemplo:
Else oscilante
Se na posição da instrução1 e instrução2 (ou blocos nessas posições) houver uma outra instrução
if, então as instruções if são encaixadas, diz-se que o else oscila entre o primeiro e o segundo if.
Consideramos um exemplo:
System.out.println(classificacao);
Nota : O java sempre associa um else com o if imediatamente anterior encontrado no mesmo
contexto (bloco de programação).
25
Capítulo 3 – Estruturas de Controle do JAVA
O identificador selector deve ser uma variávelde um tipo ordenável ( byte, short, int, char).
Portanto,long, double e float estão fora desta lista. O funcionamento do switch é o seguinte:
• Se o selector tem valor = VALOR1, executa a instrução1
• Se o selector tem valor = VALOR2, executa a instrução2
• ---------------------------------------------------------
• Se o selector tem valor = VALORn, executa a instruçãon
• Caso contrário, isto é, se o selector tiver um valor diferente de todos os valores (VALOR1,
VALOR2, …, VALORn), executa-se a instrução Default.
Notas:
A instrução break não é obrigatória, se tirá-la, a execução continua até encontrar uma instrução
break.
O valores VALOR1, VALOR2, …, VALORn, devem ser do mesmo tipo do selector mas deve ser
diferentes no seu valor.
A instrução default é opcional, no entanto, é bom utilizá-la no caso em que o selector receba um
valor diferente de todos os valores que o programador prevê.
Na posição de cada instrução, pode haver um bloco.
Exemplo:
Calculamos o último dia de um mês do ano de 2013 ( não bissexto ).Sabemos que os meses 1, 3,
5, 7, 8, 10 e 12 têm 31 dias. Os meses 4, 6, 9 e 11 têm 30 dias, o mês 2 tem 28 dias. A utilização
de uma instrução switch neste caso é ideal. O utilizador introduz o mês (um número de 1 a 12 ).
O programa imprime o último dia daquele mês introduzido.
26
Capítulo 3 – Estruturas de Controle do JAVA
import javax.swing.JOptionPane;
switch (mes) {
case 1: ultimodia = 31; break;
case 2: ultimodia = 28; break;
case 3: ultimodia = 31; break;
case 4: ultimodia = 30; break;
case 5: ultimodia = 31; break;
case 6: ultimodia = 30; break;
case 7: ultimodia = 31; break;
case 8: ultimodia = 31; break;
case 9: ultimodia = 30; break;
case 10: ultimodia = 31; break;
case 11: ultimodia = 30; break;
case 12: ultimodia = 31; break;
//o utilizador pode digitar um mes errado, para alertá-lo:
default: System.out.println(" o mês deve ser de 1 a 12");
}
System.out.println("O mes " + mes + " de 2013 tem " + ultimodia + "
dias ");
System.exit(0);
}
}
switch ( mes ) {
27
Capítulo 3 – Estruturas de Controle do JAVA
3.4 Ciclos
1. Ciclos indeterminados
O número de repetições não se conhece.
O Java tem duas formas de ciclos indeterminados.
a) while
//execução
Enquanto a condição for verdadeira executa a instrução
b) do … while
//execução
Executa a instrução enquanto a condição for verdadeira
Nota1: O que diferencia as duas formas de ciclos indeterminados? Na forma a) o bloco só pode
ser executado após a verificação da condição, enquanto que na forma b) o bloco é executado pelo
menos uma vez, pois, a condição é verificada apenas no fim.
Nota2: O programador deve alterar a condição dentro do bloco de modo que faça o ciclo ser
finito.
Exemplo:
s +=i;
i++;
}
System.out.println(“SUM=” +s);//saída: SUM=45
Exemplo:
char ch = ‘A’;
do {
System.out.println(ch);
ch++;
} while(ch < ‘Z’);
Saída: as letras de A a Z.
Atenção!
Como ch é variável do tipo char ( ordenável ), então, é legal a instrução ch++,ou seja, é possível
obter o próximo caractere dado um já existente.
2. Ciclos determinados
Os ciclos determinados tem números de repetições bem conhecido. A sintaxe de um ciclo
determinado é a seguinte:
for ( v = valor inicial; condição de continuação; ajustamento ) {
corpo do ciclo
Sendo que:
• v é uma variável denominada variável de controlo;
• Valor inicial é uma expressão numérica que atribui o valor inicial para a variável v.
• Condição da continuação é uma expressão booleana que determina a
continuação/terminação da execução do ciclo.
• Ajustamento é uma instrução que ajusta o valor da variável de controlo.
Usando as 3 grandezas valor inicial; condição da continuação; ajustamento pode se calcular o
número de repetições do ciclo.
29
Capítulo 3 – Estruturas de Controle do JAVA
Exemplos:
Exemplo 1.
int i;
Este ciclo imprime os dígitos de 0 a 9. A variável de controle é i, o corpo do ciclo tem só uma
instrução System.out.println(i); o valor inicial de i é zero, pelo ajustamento i++, depois de cada
repetição do corpo do ciclo, i aumenta o seu valor acrescentando +1 até chegar a 10, a condição de
continuação i < 10 se torna false e então o ciclo termina.
Exemplo 2.
for ( int i = 0; i < 10; i++ ) System.out.println(i);
Este ciclo imprime as mesmas informações como no exemplo anterior. A diferença entre os dois,
está na declaração da variável de controlo i. No exemplo 1 ela é global em relação ao ciclo, ou
seja, o valor de i pode ser utilizado após o término do ciclo. No exemplo 2, i é local dentro do
ciclo, quando terminar o ciclo, i não existe mais. Esta segunda utilização é mais segura e é mais
recomendada.
3. Ciclos encaixados
Se no corpo do ciclo há um outro ciclo, os ciclos são encaixados. Por exemplo, considere o código:
O ciclo com a variável com controlo k está dentro do ciclo com a variável de controlo i.
30
Capítulo 3 – Estruturas de Controle do JAVA
1 2 3 4
2 4 6 8
3 6 9 12
Os valores são imprimidos com separações de um tab (‘\t’). por defeito tab = 8 espaços.
3.5 Array
Um array é uma colecção de valores de um mesmo tipo de dados. Um array pode ter uma dimensão
ou muitas dimensões. Cada elemento do array é considerado como uma variável do mesmo tipo
que o elemento tem. Assim, pode-se fazer as operações que esse tipo aceita, com o elemento.
tipo_de_dado [] nome_da_variável;
//por exemplo:
int[] a; //a é array unidimensional podendo armazenar números inteiros
int[] a = new int[100]; //array tem memória para conter até 100 inteiros
Os elementos do array são enumerados com índices começando de 0, assim, os elementos do array
acima criado têm indices de 0 à 99.
31
Capítulo 3 – Estruturas de Controle do JAVA
nome_do_array.length;
por exemplo, para imprimirmos todos os elementos do array smallPrimes acima inicializado,
podemos escrever:
nome_do_array[indice];
sendo 0 ≤ índice ≤ length-1
g) Array anónimo. É possível criar um array sem nome como no seguinte exemplo:
Este array é criado na memória , e não tem nome. O array anónimo é utilizado nalguns casos onde
se necessita só de valores mas não tem nome do array.
h) Atribuição de array
anyArr 17
19
smallPrimes
23
29
31
37
É preciso ter atenção que depois de fazer essa atribuição, smallPrimes deixa de apontar para os
seus valores antigos e passa a apontar para os mesmos valores para os quais o array anyArr aponta.
32
Capítulo 3 – Estruturas de Controle do JAVA
A memória alocada para smallPrimes torna-se inútil. Agora qualquer alteração sobre um dos dois
arrays implica a alteração do outro.
Nota: se quiser copiar 4 elementos apartir do 2º elemento do array A para outro array B,
colocando a copia no B apartir da 5ª posição, pode usar a seguinte instrução:
System.arraycopy(A, 2, b, 5, 4);
1 2 3 4
2 3 4 5
3 4 5 6
4 5 6 7
Atribuição do valor 2 para o elemento da linha 2 coluna 3: matriz [2] [3] = 2;
3.6 String
String é uma sequência de caracteres. Um valor do tipo String é dado dentro de aspas “” , por
exemplo, “Bom dia”. String em java é um objecto, isto é, é uma variável ou uma instância da
classe String. A seguir alguns exemplos sobre String.
Exemplo:
Exemplo:
• Comparação de String
Atenção, com o operador == não se pode comparar Strings. Ele faz saber se 2 Strings apontam
para um mesmo lugar da memória ( para um mesmo objecto ).
34
Capítulo 3 – Estruturas de Controle do JAVA
Para saber se o conteúdo do String st1 é igual ao conteúdo do String st2, deve-se utilizar o método
equals como no exemplo seguinte:
st1 = “PASSWORD”;
Nota: String tem muita utilização em qualquer linguagem de programação. Em java podemos
utilizar até 3 classes sobre String.
public class StringTokenizer contém serviços que permitem a análise do String. Classe útil para
quem quer fazer compiladores.
35
Capítulo 4 – Classes e Objectos
4 Classes e Objectos
Resumo Teórico
1. Objecto
Alguma coisa como televisor, mesa, carro, peixe, pessoa, conta bancaria,… é um objecto. Cada
objecto possui seus atributos como cor, tamanho, idade, profissão, dependendo do tipo de objecto
e comportamento como uma pessoa pode falar, trabalhar e um carro pode arrancar, acelerar e
travar.
2. Encapsulamento
36
Capítulo 4 – Classes e Objectos
3. Herança
É a possibilidade de criar um novo objecto existente. O novo objecto herda todos os dados e
comportamentos do antigo objecto (o pai dele) e pode ter novos dados alem dos herdados e
comportamentos diferentes dos do seu pai, para tal utiliza-se a palavra reservada extends.
Finalmente, o que deve fazer um programador OOP? É simples: ele deve criar objectos com dados
e métodos bem específicos, e mandar executar métodos numa ordem que o programa necessita.
Logo a seguir, entendemos que cada objecto é uma instância (instance) de uma classe. E então, o
programador OOP deve saber escrever suas classes.
Em palavras, uma classe é iniciada com a palavra reservada class seguido imediatamente de um
nome que é chamado nome da classe. A classe pode ter muitos campos de dados e muitos métodos,
tudo fica dentro de um par de chavetas.
A posição dos campos de dados e dos métodos é sensível, isto é, os campos de dados podem ficar
antes ou depois dos métodos. Para as “grandes” classes, frequentemente os métodos vêm antes
dos dados, isso porque se a classe é já completa os clientes da classe só se interessam pelo que a
classe pode fazer. Mas numa classe em elaboração, ébom é recomendável que os campos de dados
fiquem antes dos métodos, porque a implementação dos métodos depende significantemente dos
dados.
Exemplo:
Definimos o Trabalhador, um objecto que tem um nome e um salario. Uma versão mais simples
pode ser:
class Trabalhador{
37
Capítulo 4 – Classes e Objectos
//alguns metodos
public Trabalhador( String seuNome, double seuSalario)
{ nome=seuNome; salario=seuSalario;}
Ambas as variantes são equivalentes e criam um trabalhador com o nome Luis e um salario
3000.0 (meticais por exemplo). Agora luis aponta para uma área da memória que armazena uma
String “Luis” e um double 3000.0.
É de notar que, aqui já utilizamos o primeiro método da classe. Esse método tem o mesmo nome
da classe, chamaremos daqui em diante qualquer método que tem o mesmo nome da classe por
construtor da classe. Então a sintaxe de criação de objectos é a seguinte:
new Contrutor(com ou sem parametros) //onde o construtor tem o nome da classe
1. Exemplo de utilização de classe e objectos no programa
a) Variante I:Usando uma classe aumentando o método mais.
//Classe Estudante
38
Capítulo 4 – Classes e Objectos
//metodo construtor
this.notaFrequencia = notaFrequencia;
return nome;
return notaFrequencia;
39
Capítulo 4 – Classes e Objectos
System.out.println("Estudante:
"+ana.getNome()+'\n'+"Nota de Frequencia:
"+ana.getNotaFrequencia());
System.out.println("Estudante:
"+ana.getNome()+'\n'+"Nota de Frequencia:
"+ana.getNotaFrequencia());
Nesta variante tira-se o método main da classe Estudante na variante I pondo-o noutra classe.
Concretamente tem-se 2 seguintes classes.
40
Capítulo 4 – Classes e Objectos
//criação do objecto
4.2.1
System.out.println("Estudante:
"+ana.getNome()+'\n'+"Nota de Frequencia:
"+ana.getNotaFrequencia());
4.2.2
4.2.3
System.out.println("Estudante:
"+ana.getNome()+'\n'+"Nota de Frequencia:
"+ana.getNotaFrequencia());
41
Capítulo 4 – Classes e Objectos
//metodo construtor
this.notaFrequencia = notaFrequencia;
return nome;
return notaFrequencia;
42
Capítulo 4 – Classes e Objectos
Nota: Aqui temos também 2 variantes sobre o assunto: onde estão os ficheiros que guardam o
conteúdo de cada classe EstudanteTesta e Estudante? Na primeira variante é para usar 2 ficheiros:
No caso geral, usam-se construtores para entregar o estado inicial aos objectos.
Overloading ocorre quando muitos métodos têm um mesmo nome e têm diferença nos parâmetros
( em quantidade, tipo, ou ordem de parâmetros ). Se a classe tem mais do que um constructor, os
constructores são overloading. Mas overloading pode ocorrer com qualquer método java.
Ter muitos constructores numa classe permite criar objectos da classe com vários estados iniciais
diferentes.
43
Capítulo 4 – Classes e Objectos
Java não inicializa por defeito para variável local dentro dos métodos.
• Se o programador escrever uma classe com nenhum construtor, java oferece a classe o
construtor por defeito, esse construtor inicializa todos os campos de dados por defeito.
• Se a classe já tem pelo menos um construtor mas não tem o construtor por defeito java não
oferece mais um construtor por defeito. Neste caso uma criação de objecto sem parâmetros
é ilegal.
• Utilizam-se construtores por defeito junto com métodos tipo setter ( métodos que
estabelecem novos valores aos campos dados para um objecto ) no momento necessário.
1. public - Se um membro é declarado modificador public, ele é público, isto é, ele é acedido
por qualquer cliente da classe.
2. protected – Um membro declarado com o modificador protected, é acessível ou visível na
classe actual e nas suas classes filhas (subclasses) e mais algumas classes (Veremos isso
nas próximas aulas práticas). O conceito de classe filha ou subclasse, será abordado no
capítulo que fala de herança.
3. private Se um membro é declarado com o modificador private, é acessível unicamente
pela classe actual, isto é, membros de outra classe não o podem aceder. É uma boa prática
utilizar o modificador private para proteger dados.
4. final - Esta palavra é frequentemente usada pela classe, constante e dados. Se um campo é
definido como final, depois de ser inicializado pelo construtor, não muda mais o seu valor
é constante. Se uma classe for declarada como final, ela não pode ser estendida por qualquer
razão. A classe String é declarada como final então não se pode estender.
5. static - Um campo static é compartilhado por todas as instâncias de uma classe (objectos),
isto é, há um único valor para esse campo, independentemente da quantidade de instâncias
existentes, mesmo que não haja nenhuma;
44
Capítulo 4 – Classes e Objectos
Temos:
Modificadores : public e static
Tipo de retorno : void
Nome do método : main
Lista de parâmetros : String[] args
Corpo do método : as instruções entre chavetas {//instruções}
Numa classe os métodos que retornam o valor de um campo de dados são métodos de acesso
(getter methods) e os que alteram valor de um campo são métodos de estabelecimento (setter
methods).
No desenho de classes os dados sempre definidos private, isto é, os clientes da classe não podem
aceder a dados privados. Mas em muitas situações de programação há necessidade de aceder aos
campos privados da classe.
45
Capítulo 4 – Classes e Objectos
Retomamos a classe Estudante, o campo nome é privado. Se o estudante tem uma conta bancária,
o banco não pode contacta-lo pelo nome, qualquer tentativa de chamar o Estudante pelo nome é
ilegal porque esse campo é privado.Neste caso a classe Estudante deve fornecer um método público
que permite aceder o campo nome:
Agora o cliente da classe Estudante já pode usar o campo nome mas não pode mudar esse campo.
É bom utilizar convenção java nos metodos de acesso e estabelecimento: use o prefixo get e set
respectivamente. Por exemplo:
3. Palavra-chave return
return expressão;
• É obrigatório usar o comando return no método em que o seu tipo de retorno é diferente
de void.
• Para um valor que não devolve nenhum valor (void), é possível usar return sem expressão
com o objectivo de terminar a execução do método.
• Pode usar tantas instruções return que forem necessárias. Mas o método termina assim que
é executado um return.
4. Chamadas de métodos
Um método entra em acção no momento em que é chamado. Isto pode ocorrer explicitamente ou
implicitamente. A chamada explícita se dá por ordem do programador através da execução de um
comando ou expressão contendo o nome do método.
A sintaxe da chamada é a seguinte:
Objecto.nome_metodo(lista de parâmetros actuais)
46
Capítulo 4 – Classes e Objectos
Java é diferente de algumas linguagens de programação, nas outras linguagens existe a passagem
por valor (pass-by-values) e a passagem por referência (pass-by-reference). Java tem só a
passagem por valor.
Só uma cópia do valor actual passa para o parâmetro formal, o valor passado não muda antes e
nem depois da passagem.
47
Capítulo 4 – Classes e Objectos
//Teste2:
System.out.println("-----------------------------");
System.out.println("Passagem de parametros - objectos do tipo
Empregado");
System.out.println("Teste outra vez: triploSalario(Empregado
x)");
48
Capítulo 4 – Classes e Objectos
}
}
class Empregado{
//Esta classe cria objectos para testar a passagem de parametros
com objectos
Este exemplo usa duas classes TestaParametros e Empregado para fazer dois testes, o primeiro
testa a passagem com parâmetro do tipo double. Imprimimos o valor do parâmetro taxa antes,
depois da chamada e dentro do método. Os resultados mostram que o valor da taxa não mudou
depois da chamada. No segundo teste, utilizamos um objecto da classe Empregado, o luis,
chamamos o método triploSalario(luis) deste objecto. Os resultados mostram que o campo salario
do luis mudou depois da chamada, isto é, o objecto – parâmetro actual, muda o seu estado na
passagem de parâmetros com objectos.
49
Capítulo 4 – Classes e Objectos
Saída do programa:
a) Dados estáticos
Se todos os objectos de uma classe têm um campo com valor em comum, pode declarar esse campo
com a palavra reservada static e o campo será designado por “variável da classe”, qualquer objecto
dessa classe pode aceder a esse campo de valor comum e todos ganham ou sofrem o efeito do
acesso.
Por exemplo, definimos um Aluno com atributos: nome, idade, e a cor do uniforme. É claro que,
o campo cor-de-uniforme é igual para todos os objectos Aluno. Uma boa solução é colocar este
campo como atributo da classe com a seguinte declaração:
50
Capítulo 4 – Classes e Objectos
Nome-da-classe.Nome-do-campo-estático ou
Objecto.Nome-do-campo-estático
Por exemplo, podemos imprimir a cor do uniforme com uma das duas instruções:
51
Capítulo 4 – Classes e Objectos
b) Métodos Estáticos
Se o método é declarado com o modificador static, ele é comum para todos os objectos da classe
e pode chamá-lo de forma semelhante ao do campo estático.
Nome-da-classe.Nome-do-método-estático ou
Objecto.Nome-do-metodo-estático
Exemplos:
A classe Math contém todos seus métodos estáticos. Para calcular xy por exemplo, escrevemos
Math.pow( x, y ) sendo Math o nome da classe, pow o nome do método.
O método main é estático. Isso é obrigatório, porque o programa inicia a sua execução com o
método main, e nessa altura, não existe nenhum objecto.
O seguinte programa ilustra o funcionamento dos campos e métodos estáticos. Ele cria um array
de 3 Trabalhadores, e chama os métodos estáticos e imprime o resultado no console. No programa
a variável da classe idSeguinte é inicializada com 1. O método estático getIdSeguinte() é usado
para contar quantos objectos criou-se até ao momento. Para isso, usa-se uma chamada ao método
setId();
O programa completo:
52
Capítulo 4 – Classes e Objectos
e.setId();
System.out.println("Nome="+e.getNome()+",
ID="+e.getId()+", Salario="+e.getSalario());
}
//Chamada ao metodo Static
int n = Empregado.getIdSeguinte();
System.out.println("O id seguinte sera: "+n);
}//End of main
}//End of class TestaStatic
class Empregado{
//Esta classe cria objectos para testar a passagem de parametros
com objectos
public Empregado(String aNome, double aSalario){
nome=aNome;
salario=aSalario;
}
public String getNome(){
return nome;
}
public double getSalario(){
return salario;
}
public void aumentoSalario(double taxa){
double aumento=salario*taxa/100;
salario=salario+aumento;
//o campo muda seu valor por esta instrucao
}
public int getId(){
return id;
}
public void setId(){
id=idSeguinte;
idSeguinte++;
}
public static int getIdSeguinte(){
return idSeguinte;
53
Capítulo 4 – Classes e Objectos
}
private String nome;
private double salario;
private int id;
private static int idSeguinte=1;//campo estatico
}
Para ter uma base de programação java, prestamos atenção aos seguintes (alguns) pacotes do Java.
• java.lang - Este pacote contém classes como Object, String, System, Math, Number,
Character, Boolean, Byte, Short, Integer, Long, Float, Double. É importado por defeito,
isto é, se o programador quiser fazer uso das classes do pacote java.lang não precisa
escrever a seguinte instrução:
import java.lang.*;
• java.awt - Este pacote contém classes para a programação gráfica (Frame, Panel, Button,
Menu, Font de caracteres, List, …)
• java.awt.event - Contém classes para tratar eventos de teclado, mouse, etc.
• java.swing – graphics user interface (GUI)
• java.applet – programação de animação para internet
• java.io – input, output de dados com ficheiros
• java.util – utilitários como data, calendário, moeda, zona mundial, vector, …
• java.net – programação para internet
2. Utilização de Pacotes
import java.util.*;
//usando .* para importar todas as classes do pacote java.util
//se o programa só precisa de uma classe do pacote, escreva o nome da classe:
import java.util.Date;
//importamos a classe apenas a classe Date do pacote java.util
54
Capítulo 4 – Classes e Objectos
Se o programador não define um pacote, o seu programa irá pertencer ao “default package” –
pacote por defeito.
4. Depois de tudo isso, poderá usar o seu pacote como qualquer outro pacote padrão do Java.
A classe deve utilizar o modificador private para os dados. Os clientes da classe não podem aceder
directamente aos dados da classe. Use esse modificador para os métodos usados apenas na própria
classe.
A classe deve fornecer os métodos de acesso e de estabelecimento aos clientes, mas só para os
dados e métodos que a classe “pensa” que podem ser fornecidos aos clientes.
Use o modificador static para os dados e métodos em comum para todos os objectos da classe. Por
exemplo, a constante Integer.MAX_VALUE é igual para todos objectos Integer, por isso essa é
estática. Ou ainda, o método parseInt() também não depende de nenhum objecto da classe Integer,
é portanto, estático.
A classe é uma fórmula (“molde”) para a criação de objectos. Seria bom dividir uma grande classe
em classes pequenas, de modo que cada uma delas tenha pouca responsabilidade. Um exemplo
típico, pela importância da utilização dos String, java tem até 3 classes para manipular Strings,
55
Capítulo 4 – Classes e Objectos
String, StringBuffer e StringTokenizer, que cada uma responsabiliza algumas manipulações com
String.
Forneça vários constructores a uma classe para permitir inicialização de objectos com diferentes
estados iniciais.
Use os recursos do Java: herança, interface, etc, de modo a agrupar campos e métodos e que duas
ou mais classes têm em comum, reduzindo assim a quantidade de código e melhorando a
manutenção do programa bem como outros benefícios
56
Capítulo 5 – Introdução aos Applets e Gráficos
A biblioteca AWT (Abstract Windows Toolkit) do Java oferece recursos que permitem ao
programador desenhar figuras geométricas elementares tais como rectas, rectângulos, elipses,
polígonos e também recursos que permitem a criação de interfaces gráficas amigáveis por meio de
objectos gráficos como botões, caixas de texto, caixa de diálogo e entre outros.
Mas o foco deste capítulo será a criação de desenhos elementares em Java. O desenho de interfaces
gráficas ou aplicações GUI (Graphics User Interface) será cabalmente explorado na cadeira de
Programação Orientada a Objectos.
57
Capítulo 5 – Introdução aos Applets e Gráficos
Não podemos criar directamente um objecto da classe Graphics com o operador new, porque esta
classe é abstracta.
Desenhar é simples: dentro da classe do componente deve ser criado um método com assinatura:
O parâmetro g é uma instância de Graphics ou uma de suas subclasses, que será passada directamente
pelo sistema para o método paint().
Todo o desenho é feito dentro do método paint(), através dos métodos de Graphics chamados a partir
do parâmetro g.
As coordenadas serão sempre considerando o ponto (0,0) como o canto superior esquerdo do
componente, com x avançando para a direita, e y para baixo. Mais adiante serão vistos alguns desses
métodos.
ATENÇÃO: O método paint() nunca deve ser chamado directamente. Quando o componente é criado,
Java chama automaticamente o método void paint(Graphics g) e lhe passa uma instância de Graphics.
Depois, caso seja necessário apagar e re-desenhar novamente sobre o componente, deve-se chamar o
método repaint() do componente, sem qualquer argumento. Esse método é quem fará com que o
método paint() seja chamado assim que for possível. (Note no programa exemplo que o método paint()
não é chamado directamente).
58
Capítulo 5 – Introdução aos Applets e Gráficos
Os métodos devem ser chamados a partir da referência a um Graphics, que será o parâmetro do método
paint() da classe do componente onde queremos desenhar:
public void drawRect(int x, int y, int largura, int altura) - desenha um rectângulo com a largura e
a altura especificadas. O canto superior esquerdo do rectângulo tem as coordenadas (x,y). Somente o
contorno do rectângulo é desenhado utilizando a cor do objecto de graphics – o corpo do rectângulo
não é preenchido com essa cor.
public void fillRect(int x, int y, int largura, int altura) - desenha um rectângulo sólido com a largura
e a altura especificadas. O canto superior esquerdo do rectângulo tem as coordenadas (x,y). O
rectângulo é preenchido com a cor do objecto de graphics.
public void clearRect(int x, int y, int largura, int altura) – desenha um rectângulo preenchido com
a largura e altura especificadas na cor de fundo actual. O canto superior esquerdo do rectângulo tem
as coordenadas (x, y). Esse método é útil se o programador quiser remover uma parte de uma imagem.
public void drawRoundRect(int x, int y, int largura, int altura, int arcwidth, int archight) –
desenha um rectângulo com cantos arredondados na cor actual com a altura e largura especificadas. A
arcwidth e a archeight determinam o arredondamento dos cantos. Somente o contorno da da forma é
desenhado.
public void fillRoundRect(int x, int y, int largura, int altura, int arcwidth, int archight) – desenha
um rectângulo preenchido com cantos arredondados na cor actual com a largura e altura especificadas.
a arcwidth e a archeight determinam o arredondamento dos cantos.
public void draw3DRect (int x, int y, int largura, int altura, boolean b) – desenha um rectângulo
tridimensional na cor actual com a largura e altura especificadas. o canto superior esquerdo do
rectângulo tem as coordenadas (x, y). O rectângulo parece em alto-relevo quando b é verdadeiro, em
baixo-relevo quando b é falso. Somente o contorno da forma é desenhado
59
Capítulo 5 – Introdução aos Applets e Gráficos
public void fill3DRect(int x, int y, int largura, int altura, boolean b) – desenha um rectângulo
tridimensional preenchido na cor actual com a largura e altura especificadas. O canto superior
esquerdo do rectângulo tem as coordenadas (x, y). O rectângulo parece em alto-relevo quando b é
verdadeiro em baixo-relevo quando b é falso.
public void drawOval(int x, int y, int largura, int altura) – desenha uma oval na cor actual com a
largura e a altura especificadas. O canto superior esquerdo do rectângulo delimitador está nas
coordenadas (x, y). A oval toca todos os quatro lados do rectângulo associado no centro de cada lado.
Somente o contorno da forma é desenhado.
public void fillOval(int x, int y, int largura, int altura) – desenha uma oval preenchida na cor actual
com a largura e altura especificadas. O canto superior esquerdo do rectângulo delimitador está nas
coordenadas (x, y). A oval toca todos os quatro lados do rectângulo no centro de cada lado.
public void drawArc(int x, int y,int width, int height, int startAngle, int arcAngle)
public void fillArc(int x, int y,int width, int height, int startAngle, int arcAngle)
sendo x, y, width e height 4 parâmetros que definem a elipse, startAngle o ângulo (em grau) inicial
e arcAngle o ângulo (em grau) que determina o tamanho do sector.
Podemos escolher uma cor-padrao ou determinar uma nova cor com o operador new. A lista de cores
padrao do java tem 13 cores seguintes:
Pode determinar uma nova cor pela mistura Red_Green_Blue (RGB color) sendo cada parte Red,
Green ou Blue varia entre 0 a 255, como por exemplo:
60
Capítulo 5 – Introdução aos Applets e Gráficos
Para realizar operações de desenho, é preciso declarar um objecto Graphics e chamar seus métodos.
Se quiser uma cor para o comportamento gráfico, chame o método setColor como seguinte:
Graphics g;
g.setColor(Color.BLACK); //se quiser a cor preta
Precisamos de um contentor para conter as imagens e um pano para nele desenharmos. No seguinte
programa o contentor é um JFrame e o pano JPanel. Uma discussão mais detalhada sobre JFrame e
JPanel será feita na Programação Orientada a Objecto.
Exemplo1:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import sun.java2d.loops.DrawLine;
public Drawing(){
//metodo construtor
setPreferredSize(new Dimension(300,400));
String option=JOptionPane.showInputDialog("Escolha Uma Opcao: 1 Linha, 2 Rectangulo, 3
Retang. redondo, 4 Elipse"+ ", 5 arco, 6 Rect3D");
op=Integer.parseInt(option);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
61
Capítulo 5 – Introdução aos Applets e Gráficos
switch(op){
case 1:drawLines(g);break;
case 2:drawRectangulo(g);break;
case 3:drawRectanguloRedondo(g);break;
case 4:drawElipse(g);break;
case 5:drawArco(g);break;
case 6:drawRect3D(g);break;
}
}
public void drawLines(Graphics g){
// este metodo desenha dois segmentos de rectas de cor vermelha e azul
g.setColor(Color.red);
g.drawLine(10, 15, 200, 15);
g.setColor(Color.BLUE);
g.drawLine(200, 15, 10, 300);
}
public void drawRectangulo(Graphics g){
// este metodo desenha 2 rectangulos pintado e nao pintado
g.setColor(Color.red);
g.drawRect(10, 15, 200, 50);// rectangulo varmelho nao pintado
g.setColor(Color.BLUE);
g.fillRect(10, 85, 200, 50);//rectangulo pintado com a cor azul
}
public void drawRectanguloRedondo(Graphics g){
// este metodo desenha 2 rectangulos pintado e nao pintado
g.setColor(Color.red);
g.drawRoundRect(10, 15, 200, 150,15,10);//rectangulo varmelho nao pintado
g.setColor(Color.BLUE);
62
Capítulo 5 – Introdução aos Applets e Gráficos
}
public void drawElipse(Graphics g){
// este metodo desenha 1 elipse e 2 circulos pintados
g.setColor(Color.red);
g.drawOval(50,15,200,100);// elipse nao pintada
g.setColor(Color.BLUE);
g.drawOval(90,130,120,120);// elipse pintada de azul
g.setColor(Color.CYAN);
g.fillOval(90,230,120,120);// elipse pintada de verde
}
public void drawArco(Graphics g){
//este metodo desenha 1 arco e 2 sectores pintados
g.setColor(Color.red);
g.drawString("No fill", 10, 30);
g.drawArc(50 , 15, 200, 100, 0, 60);// arco nao pintado
g.setColor(Color.BLUE);
g.drawString("Blue fill", 10, 120);
g.fillArc(90 , 130, 120, 120, 30, 120);// sector pintado de azul
g.setColor(Color.GREEN);
g.drawString("Green fill", 10, 220);
g.fillArc(90 , 230, 120, 120, 90, 270);// sector pintado de verde
}
public void drawRect3D(Graphics g){
g.setColor(getBackground());
g.draw3DRect(10, 10, 60, 40, true);
g.draw3DRect(100, 10, 60, 40, false);
g.fill3DRect(10, 80, 60, 40, true);
g.fill3DRect(100, 80, 60, 40, false);
63
Capítulo 5 – Introdução aos Applets e Gráficos
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
64
Capítulo 5 – Introdução aos Applets e Gráficos
Exemplo2:
O seguinte programa mostra os rectângulos pintados com uma cor padrao Java. O ultimo rectângulo
tem uma cor definida pelo programador da forma aleatória. Para desenhar os rectângulos com cores
diferentes, utilizamos o seguinte método:
• Graphics g: cria o meio gráfico com que se pode chamar os metodos de desenhar do g
• Color c: para entregar a cor a figura
• String colorName: informação do nome da cor utilizada
• int y: a coordenada em y (vertical) do rectangulo
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
65
Capítulo 5 – Introdução aos Applets e Gráficos
66
Capítulo 5 – Introdução aos Applets e Gráficos
int red=(int)(Math.random()*255);
int blue=(int)(Math.random()*255);
int green=(int)(Math.random()*255);
Color c=new Color(red,blue,green);
g.setColor(c);
g.fillRect(x, y, 200, 60);
String randomColor="Red"+Integer.toString(red)+" "+"Blue= "+Integer.toString(blue)+" "+
"Green = "+Integer.toString(green);
g.drawString(randomColor, 50, y+75);
}
private static void createAndShowGUI(){
//Criacao da Janela (Window)
JFrame frame=new JFrame("Show Colors");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public static void main(String [] args){
javax.swing.SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
createAndShowGUI();
}
});
67
Capítulo 5 – Introdução aos Applets e Gráficos
}
}
Saida:
Os estilos do Font são BOLD, ITALIC, PLAIN, BOLD+ITALIC (português: negrito, italico, normal,
negrito+italico). Os tipos (nomes) do font dependem do Sistema Operativo, mas Java fornece sempre
5 Fonts por defeito:
68
Capítulo 5 – Introdução aos Applets e Gráficos
No seguinte programa, utiliza-se um array fontListe[] para conter as fonts que o Java oferece. A
instrução:
fontListe=getToolkit().getFontList(); //recebe-se a lista de fonts
fornece a lista de fonts por defeito.
Visualizamos cada fonte com 3 estilos BOLD, ITALIC e PLAIN
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
public FontList(){
setPreferredSize(new Dimension(300,400));
}
69
Capítulo 5 – Introdução aos Applets e Gráficos
for(i=0;i<fontListe.length;i++){
g.setFont(new Font(fontListe[i],Font.PLAIN,14));
g.drawString("Esta e a fonte"+fontListe[i], 5, startY);
startY=startY+15; //passa para outra linha
g.setFont(new Font(fontListe[i],Font.BOLD,14));
g.drawString("Esta e a fonte"+fontListe[i], 5, startY);
startY=startY+15; //passa para outra linha
g.setFont(new Font(fontListe[i],Font.ITALIC,14));
g.drawString("Esta e a fonte"+fontListe[i], 5, startY);
startY=startY+15; //passa para outra linha
startY=startY+20;
}
}
//mostra a janela
frame.pack();
70
Capítulo 5 – Introdução aos Applets e Gráficos
frame.setVisible(true);
}
Saida:
71
Capítulo 5 – Introdução aos Applets e Gráficos
No programa não há chamada a esse método. O método será executado automaticamente quando
existe. Isso é um atributo da classe JPanel. Se o método não existe nenhuma acção de desenho será
feita.
Exemplo 4:
Num mapa real de Moçambique, achamos um sistema de coordenadas, de onde podemos determinar
um numero de pontos importantes do mapa. As coordenadas desses pontos estabelecem 2 arrays, um
das abcissas x. e outro das coordenadas y. No nosso exemplo, temos dois seguintes arrays (50 pontos):
private int[]y={10,120,152,165,193,220,230,250,277,266,
72
Capítulo 5 – Introdução aos Applets e Gráficos
285, 308, 320, 332, 337, 340, 350, 360, 371, 371, 352, 330,314,
275, 248, 218,192,185,177,158,145,132,132,110,88,98,
96,108,118,130,158,135,130,106,75,60,50,32,32,10
};
Programa Completo:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Polygon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
120,116,110,92,70,65,60,65,65,50,46,47,45,32,54,68,
60,67,63,65,60,30,12,8,73,80,96,102,102,90,115,118,128,
129,100,98,96,105,170,230
};
private int[]y={10,120,152,165,193,220,230,250,277,266,
285,308,320,332,337,340,350,360,371,371,352,330,314,
275,248,218,192,185,177,158,145,132,132,110,88,98,
96,108,118,130,158,135,130,106,75,60,50,32,32,10
};
73
Capítulo 5 – Introdução aos Applets e Gráficos
public MapaMoz(){
setPreferredSize(new Dimension(400,450));
}
frame.setContentPane(newContentPane);
74
Capítulo 5 – Introdução aos Applets e Gráficos
//mostra a janela
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args){
//mostrar a aplicacao GUI
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
Saída:
75
Capítulo 5 – Introdução aos Applets e Gráficos
reconhecida pelos browsers (Internet Explorer, Mozilla FireFox, …) e é utilizada dentro da página
web. A criação de um applet é relativamente simples, isso porque o código de um applet é quase igual
ao da aplicação.
Qualquer applet descende da classe Applet. Essa classe fornece a fórmula comum dos applets. Os
applets têm 4 métodos principais:
• init()
• start()
• stop()
• destroy()
O seguinte diagrama mostra a vida de um applet ou o modo de como o browser controla o applet:
init()
start()
stop()
destroy()
init() - É chamado pela primeira vez quando a página Web é carregada, e pode voltar a ser chamado
caso se volte a entrar na página que contém o applet, este método carrega o applet pondo-o pronto para
começar com a sua execução.
start() - Este método é chamado logo após o método init(), ou quando o applet é reiniciado, ele é
responsável por dar início com a execução do applet, diferentemente do método init() este método
pode ser chamado múltiplas vezes, caso o applet seja reiniciado.
stop() - Este método é chamado quando o applet para a sua execução sem que seja destruído, isto
ocorre quando o utilizador abandona a página que continha o applet ou o applet deixa de ser visível.
destroy() - Este método é chamado quando o applet está sendo destruído, ou removido da memória, e
todos os recursos alocados para a sua execução estão sendo devolvidos ao sistema operativo, assim
como o método init() este método só é chamado uma e única vez durante o ciclo de vida do applet.
76
Capítulo 5 – Introdução aos Applets e Gráficos
Nota: Como já foi referenciado acima, estes métodos estão presentes em qualquer applet, ainda que
não os declaremos no nosso programa eles estão lá, basta ser um applet eles estão lá por defeito, e
como já foi também referenciado acima podemos reescrever qualquer um destes métodos para
satisfazermos as diversas necessidades e para adaptarmos os nossos applets para realizarem tarefas
específicas, repetimos, qualquer um destes métodos pode ser reescrito.
A classe Applet pertence ao pacote AWT e funciona com pouco sucesso com elementos SWING. A
classe JApplet descendente da Applet fornece serviços mais qualitativos que Applet, e por causa
disso, hoje em dia, os applets são escritos frequentemente como descendente da JApplet.
Exemplo
Welcome to Java!
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
public class Hello extends java.applet.Applet{
/** Initialization method that will be called after the applet is loaded
* into the browser
*/
77
Capítulo 5 – Introdução aos Applets e Gráficos
Salve a classe num ficheiro de nome Hello.java. Observamos que na classe não existe o método
main(), compile a classe para o tipo bytecode, isto é, para o ficheiro Hello.class.
Antes de correr o Applet, é preciso criar um ficheiro na mesma pasta com a extensão html, por
exemplo, Hello.html com o seguinte conteúdo:
3. Correr Applet
Pode ver o applet de duas formas. Na primeira forma, utilizamos o programa appletviewer.exe do Java
escrevendo o seguinte comando na janela DosShell ou cmd:
Appletviewer Hello.html
78
Capítulo 5 – Introdução aos Applets e Gráficos
Na segunda forma, podemos correr o applet com um browser. Entre no browser, e procura até
encontrar o ficheiro Hello.html, faça duplo click no ficheiro e veremos o applet. É de notar que, alguns
sistemas operativos, pela segurança, podem não permitir a execução de um applet desta forma.
Nota: Alguns assuntos que aqui não são discutidos acerca de applets:
79
Capítulo 7 – Ficheiros de Texto
• Introdução;
• A classe JComponent;
• Layout Manager;
• Componentes Swing.
6.1 Introdução
Em muitos casos ao desenvolver um software devemos nele apresentar uma interface gráfica que
permita ao usúario final poder interagir com ele com muita facilidade. O Java proporciona-nos
recursos que permite-nos criar uma interface gráfica amigável, que contenha botões, janelas,
tabelas, campos de texto, e outros componentes gráficos úteis e práticos.
Inicialmente, todos componentes gráficos fornecidos pelo java para o desenho de interfaces
gráficas ficavam na biblioteca de nome AWT (Abstract Window Toolkit). Mas a partir da versão
1.2 do JDK até hoje, componentes gráficos mais completos e atraentes foram adicionados e os
anteriores foram remodelados e estão disponíveis na biblioteca SWING. Apesar da biblioteca
SWING ter sido adicionada, ainda podemos fazer uso da biblioteca AWT que mesmo estando
obsolete, ainda fornece-nos recursos úteis no desenho de interfaces gráficas.
A biblioteca SWING contém algumas classes que estendem de classes existentes na AWT e essas
levam o prefixo “J”, como exemplo a classe Frame existente na AWT tem a sua subclasse JFrame
na biblioteca Swing. Na realidade todas classes da biblioteca SWING levam o prefixo “J”.
/***ANEXAR FIGURA***/
80
Capítulo 7 – Ficheiros de Texto
é seu tamanho. O método getSize() permite obter as dimensões do componente, expressas na forma
de um objecto da classe Dimension (um objecto dessa classe tem campos públicos width e height
que indicam respectivamente as dimensões horizontais e verticais do componente em pixels). Já o
método setSize() permite definir a dimensão do componente.
Componentes são objectos que geram eventos, os quais serão relevantes para determinar como
cada elemento da GUI irá responder às acções dos utilizadores.
Além de decidirmos que componentes farão parte da interface gráfica da nossa aplicação um dos
aspectos fundamentais é definir como esses componentes estarão organizados para que a aplicação
seja atraente e de fácil interacção com o utilizador.
Visto que o Java tem o nobre objectivo de permitir o desenvolvimento de aplicações que funcionem
em múltiplas plataformas, ele apresenta diversos Laytout Managers. Os Layout Manager são
gestores de layout (ou por outra são gestores de “organização”, “design”, etc, conforme desejar
traduzir) que permitem ao programador especificar como os componentes estarão organizados no
ecrã, sem definir o local fixo de cada um, deixando os detalhes específicos de posicionamento e
de tamanhos a cargo dos diversos Laytout Managers.
• Existem varios Layout Managers (Gestores de Layout) disponiveis para uso, sendo
que cada um supre necessidades especificas. Muitas vezes, sentiremos a necessidade
de combinar varios Layout Managers na mesma interface para conseguirmos o
resultado desejado. Abaixo vemos a descricao dos Layout Managers mais usados:
6.3.1 FlowLayout
Esta classe organiza a adição de componentes ao contentor pela ordem de esquerda para direita e
passa para a outra fila assim que os componentes adicionados toquem a fronteira do contentor.
81
Capítulo 7 – Ficheiros de Texto
Construtores:
public FlowLayout()
Neste construtor os componentes são adicionados com 5 pixels de separação horizontal e vertical
entre eles;
Exemplos:
//O 1° constructor
FlowLayout meuLayout = new FlowLayout();
//O 2° constructor
FlowLayout meuLayout = new FlowLayout(FlowLayout.CENTER);
FlowLayout nossoLayout = new FlowLayout(FlowLayout.LEFT);
//O 3° constructor
FlowLayout meuLayout = new FlowLayout(FlowLayout.CENTER, 10, 5);
FlowLayout meuLayout = new FlowLayout(FlowLayout.RIGHT, 5, 15);
6.3.2 GridLayout
Como o nome sugere este layout organiza os compontentes como se de uma grelha se trata-se,
isto é, cada componente ocupa a sua célula e todos têm o mesmo tamanho.
Construtores:
public GridLayout()
Os componentes são adicionados em forma de “grelha” considerando o número actual de linhas e
colunas;
Exemplos:
//O 1° constructor
82
Capítulo 7 – Ficheiros de Texto
//O 2° constructor
GridLayout meuLayout = new GridLayout(2,3);
//O 3° constructor
GridLayout meuLayout = new GridLayout(2,3,5,5)
6.3.3 BorderLayout
Este layout devide o ecrã em 5 partes, nomedamente: North, South, East, West e Center. E em
cada parte é adicionado o component desejado. Caso não seja especificada a ocupação de uma
destas partes a zona central ocupará a parte que estiver faltando.
Construtores:
public BorderLayout()
Cria um borderLayout sem separação entre zonas;
Exemplos:
import java.awt.*;
import javax.swing.*;
public JanelaBorder() {
setTitle("BorderLayout");
setSize(340,200);
add(new JButton("North"), BorderLayout.NORTH);
add(new JButton("South"), BorderLayout.SOUTH);
83
Capítulo 7 – Ficheiros de Texto
Neste exemplo fazemos uso do método add() que a nossa classe JanelaBorder estende do JFrame
para adicionarmos os botões e definirmos em que zona da tela estará localizado. Importa
mencionar que o método add é sobrecarregado (overloading).
Importante:
• Caso não indique o LayoutManager, o layout por defeito é o FlowLayout;
• É possível criar novos layouts pela combinação de layouts existentes, bastando
apenas adicionar contentores que também tragam consigo os seus próprios layouts
adicionados pelo programador.
O JFrame representa a janela principal de uma aplicação GUI, e por ser principal ela não pode
ser adicionada a qualquer outra janela. O JFrame é o contentor que pode conter outros
componentes gráficos.
Exemplo:
import javax.swing.*;
84
Capítulo 7 – Ficheiros de Texto
// Exemplo 2 - Criando uma janela instanciando uma classe que estende o JFrame
/*
public class Janela extends JFrame {
6.4.1 JPanel
O JPanel é apenas um contentor que pode adicionar outros componentes e também outros
painéis. Ele é bastante útil na organização dos componentes na tela, obviamente sem dispensar
ajuda dos Layout Managers.
A adição de um JPanel num JFrame pode comparar-se a colocar um quadro numa parede, e neste
caso o JPanel será o quadro e a parede será o JFrame.
6.4.2 JTabbedPane
• Com este componente, varios paineis partilham o mesmo espaco. O usuario escolhe que
componente visualizar atraves de abas.
6.4.3 JScrollPane
Objectos dessa classe fornecem a capacidade de rolagem a componentes da classe JComponent,
quando estes necessitam de mais espaço para exibir dados.
6.4.4 JCheckBox
Para fazer uso de caixas de selecção ou marcação em que qualquer número de itens pode ser
seleccionado usamos a classe JCheckBox.
6.4.5 JButton
É um dos componentes mais familiares e intuitivos ao utilizador. Os botões de comando são
criados com a classe JButton e seu pressionamento geralmente dispara a acção especificada em
seu rótulo, que também suporta a exibição de ícones.
6.4.6 JRadioButton
A classe JRadioButton dá suporte a criação de botões com caixa de marcação, sendo que apenas
um item pode ser seleccionado.
85
Capítulo 7 – Ficheiros de Texto
6.4.7 JComboBox
Assemelha-se a um botão, porém, quando clicado, abre uma lista de possíveis valores ou opções.
Mais precisamente é uma caixa de combinação que permite ao utilizador fazer uma selecção a
partir de uma lista de itens predefinidos.
6.4.8 JTextField
A classe JTextField é usada para a criação de campos de textos.
6.4.9 JPasswordField
A classe JPasswordField é uma subclasse de JTextField, ela apresenta semelhanças com a sua
classe mãe e trás consigo métodos para o tratamento de senhas, importa salientar também que
quando o texto nele é digitado o seu conteúdo é ocultado através de asteriscos.
6.4.10 JTextArea
É uma área dimensionável que permite que múltiplas linhas de texto sejam editadas com a mesma
fonte. Esta classe é herdada de JTextComponent, que define métodos comuns para JTextField,
JTextArea e outros elementos GUI baseados em texto.
6.4.11 JSlider
É um marcador que desliza entre um intervalo de valores inteiros, podendo seleccionar qualquer
valor de marca de medida em que o marcador repouse. Uma das inúmeras utilidades desse controle
deslizante é restringir os valores de entrada em um aplicativo, evitando que o usurário informe
valores que causem erros.
6.4.12 JPopupMenu
São menus sensíveis ao contexto, ou seja, em virtude da localização do cursor do mouse, um clique
no botão direito do mesmo dispara um evento que abre um menu flutuante. Tal menu fornece
opções seleccionáveis ao determinado componente sobre o qual o evento de disparo foi gerado.
6.4.13 JTable
• Com esta classe torna-se possivel exibir dados em forma de uma tabela, podendo também
permitir a edição destes dados pelo usuario.
86
Capítulo 7 – Ficheiros de Texto
Resumo Teórico
Nota: Uma discussão mais aprofundada sobre os algoritmos de ordenação será objectivo
de outra cadeira.
Escolher o número máximo e colocá-lo no fim do array. Assim o elemento máximo já está na
posição correcta, devemos verificar apenas o subarray de (N-1) primeiros elementos. Repetindo
esse processo até quando o subarray conter apenas um elemento, e teremos um array ordenado.
Exemplo:
2 9 5 4 8 1 6
O número 9 é o número máximo, portanto, este deve trocar de posição com o último elemento do
array, isto é, 9 e 6 trocam de posição, e o novo array será:
2 6 5 4 8 1 9
87
Capítulo 7 – Ficheiros de Texto
O número 9 já está na posição correcta, então consideramos o subarray dos primeiros 6 números.
2 6 5 4 8 1
2 6 5 4 1 8
Repete-se o processo com o subarray de 5 elementos, etc. até que o array esteja totalmente
ordenado.
Algoritmo
O tamanho do array será introduzido pelo utilizador. Será impresso o array antes e depois da
ordenação. O método responsável pela ordenação é o selectionSort().
88
Capítulo 7 – Ficheiros de Texto
import javax.swing.JOptionPane;
int size=Integer.parseInt(JOptionPane.showInputDialog("Qual o
tamanho do array?"));
list[i]=(int)(Math.random()*20);
printList(list);
selectionSort(list);
printList(list);
for(int i=list.length-1;i>=1;i--){
currentMax=list[i];
currentMaxIndex=i;
for(int j=i-1;j>=0;j--)
if(currentMax<list[j]){
currentMax=list[j];
currentMaxIndex=j;
if(currentMaxIndex!=i){
list[currentMaxIndex]=list[i];
list[i]=currentMax;
89
Capítulo 7 – Ficheiros de Texto
System.out.println();
1 4 18 3 9 18 17 10 8 5
1 3 4 5 8 9 10 17 18 18
A ordenação de um array de objectos não é tão simples como na ordenação de um array de tipos
primitivos. Não podemos aplicar os algoritmos de ordenação de array de elementos primitivos para
array de objectos. Mas felizmente, Java oferece a classe java.util.Arrays que podemos utilizar para
ordenação de objectos. Para que seja aplicado o método sort() da classe Arrays precisamos o
conceito de interface do java.
• Interface
Java não permite a multi-herança, isto é, não podemos ter uma classe que herda ao mesmo tempo
duas ou mais classes. Para obter efeitos da multi-herança, java introduz o conceito de interface.
Interface é considerada uma classe especial que só tem as declarações de constantes e assinaturas
de métodos. A sintaxe é a seguinte:
90
Capítulo 7 – Ficheiros de Texto
}
Em palavras, uma interface usa a palavra reservada interface, seguido do nome da interface.
Dentro das chavetas pode conter declarações de constantes ou assinaturas de métodos. Uma
assinatura de método tem só o cabeçalho mas não tem o corpo do método. Uma interface pode ter
seus modificadores (public, private, etc).
Pode se utilizar uma interface como um tipo de dados ou na conversão (casting) de tipos, mas não
pode criar instâncias com o operador new.
Para usar uma interface numa classe, digamos, classe A, o programador deve fazer 2 trabalhos.
1º Declarar que a classe A que nele se quer implementar a interface com a palavra implements.
Nota: um estudo mais profundo sobre interface será estudado na outra cadeira.
O primeiro recurso é a interface Comparable que tem apenas o método compareTo() cuja
assinatura é a seguinte:
O parâmetro do método é do tipo Object, por causa disso, na comparação de objectos de uma
classe, é preciso converter (casting) o parâmetro ob para o tipo a ser comparado.
O corpo do método compareTo() define o critério de comparação retornando um valor inteiro, por
exemplo, o programador deve determinar que a ordenação dos Empregados é pelos salários, ou
pelos nomes, ou por outro campo.
91
Capítulo 7 – Ficheiros de Texto
Além disso, a comparação deve retornar valores respectivos nos casos de comparação menor, igual
ou maior. Um exemplo usando o campo salario dos Empregados é dado como seguinte:
O Segundo recurso é o método sort() da classe java.util.Arrays. Esse método faz a ordenação dos
objectos pelo critério definido no método compareTo() da classe que define objectos a ordenar-
se. O método sort() é static pois podemos chamá-lo da seguinte maneira:
Arrays.sort(staff);
//sendo staff o array a ordenar-se. Fim desta chamada o array staff é //ordenado
Nota: o método sort() da classe Arrays é overloading para ordenar qualquer array de tipos
primitivos. Isto é, se C for array de um dos tipos int, byte, short, long, char, float ou double pode
se aplicar a chamada:
Arrays.sort(C);
Exemplo:
No seguinte programa utilizamos duas classes. A classe Empregado define objectos a ordenar-se,
ela implementa a interface Comparable para que a comparação seja possível. A classe pública
SortArrayObject cria um array staff de 3 Empregados, Tom, Dick e Harry com seus salários bem
específicos. A chamada Arrays.sort(staff) faz a ordenação. As informações são impressas antes
e depois da ordenação.
import java.util.Arrays;
92
Capítulo 7 – Ficheiros de Texto
//before sorting
System.out.println("before sorting");
staff[i].imprime();
System.out.println();
//sorting
Arrays.sort(staff);
//after sorting
System.out.println("after sorting");
staff[i].imprime();
nome = aNome;
salario = aSalario;
return nome;
93
Capítulo 7 – Ficheiros de Texto
this.nome = nome;
return salario;
this.salario = salario;
@Override
return 1;
return -1;
return 0;
94
Capítulo 7 – Ficheiros de Texto
before sorting
Nome = Tom, Salário = 4000.0
Nome = Dick, Salário = 8000.0
after sorting
Nome = Dick, Salário = 8000.0
Nome = Harry, Salário = 6500.0
Nome = Tom, Salário = 4000.0
CompareTo()na classe que faz a comparação entre os Strings. Se for necessária a ordenação de um
campo do tipo String, pode usar directamente este método, por exemplo se quisermos comparar
os apelidos de trabalhadores, faremos o seguinte:
Exemplo:
Para ordenar os trabalhadores pelo nome, o método compareTo() seria escrito da seguinte forma:
95
Capítulo 7 – Ficheiros de Texto
7.2 Pesquisa
A pesquisa é um processo de encontrar um elemento concreto num certo domínio. Por exemplo,
num array, verificar se o trabalhador de nome Luís está na lista de trabalhadores. Tal como a
ordenação, existem muitos algoritmos e estrutura de dados para a acção de pesquisa. Neste manual
utilizaremos a pesquisa linear (linear search) e a pesquisa binária (binary search).
96
Capítulo 7 – Ficheiros de Texto
Exemplo:
No seguinte programa, cria-se um array com 10 números aleatórios. O utilizador introduz a chave
(um inteiro, neste caso). Imprimimos a lista dos inteiros, também a chave e o resultado de pesquisa.
Estrutura do programa
import javax.swing.JOptionPane;
for(int i=0;i<list.length;i++)
list[i]=(int)(Math.random()*20);
System.out.println("Lista actual:");
printList(list);
String chaveStr=JOptionPane.showInputDialog("Introduza a
chave:");
int chave=Integer.parseInt(chaveStr);
System.out.println("Chave = "+chave);
97
Capítulo 7 – Ficheiros de Texto
System.exit(0);
for(int i=0;i<list.length;i++)
System.out.print(list[i]+" ");
System.out.println("");
for(int i=0;i<list.length;i++)
if(chave==list[i]) return i;
return -1;
98
Capítulo 7 – Ficheiros de Texto
Lista actual:
18 15 0 15 11 8 16 14 11 0
Chave = 10
Chave não encontrada
Pode se demonstrar que no caso “mau”, o número máximo das comparações com chave é log2n +
1, por exemplo, se o array tem 1024 elementos (210), o número de comparações é só log2(210) + 1
= 11.
Exemplo:
import javax.swing.JOptionPane;
public class TestBinarySearch {
public static void main(String[] args) {
//criação de um array de 10 elementos inteiros bem ordenados 0 2 4
... 18
int[] list = new int[10];
for (int i = 0; i < list.length; i++) {
list[i] = 2 * i;
}
System.out.println("Lista actual:");
printList(list);
99
Capítulo 7 – Ficheiros de Texto
100
Capítulo 7 – Ficheiros de Texto
return middle;
} else if (chave > list[middle]) {
return binarySearch(chave, list, middle + 1, up);
}
return -1;
}
}
Lista actual:
0 2 4 6 8 10 12 14 16 18
chave = 4
chave encontrada na posição:2
É de notar que neste programa, os métodos binarySearch() são overloading. O método com 2
parâmetros chama o com 4 parâmetros. Se quiser a pesquisa em todo o array deve-se usar o método
com 2 parâmetros, por outra, se tiver certeza que a chave se encontra entre dois índices low .. up,
chame o método com 4 parâmetros.
101
Capítulo 7 – Ficheiros de Texto
8 Ficheiros
Resumo teórico
• Excepção ( Exception )
• Ficheiros de Objectos
O fluxo de entrada ( input stream ) é qualquer coisa de fora que entra no computador. O fluxo de
saída ( output stream ) é qualquer coisa que sai do computador para fora ( via dispositivos
periféricos como monitor, impressora, ficheiros no disco, etc.).
Neste capítulo estudamos o caso mais importante: os fluxos ( entrada e saída ) que fazem ligação
entre ficheiros no disco e a memória do computador.
Particularmente o teclado, o ecrã, a impressora são considerados como ficheiros especiais: só lido
( teclado ) ou só escrito ( ecrã, impressora).
102
Capítulo 7 – Ficheiros de Texto
Java tem uma biblioteca rica de serviços de entrada e saída possuindo 45 classes para isso.
Podemos importar essa biblioteca com a instrução:
import java.io.*;
//io = (input – output)
//as classes não são todas independentes e algumas ficam num esquema de herança
8.2 Excepção
A palavra “excepção” no Java é usada para dizer que aconteceu alguma coisa indesejada ou que
ocorreu um certo erro. Mostramos alguns exemplos.
Uma excepção pode vir do lado do utilizador ou do instrumento ( user input exceptions or device
exceptions ), por exemplo, em vez de introduzir um número inteiro, introduzir um carácter. Um
outro caso, o utilizador pode clicar com o mouse no butão “print” sem observar que a impressora
não está ligada ou sem papel. Esses são “erros ligeiros”, e o programa deve dar a possibilidade de
reintroduzir o valor inteiro ou avisar ao utilizador sobre o estado da impressora.
A excepção pode também vir da parte do código. Por exemplo, um recente (ou não) programador
pode escrever uma instrução para fazer a divisão de dois números sem verificar que o denominador
é diferente de zero.
A excepção pode vir também da forma “runtime exception” , isto é, o erro só acontece
ocasionalmente quando o programa correr. Por exemplo, uma página web, pode temporiariamente
ser inválido, a impressora pode ter a falta de papeis no meio das impressões.
Todas as excepções em java são descendentes da classe Throwable. O esquema de herança divide-
se em duas direcções: Erros e Excepções. Na direcção dos erros, Java resolve os erros muito graves
que o programador não pode resolver, como por exemplo,
VirtualMachineError,OutOfMemoryError ou AWTError. Na direcção das excepções há 2
principais classes: RuntimeException e IOException.
Todas as excepções do tipo RuntimeException não são verificadas ( unchecked ) e Java não obriga
que o programador deva tratar concretamente a excepção. As excepções do tipo IOException são
verificadas ( checked ) e o programador deve tratar essas excepções. Teremos exemplos sobre
103
Capítulo 7 – Ficheiros de Texto
ArithmeticException
RuntimeException
IndexOutOfBoundsException
Exception
FileNotFoundException
IOException
Throwable
MalformedURLException
LinkageError
Error VirtualMachineError
AWTError
104
Capítulo 7 – Ficheiros de Texto
try {
Executar uma sequência de instruções
}
catch (algumaExcepção e) {
fazer os tratamentos para a excepção e
}
Podemos entender este modelo da seguinte maneira:
“tente executar uma sequência de instruções, se acontecer alguma excepção, apanhe-a e faça os
tratamentos para esta excepção”.
Caso não aconteça nenhuma excepção no bloco try, a execução das instruções irá ser completa e o
programa não irá executar as instruções do bloco catch.
try {
Executar uma sequência de instruções
}
catch ( algumaExcepção e ) {
Fazer os tratamentos para a excepção e
}
finaly {
Executar uma sequência de instruções
}
“tente executar uma sequência de instruções ( no try ), se acontecer uma excepção, apanhe-a e
faça os tratamentos para esta excepção ( no catch ). Depois de tudo isso,qualquer que seja o que
se passa nos blocos try ou catch, as instruções do bloco finally serão executadas”.
105
Capítulo 7 – Ficheiros de Texto
try {
Fazer o acesso ( abrir, ler conteúdo, fechar …) ao ficheiro
}
catch (FileNotFoundException e) {
System.out.println(“ Ficheiro não encontrado. Verifique isso! …”);
}
O nosso tratamento ( concreto ) neste caso é que imprimimos uma mensagem recomendando ao
utilizador rever o seu input. Podemos também “passar a bola” para o system Java num método
semelhante ao seguinte ( utiliza-se a palavra throws - lança):
Consideramos uma excepção não verificada. Como exemplo, consideramos o caso em que um
utilizador introduz um número inteiro com JoptionPane:
106
Capítulo 7 – Ficheiros de Texto
Se o utilizador introduzir correctamente os dados, tudo irá decorrer bem. Caso contrário, ou seja,
se o utilizador introduzir um carácter ou nada por exemplo, o método parseInt()vai lançar uma
excepção do tipo NumberFormatException – uma excepção no formato numérico. Como
NumberFormatException é derivada do tipo RuntimeException, uma excepção que o próprio Java
considera dificil de controlar, podemos “deixar passar”, isto é, não apanhamos erros e a
compilação do programa irá mesmo sem erros. Escolhemos esta solução com a esperança de que
o utilizador irá introduzir correctamente os dados. Porém, para um programador profissional,
aconselhamos usar o seguinte código:
try {
String intSTR = JOptionPane.showInputDialog(“ Introduza um inteiro ”);
int intValue = Integer.parseInt( intSTR );
}
catch ( NumberFormatException e ) {
System.out.println(“Erro no formato numérico, re-introduza por favor! ”);
}
A palavra throw é utilizada para lançar uma excepção dentro de um método. Enquanto que a
palavra reservada throws é utilizada na cabeça do método como uma declaração de que o método
pode lançar excepções. Consideramos um exemplo: Num método que faz a divisão de dois inteiros,
pode lançar uma excepção “denominador não pode ser ZERO” como a seguir:
Se quiser armazenar números no ficheiro de texto, o programador pode preparar os métodos para
converter a sequência de caracteres em valor numérico.
107
Capítulo 7 – Ficheiros de Texto
Além dos ficheiros de texto, existem os ficheiros binários ( ficheiros de imagens, músicas, etc).
• Fecho do ficheiro.
BufferedReader bfR;
Depois da abertura do ficheiro a ler, pode-se ler uma linha dele com o seguinte método:
return bfR.readLine();
}
Obs: No método acima, precisamos apenas do retorno do método readLine() do objecto da classe
BufferedReader.
108
Capítulo 7 – Ficheiros de Texto
String st = lerUmaLinha();
Podemos fazer as análises deste String st para obter o resultado pretendido. Para isso pode usar os
serviços da classe java.util.StringTokenizer. por exemplo, se cada linha é um String, devemos de
uma certa maneira, converter o String em valor inteiro.
Para a leitura de todo conteúdo do ficheiro, pode-se ler linha a linha até ao fim do ficheiro. Quando
estiver no fim do ficheiro, a linha lida será null, e podemos utilizar esse sinal organizando um ciclo
que leia todo o ficheiro.
109
Capítulo 7 – Ficheiros de Texto
Tenha atenção que, nesses métodos, as linhas são lidas e visualizadas. Podemos substituir as
instruções System.out.println(s) por qualquer tratamento com a linha lida.
Fechar o ficheiro
Nota: a apresentação dos trabalhos com ficheiros de entrada feita aqui é bastante redundante,
mas isso é necessário para destacar que cada trabalho com ficheiro é sempre preciso o tratamento
de excepção de entrada e saída. Quando o problema for pequeno, podemos agrupar os trabalhos
de modo que o programa seja mais simples e compreensível.
Exemplo
Leitura integrada do ficheiro de entrada. Neste programa vamos ler todo o conteúdo de um
ficheiro de texto, visualizando o seu conteúdo no console. Apresentamos até 3 leituras
equivalentes.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
110
Capítulo 7 – Ficheiros de Texto
111
Capítulo 7 – Ficheiros de Texto
f.abreLeitura("//home//paulo//Desktop//ficheiro"); //um
ficheiro concreto
/*
*O nome do ficheiro distingue letras maíusculas de minúsculas devido
ao *facto do programa ser testado no Linux
* No windows, para indicar o path do ficheiro deve-se usar barra
invertida
* ex: C:\\path\\ficheiro.extensao
* onde path é o caminho todo até onde está localizado o
ficheiro.extensao
*/
f.lerTodoFicheiro();
//f.lerTodoFicheiro1();
//f.lerTodoFicheiro2();
f.fechaLeitura();
}
}
112
Capítulo 7 – Ficheiros de Texto
Temos os mesmos trabalhos que tínhamos no ficheiro de entrada, ou seja, abertura e fecho. Mas
ao em vez de leitura, iremos ter um método que nos permita escrever dados num ficheiro.
Seja bfW um objecto da classe BufferedWriter, o método que abre um ficheiro para escrita, e recebe
como parâmetro o nome do ficheiro pode ser o seguinte:
113
Capítulo 7 – Ficheiros de Texto
realiza a escrita do conteúdo da linha a partir do caractere na posição índiceInicial com número de
caracteres lidos indicado no quantosCaracteres e o método
newLine();
manda passar para uma nova linha.
Usando esses dois métodos podemos elaborar os nossos métodos que escrevam dados para um
ficheiro.
114
Capítulo 7 – Ficheiros de Texto
Exemplo
Escrita de dados para um ficheiro de saída. Neste programa escrevemos um String, um número
inteiro e um número real para um ficheiro de texto de nome ficheiro.txt, criado no mesmo
directório onde corre o programa.
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
fW.write(linha, 0, linha.length());
fW.newLine();
String st = "";
st = st.valueOf(num);
escreverLinha(st);
String st = "";
st = st.valueOf(num);
escreverLinha(st);
115
Capítulo 7 – Ficheiros de Texto
fW.close();
f.abreEscrita("ficheiro.txt");
f.escreverLinha(st);
f.fechaEscrita();
/*
*/
Ficheiro.txt
116
Capítulo 7 – Ficheiros de Texto
21
21.12345
Para as análises de gramática e vocabulário ( code parse and lexical scanner ) dos String ( ficheiros
de texto em caso geral ) pode se utilizar a classe StreamTokenizer. Esta classe tem capacidade de
reconhecer os tokens ( palavras, números, pontuação, etc. ) que formam o Stream. Por exemplo, o
seguinte String:
Exemplo:
117
Capítulo 7 – Ficheiros de Texto
Numa cadeira semestral, o estudante faz 2 testes: Teste 1 com peso 2 e teste 2 com peso 3. A nota
O programa completo:
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
118
Capítulo 7 – Ficheiros de Texto
try {
frs = new FileReader("pauta_in.txt");
fws = new FileWriter("pauta_out.txt");
if (in.nextToken() == in.TT_WORD) {
sname1 = in.sval;
} else {
System.out.println("Bad file format");
}
if (in.nextToken() == in.TT_NUMBER) {
nota1 = (int) in.nval;
} else {
System.out.println("Bad file format ");
119
Capítulo 7 – Ficheiros de Texto
if (in.nextToken() == in.TT_NUMBER) {
nota2 = (int) in.nval;
} else {
System.out.println("Bad file format ");
}
// Para ficheiro
out.println(sname + " " + sname1 + " " + " " +
nota1
+ " " + nota2 + " " + nFreq + " " +
classificacao);
// Para screen
System.out.println(sname + " " + sname1 + " " + "
" + nota1
+ " " + nota2 + " " + nFreq + " " +
classificacao);
120
Capítulo 7 – Ficheiros de Texto
fws.close();
}
} catch (IOException ex) {
System.out.println(ex);
}
}
}
public static String tratamentoFrequencia(int nFreq) {
String s = "";
if (nFreq <= 9) {
s = "EXCLUIDO ";
} else if (nFreq <= 13) {
s = "ADMITIDO ";
} else {
s = "DISPENSADO";
}
return s;
}
}
121
Capítulo 7 – Ficheiros de Texto
import java.io.Serializable;
Stream
O objecto serializado já pode ser transmitido para o ficheiro por meio de um Stream que é um
objecto de transmissão de dados, onde um fluxo de dados serial é feito através de uma origem e de
um destino. A seguir vamos descrever alguns tipos de Stream.
122
Capítulo 7 – Ficheiros de Texto
Escrita de dados
123
Capítulo 7 – Ficheiros de Texto
FileOutputStream("C:\\Users\\Joss\\Desktop\\Saida.dat");
ObjectOutputStream os = new ObjectOutputStream(meuFicheiro);
os.flush();
os.close();
System.out.println("Objetos gravados com sucesso!");
}
catch(Exception e) {
e.printStackTrace( );
}
124
Capítulo 7 – Ficheiros de Texto
}
}
Temos que ter um objecto da classe FileInputStream, seja meuFicheiro o tal objecto:
Leitura de dados
import java.io.FileInputStream;
import java.io.ObjectInputStream;
125
Capítulo 7 – Ficheiros de Texto
FileInputStream meuFicheiro =
new FileInputStream("C:\\Users\\Joss\\Desktop\\Saida.dat");
ObjectInputStream in = new ObjectInputStream(meuFicheiro);
p1 = (Pessoa) in.readObject();
p2 = (Pessoa) in.readObject();
p3 = (Pessoa) in.readObject();
p4 = (Pessoa) in.readObject();
System.out.println(p1+"\n"+p2+"\n"+p3+"\n"+p4);
/*Nao existe nenhuma necessidade de fazermos uso do metodo
*flush() aqui por ser util apenas na escrita dos
dados no
* ficheiro*/
meuFicheiro.close();
in.close();
}
catch( Exception e ) {
e.printStackTrace( );
}
}
}
126
Capítulo 7 – Ficheiros de Texto
127