Exemplos de classes em Java - Dei-Isep

Propaganda
Aplicações versus Applets
Há duas maneiras diferentes de correr um programa Java:
• Como Aplicação: programa independente e autónomo (“stand-alone”) que pode
ser invocado da linha de comandos.
• Como Applet: programa embebido numa página Web, que corre quando a
página é visualizada por um browser.
Aplicações e Applets diferem nos privilégios de execução e no modo como indicam
onde começar a execução.
Browsers de páginas Web assim como o appletviewer tratam código HTML (HyperText
Markup Language).
Assim como há tags html para colocar texto em “bold”, ou incluir imagens, também há
tags html para correr um applet Java existente num ficheiro “.class”.
Um exemplo de código HTML (colocado, por exemplo, no ficheiro “exApplet.html”)
que invoca um applet existente no ficheiro “exApplet.class” mostra-se a seguir:
<title>
Exemplo de um Applet
</title>
<applet code=”exApplet.class” width=300 height=50>
</applet>
Os campos width e height (largura e altura) são obrigatórios, e são medidos em pixeis
(pontos de resolução no ecrã do computador).
Os applets correm num objecto janela, e é necessário indicar ao browser o tamanho da
janela no qual o applet deve começar.
Os applets e as aplicações são invocados de maneira diferente.
As aplicações começam a execução num método público designado “main()” com uma
assinatura específica, de um modo semelhante à linguagem C. Quando a aplicação
corre, main() é executado e a partir de main() é implementado o comportamento que se
pretende que o programa tenha.
A convenção para os applets é diferente e envolve a reescrita (override) de certos
métodos que são automaticamente chamados pelo browser. Estes métodos existem
definidos na classe Applet, sem qualquer funcionalidade. O programa de um applet deve
criar métodos que anulem os correspondentes métodos definidos na classe Applet
(tendo a mesma assinatura), para executar as tarefas específicas pretendidas.
Quando um applet é carregado, Java cria uma instância da classe carregada (que é um
objecto Applet) e uma série de métodos especiais Applet são chamados nessa instância.
Os cinco métodos mais importantes na execução de um applet são:
• public void init()
• public void start()
• public void stop()
• public void destroy()
• public void paint(Graphics g)
126
1. O browser ou o appletviewer carrega o applet no sistema e começa por chamar o
método init() – método nunca chamado pelo programa.
Este método é chamado quando o applet é carregado pela primeira vez ou
recarregado (“load” ou “reload”).
O método init() é normalmente usado para criar os objectos gráficos de interface
com o utilizador (GUI – Graphical User Interface) e threads.
2. Em seguida é automaticamente chamado o método start() – método nunca chamado
pelo programa. Só se usa se se necessitar de iniciar qualquer coisa tal como threads.
3. Depois é automaticamente chamado o método paint() – método que em geral nunca
é directamente chamado pelo programa.
Normalmente o programa chama outro método, repaint(), que por sua vez chama o
método paint().
O método paint() recebe como parâmetro um objecto da classe Graphics, criado e
passado ao método paint() pelo browser.
Este objecto gráfico contém o estado gráfico do applet, isto é, as características
correntes da superfície de desenho. Desenhando neste objecto, desenha-se no applet
e os resultados aparecem no ecrã.
Porque um applet é uma janela Java não usa o input/output standard. Usa as
facilidades disponíveis para janelas, tais como desenhar uma string em determinadas
coordenadas.
O método paint() é o lugar onde o trabalho do applet realmente ocorre. “Painting”
pode ocorrer muitas vezes durante o ciclo de vida de um applet, depois de um applet
ser inicializado, se o browser é colocado detrás de outra janela no ecrã e depois
trazido outra vez para a frente, se a janela do browser é movida para uma posição
diferente do ecrã, ou se chamado pelo programa do applet para, por exemplo,
realizar animação.
Como paint() recebe como argumento uma instância da classe Graphics, se se usa
este método é necessário importar a classe Graphics para o código do applet, através
da seguinte instrução:
import java.awt.Graphics;
4. Se o browser deixa a página, isso causa uma chamada automática ao método stop()
– método nunca chamado pelo programa.
Neste método pode-se parar threads que tenham sido lançadas pelo applet.
Se o browser regressa à página que contém o applet, isto causa uma chamada
automática ao método start() e o fluxo de actividade continua a partir do ponto 2
acima.
5. Se o browser descarrega a página causa uma chamada ao método destroy() – método
nunca chamado pelo programa. Este método informa o applet que deve terminar
tudo.
127
Gráficos, Fontes e Cores
Gráficos
Para desenhar no ecrã em Java é necessário um contexto gráfico. Um contexto gráfico é
mantido num objecto da classe “Graphics” e controla o modo como a informação é
desenhada. Objectos da classe “Graphics” contêm métodos para desenhar, manipular
fontes e cores.
É necessário usar um objecto da classe “Graphics” para se desenhar. Um objecto da
classe “Graphics” é passado pelo sistema ao método paint() como argumento, quando
uma operação paint ocorre.
O método paint() normalmente não é directamente chamado pelo programador.
Quando um applet é inicialmente executado, o método paint() é automaticamente
chamado ( depois da chamada dos métodos init() e start() ). Para que paint() volte
novamente a ser chamado é necessário que ocorra um evento tal como um
redimensionamento (“resizing”) do applet.
Se o programador necessita de chamar um método que efectue o painting, deve chamar
o método repaint() ( public void repaint() ) que efectua um “clear” seguido de um
“paint”.
O browser cria um objecto gráfico (um objecto da classe “Graphics”) que contém o
estado gráfico do applet – as características correntes da superfície de desenho, tais
como cores de foreground e background – e passa este objecto ao método paint()
sempre que invoca a sua execução.
O método paint() tem o seguinte formato:
public void paint( Graphics g) {
..............
}
Por este motivo é necessário importar a classe “Graphics” para o código do applet:
import java.awt.Graphics;
Para desenhar objectos no ecrã, chamam-se métodos de desenho disponíveis na classe
Graphics. Todos os métodos de desenho têm argumentos representando pontos no
sistema de coordenadas do applet.
O sistema de coordenadas do applet Java tem a origem (0, 0) no canto superior
esquerdo. Valores positivos da coordenada x correspondem a pontos situados à direita
da origem e valores positivos da coordenada y correspondem a pontos situados abaixo
da origem.
(0, 0)
x
y
128
Desenho e Preenchimento (“Filling”)
A classe Graphics possui um conjunto de primitivas gráficas para desenhar, incluindo:
1.
2.
3.
4.
5.
6.
Linhas,
Rectângulos,
Rectângulos arredondados,
Polígonos,
Ovais,
Arcos.
1. Desenho de Linhas
Método
drawLine
- classe Graphics
public void drawLine( int x1, int y1, int x2, int y2)
=>
desenha uma linha entre os pontos [x1, y1] e [x2, y2].
2. Desenho de Rectângulos
Método
Método
Método
drawRect
fillRect
clearRect
- classe Graphics
- classe Graphics
- classe Graphics
public void drawRect( int x, int y, int width, int heigh)
public void fillRect( int x, int y, int width, int heigh)
public void clearRect( int x, int y, int width, int heigh)
=>
Estes métodos desenham um rectângulo com o canto superior esquerdo nas
coordenadas [x, y] e de largura “width” e altura “heigh”.
drawRect() - desenha o rectângulo com uma linha na cor corrente.
fillRect()
- desenha o rectângulo sólido na cor corrente.
clearRect() - desenha o rectângulo sólido na cor corrente do background.
3. Desenho de Rectângulos Arredondados – rectângulos com cantos arredondados
Métodos drawRoundRect e fillRoundRect - classe Graphics
public void drawRoundRect(int x, int y, int width, int heigh, int arcWidth, int arcHeigh)
public void fillRoundRect( int x, int y, int width, int heigh, int arcWidth, int arcHeigh)
=>
Estes métodos desenham um rectângulo com cantos arredondados, situado dentro
de um rectângulo com o canto superior esquerdo nas coordenadas [x, y] e de
largura “width” e altura “heigh”. As ovais que formam os cantos do rectângulo
têm largura “arcWidth” e altura “arcHeigh”.
129
drawRoundRect()
fillRoundRect()
- desenha o rectângulo arredondado.
- desenha o rectângulo arredondado sólido.
O canto superior esquerdo especificado na chamada destes métodos está a alguma
distância acima e à esquerda da linha oval do canto.
4. Desenho de Polígonos
Método
Método
drawPolygon
fillPolygon
- classe Graphics
- classe Graphics
Pode-se escolher o modo como indicar a lista de coordenadas dos pontos vértices do
polígono: ou como arrays de coordenadas x e coordenadas y ou como uma instância da
classe “Polygon”.
Usando o primeiro modo, os métodos drawPolygon() e fillPolygon() recebem 3
argumentos. Java automaticamente fecha o polígono. Para deixar a linha incompleta,
tem de se usar o método “drawPolyline()”.
public void drawPolygon( int xPoints[], int yPoints[], int points)
public void fillPolygon( int xPoints[], int yPoints[], int points)
=>
Estes métodos desenham um polígono na cor corrente com o número de pontos
“points”, em que a coordenada x de cada ponto está especificada no array xPoints
e a coordenada y no correspondente elemento do array yPoints.
Usando o 2º modo é necessário primeiro criar um objecto “Polygon”.
public void drawPolygon( Polygon p)
public void fillPolygon( Polygon p)
public Polygon( int xValues[], int yValues[], int numberOfPoints)
=>
Este construtor constrói um novo objecto polígono com o número de lados
“numberOfPoints” em que cada ponto tem uma coordenada x do array “xValues”
e coordenada y do array “yValues”.
Para desenhar uma linha poligonal aberta usa-se o método “drawPolyline()” que
funciona como o 1º modo de desenhar polígonos.
5. Desenho de Ovais: elipses ou círculos
Método
Método
drawOval
fillOval
- classe Graphics
- classe Graphics
public void drawOval( int x, int y, int width, int height )
public void fillOval( int x, int y, int width, int height)
130
=>
Estes métodos desenham uma oval (elípse ou círculo) na cor corrente situada
dentro de um rectângulo com o canto superior esquerdo no ponto [x, y] e de
largura “width” e altura “height”.
drawOval()
fillOval()
- desenha uma linha oval na cor corrente.
- desenha uma oval sólida na cor corrente.
O canto superior esquerdo especificado na chamada destes métodos está a alguma
distância acima e à esquerda da linha oval. É mais simples pensar na posição do
rectângulo no qual a oval fica inscrita.
6. Desenho de Arcos
Método
drawArc e
fillArc
- classe Graphics
Um arco é parte de uma oval. O modo mais simples de pensar num arco é como uma
secção de uma oval completa.
Um arco é desenhado entre 2 ângulos: o ângulo de partida e o ângulo do arco. Os
ângulos dos arcos são medidos em graus. Zero graus corresponde à posição de um
ponteiro nas 3 horas, graus positivos correspondem ao sentido contrário ao do
movimento dos ponteiros do relógio, e graus negativos correspondem ao sentido do
movimento dos ponteiros do relógio.
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)
=>
Estes métodos desenham um arco na cor corrente que é parte de uma oval situada
dentro de um rectângulo com o canto superior esquerdo no ponto [x, y] e de
largura “width” e altura “height”. O arco começa no ângulo “startAngle” e
estende-se “arcAngle” ângulos.
drawArc()
fillArc()
- desenha a linha de um arco, parte de uma oval, na cor corrente.
- desenha um arco preenchido, parte de uma oval sólida, na cor corrente.
Arcos sólidos (preenchidos) são desenhados como se fossem secções de ovais: ambos
os pontos extremos se juntam ao centro da oval.
O canto superior esquerdo, largura e altura especificados na chamada destes métodos
não são o ponto de partida, largura e altura dos arcos desenhados no ecrã. Eles
determinam a forma da oval da qual o arco é uma parte. Os últimos 2 argumentos
determinam os pontos inicial e final do arco. O penúltimo argumento é o ângulo do
ponto inicial e o último argumento indica a amplitude do varrimento e o sentido do arco
ao longo da oval, e não indica o ângulo do ponto final.
131
Fontes e Texto
Pode-se imprimir texto no ecrã usando a classe “Graphics” em conjunção com a classe
“Font”.
Para desenhar texto no ecrã, primeiro é necessário criar uma instância da classe “Font”.
Os objectos da classe “Font” representam uma fonte individual, isto é, o nome, estilo
(plain, bold, italic) e tamanho em “points”. Os nomes das fontes são strings
representativas da família da fonte, como por exemplo “TimesRoman”, “Courier”, ou
“Helvetica”. Os estilos das fontes são constantes do tipo inteiro definidas na classe Font
com as designações Font.PLAIN, Font.BOLD, e Font.ITALIC.
Para criar uma fonte usa-se o construtor de 3 argumentos, como no exemplo:
Font f = new Font (“TimesRoman”, Font.BOLD, 14);
É necessário importar a classe Font antes de usar este construtor:
import java.awt.Font
Como os estilos de fontes são constantes inteiras podem ser adicionados para criar
estilos combinados. Por exemplo Font.BOLD + Font.ITALIC produz uma fonte que é
ao mesmo tempo bold e italic.
A fonte corrente é parte do estado (contexto) gráfico que é mantido pelo objecto gráfico
no qual se está a desenhar. Sempre que se desenha texto no ecrã, Java desenha esse
texto na fonte corrente. Para mudar a fonte de texto, é necessário primeiro criar um
objecto “Fonte” e em seguida colocá-la como fonte corrente, usando o método
“setFont()” aplicável a objectos da classe Graphics.
Ex.:
import java.awt.Font;
import java.awt.Graphics;
public class ExemploFont extends java.applet.Applet {
public void paint(Graphics g) {
Font f = new Font("TimesRoman", Font.PLAIN, 72);
g.setFont(f);
g.drawString("This is a big font", 10, 100);
}
}
Cores
Uma cor é representada como uma combinação de vermelho, verde e azul (Red, Green
and Blue – RGB).
Cada componente da cor pode ter um valor entre 0 e 255. Preto é (0,0,0) e branco é
(255, 255, 255).
Na classe Color existem definidos um conjunto de objectos representando cores
standards, para facilitar o uso das cores mais vulgares, tais como:
132
Nome da cor:
R(ed)
G(reen)
B(lue)
Color.white
Color.black
Color.gray
Color.red
Color.green
Color.blue
Color.yellow
Color.pink
Color.orange
255
0
128
255
0
0
255
255
255
255
0
128
0
255
0
255
175
200
255
0
128
0
0
255
0
175
0
Para desenhar um objecto numa cor particular, deve-se criar uma instância da classe
“Color” para representar essa cor.
Se a cor que se pretende usar não é um objecto Color standard, pode-se criar um objecto
Color com qualquer combinação de valores para red, green e blue, através do construtor
“Color(red, green, blue)”, como no exemplo:
Color c = new Color(140, 140, 140)
Para desenhar um objecto ou texto numa determinada cor é necessário primeiro criar um
objecto cor correspondente à cor pretendida, e em seguida colocá-lo como a cor
corrente, usando o método “setColor()” aplicável a objectos da classe Graphics.
Para além de ser possível colocar uma cor corrente para o contexto gráfico, também é
possível colocar as cores de “background” e “foreground” do próprio applet usando os
métodos
“setBackground()”
e
“setForeground()”
definidos
na
classe
java.awt.Component, que são herdados pela classe Applet e pelas classes por nós
criadas.
Exemplo:
import java.awt.Graphics;
import java.awt.Color;
public class ExemploCor extends java.applet.Applet {
public void init() {
setBackground(Color.white);
}
public void paint(Graphics g) {
g.setColor(Color.red);
g.drawString("Window text is this color", 20, 50);
g.setColor(Color.green);
g.fillRect(5, 60, 180, 20);
}
}
133
Eventos
As aplicações gráficas são guiadas por eventos; não fazem nada até que o utilizador
mova o rato, clique um botão ou prima uma tecla.
Um programa guiado por eventos é estruturado à volta do modelo de processamento de
eventos.
Há 2 modelos de processamento de eventos correspondentes a 2 versões da linguagem
Java: 1.0 e 1.1.
Os eventos são gerados e fluem no sistema de um modo semelhante em qualquer um
dos modelos. Os dois modelos diferem no modo como o programa que construímos
recebe e processa os eventos.
Tratamento dos Eventos
O sistema operativo reporta aos programas que estão a correr, os eventos que ocorrem.
Cada programa decide o que fazer com esses eventos.
Visual Basic esconde a fila de eventos (“event queue”) do programador.
Cada componente gráfico de interface com o utilizador responde a um conjunto fixo de
eventos (sendo impossível mudar os eventos a que responde um componente Visual
Basic). Cada componente tem um procedimento associado a cada evento a que responde
e Vbasic activa o código desse procedimento em resposta à ocorrência do evento.
No C standard, em contraste com a simplicidade do Visual Basic, um programa guiado
por eventos necessita de filtrar constantemente a fila de eventos reportada pelo sistema
operativo. Deste modo é muito mais difícil de programar mas tem a vantagem de não
limitar os eventos a que se pode responder como no Vbasic.
Java usa uma aproximação intermédia entre o C standard e Visual Basic resultando
uma técnica poderosa com uma complexidade intermédia.
É possível responder a todos os eventos conhecidos pelo AWT e especificar a que
eventos um dado componente responde.
Modelo de Eventos 1.0
Em Java 1.02 todos os eventos são representados pela classe Event.
Esta classe tem variáveis instância que descrevem o evento.
Uma destas variáveis, “id”, especifica o tipo de evento. Na classe Event define-se um
número de constantes que são os possíveis valores do campo “id”.
O campo “target” especifica o objecto que gera o evento, ou no qual o evento ocorreu.
Em Java 1.02 a ocorrência de um evento causa a chamada do método “handleEvent()”
(classe Component):
public boolean handleEvent(Event evt)
134
A implementação, por omissão, deste método verifica o campo “id” do objecto Event, e
para os tipos de eventos mais vulgarmente usados chama um dos métodos específicos
(definidos na classe Component):
id = ACTION_EVENT
id = GOT_FOCUS
id = LOST_FOCUS
id = KEY_PRESS
id = KEY_RELEASE
id = MOUSE_DOWN
id = MOUSE_UP
id = MOUSE_ENTER
id = MOUSE_EXIT
id = MOUSE_DRAG
id = MOUSE_MOVE
public boolean action(Event evt, Object arg)
public boolean gotFocus(Event evt, Object what)
public boolean lostFocus(Event evt, Object what)
public boolean keyDown(Event evt, int key)
public boolean keyUp(Event evt, int key)
public boolean mouseDown(Event evt, int x, int y)
public boolean mouseUp(Event evt, int x, int y)
public boolean mouseEnter(Event evt, int x, int y
public boolean mouseExit(Event evt, int x, int y)
public boolean mouseDrag(Event evt, int x, int y)
public boolean mouseMove(Event evt, int x, int y)
Para processar um destes eventos deve-se reescrever (override) o respectivo método.
Deve ser criado uma subclasse para definir o comportamento pretendido.
Nem todos os tipos de eventos são encaminhados por “handleEvent()” para métodos
mais específicos.
Por isso se se está interessado num evento para o qual não existe nenhum método
específico (como por exemplo eventos para “scroll bars”), deve-se reescrever
(“override”) o método “handleEvent()”.
Se se reescreve handleEvent() na classe que implementamos, nenhum dos métodos mais
específicos será chamado por omissão, a não ser que sejam chamados explicitamente no
corpo de handleEvent().
A melhor maneira de ultrapassar este problema é testar o evento no qual estamos
interessados, e se o evento não é esse, chamar super.handleEvent() para que a
superclasse que define handleEvent() possa processsar todos os outros eventos.
Exemplo:
public boolean handleEvent(Event evt) {
if (evt.id == Event.MOUSE_DOWN) {
// processar o evento mouse down
return true;
}
else return super.handleEvent(evt);
}
O método “handleEvent()”, e todos os métodos específicos de determinados tipos de
eventos, retornam valores booleanos.
Se um método de tratamento de eventos retorna false, como todos fazem por omissão,
significa que o evento não foi tratado, portanto ele vai ser passado ao “container” do
componente corrente para ver se esse “container” está interessado no seu
processamento.
135
Se um método retorna “true” significa que o evento foi tratado e não é necessário mais
processamento sobre esse evento.
O facto de os eventos não tratados serem passados para o “container” é o que permite,
por exemplo, tratar os eventos do tipo ACTION_EVENT que são gerados pelos botões
(componentes gráficos de interface com o utilizador), reescrevendo o método “action()”.
O sistema de gestão de eventos do AWT (Abstract Window Toolkit) funciona como um
sistema de filtragem de eventos.
Um dos eventos mais comuns num applet é o clique no mouse. Eventos de clique no
mouse ocorrem quando o utilizador clica no mouse algures dentro do applet.
Podem-se interceptar os cliques do mouse para desencadear alguma acção ou podem ser
usados em conjunto com movimentos do mouse para efectuar outras acções.
Quando se clica no mouse geram-se dois eventos:
• um evento “mouse down” quando o botão é premido, e
• um evento “mouse up” quando o botão é libertado.
Estes dois eventos são gerados porque em certas situações associam-se acções
diferentes (embora relacionadas) a cada um destes dois eventos. Por exemplo num menu
“pull-down”, o evento “mouse down” estende o menu e o evento “mouse up” selecciona
um item.
Para tratar eventos do mouse deve-se reescrever a definição dos métodos apropriados no
applet.
Quando ocorre um evento “mouse down” o browser ou o viewer chamam o seguinte
método:
public boolean mouseDown(Event evt, int x, int y)
Quando ocorre um evento “mouse up” é chamado o método:
public boolean mouseUp(Event evt, int x, int y)
Estes métodos recebem 3 parâmetros: o evento e as coordenadas x e y onde o evento
(mouse down ou mouse up) ocorreram.
Sempre que o mouse se move um simples pixel em qualquer direcção um evento
“mouse move” é gerado.
Como um evento é gerado por cada pixel de movimento do mouse, mover o mouse de
um lado do applet para o outro resulta em centenas de eventos.
Há 2 tipos de movimentos do rato:
“mouse drags” onde o movimento ocorre com o botão do mouse premido, que
produzem eventos que originam a chamada do método
public boolean mouseDrag(Event evt, int x, int y)
136
e movimentos do mouse sem o botão do mouse premido que produzem eventos que
originam a chamada do método
public boolean mouseMove(Event evt, int x, int y)
Para estes 2 métodos "mouseUp()” e “mouseDrag()” os argumentos das coordenadas x e
y são as novas localizações do mouse e não são a localização de partida.
Exemplo:
Construa um applet que desenhe um círculo azul quando se clica com o mouse dentro
do applet até um máximo de 10 círculos. Cada círculo deve ser desenhado à volta do
ponto onde se clica com um diâmetro de 20 pixels.
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Event;
public class Pintas extends java.applet.Applet {
final int MAX = 10;
int xPintas[] = new int[MAX];
int yPintas[] = new int[MAX];
int nPintas = 0;
public void init() {
setBackground(Color.white);
}
public boolean mouseDown(Event evt, int x, int y) {
if (nPintas < MAX) {
adicionaPinta(x,y); return true; }
else return false;
}
void adicionaPinta(int x,int y) {
xPintas[nPintas] = x; yPintas[nPintas] = y;
nPintas++;
repaint();
}
public void paint(Graphics g) {
g.setColor(Color.blue);
for (int i = 0; i < nPintas; i++) {
g.fillOval(xPintas[i] - 10, yPintas[i] - 10, 20, 20);
}
}
}
137
A cor de fundo é colocada no método init(), e não no paint(), porque é uma acção que só
é executada uma vez.
O método paint() deve ser chamado sempre que um novo pinta é adicionada; se a cor de
fundo fosse colocada no método paint(), este método tornar-se-ia desnecessariamente
mais lento.
Sempre que ocorre um evento “mouse down” o programa verifica se a quantidade de
pintas é menor que 10, adiciona as coordenadas aos respectivos arrays, incrementa a
variável que armazena a quantidade de pintas e chama repaint().
O método repaint() efectua um clear e depois chama o método paint().
Por este motivo é necessário de cada vez que uma pinta é adicionada, pintar todas. Para
pintar todas as pintas sempre que uma é adicionada, é necessário guardar as
coordenadas de todas.
Exemplo:
Construa um applet que permita desenhar segmentos de recta no ecrã, até o máximo de
10, arrastando o rato de um ponto (início) até outro (extremidade do segmento de recta).
Enquanto o rato está a ser arrastado para desenhar uma linha, essa linha deve ser
mostrada, na cor azul, desde o ponto de partida até à posição corrente do mouse.
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Event;
import java.awt.Point;
public class Linhas extends java.applet.Applet {
final int MAX = 10;
Point inicios[] = new Point[MAX];
Point fins[] = new Point[MAX];
Point ancora;
// principio da linha corrente
Point pontoCorrente;
// fim actual da linha corrente
int nLinhas = 0;
// numero de linhas
public void init() {
setBackground(Color.white);
}
public boolean mouseDown(Event evt, int x, int y) {
if (nLinhas < MAX) { ancora = new Point(x,y); return true; }
else return false;
}
public boolean mouseUp(Event evt, int x, int y) {
if (nLinhas < MAX) { adicionaLinha(x,y); return true; }
else return false;
}
138
public boolean mouseDrag(Event evt, int x, int y) {
if (nLinhas < MAX) {
pontoCorrente = new Point(x,y);
repaint(); return true;
}
else return false;
}
void adicionaLinha(int x,int y) {
inicios[nLinhas] = ancora;
fins[nLinhas] = new Point(x,y);
nLinhas++;
pontoCorrente = null;
ancora = null;
repaint();
}
public void paint(Graphics g) {
// desenha as linhas existentes
for (int i = 0; i < nLinhas; i++) {
g.drawLine(inicios[i].x, inicios[i].y, fins[i].x, fins[i].y);
}
// desenha a linha corrente
g.setColor(Color.blue);
if (pontoCorrente != null)
g.drawLine(ancora.x,ancora.y, pontoCorrente.x, pontoCorrente.y);
}
}
A classe Point é usada para representar as coordenadas x e y de um ponto encapsuladas
num simples objecto.
Este applet trata 3 eventos (se o número de segmentos de recta armazenados ainda é
menor que 10):
mouse down: -para colocar o ponto “ancora” para a linha corrente.
mouse drag: - para criar objectos referenciados por “pontoCorrente” contendo a
extremidade actual da linha que está a ser desenhada e actualizar o
desenho (“repaint()”).
mouse up: - para armazenar uma nova linha que une o ponto “ancora” até ao ponto
onde ocorreu este evento e actualizar o desenho.
Para animar a linha que está a ser desenhada, quando se arrasta o mouse, movendo-o
desordenadamente, é necessário desenhar a linha constantemente entre o ponto “ancora”
e o ponto corrente do mouse – o que se faz efectuando repaint() sempre que ocorre
“mouse drag”.
Enquanto não se está a desenhar uma linha, o método paint() não deve efectuar o
desenho da linha corrente, para o que se coloca “anchor” e “pontoCorrente” com o valor
“null”.
139
Exemplo:
/* Construa um applet que permita ao utilizador desenhar (sarrabiscar) com o rato. */
import java.awt.*;
import java.applet.*;
public class Scribble1 extends Applet {
public boolean mouseDrag(Event evt, int x, int y) {
Graphics g = getGraphics();
g.fillOval(x, y, 4, 4);
return true;
}
}
// Outras versões
import java.awt.*;
import java.applet.*;
public class Scribble2 extends Applet {
int x=0, y=0;
public boolean mouseDown(Event evt, int x1, int y1) {
x = x1;
y = y1;
return true;
}
public boolean mouseDrag(Event evt, int x1, int y1) {
Graphics g = getGraphics();
g.drawLine(x, y, x1, y1);
x = x1;
y = y1;
return true;
}
}
import java.awt.*;
import java.util.Vector;
import java.applet.*;
public class Scribble3 extends Applet {
Vector linhas = new Vector(100, 100);
Vector linCorrente;
public boolean mouseDown(Event evt, int x, int y) {
linCorrente = new Vector(100, 100);
linhas.addElement(linCorrente);
linCorrente.addElement(new Point(x,y));
return true;
}
140
public boolean mouseDrag(Event evt, int x1, int y1) {
Point p = (Point) linCorrente.lastElement();
Graphics g = getGraphics();
g.drawLine(p.x, p.y, x1, y1);
linCorrente.addElement(new Point(x1,y1));
return true;
}
public void paint(Graphics g) {
for (int j=0; j < linhas.size(); j++) {
linCorrente = (Vector) linhas.elementAt(j);
Point p = (Point) linCorrente.elementAt(0);
for (int i=1; i<linCorrente.size(); i++) {
Point p1 = (Point) linCorrente.elementAt(i);
g.drawLine(p.x, p.y, p1.x, p1.y);
p = p1;
}
}
}
}
Modelo de Eventos 1.1
Há objectos (componentes gráficos de interface com o utilizador) que podem produzir
eventos. Um evento a que se pretende responder é enviado para outro objecto que sabe
responder convenientemente a esse evento. Este modelo de tratamento de eventos é um
modelo de delegação de eventos que permite uma maior flexibilidade de programação.
No processamento de um evento intervêm 3 objectos:
1) Um objecto fonte do evento no qual ocorre o evento; é um objecto que pode registar
objectos listener para serem notificados se determinados eventos ocorrem.
2) Um objecto listener instância de uma classe que implementa um interface
apropriado – listener interface – o qual, para ser registado, é usado como argumento
de um método do objecto fonte do evento.
3) Um objecto evento, criado pelo objecto fonte do evento quando ocorre o evento, que
é enviado (pelo objecto fonte do evento) para todos os objectos listeners registados
para esse evento (invocando o método apropriado do objecto listener e passando-lhe
o objecto evento).
A ocorrência de um evento destina-se a causar uma acção, que pode ser realizada pelo
próprio objecto ou por outro qualquer objecto.
Assim o objecto mais adequado para realizar as acções a serem executadas quando
ocorre um evento é o objecto que deve ser registado como listener.
O objecto listener ao implementar o interface apropriado significa que possui métodos
com as assinaturas correctas para responderem à ocorrência dos eventos.
141
Classes internas (Inner classes”)
Uma classe interna (“inner class”) tem acesso aos membros da classe que a contém. A
classe interna mantém uma referência ao objecto particular da classe que a contém e que
criou o objecto. Um acesso a um membro da classe envolvente usa essa referência
(escondida) para seleccionar esse membro.
Um objecto de uma classe interna só pode ser criado em associação com um objecto da
classe envolvente. O processo de construção requer a inicialização da referência ao
objecto da classe envolvente e o compilador dará erro se não pode aceder a essa
referência.
Uma referência ao objecto da classe exterior obtém-se através do nome da classe
exterior seguido de ponto e seguido de this.
As 3 páginas seguintes contêm tabelas dos principais eventos gerados nos componentes
gráficos, dos correspondentes interfaces que devem ser implementados pelos objectos
listeners, e dos métodos invocados para os objectos listeners (passando-lhe o objecto
evento como parâmetro) quando os eventos ocorrem.
142
Download