• Nenhum resultado encontrado

Programação Visual em Java

N/A
N/A
Protected

Academic year: 2021

Share "Programação Visual em Java"

Copied!
114
0
0

Texto

(1)

Programação JAVA

Programação JAVA

1. Programação Visual Básica

1. Programação Visual Básica

A Interface Gráfica com o Usuário, também conhecido como GUI

-A Interface Gráfica com o Usuário, também conhecido como GUI -

Graphical User Interface

Graphical User Interface

,,

em Java, é feita através de bibliotecas de classes, sendo que a primeira a surgir foi a AWT

em Java, é feita através de bibliotecas de classes, sendo que a primeira a surgir foi a AWT

((

 Abstract Window Toolki

 Abstract Window Toolki

t). A AWT surgiu já na versão 1.0, mas se tornou confiável a partir da

t). A AWT surgiu já na versão 1.0, mas se tornou confiável a partir da

versão 1.1. A maneira como as classes dessa biblioteca trabalham garante a criação dos

versão 1.1. A maneira como as classes dessa biblioteca trabalham garante a criação dos

elementos da interface de usuário seguindo o comportamento destinado às ferramentas GUI

elementos da interface de usuário seguindo o comportamento destinado às ferramentas GUI

nativas de cada plataforma (Windows, Mac, Solaris, ...).

nativas de cada plataforma (Windows, Mac, Solaris, ...).

Alguns exemplos destes elementos são: botões, listas, menus, componentes de textos, containers

Alguns exemplos destes elementos são: botões, listas, menus, componentes de textos, containers

(janelas e barras de menus), caixas de diálogo para abrir ou salvar arquivos, além de elementos

(janelas e barras de menus), caixas de diálogo para abrir ou salvar arquivos, além de elementos

para manipulação de imagens, fontes e cores.

para manipulação de imagens, fontes e cores.

A portabilidade de plataforma funcionava bem em aplicações simples, mas aplicações que

A portabilidade de plataforma funcionava bem em aplicações simples, mas aplicações que

envolviam elementos mais complexos, como menus e barras de rolagem, por exemplo,

envolviam elementos mais complexos, como menus e barras de rolagem, por exemplo,

apresentavam diferenças de comportamento conforme a plataforma. O que aconteceu foi que as

apresentavam diferenças de comportamento conforme a plataforma. O que aconteceu foi que as

aplicações visuais feitas em Java não se pareciam, e nem tinham as mesmas funcionalidades, com

aplicações visuais feitas em Java não se pareciam, e nem tinham as mesmas funcionalidades, com

as aplicações convencionais de cada plataforma.

as aplicações convencionais de cada plataforma.

A partir da versão 2 do Java, a JFC (Java Foundation Classes) apresentou novos recursos para a

A partir da versão 2 do Java, a JFC (Java Foundation Classes) apresentou novos recursos para a

construção da GUI das aplicações, o que melhorou muito os problemas de portabilidade. São

construção da GUI das aplicações, o que melhorou muito os problemas de portabilidade. São

eles:

eles:

Java 2D: novas funções para desenhos e gráficos.

Java 2D: novas funções para desenhos e gráficos.

Drag & Drop: clicar, arrastar, copiar e colar.

Drag & Drop: clicar, arrastar, copiar e colar.

Swing: biblioteca de classes extensão da AWT, onde são apresentados novos

Swing: biblioteca de classes extensão da AWT, onde são apresentados novos

componentes de interface e o que é conhecido por

componentes de interface e o que é conhecido por

look and feel

look and feel

, que é uma adaptação

, que é uma adaptação

perfeita da GUI ao sistema operacional específico de desenvolvimento.

perfeita da GUI ao sistema operacional específico de desenvolvimento.

É bom salientar que o Swing não substitui o AWT, mas é o kit de ferramentas GUI mais utilizado

É bom salientar que o Swing não substitui o AWT, mas é o kit de ferramentas GUI mais utilizado

para desenvolvimento de aplicações visuais. O AWT continua existindo, mantendo a mesma

para desenvolvimento de aplicações visuais. O AWT continua existindo, mantendo a mesma

arquitetura criada para o Java versão 1.1.

arquitetura criada para o Java versão 1.1.

O Swing possui muito mais recursos, além de garantir maior portabilidade e, em boa parte dos

O Swing possui muito mais recursos, além de garantir maior portabilidade e, em boa parte dos

casos, é mais fácil de usar. Isso não significa que ou se utiliza AWT ou se utiliza Swing,

casos, é mais fácil de usar. Isso não significa que ou se utiliza AWT ou se utiliza Swing,

normalmente o que acontece é que elementos das duas bibliotecas são utilizados conjuntamente

normalmente o que acontece é que elementos das duas bibliotecas são utilizados conjuntamente

nas aplicações.

nas aplicações.

Referente a criação das aplicações, exitem muitas ferramentas que auxiliam na produção de

Referente a criação das aplicações, exitem muitas ferramentas que auxiliam na produção de

interfaces de usuário gráficas, mas não se comparam a ferramentas para plataformas específicas,

interfaces de usuário gráficas, mas não se comparam a ferramentas para plataformas específicas,

(2)

como Delphi e VisualBasic, que são voltadas exclusivamente para esse fim. Boa parte da

como Delphi e VisualBasic, que são voltadas exclusivamente para esse fim. Boa parte da

elaboração da interface da aplicação tem que ser feita manualmente, o que exige bastante

elaboração da interface da aplicação tem que ser feita manualmente, o que exige bastante

trabalho.

trabalho.

1.1

1.1 Frames

Frames

Na AWT, a janela de mais alto nível de uma aplicação (não está contida dentro de nenhuma

Na AWT, a janela de mais alto nível de uma aplicação (não está contida dentro de nenhuma

outra) é denominada

outra) é denominada

FrameFrame

. No Swing, existe uma versão chamada

. No Swing, existe uma versão chamada

JFrameJFrame

, que é

, que é

derivada/estendida da classe

derivada/estendida da classe

FrameFrame

, possuindo alguns poucos métodos adicionais relacionados à

, possuindo alguns poucos métodos adicionais relacionados à

manipulação da disposição visual dos frames .Todos os outros métodos são derivados da classe

manipulação da disposição visual dos frames .Todos os outros métodos são derivados da classe

Frame

Frame

. Um frame pode conter diversos outros componentes da GUI.

. Um frame pode conter diversos outros componentes da GUI.

Para se definir um frame básico baseado em AWT, deve-se:

Para se definir um frame básico baseado em AWT, deve-se:

Importar o pacote

Importar o pacote

java.awt.*java.awt.*

..

Estender a classe

Estender a classe

FrameFrame

..

Ter um método

Ter um método

main()main()

para criar o objeto a partir do operador

para criar o objeto a partir do operador

newnew

..

Torná-lo visível.

Torná-lo visível.

Assim, o código a seguir resulta no frame apresentado na figura 1.1.

Assim, o código a seguir resulta no frame apresentado na figura 1.1.

import java.awt.*;

import java.awt.*;

public class FrameUm extends Frame

public class FrameUm extends Frame

{

{

public static void main (String[] args)

public static void main (String[] args)

{

{

FrameUm fr = new FrameUm();

FrameUm fr = new FrameUm();

fr.setVisible(true); fr.setVisible(true); } } } }

Para torná-lo visível, é possível utilizar

Para torná-lo visível, é possível utilizar

fr.show();fr.show();

no lugar de

no lugar de

fr.setVisible(true);fr.setVisible(true);

..

Percebe-se que não é possível fechá-lo utilizando o botão fechar. Por enquanto, ela deve ser

Percebe-se que não é possível fechá-lo utilizando o botão fechar. Por enquanto, ela deve ser

encerrada forçando a finalização do processo (ex.: finalizar tarefa no Windows, ou terminar

encerrada forçando a finalização do processo (ex.: finalizar tarefa no Windows, ou terminar

processo na ferramenta específica de desenvolvimento).

processo na ferramenta específica de desenvolvimento).

Figura 1.1. Frame FrameUm Figura 1.1. Frame FrameUm

O frame criado não possui tamanho definido, nem título ou posicionamento. Para personalizar o

O frame criado não possui tamanho definido, nem título ou posicionamento. Para personalizar o

frame é necessário inserir um método construtor com as instruções necessárias. Exemplo:

frame é necessário inserir um método construtor com as instruções necessárias. Exemplo:

import java.awt.*;

import java.awt.*;

public class FrameDois extends Frame

public class FrameDois extends Frame

{

{

public

public

FrameDois() //construtorFrameDois() //construtor

{

{

setTitle("Frame

setTitle("Frame Dois"); Dois"); // // título título do do FrameFrame

setSize(300,

setSize(300, 200); 200); // // largura: largura: 300 300 pixels pixels altura: altura: 200 200 pixelspixels

setResizable(false); // não permite o redimensionamento

(3)

como Delphi e VisualBasic, que são voltadas exclusivamente para esse fim. Boa parte da

como Delphi e VisualBasic, que são voltadas exclusivamente para esse fim. Boa parte da

elaboração da interface da aplicação tem que ser feita manualmente, o que exige bastante

elaboração da interface da aplicação tem que ser feita manualmente, o que exige bastante

trabalho.

trabalho.

1.1

1.1 Frames

Frames

Na AWT, a janela de mais alto nível de uma aplicação (não está contida dentro de nenhuma

Na AWT, a janela de mais alto nível de uma aplicação (não está contida dentro de nenhuma

outra) é denominada

outra) é denominada

FrameFrame

. No Swing, existe uma versão chamada

. No Swing, existe uma versão chamada

JFrameJFrame

, que é

, que é

derivada/estendida da classe

derivada/estendida da classe

FrameFrame

, possuindo alguns poucos métodos adicionais relacionados à

, possuindo alguns poucos métodos adicionais relacionados à

manipulação da disposição visual dos frames .Todos os outros métodos são derivados da classe

manipulação da disposição visual dos frames .Todos os outros métodos são derivados da classe

Frame

Frame

. Um frame pode conter diversos outros componentes da GUI.

. Um frame pode conter diversos outros componentes da GUI.

Para se definir um frame básico baseado em AWT, deve-se:

Para se definir um frame básico baseado em AWT, deve-se:

Importar o pacote

Importar o pacote

java.awt.*java.awt.*

..

Estender a classe

Estender a classe

FrameFrame

..

Ter um método

Ter um método

main()main()

para criar o objeto a partir do operador

para criar o objeto a partir do operador

newnew

..

Torná-lo visível.

Torná-lo visível.

Assim, o código a seguir resulta no frame apresentado na figura 1.1.

Assim, o código a seguir resulta no frame apresentado na figura 1.1.

import java.awt.*;

import java.awt.*;

public class FrameUm extends Frame

public class FrameUm extends Frame

{

{

public static void main (String[] args)

public static void main (String[] args)

{

{

FrameUm fr = new FrameUm();

FrameUm fr = new FrameUm();

fr.setVisible(true); fr.setVisible(true); } } } }

Para torná-lo visível, é possível utilizar

Para torná-lo visível, é possível utilizar

fr.show();fr.show();

no lugar de

no lugar de

fr.setVisible(true);fr.setVisible(true);

..

Percebe-se que não é possível fechá-lo utilizando o botão fechar. Por enquanto, ela deve ser

Percebe-se que não é possível fechá-lo utilizando o botão fechar. Por enquanto, ela deve ser

encerrada forçando a finalização do processo (ex.: finalizar tarefa no Windows, ou terminar

encerrada forçando a finalização do processo (ex.: finalizar tarefa no Windows, ou terminar

processo na ferramenta específica de desenvolvimento).

processo na ferramenta específica de desenvolvimento).

Figura 1.1. Frame FrameUm Figura 1.1. Frame FrameUm

O frame criado não possui tamanho definido, nem título ou posicionamento. Para personalizar o

O frame criado não possui tamanho definido, nem título ou posicionamento. Para personalizar o

frame é necessário inserir um método construtor com as instruções necessárias. Exemplo:

frame é necessário inserir um método construtor com as instruções necessárias. Exemplo:

import java.awt.*;

import java.awt.*;

public class FrameDois extends Frame

public class FrameDois extends Frame

{

{

public

public

FrameDois() //construtorFrameDois() //construtor

{

{

setTitle("Frame

setTitle("Frame Dois"); Dois"); // // título título do do FrameFrame

setSize(300,

setSize(300, 200); 200); // // largura: largura: 300 300 pixels pixels altura: altura: 200 200 pixelspixels

setResizable(false); // não permite o redimensionamento

(4)

setLocation(200,

setLocation(200, 100); 100); // // x: x: 200 200 pixels pixels y: y: 100 100 pixelspixels

}

}

public static void main (String[] args)

public static void main (String[] args)

{

{

FrameDois fr = new FrameDois();

FrameDois fr = new FrameDois();

fr.setVisible(true); fr.setVisible(true); } } } }

A figura 1.2 mostra o resultado da execução, um frame com largura 300 x 200 pixels

A figura 1.2 mostra o resultado da execução, um frame com largura 300 x 200 pixels

((

setSize()setSize()

), com o título “Frame Dois” (

), com o título “Frame Dois” (

setTitle()setTitle()

), que não permite redimensionamento

), que não permite redimensionamento

((

setResizable()setResizable()

).

).

Figura 1.2. Frame FrameDois Figura 1.2. Frame FrameDois

Além disso, o

Além disso, o

setLocation()setLocation()

realiza o posicionamento em tela do frame, seguindo o sistema de

realiza o posicionamento em tela do frame, seguindo o sistema de

coordenadas do Java (figura 1.3), medidas em pixels, conforme a resolução atual da tela. No

coordenadas do Java (figura 1.3), medidas em pixels, conforme a resolução atual da tela. No

exemplo, o frame fica posicionado em 2

exemplo, o frame fica posicionado em 200 pixels para x

00 pixels para x e 100 pixels para

e 100 pixels para y.

y.

(0 ,0) (0 ,0) xx y y (x, y) (x, y)

Figura 1.3. Sistema de coordenadas do Java Figura 1.3. Sistema de coordenadas do Java

Conforme já mencionado, o frame ainda não pode ser fechado. Para que isso aconteça é

Conforme já mencionado, o frame ainda não pode ser fechado. Para que isso aconteça é

necessário ter uma maneira de se ter a notificação de quando ele é fechado. A partir da

necessário ter uma maneira de se ter a notificação de quando ele é fechado. A partir da

manipulação desse evento, mostrado no exemplo a seguir, é possível fechar o frame. É necessário

manipulação desse evento, mostrado no exemplo a seguir, é possível fechar o frame. É necessário

importar o pacote

importar o pacote

java.awt.event.*java.awt.event.*

para manipular eventos do AWT. O modelo de eventos e

para manipular eventos do AWT. O modelo de eventos e

os demais eventos de janela serão vistos em seções posteriores.

os demais eventos de janela serão vistos em seções posteriores.

import java.awt.*;

(5)

import java.awt.event.*;

public class FrameTres extends Frame {

public FrameTres() //construtor {

addWindowListener(new WindowAdapter()

{public void windowClosing(WindowEvent e){System.exit(0);}}); setTitle("Frame Três"); // título do Frame

setSize(300, 200); // largura: 300 pixels altura: 200 pixels setResizable(false); // não permite o redimensionamento

setLocation(200, 100); // x: 200 pixels y: 100 pixels }

public static void main (String[] args) {

FrameTres fr = new FrameTres(); fr.setVisible(true);

} }

Ainda em relação ao posicionamento, dependendo da resolução da tela onde o frame será aberto,

pode se ter situações bem desagradáveis, como, por exemplo, o frame ser aberto e ficar com parte

fora da tela. É necessário então posicionar o frame em coordenadas que independam da resolução

utilizada. O exemplo a seguir abrirá um frame com a metade do tamanho da tela, posicionado no

centro, respeitando a resolução.

import java.awt.*;

import java.awt.event.*;

public class FrameQuatro extends Frame {

public FrameQuatro() //construtor {

addWindowListener(new WindowAdapter()

{public void windowClosing(WindowEvent e){System.exit(0);}}); Toolkit tk = Toolkit.getDefaultToolkit();

Dimension d = tk.getScreenSize(); setSize(d.width / 2, d.height / 2); setLocation(d.width / 4, d.height / 4); Image img = tk.getImage("icone.gif"); setIconImage(img);

setTitle("Frame Quatro"); setResizable(false);

}

public static void main (String[] args) {

FrameQuatro fr = new FrameQuatro(); fr.setVisible(true);

} }

Para que seja possível essa tarefa de posicionamento conforme a resolução de vídeo, é necessário

obter informações do sistema operacional, e isso é feito através da classe

Toolkit

, método

getScreenSize()

, cujos dados são jogados em um objeto da classe

Dimension

, que armazena a

altura e largura nos campos

d.width

e

d.height

. Por exemplo, se a resolução de vídeo for

800x600, o

d.width

fica com 800 e o

d.height

fica com 600. Tendo esses valores, é possível

utilizar em métodos como o

setLocation()

e o

setSize()

, como foi feito no exemplo. Além

(6)

método

getImage()

, para carregar a imagem (extensão

.gif

) e jogar em um objeto da classe

Image

, para depois setar o ícone através do

setIconImage()

.

O mesmo exemplo pode ser feito baseado na biblioteca Swing, classe

JFrame

, mudando apenas a

derivação e importando o pacote

javax.swing.*

, assim:

import java.awt.*;

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

public class FrameQuatro extends JFrame {

... }

Os exemplos apresentados nas próximas seções criarão frames baseado na classe

JFrame

.

1.2 Mostrando Textos e Linhas no Frame

Para que seja possível mostrar textos em um frame é necessário criar um objeto baseado na classe

Graphics

, que será responsável pelo gerenciamento da área gráfica a ser desenhada, controlando

cores, tipos de fontes, etc. A classe

Component

possui um método

paint()

que aceita um objeto

Graphics

como parâmetro. Esse método, na classe de origem, não faz nada, por isso ele deve ser

sobrescrito com a chamada de métodos que realizam operações de escrita, pintura, desenho, etc.

Para efetuar a sobreposição do método

paint()

deve-se ter o cabeçalho:

public void paint(Graphics g)

A partir disso, métodos como

drawString()

e

drawLine()

podem ser utilizados, como no

exemplo a seguir. O resultado é apresentado na figura 1.4.

import java.awt.*;

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

public class MostrandoTextos extends JFrame {

public MostrandoTextos() {

addWindowListener(new WindowAdapter()

{public void windowClosing(WindowEvent e){System.exit(0);}}); Toolkit tk = Toolkit.getDefaultToolkit();

Dimension d = tk.getScreenSize(); int screenHeight = d.height;

int screenWidth = d.width;

setSize(d.width / 2, d.height / 2); setLocation(d.width / 4, d.height / 4); setTitle("Escrevendo Textos");

setResizable(false); }

public void paint (Graphics g) {

g.drawString("Estou escrevendo no frame", 40, 50); g.drawLine(40, 60, 200, 60);

int i = 30; while (i < 150) {

(7)

g.drawString("Estou escrevendo no frame", 40+i, 50+i); g.drawLine(40+i, 60+i, 200+i, 60+i);

i+=30; }

}

public static void main (String[] args) {

MostrandoTextos fr = new MostrandoTextos(); fr.setVisible(true);

} }

Figura 1.4. Frame MostrandoTextos

O método

drawString(String s, int x, int y)

realiza a mostragem de um texto em uma

posição definida por

x

e

y

. O método

drawLine(int x1, int y1, int x2, int y2)

desenha

uma linha que inicia nas coordenadas

x1,y1

e termina nas coordenadas

x2,y2

.

1.3 Cores

O método

setColor()

seleciona a cor que é utilizada para todas as operações de desenho dentro

do contexto gráfico ou componente. Um parâmetro

Color

define a cor a ser usada, sendo que as

treze cores padrão, apresentadas na tabela 1.1, estão definidas na classe

java.awt.Color

.

black

(preto)

magenta

(magenta)

blue

(azulo)

orange

(laranja)

cyan

(ciano)

pink

(rosa)

darkGray

(cinza-escuro)

red

(vermelho)

gray

(cinza)

white

(branco)

(8)

lightGray

(cinza-claro)

Tabela 1.1. Cores definidas em java.awt.Color

Além das cores pré-definidas, pode-se criar novas cores baseadas no conteúdo RGB

(red-vermelho, green-verde, blue-azul), expressos por inteiros de 0 a 255. O exemplo a seguir

apresenta a criação de objetos coloridos em um frame. O resultado é apresentado na figura 1.5.

import java.awt.*;

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

public class Cores extends JFrame {

public Cores() {

addWindowListener(new WindowAdapter()

{public void windowClosing(WindowEvent e){System.exit(0);}}); setSize(400, 200);

setLocation(200, 100); setTitle("Cores"); }

public void paint (Graphics g) { g.setColor(Color.blue); g.drawString("Cor Azul", 50, 50); g.setColor(Color.green); g.drawLine(50, 60, 220, 60); g.setColor(Color.red); g.drawRect(50,70,100,30); g.setColor(new Color(0,128,128)); g.fillRect(50,110,100,30); }

public static void main (String[] args) {

Cores fr = new Cores(); fr.setVisible(true); }

}

(9)

O método

drawRect(int x, int y, int width, int height)

desenha um retângulo com a

cor definida em

setColor()

, iniciando nas coordenadas

x,y

, tendo uma largura

width

e uma

altura

height

. O método

fillRect(int x, int y, int width, int height)

faz a mesma

coisa, mas preenche o retângulo.

1.4 Fontes

O método responsável por definir o tipo de fonte desejado é o

setFont()

, que precisa de um

objeto criado, baseado na classe

Font

, definindo assim o nome da fonte, o seu estilo e seu

tamanho. O nome pode ser qualquer fonte suportada pelo sistema operacional específico; o estilo

pode ser:

PLAIN

– regular,

BOLD

– negrito e

ITALIC

– itálico, sendo possível combinar os estilos

utilizando o operador

+

; o tamanho pode ser qualquer valor que represente o tamanho em pontos

da fonte. Exemplo:

import java.awt.*;

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

public class Fontes extends JFrame {

public Fontes() {

addWindowListener(new WindowAdapter()

{public void windowClosing(WindowEvent e){System.exit(0);}}); setSize(400,130);

setTitle("Tipos de Fonte"); }

public void paint (Graphics g) {

g.setColor(Color.blue);

Font f = new Font("SansSerif", Font.ITALIC, 16); g.setFont(f);

g.drawString("Fonte SansSerif itálico tamanho 16", 20, 50); g.setFont(new Font("Monospaced", Font.BOLD + Font.ITALIC, 14));

g.drawString("Fonte Monospaced negrito e itálico tamanho 14", 20, 80); g.setFont(f);

g.drawString("Novamente Fonte SansSerif itálico tamanho 16", 20, 110); }

public static void main (String[] args) {

Fontes fr = new Fontes(); fr.setVisible(true);

} }

A figura 1.6 mostra o resultado. Percebe-se que não é necessário criar explicitamente um objeto

do tipo

Font

(objeto

f

), podendo ser possível criá-lo no próprio argumento do

setFont()

. Se a

fonte for utilizada várias vezes no decorrer da aplicação, torna-se útil a criação do objeto

explicitamente.

(10)

Figura 1.6. Frame Fontes

Em termos de portabilidade, deve-se tomar cuidado quanto a fontes que não existem em alguns

sistemas operacionais. O ideal é trabalhar com fontes comuns em sistemas operacionais

diferentes. O modelo do AWT define cinco fontes disponíveis em qualquer sistema operacional.

São elas:

Serif

,

Monospaced

,

SansSerif

,

Dialog

e

DialogInput

.

1.5 Outras Formas Geométricas

Além das formas já apresentadas, existem várias outras possíveis, a maioria com a opção de

preenchimento ou não, a partir da precedência de

draw

ou

fill

. O exemplo a seguir tem como

resultado o frame apresentado na figura 1.7.

import java.awt.*;

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

public class FormasGeometricas extends JFrame {

public FormasGeometricas() {

addWindowListener(new WindowAdapter()

{public void windowClosing(WindowEvent e){System.exit(0);}}); setSize(460,140);

setTitle("Formas Geométricas"); }

public void paint (Graphics g) { g.setColor(Color.red); g.drawRoundRect(10,30,80,40,30,30); g.fillRoundRect(10,80,80,40,30,30); g.setColor(Color.yellow); g.draw3DRect(100,30,80,40,true); g.fill3DRect(100,80,80,40,false); g.setColor(Color.blue); g.drawOval(190,30,80,40); g.fillOval(190,80,80,40); g.setColor(Color.darkGray); g.drawArc(280,30,80,40,90,270); g.fillArc(280,80,80,40,90,270); g.setColor(Color.magenta); int ValoresX[] = {370,450,410,370}; int ValoresY[] = {30,30,70,30}; g.drawPolygon(ValoresX,ValoresY,3); int ValoresX2[] = {370,450,410,370}; int ValoresY2[] = {80,80,120,80}; g.fillPolygon(ValoresX2,ValoresY2,3);

(11)

}

public static void main (String[] args) {

FormasGeometricas fr = new FormasGeometricas(); fr.setVisible(true);

} }

Figura 1.7. Frame Fontes

Várias formas geométricas foram desenhadas no frame. Funcionamento de cada método:

• drawRoundRect(int x, int y, int width, int height, int arcWidth, int

arcHeight)

: Desenha um retângulo com cantos arredondados, iniciando nas coordenadas

x,y

, tendo uma largura

width

e uma altura

height

, e cantos definidos por

arcWidth

e

arcHeight

.

• fillRoundRect(int x, int y, int width, int height, int arcWidth, int

arcHeight)

: Idem a

drawRoundRect

, mas preenche o retângulo.

• draw3DRect(int x, int y, int width, int height, boolean raised)

: Desenha

um retângulo 3D, iniciando nas coordenadas

x,y

, tendo uma largura

width

e uma altura

height

, e um valor lógico para indicar a aparência do 3D.

• fill3DRect(int x, int y, int width, int height, boolean raised)

: Idem a

draw3DRect

, mas preenche o retângulo.

• drawOval(int x, int y, int width, int height)

: Desenha uma forma oval,

baseado nas coordenadas do retângulo que inicia em

x,y

, tendo uma largura

width

e uma

altura

height

.

• fillOval(int x, int y, int width, int height)

: Idem a

drawOval

, mas preenche

a forma oval.

• drawArc(int x, int y, int width, int height, int startAngle, int

arcAngle)

: Desenha um arco, baseado nas coordenadas do retângulo que inicia em

x,y

,

tendo uma largura

width

e uma altura

height

, mostrando apenas a linha que vai do

ângulo

startAngle

até o ângulo

arcAngle

.

• fillArc(int x, int y, int width, int height, int startAngle, int

(12)

• drawPolygon(int[] xPoints, int[] yPoints, int nPoints)

: Desenha um

polígono, baseado nas coordenadas dos arranjos

x,y

.

• fillPolygon(int[] xPoints, int[] yPoints, int nPoints)

:

Idem

a

drawPolygon

, mas preenche o arco.

1.6 Imagens

A classe

Image

é a responsável pelo carregamento de imagens armazenadas em disco.

Novamente, é necessário utilizar um objeto do tipo

Toolkit

para obter uma imagem, através do

método

getImage()

, e depois jogar em um objeto do tipo

Image

. O exemplo a seguir mostra a

maneira de se preencher um frame com as imagens lado a lado. A figura 1.8 mostra o resultado.

import java.awt.*;

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

public class Imagens extends JFrame {

public Imagens() //construtora {

addWindowListener(new WindowAdapter()

{public void windowClosing(WindowEvent e){System.exit(0);}}); setSize(400,200);

setTitle("Imagens"); }

public void paint (Graphics g) {

Image ima = Toolkit.getDefaultToolkit().getImage("LogoJava.gif"); int larguraTela = 400;

int alturaTela = 200;

int larguraImagem = ima.getWidth(this); int alturaImagem = ima.getHeight(this); g.drawImage(ima,4,23,null);

for (int i = 0; i <= larguraTela / larguraImagem; i++) for (int j = 0; j <= alturaTela / alturaImagem; j++)

if (i + j > 0)

g.copyArea(4,23,larguraImagem, alturaImagem, i * larguraImagem, j * alturaImagem); }

public static void main (String[] args) {

Imagens fr = new Imagens(); fr.setVisible(true);

} }

(13)

Figura 1.8. Frame Imagens

A primeira imagem, obtida pelo

getImage()

e jogada no objeto

Image ima

, é mostrada a partir

do

drawImage(Image img, int x, int y, ImageObserver observer)

, que insere a imagem

img

nas coordenadas

x,y

, para depois ser copiada lado a lado, através do método

copyArea(int x, int y, int width, int height, int dx, int dy)

, que copia o

conteúdo da área que começar nas coordenadas

x,y

com largura

width

e altura

height

, em um

local a uma distância

dx,dy

. Para realizar essa tarefa, foi necessário descobrir o tamanho da

imagem, através

getWidth()

e do

getHeight()

.

1.7 Contêiners

Contêiners servem de repositório de outros componentes, como botões, por exemplo. Alguns

exemplos de contêiners:

JFrame

,

JPanel

e

JApplet

. Um

JFrame

é uma janela de mais alto nível;

um

JPanel

é um contêiner usado para agrupar componentes, normalmente dentro de um

JFrame

;

um

JApplet

permite a execução em navegadores da Web. Pode-se desenhar algo diretamente no

frame ou definir um contêiner, como um painel, por exemplo, e desenhar nele. Não é considerada

uma boa prática de programação desenhar diretamente no frame, pois ele foi projetado para ser

contêiner de componentes específicos, como barras de menu, por exemplo. Os painéis devem ser

utilizados para agrupar outros componentes. Exemplo de adição de um painel a um frame:

import java.awt.*;

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

class Painel extends JPanel {

public void paintComponent(Graphics g) {

super.paintComponent(g);

g.drawString("Estou escrevendo em um painel", 100, 50); }

}

public class EscrevendoEmPainel extends JFrame {

public EscrevendoEmPainel() {

(14)

{public void windowClosing(WindowEvent e){System.exit(0);}}); setSize(400,130); setTitle("Painel"); Container P = getContentPane(); P.add(new Painel()); }

public static void main (String[] args) {

EscrevendoEmPainel fr = new EscrevendoEmPainel(); fr.setVisible(true);

} }

Figura 1.9. Contêiner do tipo painel

O resultado pode ser conferido na figura 1.9. Para desenhar algo em um painel, deve-se criar uma

classe derivada de

JPanel

e sobrepor o método

paintComponent()

, que está definido na classe

JComponent

, e recebe um parâmetro do tipo

Graphics

. Tal método é chamado automaticamente

toda vez que a janela é redesenhada, como na criação e no redimensionamento. Se, por algum

motivo, se desejar redesenhar o conteúdo no painel, o método a ser chamado é o

repaint()

, que

se encarrega de executar novamente o

paintComponent()

. O

super.paintComponent(g)

faz

com que o método da superclasse seja executado também. Isso normalmente é feito em

sobreposições de métodos, quando se deseja criar algo a mais que o método definido na

superclasse. A criação de uma classe derivada de

JFrame

é feita a seguir, e um objeto

Container

é criado para depois adicionar (

add

) o painel. O método

getContentPane()

retorna a área de

conteúdo do frame para que possa ser adicionado o painel.

1.8 Gerenciadores de Layout

Os gerenciadores de layout controlam o dimensionamento e posicionamento dos componentes

dentro de contêiners, sendo que cada contêiner possui um gerenciador padrão, mas pode ser

alterado através da chamada ao método

setLayout()

do contêiner específico. Por exemplo, o

gerenciador padrão do

JPanel

é o

FlowLayout

, que coloca os componentes em um tamanho

pré-definido da esquerda para a direita e de cima para baixo no contêiner. Outros gerenciadores de

layout existentes:

GridLayout

,

BorderLayout

,

BoxLayout

e

GridBagLayout

.

1.8.1 Gerenciador FlowLayout

Para que seja possível verificar a diferença entre alguns deles, exemplos são demonstrados nas

próximas seções, começando exatamente pelo gerenciador

FlowLayout

, padrão do

JPanel

. Nos

exemplos, são definidos objetos botão a partir da classe

JButton

.

import java.awt.*;

(15)

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

class PainelFlow extends JPanel { public PainelFlow() { setLayout(new FlowLayout()); add(new JButton("Um")); add(new JButton("Dois")); add(new JButton("Três")); add(new JButton("Quatro")); add(new JButton("Cinco")); } }

public class GerenciadorFlowLayout extends JFrame {

public GerenciadorFlowLayout() {

addWindowListener(new WindowAdapter()

{public void windowClosing(WindowEvent e){System.exit(0);}}); setSize(200,90); setLocation(150,150); setTitle("FlowLayout"); Container P = getContentPane(); P.add(new PainelFlow()); }

public static void main (String[] args) {

GerenciadorFlowLayout fr = new GerenciadorFlowLayout(); fr.setVisible(true);

} }

Figura 1.10. Gerenciador de Layout FlowLayout

Como o

FlowLayout

é o gerenciador padrão do

JPanel

, não seria necessário setar o layout

através do

setLayout(new FlowLayout());

. O alinhamento dos componentes fica centralizado

e, caso algum compontnte não caiba em uma linha, é jogado para a linha seguinte, como mostra a

figura 1.10. É possível alterar o alinhamento, passando-o como parâmetro na determinação do

layout (

LEFT

,

RIGHT

ou

CENTER

), assim:

setLayout(new FlowLayout(FlowLayout.RIGHT));

(16)

O

GridLayout

é um gerenciador que organiza os componentes em linhas e colunas espaçadas

regularmente. Exemplo:

import java.awt.*;

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

class PainelGrid extends JPanel { public PainelGrid() { setLayout(new GridLayout(3,2)); add(new JButton("Um")); add(new JButton("Dois")); add(new JButton("Três")); add(new JButton("Quatro")); add(new JButton("Cinco")); } }

public class GerenciadorGridLayout extends JFrame {

public GerenciadorGridLayout() {

addWindowListener(new WindowAdapter()

{public void windowClosing(WindowEvent e){System.exit(0);}}); setSize(200,150); setLocation(150,150); setTitle("GridLayout"); Container P = getContentPane(); P.add(new PainelGrid()); }

public static void main (String[] args) {

GerenciadorGridLayout fr = new GerenciadorGridLayout(); fr.setVisible(true);

} }

Figura 1.11. Gerenciador de Layout GridLayout

O tamanho de cada componente é redimensionado automaticamente, como mostra a figura 1.11,

podendo ficar espaços vazios. É necessário definir o número de linhas e colunas no

(17)

setLayout()

. Os componentes são adicionados a partir da posição na parte superior esquerda da

grade, seguindo para a direita até preencher a linha e passar para baixo.

Também é possível espaçar os componentes horizontal e verticalmente. Nesse caso, na definição

do layout, deve-se passar esses valores também. O layout abaixo, por exemplo, define

5

pixels de

espaçameno horizontal e

8

pixels de espaçamento vertical:

setLayout(new GridLayout(3,2,5,8));

1.8.3 Gerenciador BorderLayout

Existem gerenciadores mais interessantes, como o

BorderLayout

, que organiza os objetos em

locais determinados por

NORTH

,

SOUTH

,

EAST

,

WEST

e

CENTER

. Exemplo:

import java.awt.*;

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

class PainelBorder extends JPanel { public PainelBorder() { setLayout(new BorderLayout()); add(new JButton("Um"),BorderLayout.NORTH); add(new JButton("Dois"),BorderLayout.SOUTH); add(new JButton("Três"),BorderLayout.EAST); add(new JButton("Quatro"),BorderLayout.WEST); add(new JButton("Cinco"),BorderLayout.CENTER); } }

public class GerenciadorBorderLayout extends JFrame {

public GerenciadorBorderLayout() {

addWindowListener(new WindowAdapter()

{public void windowClosing(WindowEvent e){System.exit(0);}}); setSize(300,150); setLocation(150,150); setTitle("BorderLayout"); Container P = getContentPane(); P.add(new PainelBorder()); }

public static void main (String[] args) {

GerenciadorBorderLayout fr = new GerenciadorBorderLayout(); fr.setVisible(true);

} }

(18)

Figura 1.12. Gerenciador de Layout GridLayout

Na figura 1.12 se observa o resultado da aplicação, com um botão em cada localização geográfica

dentro do painel. O

BorderLayout

é o gerenciador padrão para os contêiners

JWindow

e

JFrame

.

Não é necessário ter todas as localizações preenchidas. Se alguma das localizações (norte, sul,

leste ou oeste) não for ocupada, as demais ocupam o lugar da(s) omitida(s). Porém, se a

localização central não for ocupada, ela ficará vazia.

Na definição do layout é possível determinar o espaçamento horizontal e vertical entre as

localizações. O layout abaixo, por exemplo, define

5

pixels de espaçameno horizontal e

8

pixels

de espaçamento vertical:

setLayout(new BorderLayout(5,8));

1.8.4 Gerenciador BoxLayout

Os gerenciadores de layout foram criados ainda na versão 1.0 do Java. O Swing possui apenas

um gerenciador de layout de uso geral, chamado

BoxLayout

, sendo mais utilizado para criar

barras de ferramentas, podendo inserir componentes em apenas uma linha ou uma coluna. Ao

invés de utilizar o

BoxLayout

diretamente, pode-se usar um outro contêiner do Swing chamado

Box

, como no exemplo a seguir.

import java.awt.*;

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

class PainelBox extends JPanel { public PainelBox() { add(Box.createHorizontalGlue()); add(new JButton("Um")); add(Box.createHorizontalGlue()); add(new JButton("Dois")); add(Box.createHorizontalStrut(10)); add(new JButton("Três")); add(Box.createHorizontalStrut(30)); add(new JButton("Quatro")); add(Box.createHorizontalGlue()); add(new JButton("Cinco")); add(Box.createHorizontalGlue()); } }

(19)

{

public GerenciadorBoxLayout() {

addWindowListener(new WindowAdapter()

{public void windowClosing(WindowEvent e){System.exit(0);}}); setSize(500,100); setLocation(150,150); setTitle("BoxLayout"); Container b = Box.createHorizontalBox(); getContentPane().add(b,BorderLayout.CENTER); b.add(new PainelBox()); }

public static void main (String[] args) {

GerenciadorBoxLayout fr = new GerenciadorBoxLayout(); fr.setVisible(true);

} }

Figura 1.13. Gerenciador de Layout BoxLayout

Observa-se, na figura 1.13, que os botões não ficaram distanciados uniformemente. Isso porque

dois métodos foram utilizados: o

createHorizontalGlue()

, que determina um espaçamento

variável, conforme o tamanho da janela e o

createHorizontalStrut()

, que determina um

espaçamento fixo, determinado pelo seu parâmetro.

1.8.5 Gerenciador GridBagLayout

O gerenciador

GridBagLayout

é bastante flexível, permitindo posicionamento dos componentes

em relação aos outros. Assim, é possível criar praticamente qualquer tipo de layout. Por ser mais

flexível, é também mais difícil de ser utilizado. O construtor não possui argumentos e a aparência

do layout é controlada pela classe

GridBagConstraints

. Os componentes gerenciados devem

estar associados a um objeto

GridBagConstraints

, que possui campos, mostrados na tabela 1.1,

para controle dos componentes.

Campo

Descrição

int gridx, gridy

Utilizado para controlar o posicionamento dos componentes

na grade do layout.

int weightx, weighty

Utilizado para especificar um percentual de aumento do local

destinado aos componentes, que irão aumentar também se

estiverem expandidos.

int fill

Utilizado para expandir o componente a fim de preencher o

espaço reservado a ele.

(20)

componente irá se espalhar.

int anchor

Utilizado para controlar a posição do componente, caso ele

não esteja espalhado.

int ipadx, ipady

Utilizado para controlar o aumento do tamanho mínimo dos

componente.

Insets insets

Utilizado para controlar o afastamento entre componentes.

Tabela 1.1. Campos da classe GridBagConstraints

A utilização desses campos são demonstradas através de exemplos. O primeiro deles mostra um

GridBagLayout

com cinco botões inseridos em posições determinadas pelo

gridx

e

gridy

.

import java.awt.*;

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

class PainelGridBag extends JPanel {

GridBagConstraints restricoes = new GridBagConstraints(); public PainelGridBag() { setLayout(new GridBagLayout()); addGridBag(new JButton("Um"), 1, 0); addGridBag(new JButton("Dois"), 0, 1); addGridBag(new JButton("Três"), 1, 1); addGridBag(new JButton("Quatro"), 2, 1); addGridBag(new JButton("Cinco"), 1, 2); }

void addGridBag(Component objeto, int x, int y) { restricoes.gridx = x; restricoes.gridy = y; add(objeto, restricoes); } }

public class GerenciadorGridBagLayout extends JFrame {

public GerenciadorGridBagLayout() {

addWindowListener(new WindowAdapter()

{public void windowClosing(WindowEvent e){System.exit(0);}}); setSize(270,130); setLocation(150,150); setTitle("GridBagLayout"); Container P = getContentPane(); P.add(new PainelGridBag()); }

public static void main (String[] args) {

GerenciadorGridBagLayout fr = new GerenciadorGridBagLayout(); fr.setVisible(true);

(21)

} }

Figura 1.13. Gerenciador de Layout GridBagLayout com cinco botões

O resultado, mostrado na figura 1.13, apresenta cinco botões inseridos em coordenadas que

indicam a presença de três linhas por três colunas (0, 1 e 2). O tamanho da grade é definido por

essas coordenadas, sendo possível, por isso, ter quantas colunas e linhas se desejar. O método

addGridBag()

criado serve para auxiliar na definição dos valores que os campos de controle do

GridBagConstraints

irão assumir.

Para que os botões preencham toda a área do painel é necessário definir, no construtor, a restrição

fill

para

BOTH

e os campos

weigthx

e

weigthy

para

1

, assim:

public PainelGridBag() { setLayout(new GridBagLayout()); restricoes.weightx = 1.0; restricoes.weighty = 1.0; restricoes.fill = GridBagConstraints.BOTH; addGridBag(new JButton("Um"), 1, 0); addGridBag(new JButton("Dois"), 0, 1); addGridBag(new JButton("Três"), 1, 1); addGridBag(new JButton("Quatro"), 2, 1); addGridBag(new JButton("Cinco"), 1, 2); }

Figura 1.14. Gerenciador de Layout GridBagLayout ocupando todo espaço disponível

O resultado é o preenchimento de todo painel, como mostra a figura 1.14. O

fill

ainda pode ser

definido como:

HORIZONTAL

, preenchendo o espaço horizontal disponível;

VERTICAL

,

preenchendo o espaço vertical disponível e;

NONE

, não preenchendo o espaço disponível. Os

campos

weigthx

e

weigthy

devem receber um valor diferente de zero, pois o preenchimento não

ocorre se esse valor for igual a zero, que é o valor default.

É possível realizar um espalhamento dos componentes em mais do que uma linha e/ou coluna.

Para isso, é necessário combinar os valores de

gridx

e

gridy

com a determinação da altura (em

(22)

número de linhas) e largura (em número de colunas) através dos campos

gridwidth

e

gridheight

, assim:

public PainelGridBag() { setLayout(new GridBagLayout()); restricoes.weightx = 1.0; restricoes.weighty = 1.0; restricoes.fill = GridBagConstraints.BOTH; restricoes.gridwidth = 3; addGridBag(new JButton("Um"), 0, 0); restricoes.gridwidth = 1; addGridBag(new JButton("Dois"), 0, 1); addGridBag(new JButton("Três"), 1, 1); restricoes.gridheight = 2; addGridBag(new JButton("Quatro"), 2, 1); restricoes.gridheight = 1; addGridBag(new JButton("Cinco"), 0, 2); addGridBag(new JButton("Seis"), 1, 2); }

Figura 1.15. Gerenciador de Layout GridBagLayout utilizando espalhamento

Percebe-se, pelo resultado apresentado na figura 1.15, que o botão

Um

ocupou três colunas e uma

linha, enquanto o botão

Quatro

ocupou duas linhas e uma coluna. No momento que o número de

colunas/linhas é definido, todos os componentes utilizarão esse tamanho de espaço daí pra diante,

a não ser que este seja redefinido.

É possível também definir o tamanho dos componentes através do peso atribuído aos campos

weigthx

e

weigthy

, como no exemplo:

public PainelGridBag() { setLayout(new GridBagLayout()); restricoes.weighty = 1.0; restricoes.fill = GridBagConstraints.BOTH; restricoes.weightx = 0.2; addGridBag(new JButton("Um"), 0, 0); restricoes.weightx = 0.6; addGridBag(new JButton("Dois"), 1, 0); restricoes.weightx = 1.5; addGridBag(new JButton("Três"), 2, 0); restricoes.weightx = 4.0; addGridBag(new JButton("Quatro"), 3, 0); }

(23)

Figura 1.16. Gerenciador de Layout GridBagLayout com determinação de pesos

Para que o exemplo fique igual ao apresentado na figura 1.16, é necessário mudar o

setSize()

do frame para

(400,60)

. Os botões ficam dispostos em uma única linha, com tamanhos

diferentes, determinados pela atribuição de seus respectivos pesos, sabendo-se que o valor

específico do peso não é o que importa, e sim as proporções relativas entre os botões e o tamanho

do painel.

O aumento do tamanho de alguns componentes pode ser feito pelos campos

ipadx

e

ipady

, que

especificam valores de aumento vertical e horizontal. Além disso, é possível fixar uma posição

do componente, dentro do espaço reservado a ele, desde que ele não esteja espalhado em mais

que uma coluna e/ou linha. Isso é feito através do

anchor

. Exemplo:

public PainelGridBag() { setLayout(new GridBagLayout()); addGridBag(new JButton("Um"), 1, 0); restricoes.ipadx=10; restricoes.ipady=10; addGridBag(new JButton("Dois"), 0, 1); restricoes.ipadx=0; restricoes.ipady=0; restricoes.anchor = GridBagConstraints.SOUTHEAST; addGridBag(new JButton("Três"), 1, 1); restricoes.ipadx=10; restricoes.ipady=10; restricoes.anchor = GridBagConstraints.CENTER; addGridBag(new JButton("Quatro"), 2, 1); restricoes.ipadx=0; restricoes.ipady=0; addGridBag(new JButton("Cinco"), 1, 2); }

Figura 1.17. Gerenciador de Layout GridBagLayout com aumento do tamanho e posicionamento de componentes

Novamente, para que o exemplo fique igual ao da figura 1.17, é necessário alterar o

setSize()

do frame para

(270,130)

. Percebe-se que o tamanho dos componentes

Dois

e

Quatro

foi

aumentado, sendo mantido o tamanho mínimo do botão

Três

. Para esse mesmo botão

Três

foi

especificado um posicionamento fixo no canto inferior direito, dentro de sua área definida. O

(24)

concedida. O valor padrão é

concedida. O valor padrão é

CENTERCENTER

, e os outros valores possíveis são:

, e os outros valores possíveis são:

NORTHNORTH

,,

NORTHEASTNORTHEAST

,,

EASTEAST

,,

SOUTHEAST

SOUTHEAST

,,

SOUTHSOUTH

,,

SOUTHWESTSOUTHWEST

,,

WESTWEST

, e

, e

NORTHWESTNORTHWEST

..

Através do campo

Através do campo

insetsinsets

é possível indicar as distâncias entre os componentes do layout. Uma

é possível indicar as distâncias entre os componentes do layout. Uma

classe

classe

InsetsInsets

possui valores para as quatro direções: cima, baixo, direita e esquerda, dando

possui valores para as quatro direções: cima, baixo, direita e esquerda, dando

muita flexibilidade ao layout. O valor padrão é

muita flexibilidade ao layout. O valor padrão é

(0, 0, 0, 0)(0, 0, 0, 0)

. Exemplo:

. Exemplo:

public PainelGridBag() public PainelGridBag() { { setLayout(new GridBagLayout()); setLayout(new GridBagLayout()); restricoes.weightx = 1.0; restricoes.weightx = 1.0; restricoes.weighty = 1.0; restricoes.weighty = 1.0; restricoes.fill = GridBagConstraints.BOTH; restricoes.fill = GridBagConstraints.BOTH;

restricoes.insets = new Insets(3,3,3,3);

restricoes.insets = new Insets(3,3,3,3);

addGridBag(new JButton("Um"), 1, 0); addGridBag(new JButton("Um"), 1, 0); addGridBag(new JButton("Dois"), 0, 1); addGridBag(new JButton("Dois"), 0, 1); addGridBag(new JButton("Três"), 1, 1); addGridBag(new JButton("Três"), 1, 1); addGridBag(new JButton("Quatro"), 2, 1); addGridBag(new JButton("Quatro"), 2, 1); addGridBag(new JButton("Cinco"), 1, 2); addGridBag(new JButton("Cinco"), 1, 2); } }

Figura 1.18. Gerenciador de Layout GridBagLayout utilizando Insets Figura 1.18. Gerenciador de Layout GridBagLayout utilizando Insets

A figura 1.18 mostra que cada componente ganhou um espaço adicional de três pixels para cada

A figura 1.18 mostra que cada componente ganhou um espaço adicional de três pixels para cada

uma das direções: cima, baixo, direita e esquerda.

uma das direções: cima, baixo, direita e esquerda.

1.8.6

1.8.6 Layouts Compostos

Layouts Compostos

Normalmente, ao querer criar um determinado layout, a utillização de um gerenciador apenas não

Normalmente, ao querer criar um determinado layout, a utillização de um gerenciador apenas não

é suficiente. É necessário, então, combinar os diferentes layouts, como no exemplo a seguir.

é suficiente. É necessário, então, combinar os diferentes layouts, como no exemplo a seguir.

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

class PainelComposto extends JPanel

class PainelComposto extends JPanel

{ { public PainelComposto() public PainelComposto() { { setLayout(new BorderLayout()); setLayout(new BorderLayout());

add(new JTextField("Digite seu texto aqui"),BorderLayout.NORTH);

add(new JTextField("Digite seu texto aqui"),BorderLayout.NORTH);

add(new PainelTipoFlow(),BorderLayout.SOUTH); add(new PainelTipoFlow(),BorderLayout.SOUTH); } } } }

class PainelTipoFlow extends JPanel

class PainelTipoFlow extends JPanel

{

(25)

public PainelTipoFlow() public PainelTipoFlow() { { setLayout(new FlowLayout()); setLayout(new FlowLayout()); add(new JButton("Um")); add(new JButton("Um")); add(new JButton("Dois")); add(new JButton("Dois")); add(new JButton("Três")); add(new JButton("Três")); add(new JButton("Quatro")); add(new JButton("Quatro")); add(new JButton("Cinco")); add(new JButton("Cinco")); } } } }

public class LayoutsCompostos extends JFrame

public class LayoutsCompostos extends JFrame

{ { public LayoutsCompostos() public LayoutsCompostos() { { addWindowListener(new WindowAdapter() addWindowListener(new WindowAdapter()

{public void windowClosing(WindowEvent e){System.exit(0);}});

{public void windowClosing(WindowEvent e){System.exit(0);}});

setSize(400,120); setSize(400,120); setLocation(150,150); setLocation(150,150); setTitle("Layouts Compostos"); setTitle("Layouts Compostos"); Container P = getContentPane(); Container P = getContentPane(); P.add(new PainelComposto()); P.add(new PainelComposto()); } }

public static void main (String[] args)

public static void main (String[] args)

{

{

LayoutsCompostos fr = new LayoutsCompostos();

LayoutsCompostos fr = new LayoutsCompostos();

fr.setVisible(true); fr.setVisible(true); } } } }

Figura 1.17. Layouts Compostos – BorderLayout e

Figura 1.17. Layouts Compostos – BorderLayout e FlowLayoutFlowLayout

A figura 1.17 mostra que o painel com layout

A figura 1.17 mostra que o painel com layout

FlowLayoutFlowLayout

foi inserido na localização sul do

foi inserido na localização sul do

painel com layout

painel com layout

BorderLayoutBorderLayout

. Isso é uma prática bastante comum para se alcançar layouts

. Isso é uma prática bastante comum para se alcançar layouts

com disposição de componentes que satisfaçam aos objetivos da aplicação. A localização do

com disposição de componentes que satisfaçam aos objetivos da aplicação. A localização do

centro ficou vazia porque isso é uma característica do

centro ficou vazia porque isso é uma característica do

BorderLayoutBorderLayout

: não expandir as outras

: não expandir as outras

localizações se a do centro estiver vazia.

localizações se a do centro estiver vazia.

2. Interface Gráfica com o Usuário e a Manipulação de Eventos

2. Interface Gráfica com o Usuário e a Manipulação de Eventos

Os componentes de uma Interface Gráfica com o Usuário (GUI) são baseados em eventos, os

Os componentes de uma Interface Gráfica com o Usuário (GUI) são baseados em eventos, os

quais são gerados na interação do usuário com a interface. Alguns exemplos de eventos possíveis:

quais são gerados na interação do usuário com a interface. Alguns exemplos de eventos possíveis:

mover/clicar o mouse, clicar em um botão, fechar o frame, digitar um texto em um campo de

mover/clicar o mouse, clicar em um botão, fechar o frame, digitar um texto em um campo de

edição, etc. É necessário, então, realizar uma manipulação dos eventos gerados. As próximas

edição, etc. É necessário, então, realizar uma manipulação dos eventos gerados. As próximas

(26)

seções descrevem o modelo de manipulação de eventos AWT a partir de alguns elementos GUI

seções descrevem o modelo de manipulação de eventos AWT a partir de alguns elementos GUI

simples.

simples.

2.1

2.1 O Modelo de Manipulação de Eventos AWT

O Modelo de Manipulação de Eventos AWT

É muito comum encontrar, em linguagens de programação visuais, o tratamento dos eventos que

É muito comum encontrar, em linguagens de programação visuais, o tratamento dos eventos que

são gerados por seus componentes visuais. Com Java não é diferente, tanto na biblioteca AWT,

são gerados por seus componentes visuais. Com Java não é diferente, tanto na biblioteca AWT,

quanto na biblioteca Swing, existem classes para manipulação de eventos. A maneira como essa

quanto na biblioteca Swing, existem classes para manipulação de eventos. A maneira como essa

manipulação acontece não é tão simples como nas linguagens Delphi e Visual Basic, exigindo

manipulação acontece não é tão simples como nas linguagens Delphi e Visual Basic, exigindo

que haja a designação de pelo menos um (pode ter mais que um) objeto

que haja a designação de pelo menos um (pode ter mais que um) objeto

ouvinte de eventos

ouvinte de eventos

, que

, que

deve ser um objeto de uma classe que implemente a interface ouvinte (

deve ser um objeto de uma classe que implemente a interface ouvinte (

listener interfacelistener interface

). O

). O

objeto deve efetuar convenientemente a resposta desejada ao evento. É necessário lembrar que as

objeto deve efetuar convenientemente a resposta desejada ao evento. É necessário lembrar que as

interfaces possuem métodos

interfaces possuem métodos

abstractabstract

para serem redefinidos pelas classes que as

para serem redefinidos pelas classes que as

implementarem. Além disso, “todos” os métodos

implementarem. Além disso, “todos” os métodos

abstractabstract

devem

devem ser

ser redefinidos.

redefinidos. O

O registro

registro

desses ouvintes é feito em objetos conhecidos como

desses ouvintes é feito em objetos conhecidos como

origem do evento

origem do evento

, como um botão, por

, como um botão, por

exemplo. A origem envia objetos eventos para o(s) ouvinte(s) na ocorrência de um evento, e

exemplo. A origem envia objetos eventos para o(s) ouvinte(s) na ocorrência de um evento, e

esse(s) usa(m) essa informação para determinar o que será feito em reação ao evento.

esse(s) usa(m) essa informação para determinar o que será feito em reação ao evento.

Um exemplo de registro de um objeto ouvinte

Um exemplo de registro de um objeto ouvinte

painelpainel

em um objeto de origem

em um objeto de origem

botãobotão

::

MeuPainel painel = new MeuPainel();

MeuPainel painel = new MeuPainel();

Jbutton botao = new Jbutton(“OK”);

Jbutton botao = new Jbutton(“OK”);

botao.addActionListener(painel); botao.addActionListener(painel);

seguindo a sintaxe:

seguindo a sintaxe:

ObjetoOrigem.addEventListener(ObjetoOuvinte); ObjetoOrigem.addEventListener(ObjetoOuvinte);

Assim, o objeto

Assim, o objeto

painelpainel

é notificado sempre que um evento ocorrer em

é notificado sempre que um evento ocorrer em

botaobotao

, como o clique,

, como o clique,

por exemplo. No exemplo, a classe onde o objeto ouvinte

por exemplo. No exemplo, a classe onde o objeto ouvinte

painelpainel

é registrado deve implementar

é registrado deve implementar

a interface

a interface

ActionListenerActionListener

e definir o método

e definir o método

actionPerformed()actionPerformed()

, que recebe um objeto

, que recebe um objeto

ActionEvent

ActionEvent

como parâmetro. Assim:

como parâmetro. Assim:

public class MeuPainel extends Jpanel implements ActionListener

public class MeuPainel extends Jpanel implements ActionListener

{

{

...

...

public void actionPerformed(ActionEvent evt)

public void actionPerformed(ActionEvent evt)

{

{

//código para a reação ao evento

//código para a reação ao evento

}

}

}

}

2.2

2.2 Eventos em Botões

Eventos em Botões

O exemplo a seguir apresenta um painel com três botões, sendo que o próprio painel é definido

O exemplo a seguir apresenta um painel com três botões, sendo que o próprio painel é definido

como ouvinte para monitorar os eventos que podem acontecer nos botões.

como ouvinte para monitorar os eventos que podem acontecer nos botões.

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

class PainelEventosBotao extends JPanel implements ActionListener

class PainelEventosBotao extends JPanel implements ActionListener

{

{

private JButton BotaoVerde;

private JButton BotaoVerde;

private JButton BotaoPreto;

(27)

private JButton BotaoBranco; public PainelEventosBotao() {

BotaoVerde = new JButton("Verde"); BotaoPreto = new JButton("Preto"); BotaoBranco = new JButton("Branco"); add(BotaoVerde); add(BotaoPreto); add(BotaoBranco); BotaoVerde.addActionListener(this); BotaoPreto.addActionListener(this); BotaoBranco.addActionListener(this); }

public void actionPerformed(ActionEvent evt) {

Object origem = evt.getSource(); Color cor = getBackground(); if (origem == BotaoVerde)

cor = Color.green;

else if (origem == BotaoPreto) cor = Color.black;

else if (origem == BotaoBranco) cor = Color.white;

setBackground(cor); repaint();

} }

public class TesteEventosBotao extends JFrame {

public TesteEventosBotao() {

addWindowListener(new WindowAdapter()

{public void windowClosing(WindowEvent e){System.exit(0);}}); setSize(400,130);

setTitle("Eventos em Botões"); Container P = getContentPane(); P.add(new PainelEventosBotao()); }

public static void main(String[] args) {

JFrame fr = new TesteEventosBotao(); fr.setVisible(true);

} }

(28)

Figura 2.1. Eventos em objetos JButton

Na criação do painel, três botões foram adicionados a ele. Logo após, foi determinado que o

próprio painel (

this

) seria o ouvinte das ações dos três botões. O método

actionPerformed()

é

o único método da interface

ActionListener

, por isso apenas ele deve ser implementado. Esse

método recebe como parâmetro um objeto do tipo

ActionEvent

, que fornece informações sobre

o evento ocorrido, sendo o local para implementar as ações a serem realizadas. A classe

TesteEventosBotao

adiciona o painel com os botões.

2.3 Eventos em Caixas de Texto

O exemplo a seguir apresenta um painel com duas caixas de texto do tipo

JTextField

e uma do

tipo

JPasswordField

. O objeto ouvinte definido foi o próprio painel e, quando for dado um

Enter em qualquer uma das caixas, o conteúdo digitado irá aparecer em uma caixa de mensagens.

import java.awt.*;

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

class PainelEventosCaixaTexto extends JPanel implements ActionListener {

private JTextField Codigo; private JTextField Nome;

private JPasswordField Senha; public PainelEventosCaixaTexto() {

Codigo = new JTextField(3); add(Codigo);

Nome = new JTextField("Digite seu nome"); add(Nome);

Senha = new JPasswordField(10); add(Senha);

Codigo.addActionListener(this); Nome.addActionListener(this); Senha.addActionListener(this); }

public void actionPerformed(ActionEvent evt) {

Object origem = evt.getSource(); if (origem == Codigo)

JOptionPane.showMessageDialog(null,"Código = "+ evt.getActionCommand()); else if (origem == Nome)

JOptionPane.showMessageDialog(null,"Nome = "+ evt.getActionCommand()); else if (origem == Senha)

JOptionPane.showMessageDialog(null,"Senha = "+ evt.getActionCommand()); }

}

public class TesteEventosCaixaTexto extends JFrame {

public TesteEventosCaixaTexto() {

(29)

{public void windowClosing(WindowEvent e){System.exit(0);}}); setSize(300,70);

setLocation(300,350);

setTitle("Eventos em Caixas de Texto"); Container P = getContentPane();

P.add(new PainelEventosCaixaTexto()); }

public static void main(String[] args) {

JFrame fr = new TesteEventosCaixaTexto(); fr.setVisible(true);

} }

Figura 2.2. Eventos em objetos JTextField e JPasswordField

A figura 2.1 mostra o que acontece se for digitado algo em código e logo a seguir for pressionada

a tecla Enter. Novamente, o método

actionPerformed()

foi sobreposto e, no momento que for

pressionado o Enter, o

getSource()

pega o objeto onde está o foco naquele momento e mostra

em uma caixa de mensagens, criada a partir do método

showMessageDialog()

, pertencente à

classe

JOptionPane

.

2.4 Utilizando Eventos para Alterar o Aspecto Visual da Aplicação

O Look and Feel é a aparência que sua aplicação irá tomar, definindo a forma como seus

componentes serão mostrados na tela. Ao utilizar componentes da biblioteca Swing, o aspecto

visual é determinado pelo estilo Metal, mas existem outros, e a alteração é feita através do

método

UIManager.setLookAndFeel()

, passando como parâmetro o aspecto visual desejado,

localizados em pacotes diferentes:

Aspecto Metal:

javax.swing.plaf.metal.MetalLookAndFeel

Aspecto Windows:

com.sun.java.swing.plaf.windows.WindowsLookAndFeel •

Aspecto Motif:

com.sun.java.swing.plaf.motif.MotifLookAndFeel

Aspecto GTK:

com.sun.java.swing.plaf.gtk.GTKLookAndFeel •

Aspecto Mac:

javax.swing.plaf.mac.MacLookAndFeel

Logo após, é necessário chamar o método

SwingUtilities.updateComponentTreeUI

para

atualizar todo o conjunto de componentes.

import java.awt.*;

(30)

import javax.swing.*;

class PainelAV extends JPanel implements ActionListener {

private JButton BotaoMetal; private JButton BotaoWindows; private JButton BotaoMotif; private JButton BotaoGTK; private JButton BotaoMac; private JTextField Texto; public PainelAV()

{

BotaoMetal = new JButton("Metal"); BotaoWindows = new JButton("Windows"); BotaoMotif = new JButton("Motif"); BotaoGTK = new JButton("GTK"); BotaoMac = new JButton("Mac");

Texto = new JTextField("Digite seu texto aqui"); add(BotaoMetal); add(BotaoWindows); add(BotaoMotif); add(BotaoGTK); add(BotaoMac); add(Texto); BotaoMetal.addActionListener(this); BotaoWindows.addActionListener(this); BotaoMotif.addActionListener(this); BotaoGTK.addActionListener(this); BotaoMac.addActionListener(this); }

public void actionPerformed(ActionEvent evt) {

Object origem = evt.getSource(); String modelo = "";

if (origem == BotaoMetal)

modelo = "javax.swing.plaf.metal.MetalLookAndFeel"; else if (origem == BotaoWindows)

modelo = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel"; else if (origem == BotaoMotif)

modelo = "com.sun.java.swing.plaf.motif.MotifLookAndFeel"; else if (origem == BotaoGTK)

modelo = "com.sun.java.swing.plaf.gtk.GTKLookAndFeel"; else if (origem == BotaoMac)

modelo = "javax.swing.plaf.mac.MacLookAndFeel"; try { UIManager.setLookAndFeel(modelo); SwingUtilities.updateComponentTreeUI(this); } catch (Exception e) {} } }

public class AspectosVisuais extends JFrame {

Referências

Documentos relacionados

Os casos de FMB confirmados laboratorialmente pela FUNED entre 1995 a 2002 foram 103, sendo excluídos 21 pela ausência da FE ou que apresentaram preenchimen- to insuficiente para

Fale como encontramos essa lição no texto, o que tem no texto que nos ensina essa lição e explique o que acontece se não praticarmos essa lição. Termine explicando como o ouvinte

O desenvolvimento do software Face Match - Human Face Image Retrieval Software compreende 3 etapas de desenvolvimento, no qual a primeira etapa está completa e consiste do

Imaginemos o problema que seria, se os Espíritos chegassem lá, plano mais feliz e consequentemente com muito mais beleza que a esfera material da Terra e ficassem sem saber qual

SHIFT + CTRL + ñ do cursor até o início do parágrafo SHIFT + PGUP tela para cima(área de edição) SHIFT + PGDN tela para baixo(área de edição) SHIFT + HOME até o início da

Índices de riqueza, abundância, diversidade de shannon- wiener (h’) e equitabilidade (j), por ponto de coleta nos tributários do rio correntes, piquiri e são lourenço

Molhos: Fonduta de Amêndoa Defumada, Fonduta de Limão Siciliano, Fonduta de Parmesão, Funghi, Manteiga com Sálvia, Manteiga Trufada, Pesto de Manjericão, Pomodoro e Ragu de

Our Chef aims to share the most distinctive tastes of Portugal with a selection of dishes which invite one to discover our gastronomic culture through local products such as veal