Você está na página 1de 128

FACULDADE DE CIÊNCIAS

DEPARTAMENTO DE MATEMÁTICA E INFORMÁTICA

Manual de Fundamentos de Programação em Java

Versão: 1.0

Versão JDK: 1.7

Autor:

Ermínio Jasse

Colaboradores:

Bruno Estevão Chichava

Elpídio Maúnde

Job de Vera Taimo Guitiche

Jordão Joaquim Uache

Juvêncio Abílio Comé

Paulo Jorge Braga Zacarias

Fevereiro de 2013
FUNDAMENTOS DE PROGRAMAÇÃO

Bibliografia
Caelum. 2005.Java e Orientação à Objectos. 2005.

JAQUES, Patrícia Augustin. 2007.Programação Básica em Java. 2007.

QUYNH, NGUYEN NGOC. 2010.FP: Resumo Teórico e Ficha de Exercícios. 2010.

RICARTE, Ivan Luiz Marques. 2001.Programação Orientada à Objectos: Uma


abordagem com java. s.l. : UNICAMP, 2001.

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 Estruturas Principais da Programação JAVA ..................................... 9


2.1 Um programa simples ............................................................................................... 9
2.2 Identificadores .........................................................................................................12
2.3 Tipos de Dados Primitivos .......................................................................................13
2.4 Declaração e Inicialização de Variáveis....................................................................13
2.5 Constantes ...............................................................................................................14
2.6 Operadores ..............................................................................................................15
2.7 Funções e Constantes Matemáticas ..........................................................................17
2.8 Conversões entre Tipos Numéricos ..........................................................................18
2.9 Leitura de Dados com JOptionPane..........................................................................19
2.10 Impressao e Formatação de Saida............................................................................23

3 Estruturas de Controle do Java ...................................................... 24


3.1 Blocos .....................................................................................................................24
3.2 Instruções condicionais ............................................................................................24
3.3 Multiselecções Switch .............................................................................................26
3.4 Ciclos ......................................................................................................................28
3.5 Array .......................................................................................................................31
3.6 String.......................................................................................................................34

4 Classes e Objectos ........................................................................ 36


4.1 Introdução a OOP (Programação Orientada a Objectos) ...........................................36
4.2 Classe e Objectos de uma classe...............................................................................37
4.3 Construção de objectos de uma classe ......................................................................43
4.4 Modificadores public, private, static, final ..................... Error! Bookmark not defined.
4.5 Métodos da classe ....................................................................................................44
4.6 Parâmetros de métodos ............................................................................................47

2
4.7 Pacote (package) ......................................................................................................54
4.8 Sugestão de desenho de classes ................................................................................55

5 Introdução aos Applets e Gráficos ................................................. 57


5.1 Introdução a programação gráfica ............................................................................57
5.2 Sistemas de Coordenadas no modo gráfico ...............................................................57
5.3 Objectos da classe graphics ......................................................................................58
5.4 Métodos da classe Graphics .....................................................................................59
5.5 Desenho e pintura de sectores ..................................................................................60
5.6 Utilização de cores ...................................................................................................60
5.7 Utilização de Font ....................................................................................................68
5.8 Método paintComponent() .......................................................................................71
5.9 Classe Polygon ........................................................................................................72
5.10 Introdução a Applets ................................................................................................75

6 Interface Gráfica do Utilizador ...................................................... 80


6.1 Introdução ...............................................................................................................80
6.2 A classe JComponent ...............................................................................................80
6.3 Layout Manager – O que é? Para que serve? ............................................................81
6.3.1 FlowLayout......................................................................................................81
6.3.2 GridLayout ......................................................................................................82
6.3.3 BorderLayout ...................................................................................................83
6.4 Componentes SWING .............................................................................................84
6.4.1 JPanel ..............................................................................................................85
6.4.2 JTabbedPane ....................................................................................................85
6.4.3 JScrollPane ......................................................................................................85
6.4.4 JCheckBox.......................................................................................................85
6.4.5 JButton ............................................................................................................85
6.4.6 JRadioButton ...................................................................................................85
6.4.7 JComboBox .....................................................................................................86
6.4.8 JTextField ........................................................................................................86
6.4.9 JPasswordField ................................................................................................86
6.4.10 JTextArea ........................................................................................................86
6.4.11 JSlider..............................................................................................................86
6.4.12 JPopupMenu ....................................................................................................86
6.4.13 JTable ..............................................................................................................86

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 Introdução a Linguagem de Programação Java


Resumo teórico

Neste capítulo abordamos os seguintes tópicos:

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!!!

Leia na íntegra a história da linguagem Java em: http://www.java.com/en/javahistory/

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

1.2 Porquê Java?


Os autores do Java lançaram um "livro branco" (white paper) que explica os objectivos da
linguagem. As seguintes "buzzwords" estão incluídas no livro:

Simple Simples

Object Oriented Orientada a Objectos

Robust Forte

Secure Seguro

Architecture Neutral Código Neutral

Portable Portátil

Interpreted Interpretado

High Performance Maior desempenho

Multithreaded Multi-ramo de execução

Dynamic Dinâmico

Ao ouvir essas palavras amamos imediatamente Java.

1.3 Características da Linguagem Java


São características mais sonantes do java, as seguintes:

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 {

public static void main( String[] args ) {

System.out.println(“Helllo, World”);

HelloWorld.java

Compilador

HelloWorld.class

Interpretador Interpretador Interpretador

Windows Solaris MacOS

7
Capítulo 2 – Estruturas Principais da Programação JAVA

1.4 Ambiente de Desenvolvimento Java


O que é necessário para ter o ambiente de programação a funcionar? Ou seja, para fazer um
programa em java, o que é necessário? O que devemos descarregar do site da Oracle/Sun?

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).

1.4.1 Java IDE (Java Integrated Development Environment )


Será que é sempre necessário digitar o programa java num editor de texto como o wordpad e depois
passar por todas as fases até ter o programa interpretado?

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

2 Estruturas Principais da Programação JAVA


Neste capítulo abordaremos os seguintes tópicos:
1. Primeiro programa;
2. Identificadores;
3. Tipos de dados primitivos;
4. Declaração e Inicialização de Variáveis
5. Constantes;
6. Operadores;
7. Funções e constantes matemáticas;
8. Conversão entre tipos numéricos;
9. Leitura de dados com JOptionPane;
10. Formatação de Saida.

2.1 Um programa simples


Nesta secção iremos escrever, compilar e executar o tradicional programa “Hello World”. O código
deste programa será explicado posteriormente para que você possa começar a entender os
fundamentos da programação Java.

Crie um projecto com o nome PrimeiroProgramaJava e um ficheiro HelloWorld.java. Digite o


código abaixo, no ficheiro criado, de seguida compile e execute. A saída deverá ser:

Hello, World!

O código fonte do programa:


1. /* Meu programa Java */
2. public class HelloWorld {

4. public static void main (String args[ ]) {


6. System.out.println (“Hello, World!”);

7. } // Fim da rotina (método) main


8. } // Fim da classe

9
Capítulo 2 – Estruturas Principais da Programação JAVA

Explicação Passo a Passo:


• Linha 2: public class HelloWorld
Esta linha utiliza a palavra reservada class para declarar que uma nova classe está sendo definida.
HelloWorld é o nome usado para identificar a classe em criação. Toda a definição da classe,
incluindo todo o código e os dados pré-definidos, estará entre a chave de abertura “{“ e a chave de
fecho de classe “}” que se encontram nas linhas 5 e 8 deste exemplo.
• Linha 4: public static void main (String args[ ]);
A linha 4 contém a declaração do método main. O método main é simplesmente um ponto de
partida para o interpretador Java. É por onde será iniciada a execução de todo o programa e
projecto.O main não requer mudanças na sintaxe, e deverá sempre ser declarado na forma acima,
porém o args pode mudar já que é apenas nome de um array de String.

• Linha 6:System.out.println (“Hello, World!”);


Esta linha executa o método println do objecto out. Este objecto é uma instância da classe
OutputStream e foi declarado como variável de classe (static) na classe System. Este método
imprime na tela uma mensagem texto, no caso, “Hello, World!”.
Por causa do modelo de objecto, uma saída simples de console é complicada para entender. Por
isso, até aprofundarmos o conteúdo suficientemente, pense apenas em System.out.println como
um método para impressão na tela (saída do console).

Verifique se na pasta corrente(pasta do projecto), aparece um novo ficheiro HelloWorld.class.


Não podemos ver o conteúdo desse ficheiro com qualquer processador de texto. O ficheiro está
embytecode, um formato especial dos programas Java. O formato bytecode é neutral; isto é, ele
pode ser executado em qualquer sistema operativo equipado com um interpretador java. Por esta
razão, a linguagem Java desprende orgulho pela expressão:

“write one, run anywhere!”

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:

public class HelloWorld{public static void main (String a[ ] )


{System.out.println (“Oi, mundo!”);}}

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:

1- De uma linha, 2- de várias linhas e 3- de documentação. Os comentários de uma linha começam


com // (duas barras) e terminam no final da mesma linha. Este tipo de comentário é útil para
explicações curtas, de uma única linha de código. Nas linhas 7 e 8 do código exibido no início
deste capítulo encontramos dois comentários desse tipo.

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.

Existe ainda o comentário de documentação que começa com /** (barra-asterisco-asterisco) e


finaliza com */ (asterisco-barra). É através desta que elaboramos a documentação do nosso
código/aplicação.

3. Algumas palavras-chave reservadas


As palavras-chave reservadas Java são usadas para identificar os tipos, modificadores e
mecanismos de controlo de fluxo. Essas palavras, juntamente com os operadores e separadores,
formam a definição da linguagem Java. Elas não podem ser usadas como nome de variável, de
método nem de classe.

Abstract Boolean Break Byte byvalue


Case Cast Catch Char class
Const Continue Default Do double

11
Capítulo 2 – Estruturas Principais da Programação JAVA

Else Extends False final finally


Float For Future generic goto
If Implements Import inner instanceof
int Interface Long native new
null Operator Outer package private
protected Public Rest return short
Static Super Switch synchronized this
Throw Throws transiente true try
Var Void Volatile while

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.

4. Convenções para nomenclatura de identificadores


a) Variáveis e métodos (convenções de nomenclatura)
Segundo a convenção para identificadores Java, os métodos e variáveis devem ser nomeados com
letras minúsculas. No caso de o identificador ser formado por mais de um termo, o segundo termo
e os termos seguintes devem iniciar com letra maiúscula. As variáveis são compostas por
substantivos e adjectivos, enquanto que os nomes de métodos começam sempre com um verbo e
terminam em (), podendo ter parâmetros dentro dos parêntesis.

Exemplos: hora, horaDoDia, valorCorrente, obterHoraDoDia().

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.

Exemplos: VALOR_P1, DIA_SEXTA, VERDE.

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.

2.3 Tipos de Dados Primitivos


Java tem oito tipos simples de dados que podem ser classificados em quatro grupos:
• Inteiros: byte, short, int e long que são usados para números inteiros;
• Números de Ponto flutuante: float e double que correspondem aos números com
precisão de fracção;
• Caracteres: char;
• Valores lógicos: boolean que é um tipo especial usado para representar valores lógicos.

Grupo Tipo Tamanho Intervalo Valor


Default
Int 4 bytes -2.147.783.648 até 2.147.483.647 0
Short 2 bytes -32.768 até 32.767 0
Inteiros Long 8 bytes -9.223.372.036.854.775.808L até 0L
9.223.372.036.854.775.807L
Byte 1 byte -128 até 127 0
Float 4 bytes +- 3,40282347e+38F (6-7 dígitos significativos) 0.0f
Ponto
double 8 bytes +- 1,79769313486231570E+308 (15 dígitos 0.0d
flutuante
significativos)
Char 2 bytes representa um unicode ‘\u0000’
boolean 1 bit true ou false false

2.4 Declaração e Inicialização de Variáveis


As variáveis do tipo byte, short, int, long, float, double, char e boolean podem ser declaradas de
acordo com uma das formas exibidas abaixo:

int a, b, c; Declarando as variáveis a, b e c.


int d = 3, e, f = 5; Declarando d, e, f e inicializando d com 3 e f com 5.

13
Capítulo 2 – Estruturas Principais da Programação JAVA

double pi = 3.14.159; Declarando e inicializando pi com o valor 3.14159;


char c = ‘x’; Declarando e inicializando c com o caractere ‘x’;

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 {

public static void main(String[] args) {

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);

System.out.println("short s = " + s);


System.out.println("int i = " + i);

System.out.println("long l = " + l);


System.out.println("float f = " + f);
System.out.println("double d = " + d);

}
}

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:

public class UsesConstants {


public static final double GRAVIDADE = 32;
14
Capítulo 2 – Estruturas Principais da Programação JAVA

public static void main (String[] args) {

System.out.println("A gravidade é: "+GRAVIDADE);


}
}

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.

Operador Operação Exemplo Resultado


+ Adição x = 1+2; x=3
- Subtracção x = 3-1; x=2
* Multiplicação x = 2*3; x=6
/ Divisão x = 6/2; x=3
% Módulo (resto da divisão inteira) x = 7%2; x =1
Incremento (equivale a x=x+1) x=1; x++; x=2
Equivale a y=x e x=x+1 x=1; y=0; x=2, y=1
++ y=x++;
Equivale a x=x+1 e y=x x=1; y=0; x=2, y=2
y=++x;
Decremento (equivale a x=x-1) x=1; x--; x=0
-- Equivale a y=x e x=x-1 x=1; y=0; y=x--; x=0, y=1
Equivale a x=x-1 e y=x x=1; y=0; y=--x; x=0, y=0
+= Soma e atribui (equivale a i=i+2) i=1; i+=2; i=3
-= subtrai e atribui (equivale a i=i-2) i=1; i-=2; i=-1
*= multiplica e atribui (equivale a i=i*2) i=1; i*=2; i=2
/= divide e atribui (equivale a i=i/2) i=2; i/=2; i=1
%= módulo e atribui (equivale a i=i%2) i=1; i%=2; i=1

2.6.1 Operadores Relacionais


Para comparar valores são usados os seguintes operadores relacionais:

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.

2.6.2 Operadores Lógicos


Os operadores lógicos operam apenas com operandos (variáveis) do tipo boolean. Esses
operadores servem para combinar expressões relacionais e devolvem como resultado um valor
boolean (true ou false).

Operador Resultado
&& AND lógico
|| OR lógico
! Negação

2.6.3 Precedência de Operadores


A tabela a seguir mostra a ordem de todas as operações possíveis em Java, de precedência mais
alta para mais baixa. Os operadores que estão no mesmo nível, geralmente, são processados da
esquerda para a direita na linha de comando.

Prioridade Operadores
Mais alta Casting
++, --, (prefixa)

16
Capítulo 2 – Estruturas Principais da Programação JAVA

*, /, %
+, -
<, <=, >, >=
==, !=
&&
||
=, +=, -=, *=, /=, %=
Mais baixa ++, --(postfixa)

2.7 Funções e Constantes Matemáticas


As funções e constantes matemáticas podem ser parte de expressões. Por exemplo, se quisermos
calcular a área limitada por uma circunferência de raio R, usamos a fórmula A = pR 2 ou se
quisermos calcular a diagonal (d) de um rectângulo de dimensões x e y, usamos a fórmula

d = x 2 + y 2 , isto é, a função da extracção da raíz quadrada é utilizada.

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:

A = Math.PI*Math.pow(R,2); //pow(R,2) é R*R ou R2


D = Math.sqrt(x*x+y*y); //x*x é x2

Algumas Funções Java

Função Java matemática valor de retorno


Math.abs(x) modulo de x |x| do mesmo tipo do argument
Math.atan(x) Arctgx x double, retorno double
Math.cos(x) Coxs x double, retorno double
Math.exp(x) ex x double, retorno double
Math.log(x) Lnx x double, retorno double
Math.pow(x,a) xa x double, a double, retorno double
Math.sin(x) sinx x double, retorno double
Math.round(x) arrendodamento de x x double, retorno long
Math.toDegrees(x) converte x para graus x double, retorno double
Math.roRadians(x) converte x para rad x double, retorno double
Math.random(x) gera número aletório no intervalo de [0.0*x.. 1.0*x]
Math.tan(x) tgx x double, retorno double

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

2.8 Conversões entre Tipos Numéricos


Qualquer operação numérica em variáveis de tipos diferentes será realizada da seguinte maneira:
• Se um dos operandos é do tipo double, o outro será tratado como um double no escopo
da operação;
• Senão, se um dos operandos for float, o outro será tratado como float;
• Senão, se um dos operandos é do tipo long, o outro será tratado como long;
• Senão, os operandos serão tratados como inteiros.

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:

byte ® short ® int ® long ® float ® double

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:

public class ConverteCaracteres {


public static void main (String args []) {
int i = 3;
char c = '1';
// converte char em inteiro. Ex: '1' -> 1
int res1 = Character.digit (c, 10);
// converte inteiro em char. Ex: 1 -> '1'
char res2 = Character.forDigit (i, 10);
System.out.println ("char -> int = " + res1);
System.out.println ("int -> char = " + res2);
}
}

2.9 Leitura de Dados

2.9.1 leitura com Scanner

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:

importar o pacote java.util:


[1]
import java.util.Scanner;
Instanciar e criar um objeto Scanner:
[2]
Scanner ler = new Scanner(System.in);
[ 3 ] Lendo valores através do teclado:

19
Capítulo 2 – Estruturas Principais da Programação JAVA

Lendo um valor inteiro:


int n;
[ 3.1 ]
System.out.printf("Informe um número para a tabuada: ");
n = ler.nextInt();
Lendo um valor real:
float preco;
[ 3.2 ]
System.out.printf("Informe o preço da mercadoria = R$ ");
preco = ler.nextFloat();
Lendo um valor real:
double salario;
[ 3.3 ]
System.out.printf("Informe o salário do Funcionário = R$ ");
salario = ler.nextDouble();
Lendo uma String, usado na leitura de palavras simples que não usam o caractere de
espaço (ou barra de espaço):
String s;
[ 3.4 ]
System.out.printf("Informe uma palavra simples:\n");
s = ler.next();
Lendo uma String, usado na leitura de palavras compostas, por exemplo, Pato Branco:
String s;
[ 3.5 ]
System.out.printf("Informe uma cadeia de caracteres:\n");
s = ler.nextLine();
Na leitura consecutiva de valores numéricos e String deve-se esvaziar o buffer do
teclado antes da leitura do valor String, por exemplo:
int n;
String s;

System.out.printf("Informe um Número Inteiro: ");


[ 3.6 ]
n = ler.nextInt();

ler.nextLine(); // esvazia o buffer do teclado

System.out.printf("Informe uma cadeia de caracteres:\n");


s = ler.nextLine();
Lendo um caractere usando o método read() do pacote de classes System.in:
public static void main(String args[]) throws Exception {
char c;
[ 3.7 ]
System.out.printf("Informe um Caractere: ");
c = (char)System.in.read();
}

20
Capítulo 2 – Estruturas Principais da Programação JAVA

2.9.2 leitura com JOptionPane

Nesta disciplina “FUNDAMENTOS DE PROGRAMAÇÃO”, ainda não temos meios gráficos


como caixa ou área de texto para introduzir dados. É claro que é possível escrever uma classe para
ajudar na introdução de dados mas a solução mais favorável de introdução de dados para iniciantes
na programação java que é utilizar a classe JOptionPane do 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) {

//get first input


String name = JOptionPane.showInputDialog("What is your
name?");

//get second input


String ageStr = JOptionPane.showInputDialog("How old are
you?");

//converte agStr paraInteger


int age = Integer.parseInt(ageStr);

//Display output on console


//tenha atenção: (age + 1) deve estar dentro de parentesis para ser
//a idadeno próximo ano

System.out.println("Hello, "+name+". Next year you'll be "+(age+1));


System.exit(0);

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:

Hello, FILZA AZIZE. Next year you'll be 23

Dica: teste o programa várias vezes, com dados diferentes, e também com dados incorrectos para
ver a saída.

Passo a passo:

Para uma leitura correcta de dados, faremos o seguinte:

1. No início do ficheiro, escreva:


import javax.swing.JOptionPane;

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:

• Um número inteiro, use o método Integer.parseInt(inputString);


• Um número real, use o método Double.parseDouble(inputString);
4. No fim do main escreva:
System.exit(0);

22
Capítulo 2 – Estruturas Principais da Programação JAVA

2.10 Impressao e Formatação de Saída


1. Funcionamento da instrução print/println
As instruções print e println funcionam quase da mesma maneira havendo diferença apenas no
facto de que, o println move o cursor (invisível mas existente) para linha seguinte depois de
visualizar a informação, enquanto o print não o faz, ou seja, mantém o cursor na mesma linha.

A sintaxe da instrução println/print é:


println(lista de itens);

• se um item é um String, o conteúdo do String será imprimido;


• se um item é uma variável, o valor da variável será imprimido;
• se um item é uma expressão, o valor da expressão será imprimido;
• se um item é um objecto, o método toString() do objecto será chamado.

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

3 Estruturas de Controle do Java


Resumo Teórico

Neste capítulo, abordaremos os seguintes pontos:

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.

3.2 Instruções condicionais


Na programação, torna-se necessário para o programador, tratar uma certa condição. Por exemplo,
quando resolvemos a equação quadrática, ax 2 + bx + c = 0 , a existência de raízes reais depende da
condição b 2 - 4ac ³ 0 . O programa pode continuar o cálculo das raízes caso se cumpra a
condição, ou imprimir uma mensagem afirmando que não existem raízes.

Java tem duas formas de instruções condicionais.

1. Primeira forma
if (condição) instrução;

Execução: se a condição for verdadeira, executa a instrução. Na posição da instrução pode


haver um bloco ou vazio. É de notar que a condição é sempre escrita entre parentesis.

Exemplo: se x ³ 0 calcula a raíz quadrada de x

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!

Exemplo: o seguinte conjunto de instruções calcula as raízes da equação quadrática:

delta = b*b – 4*a*c;

if ( delta >= 0 ) { //um bloco de 2 instruções


double r1 = (-b + Math.sqrt(delta))/(2*a);
double r2 = (-b – Math.sqrt(delta))/(2*a);

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:

Imprima o valor máximo entre x e y


if ( x < y ) max = y; else max = x;

System.out.println("Max = " + max);

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:

if ( notaFrequencia < 10 ) classificacao = "EXCLUÍDO"; else

if ( notaFrequencia < 14 ) classificacao = "ADMITIDO"; else


classificacao = "APROVADO";

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

3.3 Multiselecções Switch


É possível utilizar uma sequência de instruções if … else para a multiselecção, mas isso pode ser
redundante. Java tem a instrução switch que nalguns casos pode substituir as instruções if … else
e com maior eficiência.

Esta instrução tem a seguinte sintaxe:


Switch (selector) {
case VALOR1 : intrução1; break;
case VALOR2 : instrução2; break;
…………………………………………………………………………………
case VALORn : intruçãon; break;
default : intruçãoDefault; break;
}

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;

public class UltimoDiaDoMes2013 {


public static void main(String[] args) {
int mes, ultimodia = 0;
//introduzindo um mes;
String mesStr = JOptionPane.showInputDialog("Introduza um
mês:");
mes = Integer.parseInt(mesStr);
//avaliacao do mês introduzido

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);
}
}

Obs: pode substituir a intrução switch acima pela seguinte:

switch ( mes ) {

27
Capítulo 3 – Estruturas de Controle do JAVA

case 1: case 3: case 5: case 7: case 8: case 10: case 12:


ultimodia = 31; break;
case 2: ultimodia = 28; break;

case 4: case 6: case 9: case 11: ultimodia = 30; break;


default: System.out.println(“O mês deve ser de 1 a 12”);
}

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

while (condição) bloco

//execução
Enquanto a condição for verdadeira executa a instrução

b) do … while

do bloco while (condição)

//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:

int n = 10; int i = 1; int s = 0;


while ( i < n) {
28
Capítulo 3 – Estruturas de Controle do JAVA

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

Execução: Executa o corpo do ciclo enquanto a condição de continuação for verdadeira.

Nota: É proibido alterar o valor da variável de controlo dentro do corpo do ciclo.

Exemplos:

Exemplo 1.
int i;

for (i = 0; i < 10; i++ ) System.out.println(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:

for ( int i = 1; i <= 3; i++ ) { //outter loop


for ( int k = 1; k <= 4; k++ ) { //inner loop
System.out.println(i*k + ‘\t’);
}
System.out.println();
}

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

Esse código imprime a matriz na forma natural:

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.

1. Array de uma dimensão


a) Declaração de array com os símbolos []

O array de uma dimensão é declarada da seguinte forma:

tipo_de_dado [] nome_da_variável;
//por exemplo:
int[] a; //a é array unidimensional podendo armazenar números inteiros

b) Criação do array com o operador new, por exemplo

int[] a = new int[100]; //array tem memória para conter até 100 inteiros

c) índice ou posição de um elemento do Array.

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.

d) Inicialização de um array. Por exemplo

int[] smallPrimes = { 2, 3, 5, 7, 11, 13};

Nesta inicialização, a parte da esquerda da atribuição é a declaração do array de nome smallPrimes,


a parte na direita é o valor inicial atribuído ao array. A lista de valores iniciais contém valores
ficando dentro de chavetas, e separados por vírgula.

e) Para saber o número de elementos de um array, usa-se a seguinte sintaxe:

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:

//o ciclo significa: começando com 1º elemento até ao último


for ( int i = 0; i <smallPrimes.length; i++ )
System.out.println(smallPrimes[i]);

f) O acesso a um elemento individual do array é feito com a seguinte sintaxe:

nome_do_array[indice];
sendo 0 ≤ índice ≤ length-1

Por exemplo, smallPrimes[i] é o acesso ao elemento na posição i ( 0 ≤ i ≤ 5) do array smallPrimes.

g) Array anónimo. É possível criar um array sem nome como no seguinte exemplo:

new int[] = { 17, 19, 23, 29, 31, 37 };

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

É possível a seguinte instrução:

int[] anyArr = { 17, 19, 23, 29, 31, 37};


smallPrimes = anyArr;

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);

2. Array de duas dimensões

Temos os mesmo problemas de declaração, criação, inicialização e atribuição para um array


bidimensional. Estudamos isso através de um exemplo.

Declaração de uma matriz de nome matriz dos inteiros: int [] [] matriz;

Criação de matriz 4 linha, 4 colunas: matriz = new int [4] [4];

Se for para inicializar podemos escrever:

int[] [] matriz = {{ 1, 2, 3, 4}, { 2, 3, 4, 5}, { 3, 4, 5, 6}, { 4, 5, 6, 7}}

Esta inicialização, inicializa o seguinte array:

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;

Número de linhas da matriz: matriz.length

E o número de colunas da matriz: matriz[0].length ( é o número de elementos da primeira linha


da matriz )

Para imprimir a matriz da sua forma natural, usa-se um ciclo duplo:

for ( int i = 0; i < matriz.length; i++ ) { //outter loop


for (int k = 0; k < matriz[0].length; k++) { //inner loop
System.out.print( matriz[i][k] + “\t” );
}
33
Capítulo 3 – Estruturas de Controle do JAVA

System.out.println(); //passa para outra linha depois de cumprir inner loop


}

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.

String meuNome, dataNascimento; //declaração de tipo String

String meuNome = “AMARILDO”; //inicialização


String meuNome = new String(“AMARILDO”); //criação de um objecto com new

O String é frequentemente utilizado na instrução println() para visualizar uma mensagem no


concole. Com String podemos fazer muitas operações, a seguir as mais utilizadas (algumas):

• Comprimento: int length()


• Caractere numa dada posição: char charAt( index )

Exemplo:

String meuDepartamento = “Depart. Matemática e Informática”;


System.out.println(meuDepartamento.length()); //imprime 32
System.out.println(meuDepartamento.charAt(8)); //imprime M

• Concatenação de 2 String: usar o operador +

Exemplo:

String apelido = “COSSA”;


String nomes = “Osvaldo Fernando”;
System.out.println(apelido+”,”+nomes); //COSSA, Osvaldo Fernando
System.out.println(nomes+”,”+apelido); //Osvaldo Fernando, COSSA

• 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”;

st2 = JOptionPane.showInputDialog(“Introduza o seu Password”);

if (st1.equals(st2)) System.out.println(“Password Correct!”);

else System.out.println(“Password incorrect!”);

Nota: String tem muita utilização em qualquer linguagem de programação. Em java podemos
utilizar até 3 classes sobre String.

public class String contém serviços comuns

public class StringBuffer contém serviços para input/output

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

Neste capítulo, estudamos os seguintes tópicos:

1. Introdução a OOP (Object Oriented Programming )


2. Classe e Objectos Classe e Objectos de uma classe que nem no índice
3. Construção de Objectos Construção de Objectos de uma classe que nem no índice
4. Modificadores public, protected, private, static, final acho relevante colocarmos o
modificador protected tambem no índice e no início do tópico 4 deste capítulo assim como
se foi feito aqui no Resumo Teórico
5. Métodos da classe
6. Parâmetros de métodos
7. Pacote (package)
8. Sugestão de que nem no índice desenho de classes

4.1 Introdução a OOP (Programação Orientada a Objectos)

Na programação procedural (comoem como em Pascal, por exemplo) criam-se procedimentos


(procedure) e funções (function) e passam parâmetros actuais para esses procedimentos e funções
para eles executarem. Quando o programa se torna grande, só uma alteração pequena no programa
faz com que o programador devesse fazer um rastreio em todo código do seu programa. Nicolas
Wirth, o pai da linguagem de programação Pascal, definiu programação procedural como seguinte:
Programa = Algoritmo + Dados

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

Os dados e comportamentos de um objecto são combinados no próprio objecto. Quando falamos


de um carro já sabemos o que um carro tem e o que pode fazer.
Em termos de programação orientada a objecto (OOP), a combinação de dados e comportamentos
no objecto é o encapsulamento (encapsulation). Cada comportamento que o objecto sabe
comunicar ao mundo é chamado de um método dele. Quando manda um objecto executar um seu
método, o programa dá-lhe uma mensagem (message).

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.

4.2 Classe e Objectos de uma classe


1. Classe
Em JAVA, classe é uma estrutura que define objectos. A classe JAVA contém os campos de dados
e métodos. A forma geral de uma classe é a seguinte:
classnome class nome acho relevante colocar o espaço para deixarmos sozinha a palavra
reservada class
{
campos de dados
métodos
}

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

//área de campos de dados


private String nome;
private double salario;

//alguns metodos
public Trabalhador( String seuNome, double seuSalario)
{ nome=seuNome; salario=seuSalario;}

public String getNome(){ return nome;}

public double getSalario(){ return salario;}


}

2. Declaração e criação de objectos


A classe é uma fórmula para produzir objectos. Um objecto, ou uma instância de uma classe é uma
entidade produzida com essa fórmula. Podemos declarar objectos com a seguinte sintaxe:
Nome_da_classe Nome_do_objecto
Por exemplo:
Trabalhador luis; //luis é o objecto, Trabalhador é o nome da classe
É a declaração do objecto luis e este é do tipo Trabalhador.
A declaração acima feita não é ainda a criação do objecto. Isto é, o objecto luis ainda não tem lugar
na memória do computador. A criação será feita com o operador new por exemplo:
Trabalhador luis = new Trabalhador(“Luis”,3000.0);
E apos isso, diz se diz-se também que luis é uma instância da classe Trabalhador.
Ou com 2 linhas: Ou com 2 linhas: a negrito uma vez que “Por exemplo” está a negrito
Trabalhador luis;
luis= new Trabalhador(“Luis”,3000.0);

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

public class Estudante {

// declaração das variáveis da classe Estudante

private String nome;

private double notaFrequencia;

//metodo construtor

public Estudante (String nome, double notaFrequencia) {

this.nome = nome; //this refere ao objecto desta classe

this.notaFrequencia = notaFrequencia;

//metodos de retorno (metodos get)

public String getNome () {

return nome;

public double getNotaFrequencia () {

return notaFrequencia;

//método para calculo da nota media

public void calculoDaNota (double teste1,double teste2) {

notaFrequencia = (teste1 + teste2)/2;

39
Capítulo 4 – Classes e Objectos

//utilização do método main para impressão

public static void main(String[]arg){

Estudante ana = new Estudante("ANA",0); // Criação e //construção


da instância “ana”.

// Impressão sem a chamada do método calculoDaNota

System.out.println("Estudante:
"+ana.getNome()+'\n'+"Nota de Frequencia:
"+ana.getNotaFrequencia());

ana.calculoDaNota(16, 12); //chamada ao método


//calculoDaNota…recebe 2 parâmetros

//Impressão depois da chamada do método calculoDaNota

System.out.println("Estudante:
"+ana.getNome()+'\n'+"Nota de Frequencia:
"+ana.getNotaFrequencia());

Nesse programa criamos o objecto ana com a linha:


Estudante ana = new Estudante("ANA",0);
E depois mandamos a execução dos seguintes métodos:
ana.getNome(), ana.getNotaFrrequencia() e ana.calculoDaNota()…
b) Variante II:Usando duas classes uma para definir o trabalhador e outra para testar

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

//Esta classe precisa a classe Estudante

public class EstudanteTesta { public class EstudanteTeste {

public static void main(String[] args) {


//criação do objecto
Estudante ana = new Estudante("Ana", 0);

// Impressão sem a chamada do método calcaluDaNota


System.out.println("Estudante: " + ana.getNome() + '\n' +
"Nota de Frequencia: " + ana.getNotaFrequencia());

ana.calculoDaNota(16, 12); //chamada ao método


//calculoDaNota…recebe 2 parâmetros

//Impressão depois da chamada do método calculoDaNota


System.out.println("Estudante: " + ana.getNome() + '\n' +
"Nota de Frequencia: " + ana.getNotaFrequencia());
}

} faltava o método main(String[] args) neste exemlplo ; acho também


relevante declararmos o nome da classe como EstudanteTeste

//criação do objecto

Estudante ana=new Estudante(“Ana”,0);

4.2.1

// Impressão sem a chamada do método calcaluDaNota

System.out.println("Estudante:
"+ana.getNome()+'\n'+"Nota de Frequencia:
"+ana.getNotaFrequencia());

4.2.2

ana.calculoDaNota(16, 12); //chamada ao método


//calculoDaNota…recebe 2 parâmetros

4.2.3

//Impressão depois da chamada do método calculoDaNota

System.out.println("Estudante:
"+ana.getNome()+'\n'+"Nota de Frequencia:
"+ana.getNotaFrequencia());

41
Capítulo 4 – Classes e Objectos

//esta classe é usada pela classe EstudanteTesta

public class Estudante {

// declaração das variáveis da classe Estudante

private String nome;

private double notaFrequencia;

//metodo construtor

public Estudante (String nome, double notaFrequencia){

this.nome = nome; //this refere ao objecto desta classe

this.notaFrequencia = notaFrequencia;

//metodos de retorno (metodos get)

public String getNome () {

return nome;

public double getNotaFrequencia () {

return notaFrequencia;

//método para calculo da nota media

public void calculoDaNota (double teste1,double teste2) {

notaFrequencia = (teste1 + teste2)/2;

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:

EstudanteTesta.java para guardar o conteúdo da public class EstudanteTesta


Estudante.java para guardar o conteúdo da public class Estudante

A segunda variante é que usa um ficheiro apenas:

EstudanteTesta.java para guardar o conteúdo das duas classes


public class EsudanteTesta (pública contendo o main())
class Trabalhador (não pública)

4.3 Construção de objectos de uma classe


1. Princípios

Como no exemplo anterior, utilizamos o construtor na criação do objecto ana

Estudante ana = new Estudante(“Ana”,0);

No caso geral, usam-se construtores para entregar o estado inicial aos objectos.

A utilização de construtores deve sujeitar os seguintes critérios:

• Um construtor tem o mesmo nome da classe


• Um construtor é sempre prefixado com a palavra reservada public
• Uma classe pode ter zero, um ou mais construtores
• Um construtor pode ter zero, um ou mais parâmetros
• Um construtor não devolve valores (não tem instrução return, nem do tipo void)
• Um construtor é sempre chamado pela instrução new com objectivo de criar um objecto e
estabelecer o estado inicial ao objecto
2. Overloading

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.

3. Inicialização dos campos de dados por defeito

Se o programador não inicializa explicitamente um campo no constructor, esse campo é


automaticamente inicializado por defeito.

• Campo numérico: inicializado com zero


• Campo booleano: inicializado com false
• Campo caractere: inicializado com o caractere ‘\u0000’

43
Capítulo 4 – Classes e Objectos

• Campo objecto: inicializadocom inicializado com null

Java não inicializa por defeito para variável local dentro dos métodos.

4. Construtor por defeito (default construtor)

O construtor por defeito é aquele construtor que não tem parâmetros

• 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.

4.4 Modificadores public, protected, private, static, final


Chamaremos um campo de dados, um método, ou a própria classe por membro da classe. Cada
membro pode ser acompanhado com uma ou mais palavras reservadas public, private, static,
final. Cada uma dessas palavras é um modificador (modifier) usado para intervir no acesso aos
membros da classe.

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;

Nota: A utilização de modificadores é opcional. Se um membro não usa modificadores, a


visibilidade dele é entendida por defeito como (package), isto é, só é visível para as classes que se
encontram no mesmo pacote.

1. Formato geral de métodos

44
Capítulo 4 – Classes e Objectos

No caso geral um método tem a seguinte forma:

Modificadores Tipo_de_retorno Nome_do-metodo (lista de parametros)


{ //corpo do método
//instruções que definem o que o método faz
}

Por exemplo, no método main:

public static void main (String [] args) {


//instruções
}

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}

A cabeça de um método pode conter:

• Modificadores: (public, static, void, final), são opcionais, mas se existirem, os


modificadores informam ao compilador a maneira de chamar o método.
• Tipo de valor de retorno, obrigatório. O valor de retorno pode ser primitivo (int, double,
boolean, char) ou objecto (do java ou definido pelo programador). Se o método não tem
valor de retorno, obrigamos que a retornar retorne o tipo void (nada).
• Nome do método, obrigatório. Este deve ser qualquer nome legal do java.
• Lista de parâmetros, é opcional, dependendo de cada método concreto.

O corpo do método, é um conjunto de instruções ficando dentro de chavetas. O corpo define o


trabalho que o método irá executar quando for chamado.

2. Métodos de acesso e método de estabelecimento

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:

public String getNome () {return nome;}


//por ser public, o método getNome() é utilizado por todo mundo (classes)

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:

public String getNome() {


return nome;
}
public void setNotaFrequencia(double novaNota) {
notaFrequencia= novaNota;
}

3. Palavra-chave return

Este comando é usado para retornar um valor. A forma geral é a seguinte:

return expressão;

onde expressão pode ser variável, funções e objectos.

• É 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

Usando o símbolo de ponto (.) para separar o objecto do nome do método.

Critérios de chamada correcta de um método:


• Há uma correspondência rigorosa entre os parâmetros actuais e os formais em número, ordem
(posições) e tipo de dados.
• Se o método for do tipo void, a chamada a ele é uma instrução independente, se o método for
uma função, a chamada é só uma parte de uma expressão.
Quando há uma chamada ao método executa-se as seguintes acções:

• No lugar da chamada há um salto para o método chamado;


• Executa-se a passagem de parâmetros actuais para formais respectivos (se existirem);
• Executa-se o corpo do método;
• No fim da execução do corpo do método (a última instrução ou o return) será a entrega do
valor de retorno (para a função, se existir) e continuará o fluxo do programa.

4.5 Parâmetros de métodos

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.

Há dois casos importantes da passagem de parâmetros em Java.

1. Passagem com valores primitivos

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.

2. Passagem com objectos

É possível mudar o estado de um objecto – parâmetro actual na passagem de parâmetros.


Consideremos o seguinte exemplo:
//Classes TestaParametros e Empregado. Para poder correr coloquei uma
como publica, no caso foi //a classe TestaParametros.
public class TestaParametros{
public static void main(String[]args){
System.out.println("Teste: triploSalario(double taxa):");

47
Capítulo 4 – Classes e Objectos

System.out.println("Passagem de parametros primitivos - double


taxa");
double taxa=10;
System.out.println("Antes da chamada, taxa="+taxa);
triploSalario(taxa);//chamada ao metodo com param. double - taxa
System.out.println("Depois da chamada, taxa="+taxa);

//Teste2:
System.out.println("-----------------------------");
System.out.println("Passagem de parametros - objectos do tipo
Empregado");
System.out.println("Teste outra vez: triploSalario(Empregado
x)");

Empregado luis = new Empregado("Luis",5000);// criacao do


objecto luis

System.out.println("Antes da chamada, salario="


+luis.getSalario());

triploSalario(luis);//chamada ao metodo com param. objecto luis

System.out.println("Depois da chamada, salario="


+luis.getSalario());
}
public static void triploSalario(double x){
x=3*x;
System.out.println("Fim do metodo x="+x);
}
//overloading triploSalario
public static void triploSalario(Empregado x){
x.aumentoSalario(200);
//chamada ao metodo do objecto x, este x muda seu estado
propriamente
System.out.println("Fim do metodo salario="
+x.getSalario());

48
Capítulo 4 – Classes e Objectos

}
}
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
}
private String nome;

private double salario;


}

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.

No exemplo, os métodos triploSalario(Empregado x) e triploSalario(double taxa) são


overloading, à custa do tipo de parâmetros, Java sabe chamar correctamente o método pretendido.

49
Capítulo 4 – Classes e Objectos

Saída do programa:

Teste: triploSalario(double taxa):


Passagem de parametros primitivos - double taxa
Antes da chamada, taxa=10.0
Fim do metodo x=30.0
Depois da chamada, taxa=10.0
-----------------------------
Passagem de parametros - objectos do tipo Empregado
Teste outra vez: triploSalario(Empregado x)
Antes da chamada,salario=5000.0
Fim do metodo salario=15000.0
Depois da chamada,salario=15000.0

3. Dados e métodos Estáticos

Neste ponto, explicamos o significado do modificador static.

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:

public class Aluno {


private String nome;
private int idade;
private static String uniformeCor; //variável da classe
------------------------
}

50
Capítulo 4 – Classes e Objectos

O acesso a um campo estático pode ser o seguinte:

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:

System.out.println(Aluno.uniformeCor); //usando o nome da classe


System.out.println(luis.uniformeCor); //usando um objecto da classe Aluno

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();

id = idSeguinte(); //guardando o valor actual da idSeguinte


idSeguinte++; //aumento de uma unidade para idSeguinte

O programa completo:

public class TestaStatic{


//Precisa da classe Empregado
public static void main (String[] args) {
Empregado[] staff=new Empregado[3]; //Criacao do array com
3 Empregados
staff[0]=new Empregado("Tom",4000);
staff[1]=new Empregado("Dick",6000);
staff[2]=new Empregado("Harry",6500);

//imprime informacao de todos os Empregados


for(int i=0;i<staff.length;i++){
Empregado e=staff[i];

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
}

4.6 Pacote (package)


Pacote é uma colecção de classes. O programador pode colocar as classes completas no seu pacote
e de seguida vender para outros programadores. A própria linguagem java possui muitos pacotes,
por exemplo, a versão 1.4.0 tem 61 pacotes, a versão 1.6.0 tem 202 pacotes.

1. Alguns pacotes importantes do Java:

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

Utilize a instrução import para importar o pacote, por exemplo:

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

3. Criação do seu próprio pacote

Se o programador não define um pacote, o seu programa irá pertencer ao “default package” –
pacote por defeito.

O programador pode criar o seu pacote com o seguinte procedimento:

1. Criar um novo subdirectório (pasta) dentro do seu projecto


2. Corrigir a variável de ambiente CLASSPATH de modo a conter esse subdirectório
3. Escrever na 1ª linha de cada classe do pacote a seguinte instrução

package <nome do pacote>;

4. Depois de tudo isso, poderá usar o seu pacote como qualquer outro pacote padrão do Java.

4.7 Sugestão de desenho de classes


O desenho de classes é muito importante na OOP. Um desenho com cuidado permite controlar
com facilidades o funcionamento do programa. Primeiramente, o programador deve dividir o seu
problema em subproblemas e dividir os subproblemas em subproblemas de modo que cada
problema possa ser resolvido numa classe. Se o encapsulamento de dados e métodos na classe é
bem organizado, é fácil detectar erros e de manipular o programa.

Boas práticas para o desenho de classes:

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.

Use as convenções do Java para nomenclatura dos métodos e identificadores.

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

5 Introdução aos Applets e Gráficos


Resumo Teórico:

1. Introdução a programação gráfica


2. Sitemas de coordenadas no modo gráfico
3. Objectos da classe Graphics
4. Métodos da classe Graphics
5. Desenho e Pintura de Sectores
6. Utilização de Cores
7. Font
8. Método paintComponent()
9. Polygon
10. Introdução a Applet

5.1 Introdução a programação gráfica


Talvez o leitor sinta que ainda não tenha começado verdadeiramente a programar ou construir
aplicações úteis. Talvez esperasse logo de início, desenvolver aplicações com interfaces gráficas muito
atractivas e cheias de detalhes. Realmente, programar em uma linguagem de programação não se
resume apenas em criar um código que resolva pequenos problemas matemáticos e (ou) de lógica.

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.

5.2 Sistemas de Coordenadas no modo gráfico


No contexto de programação gráfica o ecrã é considerado um sistema cartesiano de coordenadas, e
cada ponto é chamado de pixel (picture element). O eixo Ox é representado como na matemática, mas
o eixo Oy é diferente pois os valores crescem de cima para baixo.

57
Capítulo 5 – Introdução aos Applets e Gráficos

5.3 Objectos da classe graphics


A classe Graphics fornece alguns métodos para desenhar figuras gráficas como rectas, elipse e
circunferência, rectângulo, polígono…, e qualquer outra figura composta pelos componentes acima
descritos. Para desenhar as figuras, utilizamos um objecto da classe Graphics, que estabelece o ambiente de
desenho, da seguinte forma:
Graphics g

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:

public void paint(Graphics g)

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).

Métodos de instâncias da classe Graphics

58
Capítulo 5 – Introdução aos Applets e Gráficos

Alguns métodos de instância da classe Graphics são mostrados abaixo.

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:

5.4 Métodos da classe Graphics


public void drawLine(int x1, int y1, int x2, int y2) - desenha uma linha entre o ponto (x1,y1) e o
ponto (x2, y2).

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.

5.5 Desenho e pintura de sectores


Um sector de elipse (ou de circulo) é determinado por dois ângulos, startAngle e arcAngle. Os

métodos para desenhar e pintar um sector são:

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.

5.6 Utilização de cores


Para determinar uma cor do objecto, utiliza-se a classe Color.

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:

Color.BLACK, Color.BLUE, Color.CYAN, Color.DARK_GRAY, Color.GRAY, Color.GREEN,


Color.LIGHT_GRAY, Color.MAGENTA, Color.ORANGE, Color.PINK, Color.RED,
Color.WHITE, Color.YELLOW

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:

newColor = new Color(120,82,200); // Red=120, Green=82, Blue=200

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 class Drawing extends JPanel{


private int op;

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);

g.fillRoundRect(10, 185, 200, 150,15,10);//rectangulo pintado com a cor azul

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

//dois metodos para correr a aplicacao


private static void createAndShowGUI(){
//Criacao da Janela (Window)
JFrame frame=new JFrame("Drawing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

JComponent newContentPane= new Drawing();


newContentPane.setOpaque(true);
frame.setContentPane(newContentPane);

frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {

javax.swing.SwingUtilities.invokeLater(new Runnable() {

public void run() {


createAndShowGUI();
}
});
}
}

As saídas com as opções 4 e 5 respectivamente:

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:

public void barColors(Graphics g, Color c, String colrName, int y){


g.setColor(c);
g.fillRect(10,y,20,20); //rectangulo pintado com a cor c
g.setColor(Color.BLACK);
g.drawString(colorName,40,y+15); //nome da cor sai preto
}

Os parâmetros têm seguintes significados:

• 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

public class ColorList extends JPanel{

private Color[] color = { Color.BLACK, Color.BLUE, Color.CYAN, Color.DARK_GRAY,


Color.GRAY, Color.GREEN, Color.LIGHT_GRAY, Color.MAGENTA, Color.ORANGE,
Color.PINK, Color.RED, Color.WHITE, Color.YELLOW };

private String[] colorName={"Black","Blue","Cyan","Dark_Gray","Gray","Green",


"Light_Gray","Magenta","Orange","Pink","Red","White","Yellow"
};
public ColorList(){
setPreferredSize(new Dimension(300,400));
}
public void paintComponent(Graphics g){
super.paintComponent(g);
int inicialY=10;
int separation=22;
for(int i=0;i<color.length;i++){
barColors(g,color[i],colorName[i],inicialY);
inicialY=inicialY+separation;
}
barRandomize(g,50,inicialY+10);
}
public void barColors(Graphics g, Color c, String colorName, int y){
g.setColor(c);
g.fillRect(10, y, 20, 20);
g.setColor(Color.BLACK);
g.drawString(colorName, 40, y+15);
}
public void barRandomize(Graphics g, int x, int y){

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);

JComponent newContentPane= new ColorList();


newContentPane.setOpaque(true);
frame.setContentPane(newContentPane);

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:

5.7 Utilização de Font


O objecto Font é utilizado na programação de textos com estilos e tamanhos diferentes. Juntando com
as cores, podemos apresentar textos bonitos para vários fins.

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:

SansSerif, Serif, Monospaced, Dialog, DialogInput

Para criar um objecto font, pode se utilizar o construtor:

Font font = new Font(fontNome, fontStyle, fontSize);

Os tamanhos do Font variam frequentemente entre 8 a 72. Na visualização de um texto, definimos


uma cor, uma font, e uma posição onde começa o texto. Por exemplo, para visualizar o texto “Hello
World !” , na cor verde, com tamanho 40, e na posição (10,100) podemos escrever:

String message = “Hello World”;


Font myFont = new Font(“SansSerif”,Font.BOLD,40);
g.setFont(myFont) //g- objecto da classe Graphics

68
Capítulo 5 – Introdução aos Applets e Gráficos

g.drawString(message, 10, 100);


Exemplo:

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 class FontList extends JPanel{

public FontList(){
setPreferredSize(new Dimension(300,400));
}

public void paintComponent(Graphics g){


super.paintComponent(g);
String fontListe[]; //contem fontList num array
fontListe=getToolkit().getFontList(); //recebe-se a lista de fontes
int i;
int startY=15;

//Visualiza 3 estilos: PLAIN, BOLD e Italic

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;
}
}

private static void createAndShowGUI(){


//cria e monta a janela
JFrame frame=new JFrame("Show fonts and Styles");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

//cria e prepara o conteudo


JComponent newContentPane=new FontList();
newContentPane.setOpaque(true);
frame.setContentPane(newContentPane);

//mostra a janela

frame.pack();

70
Capítulo 5 – Introdução aos Applets e Gráficos

frame.setVisible(true);
}

public static void main(String [] args){


//mostrar a aplicacao GUI
javax.swing.SwingUtilities.invokeLater(new Runnable() {

public void run() {


createAndShowGUI();
}
});
}
}

Saida:

5.8 Método paintComponent()


Como vimos nos dois exemplos anteriores, utiliza-se o método paintComponent() cuja forma completa
é a seguinte:

71
Capítulo 5 – Introdução aos Applets e Gráficos

public void paintComponent( Graphics g){


super.paintComponent(g); //é obrigatória esta chamada neste 1º lugar
//acção de desenho nessa área
//podemos desenhar directamente ou chamar os metodos que desenham
}

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.

5.9 Classe Polygon


Uma figura complexa composta de muitos segmentos de rectas, o mapa de Moçambique por exemplo,
pode ser definida como um polígono. Pode utilizar o método drawPolygon() para visualizar a figura
(o polígono) ou fillPolygon() para pintar o polígono. Um polígono é determinado pelos dois arrays
das coordenadas de vértices como seguinte:

Polygon p=new Polygon(int[] x, int[] y, int numberPoints)

Exemplo 4:

Desenharemos o mapa de Moçambique. Para simplificar, desenhamos so a fronteira do país, quanto a


fronteira de províncias a questão é semelhante. Os arrays de coordenadas podem ser obtidos ao fazer
o seguinte procedimento:

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[]x = {230, 230,195,160,137,105,103,112,117,119,


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,

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;

public class MapaMoz extends JPanel{

//coordenads da fronteira de Mocambique ficam em 2 arrays x e y


private int[]x={230,230,195,160,137,105,103,112,117,119,

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

private static final int transX=80; //translacao X e Y para que o mapa


private static final int transY=10; //seja centrado no painel

public MapaMoz(){
setPreferredSize(new Dimension(400,450));
}

public void paintComponent(Graphics g){


super.paintComponent(g);
drawMozambique(g,Color.RED,x,y,50);
}

private void drawMozambique(Graphics g, Color c, int[]x,int[]y,int numPoints){

Polygon p=new Polygon(x,y,numPoints);


p.translate(transX, transY);//translacao do mapa para um lugar central
g.setColor(c);
g.fillPolygon(p);
}

private static void createAndShowGUI(){


//cria e monta a janela
JFrame frame=new JFrame("Mapa Mozambique");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

//cria e prepara o conteudo


JComponent newContentPane=new MapaMoz();
newContentPane.setOpaque(true);

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:

5.10 Introdução a Applets


Até agora os nossos programas são aplicações, isto é, são programas que podem correr sozinhos
(stand-alone application ). Ao contrário, os applets não podem ser executados sozinhos e sempre
precisam de um ficheiro HTML (Hyper Text Markup Language). HTML é uma linguagem

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.

1. Classes Applet e JApplet

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.

Nota: Um applet pode não ter todos os 4 métodos acima citados.

Exemplo

Faremos um exemplo simples da Applet. Apresentaremos a seguinte mensagem na forma de Applet:

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
*/

public void init() {


//TODO start asynchronous download of heavy resources
}
public void paint(Graphics g){
g.setColor(Color.RED);

77
Capítulo 5 – Introdução aos Applets e Gráficos

g.setFont(new Font("Serif", Font.PLAIN, 36));


g.drawString("Welcome to Java", 10, 60);
}
}

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.

2. Ficheiro HTML associado

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:

< applet code =”Hello.class”


Width = “300”
Height = “200” >
</applet >

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.

4. Sugestão na programação de applet


o Ofereça uma classe que estenda da JApplet ou Applet com modificador public.
o Apague o método main(), não use o Jframe. O Applet será visualizado na página web.
o Passe as inicializações do frame para o método init(). Não deve construir explicitamente o
objecto JApplet. O browser inicializa-o quando chamar o método init()
o Apague o método setSize(), o applet terá tamanho com parâmetros width w height h do
ficheiro .html associado.
o Se o applet tem chamada para setTitle apague-a passando o título para o ficheiro .html com
a tag title.
o Não chame o setVisible(), o applet será visualizado automaticamente
o Cria um ficheiro HTML na mesma pasta para carregar o applet.

Nota: Alguns assuntos que aqui não são discutidos acerca de applets:

• Segurança para applets


• Passagem de parâmetros de HTML para applet
• Popup windows no applet
• Multimedia
• Animação
• URL

79
Capítulo 7 – Ficheiros de Texto

6 Interface Gráfica do Utilizador


Resumo teórico

Neste capítulo abordamos os seguintes tópicos:

• 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”.

Veja a seguir a hierarquia das classes gráficas:

/***ANEXAR FIGURA***/

6.2 A classe JComponent


A raiz de classes gráficas na biblioteca AWT é a classe abstracta Component, que representa
qualquer objecto que pode ser apresentado na tela e ter interacção com os utilizadores. Os
componentes definidos na biblioteca Swing têm por raiz a classe JComponent, que é uma
extensão de Component.
Uma das subclasses de JComponent amplamente utilizada no desenvolvimento de aplicações
gráficas é o JContainer cuja instância pode conter outros componentes.
A classe JComponent define propriedades e funcionalidades que dizem respeito à manipulação de
qualquer componente gráfico em Java. Por exemplo, todo componente tem uma propriedade que

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.

6.3 Layout Manager – O que é? Para que serve?

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.

Em outras linguagens de programação só é possível apenas definir a organização dos componentes


marcando seus tamanhos e extensões através de pixels. Embora seja mais simples, isso traz como
desvantagem a não garantia de usabilidade de nossa interface em outras plataformas. Pois ao
posicionar componentes visuais de forma fixa, variações de alguns pixels numa outra plataforma
no contorno dos botões, por exemplo, pode desconfigurar a nossa interface.

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.

A seguir veremos a descrição de alguns Laytout Managers e exemplos de uso.

Nota: O Java também possibilita a marcação fixa em pixels de diversos elementos da


interface para quem assim desejar, através do método setBounds().

• 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;

public FlowLayout(int alignment)


Os componentes são adicionados com o seu alinhamento definido através do construtor;

public FlowLayout(int alignment, int hgap, int vgap)


Os componentes são adicionados com o seu alinhamento definido através do construtor,
juntamente com o seu número de pixels de espaçamento horizontal e vertical.

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;

public GridLayout(int row, int col)


A grelha de componentes é criada com o número de linhas (row) e colunas (col) determinados no
construtor;

public GridLayout(int row, int col, int hgap, int vgap)


A grelha de componentes é criada com o número de linhas (row) e colunas (col), juntamente com
a separação horizontal (hgap) e vertical (vgap) determinado no construtor.

Exemplos:

//O 1° constructor

82
Capítulo 7 – Ficheiros de Texto

GridLayout meuLayout = new GridLayout();

//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;

public BorderLayout (int hgap, int vgap)


Cria um BorderLayout com separação horizontal e vertical;

Exemplos:

import java.awt.*;
import javax.swing.*;

public class JanelaBorder extends JFrame {

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

add(new JButton("East"), BorderLayout.EAST);


add(new JButton("West"), BorderLayout.WEST);
add(new JButton("Center"), BorderLayout.CENTER);
}

Public static void main(String[] args) {


JanelaBorder j = new JanelaBorder();
j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
j.setVisible(true);
}
}

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.

6.4 Componentes SWING


Ao fazer uma aplicação GUI o programador deve importar as duas bibliotecas AWT e SWING,
para ter acesso aos componentes do SWING e fazer uso de classes como Layout Manager,
Graphics e Color que pertencem a biblioteca AWT.

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.*;

// Exemplo 1 - Criando uma janela instanciando directamente a classe Janela


Public class Janela {

Public static void main(String[] args) {

JFrame j = new JFrame();


j.setTitle("Janela");
j.setSize(300,300);
j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
j.setVisible(true);
}

84
Capítulo 7 – Ficheiros de Texto

// Exemplo 2 - Criando uma janela instanciando uma classe que estende o JFrame

/*
public class Janela extends JFrame {

public static void main(String[] args) {

Janela j = new Janela();


j.setTitle("Janela");
j.setSize(300,300);
j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
j.setVisible(true);
}
}
*/

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

7 Array de Objectos – Algoritmos de Ordenação e Pesquisa

Resumo Teórico

Neste capítulo serão abordados os seguintes pontos:

• Ordenação de array de tipos primitivos

• Pesquisa Linear e binária

• Ordenação de array de objectos

7.1 Ordenação de Array de tipos primitivos


A ordenação de elementos de um array é uma acção frequentemente encontrada na programação.
Existem muitos algoritmos de ordenação tais como: pela selecção, pela inserção, bubbleSort entre
outros. O algoritmo mais simples da ordenação é a ordenação pela selecção.

Nota: Uma discussão mais aprofundada sobre os algoritmos de ordenação será objectivo
de outra cadeira.

7.1.1 Ordenação por selecção


Considere um array de N elementos de tipos primitivos, dos números inteiros por exemplo.
Supondo que queremos ordenar o array pela ordem crescente, o algoritmo pode ser o seguinte:

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:

Tomamos como exemplo, o seguinte array de 7 elementos inteiros.

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

Agora 8 é máximo, e terá de trocar de posição com o número 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

Em palavras o algoritmo é o seguinte:

for (int i = array.length-1; i >= 1; i--){


Escolher o máximo do subarray de índice 0 a índice i;
Trocar de posição entre o elemento máximo com o de índice i (se necessário);
}
• Teste do Algoritmo
O seguinte programa faz um teste do algoritmo de ordenação pela selecção. A estrutura do
programa é a seguinte:

public class TestSelectionSort


• main()
• printList()
• selectionSort()
O método main() será responsável pela criação de dados para o teste. Cria-se um array com valores
aleatórios onde variam entre 0 e 20.

A[i] = (int) (Math.random()*20)

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;

public class TestSeletionSort {

public static void main(String args[]){

int size=Integer.parseInt(JOptionPane.showInputDialog("Qual o
tamanho do array?"));

int[] list=new int[size];

for(int i=0; i<list.length;i++)

list[i]=(int)(Math.random()*20);

printList(list);

selectionSort(list);

printList(list);

public static void selectionSort(int[] list){

int currentMax, currentMaxIndex;

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

public static void printList(int[] list){

for(int i=0; i<list.length;i++)

System.out.print(list[i] + " ");

System.out.println();

Uma saída do programa:

1 4 18 3 9 18 17 10 8 5
1 3 4 5 8 9 10 17 18 18

7.1.2 Ordenação de Array de Objectos

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:

Modificadores interface nome {


(Não tem campos de dados)
Declaração de constantes
Assinaturas de métodos

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.

public class A implements Comparable {



}
Sendo Comparable o nome da interface, e A o nome da classe.

2º Implementar na classe A todos os métodos cujas assinaturas estão presentes na interface.

Nota: um estudo mais profundo sobre interface será estudado na outra cadeira.

• Ordenação de Array de Objectos

Para ordenar um array de objectos, utilizamos dois recursos do java.

O primeiro recurso é a interface Comparable que tem apenas o método compareTo() cuja
assinatura é a seguinte:

public int compareTo( Object ob);

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:

public int compareTo( Object ob ){


Empregado outro = (Empregado) ob; //casting
if (salario <outro.salario) return -1;
if (salario>outro.salario) return 1;
return 0;
}

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);

//e o resultado da ordenação é colocado no próprio array 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;

public class SortArrayObject {

public static void main(String[] args) {

Empregado[] staff = new Empregado[3];

92
Capítulo 7 – Ficheiros de Texto

staff[0] = new Empregado("Tom", 4000);

staff[1] = new Empregado("Dick", 8000);

staff[2] = new Empregado("Harry", 6500);

//before sorting

System.out.println("before sorting");

for (int i = 0; i < staff.length; i++) {

staff[i].imprime();

System.out.println();

//sorting

Arrays.sort(staff);

//after sorting

System.out.println("after sorting");

for (int i = 0; i < staff.length; i++) {

staff[i].imprime();

class Empregado implements Comparable {

public Empregado(String aNome, double aSalario) {

nome = aNome;

salario = aSalario;

public String getNome() {

return nome;

93
Capítulo 7 – Ficheiros de Texto

public void setNome(String nome) {

this.nome = nome;

public double getSalario() {

return salario;

public void setSalario(double salario) {

this.salario = salario;

@Override

public int compareTo(Object o) {

//ordenacao decrescente pelos salarios

Empregado outro = (Empregado) o;

if (salario < outro.salario) {

return 1;

if (salario > outro.salario) {

return -1;

return 0;

public void imprime() {

System.out.println("Nome = " + this.getNome() + ", Salário


= " + this.getSalario());

private String nome;

94
Capítulo 7 – Ficheiros de Texto

private double salario;

Uma saída do programa:

before sorting
Nome = Tom, Salário = 4000.0
Nome = Dick, Salário = 8000.0

Nome = Harry, Salário = 6500.0

after sorting
Nome = Dick, Salário = 8000.0
Nome = Harry, Salário = 6500.0
Nome = Tom, Salário = 4000.0

Nota: A classe String implementa a interface Comparable, isto é, existem o método

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:

int comp = apelido.compareTo(outroTrabalhador.apelido);


if (comp == 0) …………
A semelhança é aplicada para qualquer outra classe que implementa a interface Comparable.

Exemplo:

Para ordenar os trabalhadores pelo nome, o método compareTo() seria escrito da seguinte forma:

public int compareTo(Object o) {


//ordenacao decrescente pelos nomes
Empregado outro = (Empregado) o;
int comp = nome.compareTo(outro.nome);
return comp;
}

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).

7.2.1 Pesquisa Linear (linear Search)


A pesquisa linear faz a comparação do elemento chave com cada elemento do array. A pesquisa
continua até se encontrar um elemento igual à chave. Se a pesquisa for bem sucedida, irá nos
retornar o índice do elemento encontrado, caso contrário, retorna um valor negativo, -1.

Em palavras o algoritmo é o seguinte:

for (int i = 0; i < array.length; i++)


se (chave == array[i]) return i;
return -1;

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.

Recomendação: Corra o programa várias vezes para verificar o funcionamento da pesquisa.

Estrutura do programa

Public class TestLinearSearch


• Main()
• printList()
• linearSearch()

import javax.swing.JOptionPane;

public class TestLinearSearch {

public static void main(String args[]){

//criação de um array de 10 elementos inteiros aleatórios

int[] list = new int[10];

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);

int index = linearSearch(chave,list);

if(index!=-1) System.out.println("Chave encontrada na posição


"+index);

97
Capítulo 7 – Ficheiros de Texto

else System.out.println("Chave não encontrada");

System.exit(0);

public static void printList(int[] list){

for(int i=0;i<list.length;i++)

System.out.print(list[i]+" ");

System.out.println("");

public static int linearSearch(int chave,int[] list){

for(int i=0;i<list.length;i++)

if(chave==list[i]) return i;

return -1;

98
Capítulo 7 – Ficheiros de Texto

Uma saída do programa:

Lista actual:
18 15 0 15 11 8 16 14 11 0
Chave = 10
Chave não encontrada

7.2.2 Pesquisa Binária (binary Search)

A pesquisa binária é um algoritmo recursivo. O algoritmo funciona com arrays ordenados. A


pesquisa começa com a comparação da chave com o elemento na posição central do array, digamos
o middle. São 3 casos possíveis:

• chave < middle , aplique a pesquisa para a primeira parte da lista


• chave = middle , encontra-se a chave, e a pesquisa termina
• chave > middle, aplique a pesquisa para a segunda parte da lista

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

String chaveStr = JOptionPane.showInputDialog("A chave:");


int chave = Integer.parseInt(chaveStr);
System.out.println("chave = " + chave);

int index = binarySearch(chave, list);


if (index != -1) {
System.out.println("chave encontrada na posição:" +
index);
} else {
System.out.println("chave nao encontrada");
}
}
public static void printList(int[] list) {
for (int i = 0; i < list.length; i++) {
System.out.print(list[i] + " ");
}
System.out.println("");
}
public static int binarySearch(int chave, int[] list) {
int low = 0;
int up = list.length - 1;
return binarySearch(chave, list, low, up);
}
public static int binarySearch(int chave, int[] list, int low,
int up) {
//binary search in the list[low..up]
if (low > up) {
return -1;//the list has been wxhausted without a match
key
}
int middle = (low + up) / 2;
if (chave < list[middle]) {
return binarySearch(chave, list, low, middle - 1);
} else if (chave == list[middle]) {

100
Capítulo 7 – Ficheiros de Texto

return middle;
} else if (chave > list[middle]) {
return binarySearch(chave, list, middle + 1, up);
}
return -1;
}
}

Uma saída do programa:

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

Neste capítulo, estudamos os seguintes assuntos:

• Fluxo de dados e ficheiros (Streams)

• Excepção ( Exception )

• Ficheiro de Texto ( text files )

• Ficheiro de entrada ( input files )

• Ficheiro de saída ( output files )

• Análises de dados com StreamTokenizer

• Ficheiros de Objectos

8.1 Fluxo de dados e Ficheiros


Na comunicação homem-computador sempre ocorre entrada e saída de dados. As entradas podem
ser, por exemplo, uma introdução de dados por teclado, um clique no mouse, um scan de imagens,
ou uma importação de dados de rede, etc. As saídas podem ser uma visualização de informações
no monitor, a impressão de informações numa impressora, uma escrita de dados para ficheiros do
computador ou para a rede, etc. Essas entradas e saídas são consideradas como fluxo de dados ou
Streams.

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.).

Um fluxo de dados interessa só a informação transportada e não interessa o dispositivo relativo. É


semelhante ao condutor eléctrico, que interessa a energia que corre dentro e não interessa para
onde a energia chega ( TV, lâmpada, ou máquina de lavar, ….).

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.

Java apresenta um grande esforço na resolução de excepçõ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

diferença entre excepções “checked” e “unchecked”. A seguir apresentamos o esquema de herança


de excepções ( principais ).

ArithmeticException

RuntimeException

IndexOutOfBoundsException

Exception

FileNotFoundException

IOException

Throwable
MalformedURLException
LinkageError

Error VirtualMachineError

AWTError

Figura 1- Algumas excepções principais

8.2.1 Tratamento de Excepção


Java usa até 5 palavras reservadas ( try, catch, throw, throws e finaly ) para o tratamento de
excepção. Uma apresentação completa sobre a utilização dessas palavras precisa de um grande
capítulo. Aqui, discutimos alguns modelos mais utilizados no tratamento de ficheiros.

A classe IOException é a superclasse das classes FileNotFoundException e algumas subclasses


que não apresentamos na lista. Por sua vez, IOException é subclasse da Exception. Esta relação de
herança traz-nos uma situação bastante “agradável”, é que, quando não soubermos um tratamento
concreto da excepção, poderemos “passar a bola” para o Java tratar, isto é, deixarmos a superclasse
IOException ou a mais alta superclasse Exception apanhar a excepção.

Modelo try … catch

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.

Modelo try … catch … finaly …

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

8.2.2 Apanhar uma excepção

Consideramos as seguintes possibilidades com 2 casos mais encontrados:

• Uma excepção verificada ( checked ), por exemplo, FileNotFoundException

• Uma excepção não verificada (unchecked ), por exemplo, NumberFormatException

A excepção FileNotFoundException será lançada quando um programa tentar fazer acesso a um


ficheiro não existente no disco. Isso pode ser, quando o utilizador introduz um nome errado do
ficheiro, ou coloca o ficheiro numa pasta incorreta.

Podemos tratar este erro da seguinte forma:

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):

private void openMyFile() throws IOException {


corpo de método
}
Neste caso não tratamos nenhum erro concreto e passamos o problema para a nossa “mãe”, que é
a classe IOException. A localização do erro começa com o método openMyFile() subindo pelo
esquema de herança até a classe IOException, onde se tratam erros de entrada e saída.

Consideramos uma excepção não verificada. Como exemplo, consideramos o caso em que um
utilizador introduz um número inteiro com JoptionPane:

String intSTR = JOptionPane.showInputDialog(“ Introduza um inteiro: ” );


int intValue = Integer.parseInt( intSTR );

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! ”);
}

8.2.3 Utilização da palavra reservada throw

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:

public int divide ( int A, int B ) throws IOException{


if( B == 0 ) throw new IOException(“ Denominator cannot be zero ”);
return A/B;
}

8.3 Ficheiro de Texto


Os ficheiros de texto só podem conter caracteres. Eles contêm as linhas de informação de diferentes
comprimentos. A manutenção de ficheiros de texto é simples, podendo ser editada ou visualizada
com qualquer programa de editor de texto ( notepad, wordpad, edit.com, …).

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).

8.3.1 Ficheiro de Entrada ( input files)


Supomos que o ficheiro ( de texto ) existe e queremos abri-lo para ler o seu conteúdo e atribuir os
valores lidos para as variáveis do programa. Em geral, a leitura do ficheiro é executada em 3
passos:
• Abertura do ficheiro para ler;

• Ler o conteúdo e fazer tratamento com os valores lidos;

• Fecho do ficheiro.

Abertura do ficheiro para ler


O objectivo do seguinte método é de abrir um ficheiro existente, tornando-o disponível para ler o
seu conteúdo. Para isso precisam-se de duas classes:

Classe FileReader para os tratamentos de caracteres

Classe BufferedReader para ler linha por linha do ficheiro

O método pode lançar uma excepção.

Seja bfR um objecto da classe BufferedReader:

BufferedReader bfR;

O método abreLeitura()a seguir, vai abrir um ficheiro com o nome indicado.

public void abreLeitura(String nomeFicheiro) throws IOException {


bfR = new BufferedReader ( new FileReader ( nomeFicheiro ) );
}

Leitura de uma linha

Depois da abertura do ficheiro a ler, pode-se ler uma linha dele com o seguinte método:

public String lerUmaLinha() throwsIOException {

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

Tratamentos com a linha lida

O resultado da chamada do método lerUmaLinha() é um String.

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.

Nota: A classe StringTokenizer tem o seguinte construtor (entre outros):

public StringTokenizer ( String str )


//criando um StringTokenizer que use os caracteres usados por defeito //(espaço, tab, enter, etc.)
como separações dos seus tokens
O método public boolean hasMoreTokens() testa se houver mais tokens ( true caso existam, false
caso contrário ). À custa deste método é definido a continuação da análise do String ou não.

O método public String nextToken() retorna o String que representa o token.

Nota: usando esses métodos, é possível analisar toda a linha.

Ler todo o conteúdo do ficheiro

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.

public void lerTodoFicheiro() throws IOException {


String s;
do{
s = lerLinha();
if (s != null)
System.out.println(s);
//tratamentos para a linha lida estão nesta área
}
while(s != null);
}
//ou equivalente

109
Capítulo 7 – Ficheiros de Texto

public void lerTodoFicheiro1() throws IOException {


String s;
while((s = lerLinha()) != null){
System.out.println(s);
//tratamentos para a linha lida estão nesta área
}
}

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

Uma vez terminado o trabalho com o ficheiro, é preciso fechá-lo.

public void fechaLeitura() throws IOException {


bfR.close(); }

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;

public class FicheiroTextoEntrada {


private BufferedReader fR;

110
Capítulo 7 – Ficheiros de Texto

public void abreLeitura(String nomeFicheiro) throws


IOException{
fR=new BufferedReader(new FileReader(nomeFicheiro));
}
public String lerLinha() throws IOException{
return fR.readLine();
}
public void fechaLeitura() throws IOException{
fR.close();
}
public void lerTodoFicheiro() throws IOException{
String s;
do{
s = lerLinha();
if (s != null)
System.out.println(s);
//tratamentos para a linha lida estão nesta área
}
while(s != null);
}
public void lerTodoFicheiro1() throws IOException{
String s;
while((s = lerLinha()) != null){
System.out.println(s);
//tratamentos para a linha lida estão nesta área
}
}
public void lerTodoFicheiro2() throws IOException{
String s;
boolean fim = false;
while (!fim) {
s = lerLinha();
if (s != null) {
System.out.println(s);

111
Capítulo 7 – Ficheiros de Texto

//Tratamentos para a linha lida estão nesta área


}
else
fim = true;
}
}
public static void main(String[] args) throws IOException{
FicheiroTextoEntrada f = new FicheiroTextoEntrada();

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();
}
}

8.3.2 Ficheiro de Saída ( output files )

Já estudamos a forma de input de ficheiros, ou seja, a partir de um ficheiro existente, aprendemos


a ler o seu conteúdo e imprimir na tela, agora, vamos estudar a forma de transportação de dados (
String, Números, etc – resultados da execução de um programa ) a partir da memória do
computador para um ficheiro. Esse ficheiro por sua vez, pode ser utilizado por um outro programa.

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.

Abertura para escrita

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:

public void abreEscrita(String nomeFicheiro) throwsIOException{


bfW = new BufferedWriter(new FileWriter(nomeFicheiro));
}

113
Capítulo 7 – Ficheiros de Texto

Fecho do ficheiro escrito

public void fechaEscrita() throwsIOException {


fW.close();
}

Escrita de dados para o ficheiro


Na classe BufferedWriter o método

write( linha, índiceInicial, quantosCaracteres )

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.

//Escreve uma linha inteira


public void escreverLinha(String linha) throwsIOException{
bfW.write(linha, 0, linha.length());
bfW.newLine();
}

//Escreve um número inteiro


public void escreverNumero(int num) throwsIOException{
String st = "";
st = st.valueOf(num); //conversão de número para string
escreverLinha(st);
}

//Escreve um número real


public void escreverNumero(double num) throws IOException{
String st = "";
st = st.valueOf(num);
escreverLinha(st);
}

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;

public class FicheiroTextoSaida {

private BufferedWriter fW;

public void abreEscrita(String nomeFicheiro) throws


IOException{

fW = new BufferedWriter(new FileWriter(nomeFicheiro));

public void escreverLinha(String linha) throws IOException{

fW.write(linha, 0, linha.length());

fW.newLine();

public void escreverNumero(int num) throws IOException{

String st = "";

st = st.valueOf(num);

escreverLinha(st);

public void escreverNumero(double num) throws IOException{

String st = "";

st = st.valueOf(num);

escreverLinha(st);

115
Capítulo 7 – Ficheiros de Texto

public void fechaEscrita() throws IOException{

fW.close();

public static void main(String[] args) throws IOException{

FicheiroTextoSaida f = new FicheiroTextoSaida();

f.abreEscrita("ficheiro.txt");

String st = "Universidade Eduardo Mondlane";

f.escreverLinha(st);

f.escreverNumero(21); //escrevendo um número inteiro

f.escreverNumero(21.12345); //escrevendo um número do tipo


double

f.fechaEscrita();

/*

* o ficheiro ficheiro.txtfoi criado na pasta corrente. Pode ver o


seu *conteúdo com o programa NotePad ou WordPad ou qualquer outro
Editor de *texto. A sequir está o conteúdo do ficheiro.

*/

Ficheiro.txt

Universidade Eduardo Mondlane

116
Capítulo 7 – Ficheiros de Texto

21

21.12345

8.4 Análise de dados com StreamTokenizer

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:

Luis Simango, 19 anos

Tem os seguintes tokens:


• Luis
• Simango
• ,
• 19
• anos
é um stream intermediário, o construtor da classe StreamTokenizerprecisa de um objecto
InputStrean, ou um Reader ( um ficheiro de texto, por exemplo ). Depois da criação, pode chamar
o método nextToken() para tirar token a token. A assinatura do método é:
public intnextToken() throws IOException

Este método devolve os seguintes valores (constantes)


StringTokenizer.TT_WORD Se token lido é uma palavra
StringTokenizer.TT_NUMBER Se token lido é um número
StringTokenizer.TT_EOL Se está no fim da linha
StringTokenizer.TT_EOF Se está no fim do ficheiro ( stream )
No caso do token lido ser TT_WORD pode-se receber a palavra lida através da variável sval, se
for TT_NUMBER pode-se receber o valor numérico lido na variável nval. E sempre pode-se usar
a variável public int ttype que após uma chamada ao nextToken(), esta variável conserva o tipo do
token lido anteriormente, e por causa disso, uma comparação com as constantes acima listadas faz
saber e receber o valor lido.

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

de frequência é calculada pela fórmula: . A pauta é armazenada num ficheiro


pauta_in.txt cuja cada linha lida contém Apelido, Nome, nota do teste 1 e nota do teste 2 do
estudante. É preciso criar um novo ficheiro pauta_out.txt que aumenta mais duas colunas: das
notas de frequência e das classificações EXCLUIDO, ADMITIDO, DISPENSADO processando
as notas respectivas sabendo que:

• Se , o estudante está EXCLUÍDO

• Se , o estudante está ADMITIDO

• Se , o estudante está DISPENSADO


Exemplo de input Exemplo de output
(pauta_in.txt) (pauta_out.txt)
Bhavika Rugnath 16 14 Bhavika Rugnath 16 14 15 DISPENSADO
Amarildo Come 16 12 Amarildo Come 16 12 14 DISPENSADO
Natalia Mondlane 16 10 Natalia Mondlane 16 10 12 ADMITIDO
Francisco 13 6 Francisco Adriano 13 6 9 EXCLUÍDO
Adriano

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;

public class PautaStream {


public static void main(String[] args) {
FileReader frs = null;
FileWriter fws = null;
StreamTokenizer in = null;
PrintWriter out = null;

118
Capítulo 7 – Ficheiros de Texto

String sname = null;


String sname1 = null;
int nota1 = 0;
int nota2 = 0;
int nFreq = 0;

try {
frs = new FileReader("pauta_in.txt");
fws = new FileWriter("pauta_out.txt");

in = new StreamTokenizer(frs); //faz-se um Stream com todo o


//ficheiro pauta_in.txt
out = new PrintWriter(fws); // cria-se outro Stream para
//guardar resultado

in.nextToken(); // tira-se o primeiro token

while (in.ttype != in.TT_EOF) {


// ttype é uma variavel da classe StringTokenizer
if (in.ttype == in.TT_WORD) {
sname = in.sval;
} else {
System.out.println("Bad file format ");
}

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 ");
}

nFreq = (int) (Math.round((2 * nota1 + 3 * nota2) /


5.));
String classificacao = tratamentoFrequencia(nFreq);

// Para ficheiro
out.println(sname + " " + sname1 + " " + " " +
nota1
+ " " + nota2 + " " + nFreq + " " +
classificacao);
// Para screen
System.out.println(sname + " " + sname1 + " " + "
" + nota1
+ " " + nota2 + " " + nFreq + " " +
classificacao);

in.nextToken(); // passa para o token seguinte


}
} catch (FileNotFoundException ex) {
System.out.println("File not found:pauta_in");
} catch (IOException ex) {
System.out.println(ex.getMessage());
} finally {
try {
if (frs != null) {
frs.close();
}
if (fws != null) {

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;
}
}

8.5 Ficheiro de Objectos


No capítulo anterior você viu como armazenar e ler dados em ficheiros de textos. Mas com certeza
percebeu quão laborioso era realizar essa tarefa pois era necessário definir com exactidão como
esses dados estariam organizados no ficheiro em causa.
Mas este capítulo apresenta uma abordagem diferente no armazenamento de dados que consiste
em armazenar objectos em ficheiros. Essa abordagem permite que um objecto seja gravado num
ficheiro e por consequência levando consigo informação completa sobre si próprio.
8.5.1 Serialização
Para que um objecto possa ser gravado em um ficheiro ele deve ser transformado em bytes, e a
essa transformação designa-se por Serialização. A principio nenhum objecto pode ser serializado,
e para que um objecto possa ser serializado ele deverá implementar a interface Serializable, que
não traz consigo nenhum método para implementar, serve apenas para indicar que os objectos da
classe em causa podem ser serializados. Por essa razão ela é considerada uma interface de
marcação ou de tag.
Segue o exemplo abaixo de implementação da interface Serializable na classe Pessoa.
package ficheiro.de.objectos;

121
Capítulo 7 – Ficheiros de Texto

import java.io.Serializable;

public class Pessoa implements Serializable{

private String nome;


private String apelido;

public Pessoa(String nome, String apelido) {


super();
this.nome = nome;
this.apelido = apelido;
}

public String getNome() {


returnnome;
}
publicvoid setNome(String nome) {
this.nome = nome;
}
public String getApelido() {
returnapelido;
}
publicvoid setApelido(String apelido) {
this.apelido = apelido;
}

public String toString(){


return getNome()+" "+getApelido();
}
}

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.

FileInputStream && FileOutputStream


São fluxos de conexão com ficheiros que permitem a gravação e leitura de um ficheiro em disco.
Eles apresentam métodos de gravação em bytes. Mas nós não queremos gravar bytes, mas sim
objectos. Por essa razão, como é próprio da leitura e escrita de ficheiros é necessário usar ou
combinar dois Streams diferentes para que algo útil possa ser feito. Neste caso, combinaremos a

122
Capítulo 7 – Ficheiros de Texto

Stream ObjectOutputStream e ObjectInputStream com a Stream FileOutputStream e


FileInputStream respectivamente para a escrita e leitura de objectos em ficheiros.

ObjectInputStream && ObjectOutputStream


Elas são responsáveis por inserir e recuperar objectos serializados do Stream FileInputStream e
FileOutputStream.

8.5.2 Ficheiro de saida


Tal como em ficheiros de textos, a escrita de dados em ficheiros de objectos tem que ser executada
em três fases: abertura para escrita, escrita de dados e fecho.

Abertura para escrita


Temos que ter um objecto da classe FileOutputStream, seja meuFicheiro o tal objecto:

FileOutputStream meuFicheiro=new FileOutputStream (nomeFicheiro);

Temos que ter um objecto da classe ObjectOutputStream, seja os o tal objecto:

ObjectOutputStream os=new ObjectOutputStream (meuFicheiro);

Escrita de dados

Usamos o método writeObject(Object obj)


os.writeObject(Object obj);
Fecho do ficheiro
Usamos os métodos flush() e close().
//Para o fileOutputStream
meuFicheiro.flush();
meuFicheiro.close();
//Para o ObjectOutputStream
os.flush();
os.close();
Nota: O método flush garante que todo conteudo seja guardado no ficheiro caso parte do conteúdo
ainda não tenha sido gravado ao ser accionado o metodo close().

123
Capítulo 7 – Ficheiros de Texto

Exemplo de ficheiro de saida, usando a classe Pessoa acima criada:


import java.io.FileOutputStream;
import java.io.ObjectOutputStream;

public class GuardarObjecto {


public static void main(String []args) {
Pessoa pessoa1 = new Pessoa("Bhavika","Rugnath");
Pessoa pessoa2 = new Pessoa("Erminio","Jasse");
Pessoa pessoa3 = new Pessoa("Job","Guitiche");
Pessoa pessoa4 = new Pessoa("Paulo","Braga");
try {
//Cria o ficheiro Saida.dat para armazenar os objetos
FileOutputStream meuFicheiro = new

FileOutputStream("C:\\Users\\Joss\\Desktop\\Saida.dat");
ObjectOutputStream os = new ObjectOutputStream(meuFicheiro);

//Gravando os objetos no ficheiro


os.writeObject(pessoa1);
os.writeObject(pessoa2);
os.writeObject(pessoa3);
os.writeObject(pessoa4);

//fechando os ficheiros abertos


meuFicheiro.flush();
meuFicheiro.close();

os.flush();
os.close();
System.out.println("Objetos gravados com sucesso!");
}
catch(Exception e) {
e.printStackTrace( );
}

124
Capítulo 7 – Ficheiros de Texto

}
}

8.5.3 Ficheiro de entrada


Abertura para leitura

Temos que ter um objecto da classe FileInputStream, seja meuFicheiro o tal objecto:

FileInputStream meuFicheiro=new FileInputStream (nomeFicheiro);

Temos que ter um objecto da classe ObjectInputStream, seja in o tal objecto:

ObjectInputStream in=new ObjectInputStream (meuFicheiro);

Leitura de dados

Usamos o metodo readObject()


in.readObject();
Fecho do ficheiro
Usamos o método close().
meuFicheiro.close();
in.close();

• Exemplo de ficheiro de entrada, usando a classe Pessoa acima criada:

import java.io.FileInputStream;
import java.io.ObjectInputStream;

public class CarregarObjecto {


public static void main(String args[]) {
try {
//Abre o ficheiro Saida.dat para ler os objetos

125
Capítulo 7 – Ficheiros de Texto

FileInputStream meuFicheiro =
new FileInputStream("C:\\Users\\Joss\\Desktop\\Saida.dat");
ObjectInputStream in = new ObjectInputStream(meuFicheiro);

/*Criamos instancias de Pessoa para recebermos e


* armazenarmos os objectos do tipo pessoa que foram
* previamente armazenados no ficheiro*/
Pessoa p1;
Pessoa p2;
Pessoa p3;
Pessoa p4;
//Pessoa p5;

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

Você também pode gostar