Você está na página 1de 119

FACULDADE DE CIÊNCIAS

DEPARTAMENTO DE MATEMÁTICA E INFORMÁTICA

Manual de Fundamentos de Programação em Java

Versão: 1.1

Versão JDK: 1.7

Autor:

Ermínio Jasse

Fevereiro de 2014
Fevereiro de 2013
FUNDAMENTOS DE PROGRAMAÇÃO EM JAVA

Agradecimentos
Em especial agradecimentos para os primeiros colaboradoes nomeadamente:

Bruno Estevão Chichava, Elpídio Maúnde, Job de Vera Taimo Guitiche, Jordão Joaquim Uache,
Juvêncio Abílio Comé e Paulo Jorge Braga Zacarias que tornaram possível a criação deste manual
na Versão 1.0 que serviu como base de todas versões posteriores.

Gradecimentos são igualmente endereçados aos monitores de luxo 2014 (Banze, Felix, Michael e
Alfredo), a Dr. Metambo e a todos que directa ou indirectamente deram seu melhor para que este
manual fosse elaborado.

Nota Introdutória
Este manual é dirigido a estudantes e programadores que pretendam entrar para o mundo do Java
e pode ser usado por qualquer indivíduo que queira programar em Java porém poderá ser
maioritariamente usado por estudantes do Departamento de Matemática e Informatica da
Universidade Eduardo Mondlane, na cadeira de Fundamentos de Programação.

Esta é a versão revisada (Versão 1.1) da primeira versão (Versão 1.0) elaborada em 2013 pelo
autor onde contou com o apoio de alguns estudantes do terceiro ano do curso de Licenciatura em
Informatica, carinhosamente chamados de “monitores de luxo”.

Na elaboração da versão de 2014 (Versao 1.1), o autor (Erminio Jasse) contou com o apoio não só
dos habituais monitores de luxo mas também de um outro docente do Departamento de Matematica
e Informatica, o Dr. João Metambo.

A Versão 1.1 conta não só com os capítulos da anterior versão (Versão 1.0), mas também com
novos capítulos nomeadamente: Desenho de Interface Gráfica, em Inglês Graphic User Interface
(GUI) e Arrays de Objectos de forma a dotar os utilizadores do manual de mais conhecimentos
iniciais e assim aumentar o espaço de manobra para em Programação Orientada a Objectos
(Programação Avançada em Java) apenas preocuparem-se com aspectos mais profundos.

Bibliografia Básica
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
Erminio Jasse – 82 2517650/ 84 2517650
2
Erminio Jasse – 82 2517650/ 84 2517650
ÍNDICE
1 Introdução a Linguagem de Programação Java ................................ ..6
1.1 Origem........................................................................................................................................... 6
1.2 Porquê Java?.................................................................................................................................. 7
1.3 Características da Linguagem Java ............................................................................................... 7
1.4 Ambiente de Desenvolvimento Java ............................................................................................. 8
1.4.1 Java IDE (Java Integrated Development Environment ) ....................................................... 9

2 Estruturas Principais da Programação JAVA..................................... 10


2.1 Um programa simples ................................................................................................................. 10
2.2 Identificadores ............................................................................................................................. 12
2.3 Tipos de Dados Primitivos .......................................................................................................... 13
2.4 Declaração e Inicialização de Variáveis ...................................................................................... 14
2.5 Constantes ................................................................................................................................... 15
2.6 Operadores .................................................................................................................................. 16
2.6.1 Operadores Relacionais ....................................................................................................... 16
2.6.2 Operadores Lógicos............................................................................................................. 17
2.6.3 Precedência de Operadores ................................................................................................. 17
2.7 Funções e Constantes Matemáticas ............................................................................................. 18
2.8 Conversões entre Tipos Numéricos............................................................................................. 18
2.9 Leitura de Dados com JOptionPane ............................................................................................ 20
2.10 Impressao e Formatação de Saida ............................................................................................... 22

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 ........................................................................................................................................... 30
3.6 String ........................................................................................................................................... 33

4 Classes e Objectos ........................................................................... 35


4.1 Introdução a OOP (Programação Orientada a Objectos) ............................................................ 35
4.2 Classe e Objectos de uma classe ................................................................................................. 36
4.3 Construção de objectos de uma classe ........................................................................................ 40
4.4 Modificadores public, private, static, final .................................................................................. 41

3
Erminio Jasse – 82 2517650/ 84 2517650
4.5 Métodos da classe........................................................................................................................ 42
4.6 Parâmetros de métodos................................................................................................................ 44
4.7 Pacote (package) ......................................................................................................................... 50
4.8 Sugestão de desenho de classes ................................................................................................... 52

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


5.1 Introdução a programação gráfica ............................................................................................... 53
5.2 Sistemas de Coordenadas no modo gráfico ................................................................................. 53
5.3 Objectos da classe graphics ......................................................................................................... 54
5.4 Métodos da classe Graphics ........................................................................................................ 55
5.5 Desenho e pintura de sectores ..................................................................................................... 56
5.6 Utilização de cores ...................................................................................................................... 56
5.7 Utilização de Font ....................................................................................................................... 64
5.8 Método paintComponent() .......................................................................................................... 67
5.9 Classe Polygon ............................................................................................................................ 67
5.10 Introdução a Applets ................................................................................................................... 71

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


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

4
Erminio Jasse – 82 2517650/ 84 2517650
6.4.12 JPopupMenu ........................................................................................................................ 83
6.4.13 JTable .................................................................................................................................. 83

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


7.1 Ordenação de Array de tipos primitivos...................................................................................... 84
7.1.1 Ordenação por selecção ....................................................................................................... 84
7.1.2 Ordenação de Array de Objectos......................................................................................... 86
7.2 Pesquisa ....................................................................................................................................... 91
7.2.1 Pesquisa Linear (linear Search) ........................................................................................... 91
7.2.2 Pesquisa Binária (binary Search) ........................................................................................ 93

8 Ficheiros .......................................................................................... 96
8.1 Fluxo de dados e Ficheiros .......................................................................................................... 96
8.2 Excepção ..................................................................................................................................... 97
8.2.1 Tratamento de Excepção ..................................................................................................... 98
8.2.2 Apanhar uma excepção ....................................................................................................... 99
8.2.3 Utilização da palavra reservada throw .............................................................................. 101
8.3 Ficheiro de Texto ...................................................................................................................... 101
8.3.1 Ficheiro de Entrada (input files) ........................................................................................ 102
8.3.2 Ficheiro de Saída ( output files ) ....................................................................................... 106
8.4 Análise de dados com StreamTokenizer ................................................................................... 109
8.5 Ficheiros de Objectos ................................................................................................................ 113
8.5.1 Serialização ....................................................................................................................... 113
8.5.2 Ficheiro de saida................................................................................................................ 114
8.5.3 Ficheiro de entrada ............................................................................................................ 116

5
Erminio Jasse – 82 2517650/ 84 2517650
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.1 Origem
1.2 Porquê Java?
1.3 Características
1.4 Ambiente de desenvolvimento

1.1 Origem
Em 1992 a Sun criou uma equipe (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 em uma ú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).

6
Erminio Jasse – 82 2517650/ 84 2517650
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
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.

7
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 2 – Estruturas Principais da Programação JAVA

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

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.

8
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 2 – Estruturas Principais da Programação JAVA

 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 editor de texto que possua syntax
highlighting ou outros recursos que por detrás executa os processos e minimiza esforços.

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.

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

9
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 2 – Estruturas Principais da Programação JAVA

2 Estruturas Principais da Programação JAVA

Neste capítulo abordaremos os seguintes tópicos:


2.1 Um programa Simples;
2.2 Identificadores;
2.3 Tipos de dados primitivos;
2.4 Declaração e Inicialização de Variáveis;
2.5 Constantes;
2.6 Operadores;
2.7 Funções e constantes matemáticas;
2.8 Conversão entre tipos numéricos;
2.9 Leitura de dados com JOptionPane;
2.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
do programa será explicado posteriormente para proporcionar o entendimento inicial.

Crie um projecto com o nome Primeiro Programa Java e um ficheiro HelloWorld.java. Digite
o código abaixo, no ficheiro criado, de seguida compile e execute. 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

A saída deverá ser: Hello, World!

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.

10
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 2 – Estruturas Principais da Programação JAVA

 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. O


ficheiro está em bytecode, um formato especial dos programas Java, um formato neutral; isto é,
apesar de não puder ser visualizado por um processador de texto, 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!”

Java é multiplataforma ou seja, os programas nele escritos são executados independentemente do


sistema operativo instalado na máquina.

1. Espaço em Branco
Java é uma linguagem de formato livre. Não é necessário indentar para que ela funcione. Por
exemplo, o nosso programa HelloWorld poderia ser escrito da seguinte maneira:

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


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

11
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 2 – Estruturas Principais da Programação JAVA

2. Comentários em Java
Em Java temos 3 tipos de comentários: 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.

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

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


finaliza com */ (asterisco-barra).

3. Algumas palavras-chave/ reservadas


As palavras reservadas 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 do Java. 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
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 como 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.

12
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 2 – Estruturas Principais da Programação JAVA

4. Convenções para nomenclatura de identificadores


De forma geral, identificadores em Java são escritos em letras minúsculas com excepção de
CONSTANTES que são escritas em maiúsculas sendo as classes em iniciais maiúsculas. Se o
identificador for composto por mais de uma palavra, a segunda e as palavras seguintes devem ter
inicial maiúscula podendo ainda assim ser separados por underscore ( _ ).
Ex. nomeCompleto, calculaMediaCompleta(), calcula_Media(), EstudanteUniversitario;

a) Variáveis e métodos (convenções de nomenclatura)


As variáveis são compostas por substantivos e adjectivos e reflectem as características dos
possíveis objectos da classe em causa, enquanto que os métodos começam sempre com um verbo
por reflectem comportamentos dos possíveis objectos da classe e terminam em (), podendo ter
parâmetros dentro dos parêntesis.
Exemplos: hora, horaDoDia, valorCorrente, obterHoraDoDia(), obter_Hora_Do_Dia.

b) Constantes
As constantes (variáveis finais), são declaradas em letras maiúsculas (todo o nome). Para as
constantes formadas por mais de uma palavra, pode usar- se underscore para separá-los. Os nomes
de constantes em Java são formados por substantivos e adjectivos.
Exemplos: VALOR_P1, DIA_SEXTA, VERDE.

c) Classes
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, pode usar-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, Interface_Simples.

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.

13
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 2 – Estruturas Principais da Programação JAVA

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.
double pi = 3.14.159; Declarando e inicializando pi com o valor 3.14159;
char c = ‘x’; Declarando e inicializando x 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.

14
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 2 – Estruturas Principais da Programação JAVA

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;
public static void main (String[] args) {
System.out.println("A gravidade é: "+GRAVIDADE);
}
}

15
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 2 – Estruturas Principais da Programação JAVA

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; y=x++; x= 2, y= 1
Equivale a x=x+1 e y=x x=1; y=0; y=++x; x= 2, y= 2
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:
Operador Operação
== Igual a
!= Diferente de
> Maior que
< Menor que
>= Maior ou igual que
<= Menor ou igual que

16
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 2 – Estruturas Principais da Programação JAVA

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

17
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 2 – Estruturas Principais da Programação JAVA

2.7 Funções e Constantes Matemáticas


As funções e constantes matemáticas podem ser partes de expressões. Por exemplo, se quisermos
calcular a área limitada por uma circunferência de raio R, usamos a fórmula A  R 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 )

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;
 Se não, se um dos operandos for float, o outro será tratado como float;
 Se não, se um dos operandos é do tipo long, o outro será tratado como long;
 Se não, os operandos serão tratados como inteiros.

18
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 2 – Estruturas Principais da Programação JAVA

Mas em alguns casos pode ser necessário converter, por exemplo, um double em um inteiro. Toda
conversão numérica em Java é possível, mas informações podem ser perdidas. Estas conversões
podem ser realizadas com o uso de casting. A sintaxe do casting é colocar o tipo desejado entre
parêntesis antes do nome da variável. Por exemplo:

double x = 9,997;
int nx = (int) x;

Java permite ainda que certas conversões sejam feitas pela atribuição de valores de um tipo para
outro sem que seja necessário o uso de casting. As conversões permitidas de forma automática
pelo compilador são:

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

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.

19
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 2 – Estruturas Principais da Programação JAVA

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

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 Serenia Fuleza Malapuza como nome e 22 como idade, obteremos como
output do programa a seguinte informação:

Hello, Serenia Fuleza Malapuza. Next year you'll be 23

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

20
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 2 – Estruturas Principais da Programação JAVA

Abaixo segue o código do referido programa:


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 para Integer


int age = Integer.parseInt(ageStr);

//Display output on console


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

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


"+(age+1));
System.exit(0) }}

Passo a passo:

21
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 2 – Estruturas Principais da Programação JAVA

Para uma leitura correcta de dados, faremos o seguinte:

1. No início do ficheiro, escreva:


import javax.swing.JOptionPane;

2. Declare uma 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);

Tente tirar/ comentar a instrução System.exit(0); e veja o que acontece executando o


programa.

Reflicta um pouco sobre esta instrução!!!

2.10 Impressao e Formatação de Saida

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, mantem 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.

22
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 2 – Estruturas Principais da Programação JAVA

2. Formatação de Saida[opcional]
Java imprime o valor double com até 15 dígitos significativos e nem sempre necessitamos
apresentar todos estes dígitos. 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:"+x);//333.3333
------------------

23
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 3 – Estruturas de Controle do JAVA

3 Estruturas de Controle do Java

Resumo Teórico
Neste capítulo, abordaremos os seguintes pontos:
3.1 Blocos de Instruções;
3.2 Instruções Condicionais;
3.3 Multiselecções Switch;
3.4 Estruturas de Repeiticao Ciclos
3.5 Array
3.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.

24
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 3 – Estruturas de Controle do JAVA

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


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 raizes 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
Erminio Jasse – 82 2517650/ 84 2517650
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ável de 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
Erminio Jasse – 82 2517650/ 84 2517650
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:

27
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 3 – Estruturas de Controle do JAVA

Switch ( mes ) {
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 pode 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) {
s +=i;
i++;
}
System.out.println(“SUM=” +s); //saída: SUM=45

28
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 3 – Estruturas de Controle do JAVA

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.

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

29
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 3 – Estruturas de Controle do JAVA

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.
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 []

30
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 3 – Estruturas de Controle do JAVA

O array de uma dimensão é declarado 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 zero à 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:


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

31
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 3 – Estruturas de Controle do JAVA

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;

17
19
anyArr
23
smallPrimes 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
anyArraponta. 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:

32
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 3 – Estruturas de Controle do JAVA

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

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: intlength()
 Caractere numa dada posição: charcharAt( index )

33
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 3 – Estruturas de Controle do JAVA

Exemplo:
String meuDepartamento = “Depart. Matemática e Informática”;
System.out.println(meuDepartamento.length()); //imprime 32

System.out.println(meuDepartamento.charAt(9)); //imprime M

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

Exemplo:
String apelido = “COSSA”;

String nomes = “Osvaldo Fernando”;


System.out.println(apelido+”,”+nome); //COSSA, Osvaldo Fernando

System.out.println(nome+”,”+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 ).

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.

34
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 4 – Classes e Objectos

4 Classes e Objectos

Resumo Teórico
Neste capítulo, estudamos os seguintes tópicos:
4.1 Introdução a OOP (Object Oriented Programming )
4.2 Classe e Objectos
4.3 Construção de Objectos
4.4 Modificadores public, protected, private, static, final
4.5 Métodos da classe
4.6 Parâmetros de métodos
4.7 Pacote (package)
4.8 Sugestão do desenho de classes

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


Na programação procedural (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).
3. Herança

35
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 4 – Classes e Objectos

É 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:
class nome
{
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 vem 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 que os campos de dados fiquem antes dos
métodos, porque a implementação dos métodos dependem 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{
//área de campos de dados
private String nome;
private double salario;

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

36
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 4 – Classes e Objectos

public String getNome(){ return nome;}

public String 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 também que luis é uma instância da classe Trabalhador.
Ou com 2 linhas:
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 memoria 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

public class Estudante {

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


private String nome;
private double notaFrequencia;

//metodo construtor

37
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 4 – Classes e Objectos

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

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

38
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 4 – Classes e Objectos

Nesta variante tira-se o método main da classe Estudante na variante I pondo-o noutra classe.
Concretamente tem-se 2 seguintes classes.

//Esta classe precisa a classe Estudante

public class EstudanteTesta {

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

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

39
Erminio Jasse – 82 2517650/ 84 2517650
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.

40
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 4 – Classes e Objectos

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’
 Campo objecto: inicializadocom 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, 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 – é acessível 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. É bom utilizar private para proteger dados.
3. 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

41
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 4 – Classes e Objectos

é 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.
4. 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, isto é, é só dentro da classe (private).

4.5 Métodos da classe

1. Formato geral de métodos


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

42
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 4 – Classes e Objectos

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.

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 double setNotaFrequencia(double novaNota) {
notaFrequencia= novaNota;
}

3. Palavra-chave return
Este comando é usado para retornar um valor. A forma geral é a seguinte:

returnexpressão;

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

43
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 4 – Classes 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)

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

44
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 4 – Classes e Objectos

1. Passagem com valores primitivos


Só uma copia 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.
Consideramos 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):");
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


abjecto luis

System.out.println("Antes da
chamada,salario="+luis.getSalario());

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


luis

45
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 4 – Classes e Objectos

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

46
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 4 – Classes e Objectos

private String nome;

private double salario;

Este exemplo usa duas classes TestaParametrose 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 luismudou 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.

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

47
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 4 – Classes e Objectos

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

------------------------
}

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

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 Mathconté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.

48
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 4 – Classes e Objectos

O seguinte programa ilustra o funcionamento dos campos e métodos estáticos. Ele cria umarray
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];
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;

49
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 4 – Classes e Objectos

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;
}
private String nome;
private double salario;
private int id;
private static int idSeguinte=1;//campo estatico
}

4.7 Pacote (package)


Pacote é uma colecção de classes. O programador pode colocar as classes completas no seu pacote
e de seguinda 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.

50
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 4 – Classes e Objectos

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

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.

51
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 4 – Classes e Objectos

4.8 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 de 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,
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

52
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 5 – Introdução aos Applets e Gráficos

5 Introdução aos Applets e Gráficos

Resumo Teórico:
5.1 Introdução a programação gráfica
5.2 Sitemas de coordenadas no modo gráfico
5.3 Objectos da classe Graphics
5.4 Métodos da classe Graphics
5.5 Desenho e Pintura de Sectores
5.6 Utilização de Cores
5.7 Font
5.8 Método paintComponent()
5.9 Polygon
5.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 interface 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.

53
Erminio Jasse – 82 2517650/ 84 2517650
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âmetrog é 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.

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

54
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 5 – Introdução aos Applets e Gráficos

Métodos de instâncias da classe Graphics


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

55
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 5 – Introdução aos Applets e Gráficos

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

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

56
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 5 – Introdução aos Applets e Gráficos

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

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 JFramee
JPanelserá 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);
switch(op){

case 1:drawLines(g);break;

case 2:drawRectangulo(g);break;

57
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 5 – Introdução aos Applets e Gráficos

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

public void drawElipse(Graphics g){

58
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 5 – Introdução aos Applets e Gráficos

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


}
//dois metodos para correr a aplicacao

private static void createAndShowGUI(){

59
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 5 – Introdução aos Applets e Gráficos

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

60
Erminio Jasse – 82 2517650/ 84 2517650
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;

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

61
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 5 – Introdução aos Applets e Gráficos

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

62
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 5 – Introdução aos Applets e Gráficos

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

}); } }

Saida:

63
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 5 – Introdução aos Applets e Gráficos

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, um font, e uma posição onde comeca 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

g.drawString(message, 10, 100);

64
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 5 – Introdução aos Applets e Gráficos

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

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

g.setFont(new Font(fontListe[i],Font.PLAIN,14));

65
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 5 – Introdução aos Applets e Gráficos

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);
frame.pack();
frame.setVisible(true); //mostra a janela
}

public static void main(String [] args){

//mostrar a aplicacao GUI


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

public void run() {


createAndShowGUI();
}
});
}

Saida:

66
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 5 – Introdução aos Applets e Gráficos

5.8 Método paintComponent()


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

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

67
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 5 – Introdução aos Applets e Gráficos

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,

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,

68
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 5 – Introdução aos Applets e Gráficos

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

};

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


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

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

69
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 5 – Introdução aos Applets e Gráficos

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

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

70
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 5 – Introdução aos Applets e Gráficos

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
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()
71
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 5 – Introdução aos Applets e Gráficos

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.

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

72
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 5 – Introdução aos Applets e Gráficos

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

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 >

73
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 5 – Introdução aos Applets e Gráficos

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

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 o applet. É de notar que,
alguns sistemas operativos, pela segurança, pode 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 parao 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 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 encarregar o applet

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

 Segurança para applets

74
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 5 – Introdução aos Applets e Gráficos

 Passagem de parâmetros de HTML para applet


 Popup windows no applet
 Multimedia
 Animação
 URL

75
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

6 Interface Gráfica do Utilizador

Resumo teórico
Neste capítulo abordamos os seguintes tópicos:
6.1 Introdução;
6.2 A classe JComponent;
6.3 Layout Manager;
6.4 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.

76
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

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
é 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 aoprogramador 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().

77
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

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

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 “grelha” considerando o número actual de linhas e
colunas;

78
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

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

79
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

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

publicclassJanelaBorderextends JFrame {

public JanelaBorder() {
setTitle("BorderLayout");
setSize(340,200);
add(new JButton("North"), BorderLayout.NORTH);
add(new JButton("South"), BorderLayout.SOUTH);
add(new JButton("East"), BorderLayout.EAST);
add(new JButton("West"), BorderLayout.WEST);
add(new JButton("Center"), BorderLayout.CENTER);
}

publicstaticvoid 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 zona da tela estará localizado. Importar 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.

80
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

Exemplo:
import javax.swing.*;

// Exemplo 1 - Criando uma janela instanciando directamente a


classe Janela
publicclass Janela {

publicstaticvoid main(String[] args) {

JFrame j = new JFrame();


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

// Exemplo 2 - Criando uma janela instanciando uma classe que


estende o JFrame

/*
publicclassJanelaextends JFrame {

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

81
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

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.

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.

82
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

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 por 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 tambem
permitir a edicao destes dados pelo usuario.

83
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

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

Resumo Teórico
Neste capítulo serão abordados os seguintes pontos:
7.1 Ordenação de array de tipos primitivos
7.2 Pesquisa Linear e binária
7.3 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
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.

84
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

2 6 5 4 1 8

O processo repete-se 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 cujo cada um fica entre 0 e 20.

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

O tamanho do array será introduzido pelo utilizador. Será imprido o array antes e depois da
ordenação. O método responsável pela ordenação é o selectionSort().

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

85
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

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

86
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

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
}
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 corpodo 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.

87
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

O primeiro recurso é a interfaceComparable 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.

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
88
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

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

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;

89
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

}
if (salario > outro.salario) {
return -1;
}
return 0;
}
public void imprime() {
System.out.println("Nome = " + this.getNome() + ", Salário
= " + this.getSalario());
}
private String nome;
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 Stringimplementa a interfaceComparable, 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:

90
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

public int compareTo(Object o) {


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

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;

91
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

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

92
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

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

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


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

93
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

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]) {
return middle;
} else if (chave > list[middle]) {
return binarySearch(chave, list, middle + 1, up);
}
return -1; }}

94
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

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.

95
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

8 Ficheiros

Resumo teórico
Neste capítulo, estudamos os seguintes assuntos:

8.1 Fluxo de dados e ficheiros (Streams)

8.2 Excepção ( Exception )

8.3 Ficheiro de Texto ( text files )

8.4 Ficheiro de entrada ( input files )

8.5 Ficheiro de saída ( output files )

8.6 Análises de dados com StreamTokenizer

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

96
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

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
diferença entre excepções “checked” e “unchecked”. A seguir apresentamos o esquema de herança
de excepções ( principais ).
97
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

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

98
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

Modelo try … catch


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 {

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

8.2.2 Apanhar uma excepção


Consideramos as possibilidades possíveis com 2 casos mais encontrados:

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

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

99
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

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çãonã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 );

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

100
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

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.

Além dos ficheiros de texto, existem os ficheiros binários ( ficheiros de imagens, músicas, etc).

101
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

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 tratamentos 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) throwsIOException
{
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.

Tratamentos com a linha lida


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

String st = lerUmaLinha();
102
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

Podemos fazer as análises deste Stringst 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() throwsIOException {


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

public void lerTodoFicheiro1() throwsIOException {


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

103
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

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() throwsIOException {


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;

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

104
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

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

105
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

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

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

Fecho do ficheiro escrito


public void fechaEscrita() throwsIOException {
fW.close();
}

106
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

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

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;

107
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

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

21
108
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

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 StreamTokenizer precisa 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.

109
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

Exemplo:
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 (pauta_in.txt) Exemplo de output


(pauta_out.txt)
Bhavika Rugnath 16 14 Bhavika Rugnath 16 14 15 DISPENSADO
Amarildo Come 16 12 Amarildo Come 16 12 14 DISPENSADO
Tapiwa Malapuza 16 10 Tapiwa Malapuza 16 10 12 ADMITIDO
Hélder Jasse 13 06 Hélder Jasse 13 06 09 EXCLUÍDO

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;

110
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

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

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

111
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

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

112
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

8.5 Ficheiros de Objectos


No capítulo anterior vimos como armazenar e ler dados em ficheiros de textos mas é muito
trabalhoso, pois é necessário definir com exactidão como os dados estão organizados no ficheiro.

Este capítulo apresenta uma abordagem diferente no armazenamento de dados que consiste em
armazenar objectos em ficheiros permitindo 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. 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;
import java.io.Serializable;

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

113
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

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
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.flash();
meuFicheiro.close();

114
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

//Para o ObjectOutputStream
os.flush();
os.close();
Nota: O método flush garante que todo conteúdo seja guardado no ficheiro caso parte do conteúdo
ainda não tenha sido gravado ao ser accionado o metodo close().

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


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

publicclass GuardarObjecto {
publicstaticvoid main(String []args) {
Pessoa pessoa1 = new Pessoa("Bhavika","Rugnath");
Pessoa pessoa2 = new Pessoa("Erminio","Jasse");
Pessoa pessoa3 = newPessoa("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("Objeto gravado com sucesso!");
}
catch(Exception e) {
e.printStackTrace( );
}
}
}

115
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

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()
os.readObject();

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

116
Erminio Jasse – 82 2517650/ 84 2517650
Capítulo 8 – Ficheiros

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


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

publicclass CarregarObjecto {
publicstaticvoid main(String args[]) {
try { //Abre o ficheiro Saida.dat para ler os objetos
FileInputStream meuFicheiro =
new FileInputStream("C:\\Users\\Joss\\Desktop\\Saida.dat");
ObjectInputStream in = new ObjectInputStream(meuFicheiro);

/*Instanciando 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 ha 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( );
}
}}

Agora sim, já posso programar a vontade em Java. E você?


117
Erminio Jasse – 82 2517650/ 84 2517650

Você também pode gostar