Você está na página 1de 114

Programao JAVA

1. Programao Visual Bsica


A Interface Grfica com o Usurio, tambm conhecido como GUI - Graphical User Interface,
em Java, feita atravs de bibliotecas de classes, sendo que a primeira a surgir foi a AWT
(Abstract Window Toolkit). A AWT surgiu j na verso 1.0, mas se tornou confivel a partir da
verso 1.1. A maneira como as classes dessa biblioteca trabalham garante a criao dos
elementos da interface de usurio seguindo o comportamento destinado s ferramentas GUI
nativas de cada plataforma (Windows, Mac, Solaris, ...).
Alguns exemplos destes elementos so: botes, listas, menus, componentes de textos, containers
(janelas e barras de menus), caixas de dilogo para abrir ou salvar arquivos, alm de elementos
para manipulao de imagens, fontes e cores.
A portabilidade de plataforma funcionava bem em aplicaes simples, mas aplicaes que
envolviam elementos mais complexos, como menus e barras de rolagem, por exemplo,
apresentavam diferenas de comportamento conforme a plataforma. O que aconteceu foi que as
aplicaes visuais feitas em Java no se pareciam, e nem tinham as mesmas funcionalidades, com
as aplicaes convencionais de cada plataforma.
A partir da verso 2 do Java, a JFC (Java Foundation Classes) apresentou novos recursos para a
construo da GUI das aplicaes, o que melhorou muito os problemas de portabilidade. So
eles:

Java 2D: novas funes para desenhos e grficos.

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

Swing: biblioteca de classes extenso da AWT, onde so apresentados novos


componentes de interface e o que conhecido por look and feel, que uma adaptao
perfeita da GUI ao sistema operacional especfico de desenvolvimento.

bom salientar que o Swing no substitui o AWT, mas o kit de ferramentas GUI mais utilizado
para desenvolvimento de aplicaes visuais. O AWT continua existindo, mantendo a mesma
arquitetura criada para o Java verso 1.1.
O Swing possui muito mais recursos, alm de garantir maior portabilidade e, em boa parte dos
casos, mais fcil de usar. Isso no significa que ou se utiliza AWT ou se utiliza Swing,
normalmente o que acontece que elementos das duas bibliotecas so utilizados conjuntamente
nas aplicaes.
Referente a criao das aplicaes, exitem muitas ferramentas que auxiliam na produo de
interfaces de usurio grficas, mas no se comparam a ferramentas para plataformas especficas,

como Delphi e VisualBasic, que so voltadas exclusivamente para esse fim. Boa parte da
elaborao da interface da aplicao tem que ser feita manualmente, o que exige bastante
trabalho.

1.1 Frames
Na AWT, a janela de mais alto nvel de uma aplicao (no est contida dentro de nenhuma
outra) denominada Frame. No Swing, existe uma verso chamada JFrame, que
derivada/estendida da classe Frame, possuindo alguns poucos mtodos adicionais relacionados
manipulao da disposio visual dos frames .Todos os outros mtodos so derivados da classe
Frame. Um frame pode conter diversos outros componentes da GUI.
Para se definir um frame bsico baseado em AWT, deve-se:

Importar o pacote java.awt.*.

Estender a classe Frame.

Ter um mtodo main() para criar o objeto a partir do operador new.

Torn-lo visvel.

Assim, o cdigo a seguir resulta no frame apresentado na figura 1.1.


import java.awt.*;
public class FrameUm extends Frame
{
public static void main (String[] args)
{
FrameUm fr = new FrameUm();
fr.setVisible(true);
}
}

Para torn-lo visvel, possvel utilizar fr.show(); no lugar de fr.setVisible(true);.


Percebe-se que no possvel fech-lo utilizando o boto fechar. Por enquanto, ela deve ser
encerrada forando a finalizao do processo (ex.: finalizar tarefa no Windows, ou terminar
processo na ferramenta especfica de desenvolvimento).

Figura 1.1. Frame FrameUm

O frame criado no possui tamanho definido, nem ttulo ou posicionamento. Para personalizar o
frame necessrio inserir um mtodo construtor com as instrues necessrias. Exemplo:
import java.awt.*;
public class FrameDois extends Frame
{
public FrameDois() //construtor
{
setTitle("Frame Dois"); // ttulo do Frame
setSize(300, 200); // largura: 300 pixels
altura: 200 pixels
setResizable(false); // no permite o redimensionamento

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


}
public static void main (String[] args)
{
FrameDois fr = new FrameDois();
fr.setVisible(true);
}

y: 100 pixels

A figura 1.2 mostra o resultado da execuo, um frame com largura 300 x 200 pixels
(setSize()), com o ttulo Frame Dois (setTitle()), que no permite redimensionamento
(setResizable()).

Figura 1.2. Frame FrameDois

Alm disso, o setLocation() realiza o posicionamento em tela do frame, seguindo o sistema de


coordenadas do Java (figura 1.3), medidas em pixels, conforme a resoluo atual da tela. No
exemplo, o frame fica posicionado em 200 pixels para x e 100 pixels para y.
x

(0 ,0)

(x, y)

Figura 1.3. Sistema de coordenadas do Java

Conforme j mencionado, o frame ainda no pode ser fechado. Para que isso acontea
necessrio ter uma maneira de se ter a notificao de quando ele fechado. A partir da
manipulao desse evento, mostrado no exemplo a seguir, possvel fechar o frame. necessrio
importar o pacote java.awt.event.* para manipular eventos do AWT. O modelo de eventos e
os demais eventos de janela sero vistos em sees posteriores.
import java.awt.*;

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 Trs"); // ttulo do Frame
setSize(300, 200); // largura: 300 pixels
altura: 200 pixels
setResizable(false); // no 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 relao ao posicionamento, dependendo da resoluo da tela onde o frame ser aberto,
pode se ter situaes bem desagradveis, como, por exemplo, o frame ser aberto e ficar com parte
fora da tela. necessrio ento posicionar o frame em coordenadas que independam da resoluo
utilizada. O exemplo a seguir abrir um frame com a metade do tamanho da tela, posicionado no
centro, respeitando a resoluo.
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 possvel essa tarefa de posicionamento conforme a resoluo de vdeo, necessrio
obter informaes do sistema operacional, e isso feito atravs da classe Toolkit, mtodo
getScreenSize(), cujos dados so jogados em um objeto da classe Dimension, que armazena a
altura e largura nos campos d.width e d.height. Por exemplo, se a resoluo de vdeo for
800x600, o d.width fica com 800 e o d.height fica com 600. Tendo esses valores, possvel
utilizar em mtodos como o setLocation() e o setSize(), como foi feito no exemplo. Alm
disso, o exemplo tambm acrescenta um cone ao frame, tambm utilizando a classe Toolkit,
4

mtodo getImage(), para carregar a imagem (extenso .gif) e jogar em um objeto da classe
Image, para depois setar o cone atravs do setIconImage().
O mesmo exemplo pode ser feito baseado na biblioteca Swing, classe JFrame, mudando apenas a
derivao e importando o pacote javax.swing.*, assim:
import
import
import
public
{
...
}

java.awt.*;
java.awt.event.*;
javax.swing.*;
class FrameQuatro extends JFrame

Os exemplos apresentados nas prximas sees criaro frames baseado na classe JFrame.

1.2 Mostrando Textos e Linhas no Frame


Para que seja possvel mostrar textos em um frame necessrio criar um objeto baseado na classe
Graphics, que ser responsvel pelo gerenciamento da rea grfica a ser desenhada, controlando
cores, tipos de fontes, etc. A classe Component possui um mtodo paint() que aceita um objeto
Graphics como parmetro. Esse mtodo, na classe de origem, no faz nada, por isso ele deve ser
sobrescrito com a chamada de mtodos que realizam operaes de escrita, pintura, desenho, etc.
Para efetuar a sobreposio do mtodo paint() deve-se ter o cabealho:
public void paint(Graphics g)

A partir disso, mtodos 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)
{

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 mtodo drawString(String s, int x, int y) realiza a mostragem de um texto em uma


posio definida por x e y. O mtodo 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 mtodo setColor() seleciona a cor que utilizada para todas as operaes de desenho dentro
do contexto grfico ou componente. Um parmetro Color define a cor a ser usada, sendo que as
treze cores padro, apresentadas na tabela 1.1, esto definidas na classe java.awt.Color.
black

(preto)

magenta

blue

(azulo)

orange

cyan

(ciano)

pink

darkGray
gray

(cinza-escuro)

(cinza)

green

(verde)

red

(magenta)

(laranja)

(rosa)

(vermelho)

white

(branco)

yellow

(amarelo)

lightGray

(cinza-claro)

Tabela 1.1. Cores definidas em java.awt.Color

Alm das cores pr-definidas, pode-se criar novas cores baseadas no contedo RGB (redvermelho, green-verde, blue-azul), expressos por inteiros de 0 a 255. O exemplo a seguir
apresenta a criao 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);
}
}

Figura 1.5. Frame Cores

O mtodo drawRect(int x, int y, int width, int height) desenha um retngulo com a
cor definida em setColor(), iniciando nas coordenadas x,y, tendo uma largura width e uma
altura height. O mtodo fillRect(int x, int y, int width, int height) faz a mesma
coisa, mas preenche o retngulo.

1.4 Fontes
O mtodo responsvel 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 especfico; o estilo
pode ser: PLAIN regular, BOLD negrito e ITALIC itlico, sendo possvel 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 itlico tamanho 16", 20, 50);
g.setFont(new Font("Monospaced", Font.BOLD + Font.ITALIC, 14));
g.drawString("Fonte Monospaced negrito e itlico tamanho 14", 20, 80);
g.setFont(f);
g.drawString("Novamente Fonte SansSerif itlico 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 no necessrio criar explicitamente um objeto
do tipo Font (objeto f), podendo ser possvel cri-lo no prprio argumento do setFont(). Se a
fonte for utilizada vrias vezes no decorrer da aplicao, torna-se til a criao do objeto
explicitamente.

Figura 1.6. Frame Fontes

Em termos de portabilidade, deve-se tomar cuidado quanto a fontes que no existem em alguns
sistemas operacionais. O ideal trabalhar com fontes comuns em sistemas operacionais
diferentes. O modelo do AWT define cinco fontes disponveis em qualquer sistema operacional.
So elas: Serif, Monospaced, SansSerif, Dialog e DialogInput.

1.5 Outras Formas Geomtricas


Alm das formas j apresentadas, existem vrias outras possveis, a maioria com a opo de
preenchimento ou no, a partir da precedncia 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 Geomtricas");
}
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);

}
public static void main (String[] args)
{
FormasGeometricas fr = new FormasGeometricas();
fr.setVisible(true);
}
}

Figura 1.7. Frame Fontes

Vrias formas geomtricas foram desenhadas no frame. Funcionamento de cada mtodo:

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


arcHeight): Desenha um retngulo 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,
arcHeight): Idem a drawRoundRect, mas preenche o retngulo.

int arcWidth,

int

draw3DRect(int x, int y, int width, int height, boolean raised): Desenha


um retngulo 3D, iniciando nas coordenadas x,y, tendo uma largura width e uma altura
height, e um valor lgico para indicar a aparncia do 3D.

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


draw3DRect, mas preenche o retngulo.

drawOval(int x, int y, int width, int height): Desenha uma forma oval,
baseado nas coordenadas do retngulo que inicia em x,y, tendo uma largura width e uma
altura height.

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

Idem a

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 retngulo 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,
arcAngle): Idem

int y,

int width,

int height,

int startAngle,

int

a drawArc, mas preenche o arco.


10

drawPolygon(int[] xPoints,

int[] yPoints,

int nPoints):

Desenha

um

Idem

polgono, baseado nas coordenadas dos arranjos x,y.

fillPolygon(int[] xPoints,
int[] yPoints,
drawPolygon, mas preenche o arco.

int nPoints):

1.6 Imagens
A classe Image a responsvel pelo carregamento de imagens armazenadas em disco.
Novamente, necessrio utilizar um objeto do tipo Toolkit para obter uma imagem, atravs do
mtodo 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);
}
}

11

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, atravs do mtodo
copyArea(int x, int y, int width, int height, int dx, int dy), que copia o
contedo da rea que comear nas coordenadas x,y com largura width e altura height, em um
local a uma distncia dx,dy. Para realizar essa tarefa, foi necessrio descobrir o tamanho da
imagem, atravs getWidth() e do getHeight().

1.7 Continers
Continers servem de repositrio de outros componentes, como botes, por exemplo. Alguns
exemplos de continers: JFrame, JPanel e JApplet. Um JFrame uma janela de mais alto nvel;
um JPanel um continer usado para agrupar componentes, normalmente dentro de um JFrame;
um JApplet permite a execuo em navegadores da Web. Pode-se desenhar algo diretamente no
frame ou definir um continer, como um painel, por exemplo, e desenhar nele. No considerada
uma boa prtica de programao desenhar diretamente no frame, pois ele foi projetado para ser
continer de componentes especficos, como barras de menu, por exemplo. Os painis devem ser
utilizados para agrupar outros componentes. Exemplo de adio 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()
{
addWindowListener(new WindowAdapter()

12

{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. Continer 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 mtodo paintComponent(), que est definido na classe
JComponent, e recebe um parmetro do tipo Graphics. Tal mtodo chamado automaticamente
toda vez que a janela redesenhada, como na criao e no redimensionamento. Se, por algum
motivo, se desejar redesenhar o contedo no painel, o mtodo a ser chamado o repaint(), que
se encarrega de executar novamente o paintComponent(). O super.paintComponent(g) faz
com que o mtodo da superclasse seja executado tambm. Isso normalmente feito em
sobreposies de mtodos, quando se deseja criar algo a mais que o mtodo definido na
superclasse. A criao de uma classe derivada de JFrame feita a seguir, e um objeto Container
criado para depois adicionar (add) o painel. O mtodo getContentPane() retorna a rea de
contedo 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 continers, sendo que cada continer possui um gerenciador padro, mas pode ser
alterado atravs da chamada ao mtodo setLayout() do continer especfico. Por exemplo, o
gerenciador padro do JPanel o FlowLayout, que coloca os componentes em um tamanho prdefinido da esquerda para a direita e de cima para baixo no continer. Outros gerenciadores de
layout existentes: GridLayout, BorderLayout, BoxLayout e GridBagLayout.
1.8.1

Gerenciador FlowLayout

Para que seja possvel verificar a diferena entre alguns deles, exemplos so demonstrados nas
prximas sees, comeando exatamente pelo gerenciador FlowLayout, padro do JPanel. Nos
exemplos, so definidos objetos boto a partir da classe JButton.
import java.awt.*;

13

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("Trs"));
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 padro do JPanel, no seria necessrio setar o layout


atravs do setLayout(new FlowLayout());. O alinhamento dos componentes fica centralizado
e, caso algum compontnte no caiba em uma linha, jogado para a linha seguinte, como mostra a
figura 1.10. possvel alterar o alinhamento, passando-o como parmetro na determinao do
layout (LEFT, RIGHT ou CENTER), assim:
setLayout(new FlowLayout(FlowLayout.RIGHT));

1.8.2

Gerenciador GridLayout

14

O GridLayout um gerenciador que organiza os componentes em linhas e colunas espaadas


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("Trs"));
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 espaos vazios. necessrio definir o nmero de linhas e colunas no

15

setLayout().

Os componentes so adicionados a partir da posio na parte superior esquerda da


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

Tambm possvel espaar os componentes horizontal e verticalmente. Nesse caso, na definio


do layout, deve-se passar esses valores tambm. O layout abaixo, por exemplo, define 5 pixels de
espaameno horizontal e 8 pixels de espaamento 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("Trs"),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);
}
}

16

Figura 1.12. Gerenciador de Layout GridLayout

Na figura 1.12 se observa o resultado da aplicao, com um boto em cada localizao geogrfica
dentro do painel. O BorderLayout o gerenciador padro para os continers JWindow e JFrame.
No necessrio ter todas as localizaes preenchidas. Se alguma das localizaes (norte, sul,
leste ou oeste) no for ocupada, as demais ocupam o lugar da(s) omitida(s). Porm, se a
localizao central no for ocupada, ela ficar vazia.
Na definio do layout possvel determinar o espaamento horizontal e vertical entre as
localizaes. O layout abaixo, por exemplo, define 5 pixels de espaameno horizontal e 8 pixels
de espaamento vertical:
setLayout(new BorderLayout(5,8));

1.8.4

Gerenciador BoxLayout

Os gerenciadores de layout foram criados ainda na verso 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
invs de utilizar o BoxLayout diretamente, pode-se usar um outro continer 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("Trs"));
add(Box.createHorizontalStrut(30));
add(new JButton("Quatro"));
add(Box.createHorizontalGlue());
add(new JButton("Cinco"));
add(Box.createHorizontalGlue());
}
}
public class GerenciadorBoxLayout extends JFrame

17

{
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 botes no ficaram distanciados uniformemente. Isso porque
dois mtodos foram utilizados: o createHorizontalGlue(), que determina um espaamento
varivel, conforme o tamanho da janela e o createHorizontalStrut(), que determina um
espaamento fixo, determinado pelo seu parmetro.
1.8.5

Gerenciador GridBagLayout

O gerenciador GridBagLayout bastante flexvel, permitindo posicionamento dos componentes


em relao aos outros. Assim, possvel criar praticamente qualquer tipo de layout. Por ser mais
flexvel, tambm mais difcil de ser utilizado. O construtor no possui argumentos e a aparncia
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

Descrio

int gridx, gridy

Utilizado para controlar o posicionamento dos componentes


na grade do layout.
Utilizado para especificar um percentual de aumento do local
destinado aos componentes, que iro aumentar tambm se
estiverem expandidos.
Utilizado para expandir o componente a fim de preencher o
espao reservado a ele.
Utilizado para indicar o nmero de linhas ou colunas que o

int weightx, weighty

int fill
int gridheight, gridwidth

18

componente ir se espalhar.
Utilizado para controlar a posio do componente, caso ele
no esteja espalhado.
Utilizado para controlar o aumento do tamanho mnimo dos
componente.
Utilizado para controlar o afastamento entre componentes.

int anchor
int ipadx, ipady
Insets insets

Tabela 1.1. Campos da classe GridBagConstraints

A utilizao desses campos so demonstradas atravs de exemplos. O primeiro deles mostra um


GridBagLayout com cinco botes inseridos em posies 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("Trs"), 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);

19

}
}

Figura 1.13. Gerenciador de Layout GridBagLayout com cinco botes

O resultado, mostrado na figura 1.13, apresenta cinco botes inseridos em coordenadas que
indicam a presena de trs linhas por trs colunas (0, 1 e 2). O tamanho da grade definido por
essas coordenadas, sendo possvel, por isso, ter quantas colunas e linhas se desejar. O mtodo
addGridBag() criado serve para auxiliar na definio dos valores que os campos de controle do
GridBagConstraints iro assumir.
Para que os botes preencham toda a rea do painel necessrio definir, no construtor, a restrio
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("Trs"), 1, 1);
addGridBag(new JButton("Quatro"), 2, 1);
addGridBag(new JButton("Cinco"), 1, 2);
}

Figura 1.14. Gerenciador de Layout GridBagLayout ocupando todo espao disponvel

O resultado o preenchimento de todo painel, como mostra a figura 1.14. O fill ainda pode ser
definido como: HORIZONTAL, preenchendo o espao horizontal disponvel; VERTICAL,
preenchendo o espao vertical disponvel e; NONE, no preenchendo o espao disponvel. Os
campos weigthx e weigthy devem receber um valor diferente de zero, pois o preenchimento no
ocorre se esse valor for igual a zero, que o valor default.
possvel realizar um espalhamento dos componentes em mais do que uma linha e/ou coluna.
Para isso, necessrio combinar os valores de gridx e gridy com a determinao da altura (em

20

nmero de linhas) e largura (em nmero de colunas) atravs 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("Trs"), 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 boto Um ocupou trs colunas e uma
linha, enquanto o boto Quatro ocupou duas linhas e uma coluna. No momento que o nmero de
colunas/linhas definido, todos os componentes utilizaro esse tamanho de espao da pra diante,
a no ser que este seja redefinido.
possvel tambm definir o tamanho dos componentes atravs do peso atribudo 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("Trs"), 2, 0);
restricoes.weightx = 4.0;
addGridBag(new JButton("Quatro"), 3, 0);
}

21

Figura 1.16. Gerenciador de Layout GridBagLayout com determinao de pesos

Para que o exemplo fique igual ao apresentado na figura 1.16, necessrio mudar o setSize()
do frame para (400,60). Os botes ficam dispostos em uma nica linha, com tamanhos
diferentes, determinados pela atribuio de seus respectivos pesos, sabendo-se que o valor
especfico do peso no o que importa, e sim as propores relativas entre os botes 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. Alm disso, possvel fixar uma posio
do componente, dentro do espao reservado a ele, desde que ele no esteja espalhado em mais
que uma coluna e/ou linha. Isso feito atravs 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("Trs"), 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, necessrio alterar o setSize()
do frame para (270,130). Percebe-se que o tamanho dos componentes Dois e Quatro foi
aumentado, sendo mantido o tamanho mnimo do boto Trs. Para esse mesmo boto Trs foi
especificado um posicionamento fixo no canto inferior direito, dentro de sua rea definida. O
anchor s pode ser utilizado quando o tamanho do componente for menor que a rea que lhe foi

22

concedida. O valor padro CENTER, e os outros valores possveis so: NORTH, NORTHEAST, EAST,
SOUTHEAST, SOUTH, SOUTHWEST, WEST, e NORTHWEST.
Atravs do campo insets possvel indicar as distncias entre os componentes do layout. Uma
classe Insets possui valores para as quatro direes: cima, baixo, direita e esquerda, dando
muita flexibilidade ao layout. O valor padro (0, 0, 0, 0). Exemplo:
public PainelGridBag()
{
setLayout(new GridBagLayout());
restricoes.weightx = 1.0;
restricoes.weighty = 1.0;
restricoes.fill = GridBagConstraints.BOTH;
restricoes.insets = new Insets(3,3,3,3);
addGridBag(new JButton("Um"), 1, 0);
addGridBag(new JButton("Dois"), 0, 1);
addGridBag(new JButton("Trs"), 1, 1);
addGridBag(new JButton("Quatro"), 2, 1);
addGridBag(new JButton("Cinco"), 1, 2);
}

Figura 1.18. Gerenciador de Layout GridBagLayout utilizando Insets

A figura 1.18 mostra que cada componente ganhou um espao adicional de trs pixels para cada
uma das direes: cima, baixo, direita e esquerda.
1.8.6

Layouts Compostos

Normalmente, ao querer criar um determinado layout, a utillizao de um gerenciador apenas no


suficiente. necessrio, ento, combinar os diferentes layouts, como no exemplo a seguir.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class PainelComposto extends JPanel
{
public PainelComposto()
{
setLayout(new BorderLayout());
add(new JTextField("Digite seu texto aqui"),BorderLayout.NORTH);
add(new PainelTipoFlow(),BorderLayout.SOUTH);
}
}
class PainelTipoFlow extends JPanel
{

23

public PainelTipoFlow()
{
setLayout(new FlowLayout());
add(new JButton("Um"));
add(new JButton("Dois"));
add(new JButton("Trs"));
add(new JButton("Quatro"));
add(new JButton("Cinco"));
}
}
public class LayoutsCompostos extends JFrame
{
public LayoutsCompostos()
{
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e){System.exit(0);}});
setSize(400,120);
setLocation(150,150);
setTitle("Layouts Compostos");
Container P = getContentPane();
P.add(new PainelComposto());
}
public static void main (String[] args)
{
LayoutsCompostos fr = new LayoutsCompostos();
fr.setVisible(true);
}
}

Figura 1.17. Layouts Compostos BorderLayout e FlowLayout

A figura 1.17 mostra que o painel com layout FlowLayout foi inserido na localizao sul do
painel com layout BorderLayout. Isso uma prtica bastante comum para se alcanar layouts
com disposio de componentes que satisfaam aos objetivos da aplicao. A localizao do
centro ficou vazia porque isso uma caracterstica do BorderLayout: no expandir as outras
localizaes se a do centro estiver vazia.

2. Interface Grfica com o Usurio e a Manipulao de Eventos


Os componentes de uma Interface Grfica com o Usurio (GUI) so baseados em eventos, os
quais so gerados na interao do usurio com a interface. Alguns exemplos de eventos possveis:
mover/clicar o mouse, clicar em um boto, fechar o frame, digitar um texto em um campo de
edio, etc. necessrio, ento, realizar uma manipulao dos eventos gerados. As prximas

24

sees descrevem o modelo de manipulao de eventos AWT a partir de alguns elementos GUI
simples.

2.1 O Modelo de Manipulao de Eventos AWT


muito comum encontrar, em linguagens de programao visuais, o tratamento dos eventos que
so gerados por seus componentes visuais. Com Java no diferente, tanto na biblioteca AWT,
quanto na biblioteca Swing, existem classes para manipulao de eventos. A maneira como essa
manipulao acontece no to simples como nas linguagens Delphi e Visual Basic, exigindo
que haja a designao de pelo menos um (pode ter mais que um) objeto ouvinte de eventos, que
deve ser um objeto de uma classe que implemente a interface ouvinte (listener interface). O
objeto deve efetuar convenientemente a resposta desejada ao evento. necessrio lembrar que as
interfaces possuem mtodos abstract para serem redefinidos pelas classes que as
implementarem. Alm disso, todos os mtodos abstract devem ser redefinidos. O registro
desses ouvintes feito em objetos conhecidos como origem do evento, como um boto, por
exemplo. A origem envia objetos eventos para o(s) ouvinte(s) na ocorrncia de um evento, e
esse(s) usa(m) essa informao para determinar o que ser feito em reao ao evento.
Um exemplo de registro de um objeto ouvinte painel em um objeto de origem boto:
MeuPainel painel = new MeuPainel();
Jbutton botao = new Jbutton(OK);
botao.addActionListener(painel);

seguindo a sintaxe:
ObjetoOrigem.addEventListener(ObjetoOuvinte);

Assim, o objeto painel notificado sempre que um evento ocorrer em botao, como o clique,
por exemplo. No exemplo, a classe onde o objeto ouvinte painel registrado deve implementar
a interface ActionListener e definir o mtodo actionPerformed(), que recebe um objeto
ActionEvent como parmetro. Assim:
public class MeuPainel extends Jpanel implements ActionListener
{
...
public void actionPerformed(ActionEvent evt)
{
//cdigo para a reao ao evento
}
}

2.2 Eventos em Botes


O exemplo a seguir apresenta um painel com trs botes, sendo que o prprio painel definido
como ouvinte para monitorar os eventos que podem acontecer nos botes.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class PainelEventosBotao extends JPanel implements ActionListener
{
private JButton BotaoVerde;
private JButton BotaoPreto;

25

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 Botes");
Container P = getContentPane();
P.add(new PainelEventosBotao());
}
public static void main(String[] args)
{
JFrame fr = new TesteEventosBotao();
fr.setVisible(true);
}
}

26

Figura 2.1. Eventos em objetos JButton

Na criao do painel, trs botes foram adicionados a ele. Logo aps, foi determinado que o
prprio painel (this) seria o ouvinte das aes dos trs botes. O mtodo actionPerformed()
o nico mtodo da interface ActionListener, por isso apenas ele deve ser implementado. Esse
mtodo recebe como parmetro um objeto do tipo ActionEvent, que fornece informaes sobre
o evento ocorrido, sendo o local para implementar as aes a serem realizadas. A classe
TesteEventosBotao adiciona o painel com os botes.

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 prprio painel e, quando for dado um
Enter em qualquer uma das caixas, o contedo 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,"Cdigo = "+ 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()
{
addWindowListener(new WindowAdapter()

27

{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 cdigo e logo a seguir for pressionada
a tecla Enter. Novamente, o mtodo 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 mtodo showMessageDialog(), pertencente
classe JOptionPane.

2.4 Utilizando Eventos para Alterar o Aspecto Visual da Aplicao


O Look and Feel a aparncia que sua aplicao ir tomar, definindo a forma como seus
componentes sero mostrados na tela. Ao utilizar componentes da biblioteca Swing, o aspecto
visual determinado pelo estilo Metal, mas existem outros, e a alterao feita atravs do
mtodo UIManager.setLookAndFeel(), passando como parmetro 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 aps, necessrio chamar o mtodo SwingUtilities.updateComponentTreeUI para


atualizar todo o conjunto de componentes.
import java.awt.*;
import java.awt.event.*;

28

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
{
public AspectosVisuais()

29

{
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e){System.exit(0);}});
setSize(370,100);
setTitle("Aspectos Visuais");
Container P = getContentPane();
P.add(new PainelAV());
}
public static void main(String[] args)
{
JFrame fr = new AspectosVisuais();
fr.setVisible(true);
}
}

Figura 2.3. Aspectos Visuais Metal, Windows, Motif, GTK e Mac

A figura 2.3 mostra e resultado da execuo aps selecionar cada um dos aspectos visuais.
importante salientar que o aspecto Windows s funciona no prprio Windows, pois a Sun no
disponibiliza esse aspecto para outras plataformas. Alguns Look And Feels podem gerar uma
exceo, por no existirem ou no serem suportados em determinadas plataformas, como o que
ocorreu como aspecto Mac. importante salientar tambm que, a depender do layout utilizado
em uma determinada aplicao, podem ocorrer problemas de aparncia, por que tamanhos de
botes, caixas de texto e outros componentes variam de plataforma para plataforma, e podem
fazer com que a aparncia de uma aplicao fique desorganizada, como o que ocorreu com o
aspecto GTK. Muitos aspectos interessantes podem ser encontrados na Internet.

2.5 Resumo de Eventos no AWT


A tabela 2.1 mostra todas as interfaces da AWT existentes para serem implementadas em classes
com objetos ouvintes, os mtodos que devem ser sobrepostos, os parmetros e os objetos origens
dos eventos.
Interface

Mtodos

Parmetros

Origens

ActionListener

actionPerformed

ActionEvent
getActionCommand
getModifiers

AdjustmentListener

AdjustementValueChanged AdjustmentEvent
getAdjustable

Button
List
MenuItem
TextField
Scrollbar

30

ItemListener

ItemStateChanged

TextListener
ComponentListenter

TextValueChanged
componentMoved
componentHidden
componentResized
componentShown
componentAdded
componentRemoved

ContainerListener

FocusListener
KeyListener

MouseListener

focusGained
focusLost
keyPressed
keyReleased
keyTyped

mousePressed
mouseReleased
mouseEntered
mouseExited
mouseClicked

MouseMotionListener mouseDragged
mouseMoved
WindowListener
windowClosing
windowOpened
windowIconified
windowDeiconified
windowClosed
windowActivated
windowDeactivated

getAdjustmentType
getValue
ItemEvent
getItem
getItemSelectable
getStateChange
TextEvent
ComponentEvent
getComponent

Checkbox
CheckboxMenuItem
Choice
List
TextComponent
Component

ComponentEvent
getChild
getContainer
FocusEvent
isTemporary
KeyEvent
getKeyChar
getKeyCode
getKeyModifiersText
getKeyText
isActionKey
MouseEvent
getClickCount
getX
getY
getPoint
translatePoint
isPopupTrigger
MouseEvent

Container

WindowEvent
getWindow

Window

Component
Component

Component

Component

Figura 2.3. Interfaces existentes para manipular eventos

Boa parte dos componentes do Swing utilizam essas mesmas interfaces para manipular eventos,
mas existem outras. Os pacotes dessas interfaces so: java.awt.event e javax.swing.event.

3. Utilizando a Biblioteca Swing para a Interface com o Usurio


A partir do conhecimento do funcionamento do modelo de eventos possvel utiliza-lo nos
muitos componentes de interface com o usurio existentes na biblioteca Swing, como listas,
menus e caixas de dilogo, por exemplo. bom lembrar que boa parte desses componentes
possui um correspondente no AWT. A diferena que, ao contrrio do AWT, os componentes do
Swing so implementados no prprio Java, garantindo que, indiferente da plataforma utilizada, a
aparncia no fique prejudicada.

31

As prximas sees se destinam a apresentao dos principais componentes do Swing, alm dos
botes e caixas de texto, que foram vistos no captulo anterior.

3.1 Labels e Botes Classes JLabel e JButton


Os labels e botes so componentes muito utilizados e de fcil manipulao. Como j visto, para
tratar eventos em botes necessrio implementar o mtodo actionPerformed() da interface
ActionListenter. O exemplo a seguir mostra as principais aes que podem ser realizadas em
labels, acionadas a partir do clique de botes.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class PainelEventosBotaoELabel extends JPanel implements ActionListener
{
private JButton BotaoUm;
private JButton BotaoDois;
private JLabel LabelUm;
private JLabel LabelDois;
public PainelEventosBotaoELabel()
{
BotaoUm = new JButton("Um");
BotaoDois = new JButton("Dois");
LabelUm = new JLabel("Label para o boto um");
LabelDois = new JLabel("Label para o boto dois");
add(BotaoUm);
add(LabelUm);
add(BotaoDois);
add(LabelDois);
BotaoUm.addActionListener(this);
BotaoDois.addActionListener(this);
}
public void actionPerformed(ActionEvent evt)
{
Object origem = evt.getSource();
Icon icone = new ImageIcon("LogoJava.gif");
if (evt.getActionCommand().equals("Um")) // primeira maneira de verificar
{
LabelUm.setText("O boto " + BotaoUm.getText() + " foi clicado");
LabelUm.setIcon(icone);
LabelUm.setVerticalTextPosition(SwingConstants.BOTTOM);
LabelUm.setHorizontalTextPosition(SwingConstants.RIGHT);
}
if (origem == BotaoDois) // segunda maneira de verificar
{
LabelDois.setText("O boto " + BotaoDois.getText() + " foi clicado");
LabelDois.setToolTipText("Esse o label do boto dois");
}
}
}

32

public class TesteEventosBotaoELabel extends JFrame


{
public TesteEventosBotaoELabel()
{
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e){System.exit(0);}});
setSize(600,130);
setTitle("Botes e Labels");
Container P = getContentPane();
P.add(new PainelEventosBotaoELabel());
}
public static void main(String[] args)
{
JFrame fr = new TesteEventosBotaoELabel();
fr.setVisible(true);
}
}

Figura 3.1. Manipulao de Botes e Labels

A figura 3.1 mostra a situao aps o clique nos dois botes. No cdigo, percebe-se que existem
duas maneiras de saber qual boto foi clicado. A primeira testando o prprio texto do boto, a
partir do getActionCommand().equals(). A segunda atravs da definio de um objeto
origem, que, atravs do mtodo getSource(), sabe qual boto gerou o evento. No clique do
BotaoUm alterado o texto do LabelUm, setado um cone para ele e realizado seu posicionamento
horizontal (setHorizontalTextPosition()) e vertical (setVerticalTextPosition()). O
clique do BotaoDois altera o texto do LabelUm, alm de utilizar o mtodo setToolTipText()
para especificar a dica de ferramenta, que exibida quando o cursor do mouse passa sobre o
label.

3.2 Botes de Estado Classes JRadioButton e JCheckBox


Os botes de estado permitem ativar ou desativar opes. Dois tipos so comumente usados: as
caixas de seleo e os botes de rdio. Uma caixa de seleo possui um rtulo (label) que a
identifica e, ao clicar nela, a opo vai ficar ativada ou no, conforme o estado atual. Botes de
rdio ficam agrupados a partir da classe ButtonGroup, sendo que apenas uma opo pode ficar
selecionada. Para tratamento dos eventos, a interface utilizada a ActionListener, como nos
botes e caixas de texto. Exemplo:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

33

class PainelBotoesDeEstado extends JPanel implements ActionListener


{
private JTextField Texto;
private JCheckBox CBItalico;
private JCheckBox CBNegrito;
private JRadioButton RBSansSerif;
private JRadioButton RBMonospaced;
private JRadioButton RBSerif;
private ButtonGroup Grupo;
public PainelBotoesDeEstado()
{
Texto = new JTextField("Texto para visualizao",15);
CBItalico = new JCheckBox("Itlico");
CBNegrito = new JCheckBox("Negrito");
RBSansSerif = new JRadioButton("SansSerif",true);
RBMonospaced = new JRadioButton("Monospaced",false);
RBSerif = new JRadioButton("Serif",false);
add(Texto);
add(CBItalico);
add(CBNegrito);
add(RBSansSerif);
add(RBMonospaced);
add(RBSerif);
Grupo = new ButtonGroup();
Grupo.add(RBSansSerif);
Grupo.add(RBMonospaced);
Grupo.add(RBSerif);
CBItalico.addActionListener(this);
CBNegrito.addActionListener(this);
RBSansSerif.addActionListener(this);
RBMonospaced.addActionListener(this);
RBSerif.addActionListener(this);
}
public void actionPerformed(ActionEvent evt)
{
Object origem = evt.getSource();
Font f = Texto.getFont();
String Fonte = f.getName();
int Negrito = Font.PLAIN;
int Italico = Font.PLAIN;
if (CBItalico.isSelected())
Italico = Font.ITALIC;
else
Italico = Font.PLAIN;
if (CBNegrito.isSelected())
Negrito = Font.BOLD;
else
Negrito = Font.PLAIN;
if (origem == RBSansSerif)
Fonte = "SansSerif";
else if (origem == RBMonospaced)
Fonte = "Monospaced";
else if (origem == RBSerif)
Fonte = "Serif";
Texto.setFont(new Font(Fonte, Negrito + Italico, 12));

34

}
}
public class BotoesDeEstado extends JFrame
{
public BotoesDeEstado()
{
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e){System.exit(0);}});
setSize(350,100);
setTitle("Botes de Estado");
Container P = getContentPane();
P.add(new PainelBotoesDeEstado());
}
public static void main(String[] args)
{
JFrame fr = new BotoesDeEstado();
fr.setVisible(true);
}
}

Figura 3.2. Botes de Estado

A figura 3.2 apresenta o resultado da execuo do exemplo, j com alguns itens selecionados. Ao
clicar em uma caixa de seleo, acionado um evento de ao, capturado no mtodo
actionPerformed(). O mtodo isSelect() retorna o estado atual da caixa de seleo e,
conforme o estado, as variveis Italico e Negrito so atualizadas, para depois servirem de
parmetro para a alterao da fonte a partir do setFont(). Os botes de rdio so criados, j
tendo setado qual o boto que ficar selecionado inicialmente. Cada um desses botes deve ser
adicionado a um grupo de botes (ButtonGroup), sendo ele responsvel pala desativao do
boto anteriormente selecionado, quando um novo for clicado. No actionPerformed()
verificado qual boto originou o evento, e a varivel Fonte atualizada com a fonte atual, para
tambm servir de parmetro no setFont(). Isso feito atravs da criao de um objeto f, do tipo
Font, incializado a partir do getFont() e passado para a varivel Fonte atravs do getName().

3.3 Bordas
O Swing oferece vrias opes de bordas para melhorar o aspecto visual da aplicao. O mtodo
setBorder(), da classe JComponent, a responsvel pela definio das bordas, recebendo como
parmetro um objeto de uma das classes de bordas existentes no pacote javax.swing.border.
Por isso, necessrio realizar um import desse pacote. O exemplo a seguir mostra as diversas
bordas existentes, permitindo a utilizao de ttulo ou no.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

35

import javax.swing.border.*;
public class Bordas extends JFrame implements ActionListener
{
private JButton RBEtched;
private JButton RBEmpty;
private JButton RBLine;
private JButton RBMatte;
private JButton RBLoweredBevel;
private JButton RBRaisedBevel;
private JButton RBCompound;
private JCheckBox CBTitled;
private Border BordaCentro = null;
public Bordas()
{
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e){System.exit(0);}});
setSize(700,250);
setTitle("Bordas");
JPanel PainelBaixo = new JPanel();
RBEtched = new JButton("Etched");
RBEmpty = new JButton("Empty");
RBLine = new JButton("Line");
RBMatte = new JButton("Matte");
RBLoweredBevel = new JButton("LoweredBevel");
RBRaisedBevel = new JButton("RaisedBevel");
RBCompound = new JButton("Compound");
CBTitled = new JCheckBox("Titled");
PainelBaixo.add(RBEtched);
PainelBaixo.add(RBEmpty);
PainelBaixo.add(RBLine);
PainelBaixo.add(RBMatte);
PainelBaixo.add(RBLoweredBevel);
PainelBaixo.add(RBRaisedBevel);
PainelBaixo.add(RBCompound);
PainelBaixo.add(CBTitled);
Border borda = BorderFactory.createEtchedBorder();
Border BordaBaixo =
BorderFactory.createTitledBorder(borda," Tipos de Borda ");
PainelBaixo.setBorder(BordaBaixo);
Container P = getContentPane();
P.setLayout(new BorderLayout());
P.add(PainelBaixo,"South");
RBEtched.addActionListener(this);
RBEmpty.addActionListener(this);
RBLine.addActionListener(this);
RBMatte.addActionListener(this);
RBLoweredBevel.addActionListener(this);
RBRaisedBevel.addActionListener(this);
RBCompound.addActionListener(this);
CBTitled.addActionListener(this);
}
public void actionPerformed(ActionEvent evt)
{
Object origem = evt.getSource();

36

JPanel PainelCentro = new JPanel();


if (origem == RBEtched)
BordaCentro = BorderFactory.createEtchedBorder();
else if (origem == RBEmpty)
BordaCentro = BorderFactory.createEmptyBorder();
else if (origem == RBLine)
BordaCentro = BorderFactory.createLineBorder(Color.red);
else if (origem == RBMatte)
BordaCentro =
BorderFactory.createMatteBorder(8, 8, 8, 8, Color.orange);
else if (origem == RBLoweredBevel)
BordaCentro = BorderFactory.createLoweredBevelBorder();
else if (origem == RBRaisedBevel)
BordaCentro = BorderFactory.createRaisedBevelBorder();
else if (origem == RBCompound)
BordaCentro = BorderFactory.createCompoundBorder
(BorderFactory.createEtchedBorder(),
BorderFactory.createMatteBorder(3, 3, 3, 3, Color.green));
if (CBTitled.isSelected())
{
Border BordaTitulo =
BorderFactory.createTitledBorder(BordaCentro," Exemplo de Ttulo ");
PainelCentro.setBorder(BordaTitulo);
}
else
PainelCentro.setBorder(BordaCentro);
Container P = getContentPane();
P.add(PainelCentro,"Center");
validate();
}
public static void main(String[] args)
{
JFrame fr = new Bordas();
fr.setVisible(true);
}
}

Figura 3.3. Tipos de Bordas no Swing

37

A figura 3.3 mostra o resultado da execuo, onde cada um dos botes realiza a mudana para a
borda especificada. O ttulo na borda somente mostrado se a caixa de seleo Titled estiver
marcada.
De forma geral, para criar uma borda necessrio criar um objeto Border e utilizar um dos
mtodos da classe BorderFactory para criar a borda desejada. Os tipos de borda existentes, os
mtodos para criao, o parmetros necessrios em cada tipo e as variaes possveis so:

EtchedBorder: cria uma borda de linha com efeito 3D.


createEtchedBorder()
createEtchedBorder(Color destaque, Color Sombra)

EmptyBorder: cria uma borda vazia, mas ocupa espao e permite insero de ttulo.
createEmptyBorder()
createEmptyBorder(int topo, int esquerda, int base, int direita)

LineBorder: cria uma borda de linha simples.


createLineBorder(Color cor)
createLineBorder(Color cor, int espessura)

MatteBorder: cria uma borda larga que pode ser preenchida com uma cor slida ou um
cone.
createMatteBorder(int topo, int esquerda, int base, int direita, Color
cor)
createMatteBorder(int topo, int esquerda, int base, int direita, Icon
icone)

BevelBorder: cria uma borda com efeito de relevo (para cima ou para baixo).
createLoweredBorder()
createRaisedBorder()

CompoundBorder: cria uma borda unindo duas outras bordas.


createCompundBorder(Border BordaExterna, Border BordaInterna)

TitledBorder: cria uma borda com um ttulo. Normalmente utilizado para inserir ttulos
em outras bordas.
createTitledBorder(String titulo)
createTitledBorder(Border borda, String titulo)
createTitledBorder(Border borda, String titulo, int alinhamento, int
posicao)
createTitledBorder(Border borda, String titulo, int alinhamento, int
posio, Font fonte, Color cor)

O alinhamento do TitledBorder pode ser uma das constantes: TitledBorder.LEFT,


TitledBorder.RIGHT ou TitledBorder.CENTER. A posio pode ser uma das constantes de
TitledBorder: ABOVE_TOP, TOP, BELOW_TOP, ABOVE_BOTTOM, BOTTOM, BELOW_BOTTOM.

3.4 Caixas de Combinao


Uma caixa de combinao uma lista do tipo abre/fecha que apresenta mltiplos valores,
sendo que apenas um pode ser selecionado. A classe que implementa esse componente a

38

JComboBox e o tratamento dos eventos tambm


ActionListener, como mostra o exemplo a seguir.
import
import
import
import

pode ser feito atravs da interface

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

public class CaixasDeCombinacao extends JFrame implements ActionListener


{
private JComboBox Cores;
private Color cor = Color.green;
private String Itens[] = {"Verde","Amarelo","Azul","Branco"};
private JPanel PainelSul;
private JPanel PainelCentro;
private Border Borda;
private JLabel Texto;
public CaixasDeCombinacao()
{
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e){System.exit(0);}});
setSize(300,160);
setTitle("Caixa de Combinao");
Container P = getContentPane();
P.setLayout(new BorderLayout());
PainelSul = new JPanel();
Cores = new JComboBox(Itens);
PainelSul.add(Cores);
Cores.addActionListener(this);
P.add(PainelSul,"South");
PainelCentro = new JPanel();
Borda = BorderFactory.createMatteBorder(8, 8, 8, 8, cor);
PainelCentro.setBorder(Borda);
Texto = new JLabel("Verde");
PainelCentro.add(Texto);
P.add(PainelCentro,"Center");
}
public void actionPerformed(ActionEvent evt)
{
JComboBox origem = (JComboBox)evt.getSource();
if ((String)origem.getSelectedItem() == "Verde")
cor = Color.green;
else if ((String)origem.getSelectedItem() == "Amarelo")
cor = Color.yellow;
else if ((String)origem.getSelectedItem() == "Azul")
cor = Color.blue;
else if ((String)origem.getSelectedItem() == "Branco")
cor = Color.white;
Borda = BorderFactory.createMatteBorder(8, 8, 8, 8, cor);
PainelCentro.setBorder(Borda);
Texto.setText((String)origem.getSelectedItem());
}
public static void main (String[] args)
{

39

CaixasDeCombinacao fr = new CaixasDeCombinacao();


fr.setVisible(true);
}
}

Figura 3.4. Manipulao de Bordas atravs de uma Caixa de Combinao

Uma borda Borda do tipo MatteBorder foi criada no PainelCentro para que as cores sejam
alteradas a partir da seleo pela caixa de combinao Cores (figura 3.4), localizada no
PainelSul. O PainelCentro tambm contm um label Texto, que mostra a cor atual da borda.
Para manipular o evento de seleo da caixa de combinao, foi implementado o mtodo
actionPerformed(), que define um objeto origem, do tipo JComboBox, e testa o item
selecionado a partir do getSelectedItem(). Conforme a seleo, um objeto cor, do tipo Color,
atualizado, para depois ser utilizado na definio da nova cor da borda. Alm disso, o label
Texto tambm atualizado com a cor selecionada.
Alguns outros mtodos so importantes:

void setEditable(Boolean editavel):

se o parmetro for true, o item selecionado

pode sofrer alteraes, caso contrrio no.

void addItem(Object Item):

void insertItemAt(Object Item, int posicao):

adiciona um item lista.


adiciona um item lista na posio

indicada.

void removeItem(Object Item):

void removeItemAt(Object Item, int posicao):

remove um item da lista.


remove o item da lista que est

posio indicada.

3.5 Continer JScrollPane e Caixas de Listagem


Sempre que se deseja incluir barras de rolagem em um componente qualquer, necessrio inserilo em um continer JScrollPane. Caso o componente inserido seja maior que o continer,
automaticamente so mostradas barras de rolagem para poder visualizar a parte do componente
que no ficou visvel, tanto vertical, quanto horizontalmente. No possvel atribuir um layout ao
JScrollPane, pois ele tem seu prprio layout, no podendo ser alterado. Tal layout aceita apenas
um componente, permitindo a insero de um outro continer, como um painel, por exemplo.

40

As caixas de listagem, criadas a partir de objetos do tipo JList, apresentam listas de valores para
selees nicas ou mltiplas. Elas, por si s, no apresenta nenhuma barra de rolagem, sendo
necessrio para isso, inseri-la em um continer JScrollPane, como no exemplo a seguir.
import
import
import
import
import

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

public class CaixasDeListagem extends JFrame


{
private JList FrutasLegumes;
private String NomesImagens[] =
{"","Abobora.gif","Alcachofra.gif","Berinjela.gif","Maca.gif"};
private Icon Imagens[] = {new ImageIcon(NomesImagens[0]),
new ImageIcon(NomesImagens[1]),
new ImageIcon(NomesImagens[2]),
new ImageIcon(NomesImagens[3]),
new ImageIcon(NomesImagens[4])};
private String ItensLista[] =
{"Nenhum","Abbora","Alcachofra","Berinjela","Ma"};
private JPanel PainelLista;
private JLabel LabelImagem;
public CaixasDeListagem()
{
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e){System.exit(0);}});
setSize(250,100);
setTitle("Caixa de Listagem");
Container P = getContentPane();
PainelLista = new JPanel();
FrutasLegumes = new JList(ItensLista);
FrutasLegumes.setVisibleRowCount(3);
FrutasLegumes.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
PainelLista.add(new JScrollPane(FrutasLegumes));
LabelImagem = new JLabel(Imagens[0]);
PainelLista.add(LabelImagem);
FrutasLegumes.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e)
{
LabelImagem.setIcon(Imagens[FrutasLegumes.getSelectedIndex()]);
}
});
P.add(PainelLista);
}
public static void main (String[] args)
{
CaixasDeListagem fr = new CaixasDeListagem();
fr.setVisible(true);
}
}

41

Figura 3.5. Caixa de Listagem de seleo nica

A figura 3.5 apresenta o resultado da execuo da aplicao, onde h uma caixa de listagem com
trs linhas e uma barra de rolagem. Ao clicar em cada opo, aparece ao lado a imagem
solicitada. Para criar a lista foi declarado um objeto FrutasLegumes, do tipo JList, passando
como parmetro um arranjo String ItensLista, com os itens desejados. A partir do mtodo
setVisibleRowCount() foi definido o nmero de itens visveis da lista. O
setSelectionMode() especifica o modo de seleo da lista, definido na classe
ListSelectionModel, que pode ser: SINGLE_SELECTION, que permite a seleo de um nico
item; SINGLE_INTERVAL_SELECTION, que permite a seleo mltipla e contgua na lista, e;
MULTIPLE_INTERVAL_SELECTION, que permite a seleo mltipla, no interessando quais itens
sero selecionados.
Para que a lista pudesse ser apresentada com a barra de rolagem, o objeto FrutasLegumes foi
adicionado a um JScrollPane que, por sua vez, foi adicionado ao painel. Por fim, para ser
possvel tratar o evento de seleo na lista, foi necessrio implementar a interface
ListSelectionListener(), que est definida em javax.swing.event, sendo preciso importar
esse pacote, e que utiliza o mtodo valueChanged() para efetuar as aes desejadas. Para alterar
a imagem do LabelImagem foi utilizado o setIcon(), relacionando o ndice do arranjo Imagens
com o ndice do item que foi selecionado na lista, buscado atravs do getSelectedIndex(). O
modo como o evento foi tratado poderia ter sido feito como nos exemplos vistos at agora, assim:
Antes de tudo, inserir o implements ListSelectionListener na criao da classe:
public class CaixasDeListagem extends JFrame implements ListSelectionListener

Depois, indicar o prprio frame como objeto ouvinte:


FrutasLegumes.addListSelectionListener(this);

Por fim, implementar o mtodo valueChanged():


public void valueChanged(ListSelectionEvent evt)
{
LabelImagem.setIcon(Imagens[FrutasLegumes.getSelectedIndex()]);
}

Para que se possa efetuar a seleo mltipla dos itens de uma caixa de listagem, necessrio
determinar se a seleo SINGLE_INTERVAL_SELECTION, permitindo selecionar um intervalo
contguo, clicando com o mouse em um primeiro item e, com a tecla Shift pressionada, clicando
no ltimo item desejado; ou MULTIPLE_INTERVAL_SELECTION, permitindo selecionar itens no
contguos, atravs da utilizao da tecla Ctrl, clicando com o mouse nos itens desejados.
Exemplo:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

42

import javax.swing.event.*;
public class ListaSelecaoMultipla extends JFrame
{
private JList Numeros;
private JList Selecionados;
private String ItensLista[] =
{"Zero","Um","Dois","Trs","Quatro","Cinco","Seis","Sete"};
private JPanel PainelListaSM;
public ListaSelecaoMultipla()
{
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e){System.exit(0);}});
setSize(250,150);
setTitle("Seleo Mltipla");
Container P = getContentPane();
PainelListaSM = new JPanel();
Numeros = new JList(ItensLista);
Numeros.setVisibleRowCount(5);
Numeros.setFixedCellWidth(60);
Numeros.setFixedCellHeight(20);
Numeros.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
PainelListaSM.add(new JScrollPane(Numeros));
Selecionados = new JList();
Selecionados.setVisibleRowCount(5);
Selecionados.setFixedCellWidth(80);
Selecionados.setFixedCellHeight(20);
Selecionados.setSelectionMode
(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
PainelListaSM.add(new JScrollPane(Selecionados));
P.add(PainelListaSM);
Numeros.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e)
{
Selecionados.setListData(Numeros.getSelectedValues());
}
});
}
public static void main (String[] args)
{
ListaSelecaoMultipla fr = new ListaSelecaoMultipla();
fr.setVisible(true);
}
}

43

Figura 3.6. Caixas de Listagem de seleo mltipla

Na figura 3.6 possvel perceber os vrios itens selecionados intercaladamente na primeira caixa
de listagem. A segunda caixa foi criada para mostrar os itens selecionados na primeira caixa.
Dois novos mtodos foram utilizados para alterar a parte visual das caixas de listagem:
setFixedCellWidth(), que determina um tamanho fixo de largura da caixa de listagem e;
setFixedCellHeight(), que determina um tamanho fixo de algura da caixa. Percebe-se que a
primeira caixa de listagem permite uma seleo intercalada de valores, atravs da utilizao da
tecla Ctrl (MULTIPLE_INTERVAL_SELECTION), enquanto a segunda caixa permite apenas a
seleo contgua, utilizando a tecla Shift (SINGLE_INTERVAL_SELECTION). A caixa de listagem
Numeros recebeu um ouvinte de eventos que, no momento que cada item selecionado, realiza a
operao de atualizao da caixa Selecionados. Isso feito atravs do mtodo setListData(),
que recebe como parmetro o conjunto de valores selecionados a partir do mtodo
getSelectedValues().

3.6 Dividindo Painis


A classe JSplitPane a responsvel pela diviso de reas. Na verdade, ele um continer
especial que permite o compartilhamento do espao para dois outros componentes, separando-os
por uma barra divisora ajustvel. O exemplo a seguir mostra dois labels com imagens
compartilhando a rea definida pelo JSplitPane.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class PainelDividido extends JFrame
{
public PainelDividido()
{
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e){System.exit(0);}});
setSize(615,300);
setTitle("Painel Dividido");
JLabel Um = new JLabel(new ImageIcon("Um.jpg"));
JLabel Dois = new JLabel(new ImageIcon("Dois.jpg"));
Component Esquerda = new JScrollPane(Um);
Component Direita = new JScrollPane(Dois);
JSplitPane Divisao =
new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, Esquerda, Direita);
Divisao.setDividerLocation(300);
Divisao.setDividerSize(10);
Container P = getContentPane();
P.add(Divisao);
}
public static void main (String[] args)
{
PainelDividido fr = new PainelDividido();
fr.setVisible(true);
}
}

44

Figura 3.7. Labels com imagens compartilhando um painel dividido pelo JSplitPane

A barra que divide as imagens (figura 3.7) redimensionvel, permitindo aumentar ou diminuir o
espao de cada um dos componentes. Depois de criados os labels Um e Dois, eles so colocados
em um JScrollPane, para que tenham barras de rolagem, e atribudos a dois objetos Esquerda e
Direita, do tipo Component. Estes, por sua vez, so os componentes que vo compartilhar a
diviso horizontal (HORIZONTAL_SPLIT) feita pelo JSplitPane. A outra forma de diviso a
VERTICAL_SPLIT, que divide o painel verticalmente. O mtodo setDividerLocation() indica a
posio onde deve ficar o divisor redimensionvel e o mtodo setDividerSize() determina o
tamanho em pixels da barra divisria.

3.8 Barra de Controle Deslizante


A partir de um objeto do tipo JSlider possvel selecionar um valor inteiro entre um intervalo
definido em uma barra de controle com um marcador de medidas. Tal componente possui
diversas configuraes possveis, como: o posicionamento horizontal ou vertical, a exibio de
marcas de medida principais e secundrias e a mostragem de rtulos para essas marcas. O
exemplo a seguir mostra uma barra de controle deslizante (JSlider) e uma barra de rolagem
normal (JScrollBar).
import
import
import
import

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

public class ControleDeslizante extends JFrame


{
private JSlider TamanhoTextoSlider;
private JScrollBar TamanhoTextoScroll;
private JLabel TextoSlider;
private JLabel TextoScroll;
public ControleDeslizante()

45

{
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e){System.exit(0);}});
setSize(570,230);
setTitle("Controle Deslizante");
Container P = getContentPane();
P.setLayout(new BorderLayout());
JPanel PainelCDNorte = new JPanel();
TextoSlider = new JLabel("JSlider tamanho 20");
TextoSlider.setFont(new Font("SansSerif",Font.PLAIN,20));
PainelCDNorte.add(TextoSlider);
P.add(PainelCDNorte,"North");
JPanel PainelCDCentro = new JPanel();
TextoScroll = new JLabel("JScrollBar tamanho 20");
TextoScroll.setFont(new Font("SansSerif",Font.PLAIN,20));
PainelCDCentro.add(TextoScroll);
P.add(PainelCDCentro,"Center");
JPanel PainelCDSul = new JPanel();
TamanhoTextoSlider = new JSlider(SwingConstants.HORIZONTAL,0,50,20);
TamanhoTextoSlider.setMajorTickSpacing(10);
TamanhoTextoSlider.setMinorTickSpacing(2);
TamanhoTextoSlider.setPaintTicks(true);
PainelCDSul.add(TamanhoTextoSlider);
TamanhoTextoScroll = new JScrollBar(JScrollBar.HORIZONTAL,20,0,0,50);
TamanhoTextoScroll.setPreferredSize(
new Dimension(200,TamanhoTextoScroll.getPreferredSize().height));
PainelCDSul.add(TamanhoTextoScroll);
P.add(PainelCDSul,"South");
TamanhoTextoSlider.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e)
{
TextoSlider.setText("JSlider tamanho "+TamanhoTextoSlider.getValue());
TextoSlider.setFont(
new Font("SansSerif",Font.PLAIN,TamanhoTextoSlider.getValue()));
}
});
TamanhoTextoScroll.addAdjustmentListener(new AdjustmentListener() {
public void adjustmentValueChanged(AdjustmentEvent e)
{
TextoScroll.setText(
"JScrollBar tamanho "+TamanhoTextoScroll.getValue());
TextoScroll.setFont(
new Font("SansSerif",Font.PLAIN,TamanhoTextoScroll.getValue()));
}
});
}
public static void main (String[] args)
{
ControleDeslizante fr = new ControleDeslizante();
fr.setVisible(true);
}
}

46

Figura 3.8. Utilizao do JSlider e e JScrollBar para alterar tamanho de fonte

Dois labels de tamanho 20 foram inseridos em dois painis (PainelCDNorte e PainelCDCentro)


para mostrar a funcionalidade dos componentes (figura 3.8). No PainelCDSul foi inserido um
componente TamanhoTextoSlider, do tipo JSlider, para controlar o tamanho do primeiro label,
e um outro componente TamanhoTextoScroll, para controlar o tamanho do segundo label. Para
criar o objeto JSlider foi identificada a orientao como sendo horizontal
(SwingConstants.HORIZONTAL), o valor mnimo como sendo 0, o valor mximo como sendo 50,
e a posio de incio como sendo 20. Aps, foram setados os marcadores principal e secundrio
como sendo 10 e 2, atravs do setMajorTickSpacing() e do setMinorTickSpacing(), para
depois serem mostrados atravs do setPaintTicks(). Para criar o objeto JScrollBar tambm
foi identificada a orientao como sendo horizontal (JScrollBar.HORIZONTAL), a posio de
incio como sendo 20, a rea visvel da barra de rolagem como sendo 0 pois, nesse tipo de
utilizao do JScrollBar, necessria a utilizao total da barra, o valor mnimo como sendo 0
e o valor mximo como sendo 50. O seu tamanho foi definido pelo mtodo
setPreferredSize(), que necessita de um objeto Dimension como parmetro, sendo passado
os valores de largura 200 e sendo mantida a altura original da barra de rolagem, atravs do
getPreferredSize().height.
Para o tratamento dos eventos do objeto TamanhoTextoSlider foi feita a implementao do
mtodo stateChanged(), a partir da interface ChangeListener, onde, a cada modificao no
controle deslizante, o texto alterado pelo setText() e a fonte alterada pelo setFont(),
passando como parmetro a posio atual do controle deslizante, a partir do getValue(). A
mesma coisa ocorre no tratamento dos eventos do objeto TamanhoTextoScroll, utilizando uma
interface diferente, a AdjustmentListener, com a implementao do mtodo
adjustmentValueChanged().

3.8 Abas Rotuladas e Caixas de Dilogo


Na construo de aplicaes, freqentemente ocorre o problema de falta de espao para inserir
todos os componentes necessrios. Uma opo muito utilizada nesses casos a criao de abas
rotuladas conforme o tipo de objetos que sero inseridos. A classe que realiza essa tarefa a
JTabbedPane, que nada mais que um continer que permite a insero de diversos painis, um
em cada aba. Para exemplificar a utilizao das abas rotuladas, o exemplo a seguir possui seis

47

abas, cada uma com um tipo diferente de caixa de dilogo, provenientes de objetos das classes
JOptionPane, JFileChooser e JColorChooser. As caixas de dilogo so, por padro, modais,
ou seja, no possvel interagir com outras janelas enquanto essa no for fechada. Elas so
utilizadas para exibir alguma mensagem ou obter algum tipo de informao do usurio, seja uma
confirmao, uma entrada de dados, ou uma seleo de algo.
import
import
import
import

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

public class AbasRotuladas extends JFrame implements ActionListener


{
private JTabbedPane Abas;
private JButton CDMensagem1;
private JButton CDMensagem2;
private JButton CDMensagem3;
private JButton CDConfirmacao1;
private JButton CDConfirmacao2;
private JButton CDConfirmacao3;
private JButton CDConfirmacao4;
private JLabel LabelConfirmacao;
private JButton CDOpcao1;
private JLabel LabelOpcao;
private JButton CDEntrada1;
private JButton CDEntrada2;
private JButton CDEntrada3;
private JLabel LabelEntrada;
private JButton CDArquivo1;
private JLabel LabelArquivo1;
private JLabel LabelArquivo2;
private JButton CDCor1;
private JLabel LabelCor;
public AbasRotuladas()
{
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e){System.exit(0);}});
setSize(450,150);
setLocation(300,200);
setTitle("Caixas de Dilogo de...");
Container P = getContentPane();
Abas = new JTabbedPane();
JPanel PCxDlgMensagem = new JPanel();
CDMensagem1 = new JButton("Mensagem 1");
CDMensagem2 = new JButton("Mensagem 2");
CDMensagem3 = new JButton("Mensagem 3");
PCxDlgMensagem.add(CDMensagem1);
PCxDlgMensagem.add(CDMensagem2);
PCxDlgMensagem.add(CDMensagem3);
JPanel PCxDlgConfirmacao = new JPanel();
CDConfirmacao1 = new JButton("Confirmao 1");
CDConfirmacao2 = new JButton("Confirmao 2");
CDConfirmacao3 = new JButton("Confirmao 3");
CDConfirmacao4 = new JButton("Confirmao 4");
LabelConfirmacao = new JLabel("Retorno:");

48

PCxDlgConfirmacao.add(CDConfirmacao1);
PCxDlgConfirmacao.add(CDConfirmacao2);
PCxDlgConfirmacao.add(CDConfirmacao3);
PCxDlgConfirmacao.add(CDConfirmacao4);
PCxDlgConfirmacao.add(LabelConfirmacao);
JPanel PCxDlgOpcao = new JPanel();
CDOpcao1 = new JButton("Opo 1");
LabelOpcao = new JLabel("Retorno:");
PCxDlgOpcao.add(CDOpcao1);
PCxDlgOpcao.add(LabelOpcao);
JPanel PCxDlgEntrada = new JPanel();
CDEntrada1 = new JButton("Entrada 1");
CDEntrada2 = new JButton("Entrada 2");
CDEntrada3 = new JButton("Entrada 3");
LabelEntrada = new JLabel("Retorno:");
PCxDlgEntrada.add(CDEntrada1);
PCxDlgEntrada.add(CDEntrada2);
PCxDlgEntrada.add(CDEntrada3);
PCxDlgEntrada.add(LabelEntrada);
JPanel PCxDlgArquivo = new JPanel();
CDArquivo1 = new JButton("Arquivo 1");
LabelArquivo1 = new JLabel("Retorno:");
LabelArquivo2 = new JLabel("Seleo:");
PCxDlgArquivo.add(CDArquivo1);
PCxDlgArquivo.add(LabelArquivo1);
PCxDlgArquivo.add(LabelArquivo2);
JPanel PCxDlgCor = new JPanel();
CDCor1 = new JButton("Cor 1");
LabelCor = new JLabel("Retorno:");
PCxDlgCor.add(CDCor1);
PCxDlgCor.add(LabelCor);
Abas.addTab("Mensagem",PCxDlgMensagem);
Abas.addTab("Confirmao",PCxDlgConfirmacao);
Abas.addTab("Opo",PCxDlgOpcao);
Abas.addTab("Entrada",PCxDlgEntrada);
Abas.addTab("Arquivo",PCxDlgArquivo);
Abas.addTab("Cor",PCxDlgCor);
P.add(Abas);
CDMensagem1.addActionListener(this);
CDMensagem2.addActionListener(this);
CDMensagem3.addActionListener(this);
CDConfirmacao1.addActionListener(this);
CDConfirmacao2.addActionListener(this);
CDConfirmacao3.addActionListener(this);
CDConfirmacao4.addActionListener(this);
CDOpcao1.addActionListener(this);
CDEntrada1.addActionListener(this);
CDEntrada2.addActionListener(this);
CDEntrada3.addActionListener(this);
CDArquivo1.addActionListener(this);
CDCor1.addActionListener(this);
}
public void actionPerformed(ActionEvent evt)
{
Object origem = evt.getSource();
int retorno = 0;

49

String valorRet = null;


Icon icone = new ImageIcon("LogoSun.gif");
if (origem == CDMensagem1)
JOptionPane.showMessageDialog(null,
"Esta uma caixa de dilogo de Mensagem");
else if (origem == CDMensagem2)
JOptionPane.showMessageDialog(null,
"Esta uma caixa de dilogo de Mensagem",
"Mensagem", JOptionPane.WARNING_MESSAGE);
else if (origem == CDMensagem3)
JOptionPane.showMessageDialog(null,
"Esta uma caixa de dilogo de Mensagem",
"Mensagem", JOptionPane.WARNING_MESSAGE, icone);
else if (origem == CDConfirmacao1)
{
retorno = JOptionPane.showConfirmDialog(null,"Confirma Operao?");
LabelConfirmacao.setText("Retorno: " + retorno);
}
else if (origem == CDConfirmacao2)
{
retorno = JOptionPane.showConfirmDialog(null,"Confirma Operao?",
"Confirmao", JOptionPane.YES_NO_OPTION);
LabelConfirmacao.setText("Retorno: " + retorno);
}
else if (origem == CDConfirmacao3)
{
retorno = JOptionPane.showConfirmDialog(null,"Confirma Operao?",
"Confirmao", JOptionPane.YES_NO_OPTION,
JOptionPane.WARNING_MESSAGE);
LabelConfirmacao.setText("Retorno: " + retorno);
}
else if (origem == CDConfirmacao4)
{
retorno = JOptionPane.showConfirmDialog(null,"Confirma Operao?",
"Confirmao", JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE, icone);
LabelConfirmacao.setText("Retorno: " + retorno);
}
else if (origem == CDOpcao1)
{
Object[] opcoes = { "OK", "Cancelar" };
retorno = JOptionPane.showOptionDialog(null,
"Esta uma caixa de dilogo de Opo",
"Opo",JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE,
null, opcoes, opcoes[0]);
LabelOpcao.setText("Retorno: " + retorno);
}
else if (origem == CDEntrada1)
{
valorRet = JOptionPane.showInputDialog(null, "Digite um valor");
LabelEntrada.setText("Retorno: " + valorRet);
}
else if (origem == CDEntrada2)
{
valorRet = JOptionPane.showInputDialog(null, "Digite um valor",
"Entrada", JOptionPane.QUESTION_MESSAGE);
LabelEntrada.setText("Retorno: " + valorRet);

50

}
else if (origem == CDEntrada3)
{
Object[] valores= {"Opo Um","Opo Dois","Opo Trs","Opo Quatro"};
Object valorSelec = JOptionPane.showInputDialog(null,
"Escolha uma opo",
"Entrada", JOptionPane.INFORMATION_MESSAGE,
null, valores, valores[0]);
LabelEntrada.setText("Retorno: " + valorSelec.toString());
}
else if (origem == CDArquivo1)
{
JFileChooser abreArquivo = new JFileChooser();
abreArquivo.setCurrentDirectory(new File("."));
abreArquivo.setSelectedFile(new File("AbasRotuladas.java"));
retorno = abreArquivo.showOpenDialog(this);
LabelArquivo1.setText("Retorno: " + retorno);
if (retorno == JFileChooser.APPROVE_OPTION)
{
File arquivoSelec = abreArquivo.getSelectedFile();
LabelArquivo2.setText("Seleo: " + arquivoSelec.getName());
}
else
LabelArquivo2.setText("Seleo: Nenhum arquivo");
}
else if (origem == CDCor1)
{
JColorChooser abreCor = new JColorChooser();
Color c = abreCor.showDialog(this, "Escolha uma cor", Color.black);
LabelCor.setForeground(c);
LabelCor.setText("Retorno: " + c.toString());
}
}
public static void main (String[] args)
{
AbasRotuladas fr = new AbasRotuladas();
fr.setVisible(true);
}
}

Figura 3.9. Abas rotuladas para demonstrao das diversas caixas de dilogo

Na figura 3.9 possvel visualizar a situao do frame na execuo da aplicao. Para que as abas
fossem criadas, foi definido um objeto Abas, do tipo JTabbedPane. Como so seis as abas, foram
criados seis painis (PCxDlgMensagem, PCxDlgConfirmacao, PCxDlgOpcao, PCxDlgEntrada,

51

e PCxDlgCor), inseridos botes e labels em cada um deles, conforme a


necessidade, para depois, atravs do mtodo addTab(), inseri-los no objeto Abas, permitindo a
incluso de um ttulo para cada aba.
PCxDlgArquivo

Figura 3.10. Caixas de dilogo de mensagem, confirmao, opo e entrada

As primeiras quatro abas correspondem s caixas de dilogo existentes na classe JOptionPane,


dividas em quatro tipos, mostrados nos exemplos da figura 3.10. O primeiro tipo a caixa de
dilogo de mensagem, onde uma mensagem mostrada, acompanhada de um boto OK. O mtodo
para criao desse tipo de caixa de dilogo o showMessageDialog() e existem variaes em
relao aos parmetros que so passados, que so:

static void showMessageDialog(Component componentePai, Object mensagem):


mostra uma caixa de mensagem com o ttulo Message e um boto OK.
static void showMessageDialog(Component componentePai, Object mensagem,
String titulo, int tipoDaMensagem): mostra uma caixa de mensagem com o ttulo
definido por titulo, um boto OK e o tipo da mensagem, que identifica o cone
apresentado, podendo ser ERROR_MESSAGE, INFORMATION_MESSAGE, WARNING_MESSAGE,
QUESTION_MESSAGE, ou PLAIN_MESSAGE.
static void showMessageDialog(Component componentePai, Object mensagem,
String titulo, int tipoDaMensagem, Icon icone): idntico ao anterior, com a

possibilidade de mostrar um cone especfico.


O segundo tipo a caixa de dilogo de confirmao, onde uma mensagem mostrada,
normalmente uma pergunta, acompanhada de botes de confirmao. O mtodo para criao
desse tipo de caixa de dilogo o showConfirmDialog(), que possui como retorno um inteiro
que indica o boto que foi pressionado (comeando por zero). No exemplo, tal retorno
armazenado em uma varivel retorno e mostrado no label LabelConfirmacao. Tambm
existem variaes em relao aos parmetros que so passados:

52

static int showConfirmDialog(Component componentePai, Object mensagem):


mostra uma caixa de confirmao com o ttulo Select an Option e os botes Yes, No e
Cancel.
static int showConfirmDialog(Component componentePai, Object message,
String titulo, int tipoDaOpcao): mostra uma caixa de confirmao com o ttulo
definido por titulo, e o o conjunto de botes definido por tipoDaOpcao, que pode ser
YES_NO_OPTION, ou YES_NO_CANCEL_OPTION.
static int showConfirmDialog(Component componentePai, Object message,
String titulo, int tipoDaOpcao, int tipoDaMensagem): idntico ao anterior, com
a possibilidade de identificar o tipo da mensagem e o cone, podendo ser ERROR_MESSAGE,
INFORMATION_MESSAGE, WARNING_MESSAGE, QUESTION_MESSAGE, ou PLAIN_MESSAGE.
static int showConfirmDialog(Component componentePai, Object message,
String titulo, int tipoDaOpcao, int tipoDaMensagem, Icon icone): idntico

ao anterior, permitindo mostrar um cone.


O terceiro tipo a caixa de dilogo de opo, onde possvel determinar as opes possveis para
os botes, na resposta de uma mensagem. O mtodo para criao desse tipo de caixa de dilogo
o showOptionDialog(), que possui como retorno um inteiro que indica o boto que foi
pressionado (comeando por zero). Nesse tipo de caixa de dilogo no existem variaes em
relao aos parmetros, sendo necessrio passar todos eles. Ento, a nica sintaxe aceita :

static int showOptionDialog(Component componentePai, Object mensagem,


String titulo, int tipoDaOpcao, int tipoDaMensagem, Icon icone, Object[]
opcoes, Object valorInicial): mostra uma caixa de opo com o ttulo definido por
titulo, uma mensagem, a escolha do conjunto de botes utilizado, definido por
tipoDaOpcao, que pode ser YES_NO_OPTION, ou YES_NO_CANCEL_OPTION, o tipo da
mensagem, que identifica o cone apresentado, podendo ser ERROR_MESSAGE,
INFORMATION_MESSAGE, WARNING_MESSAGE, QUESTION_MESSAGE, ou PLAIN_MESSAGE, um
cone, o nome dos botes, definido por um objeto opcoes, do tipo Object, e o boto que
ser o inicialmente selecionado, definido por valorInicial.

O quarto tipo a caixa de dilogo de entrada, que um pouco diferente que as outras, pois
permite a insero ou seleo de valores textuais. Se a caixa de dilogo permitir a insero de um
valor, o retorno do tipo String, j que o que vai ser digitado um texto. No caso de ser
permitida a seleo de um dos valores em uma lista, o retorno um objeto do tipo Object, onde,
atravs de um mtodo toString() possvel obter o contedo textual do tem selecionado. O
mtodo para criao desse tipo de caixa de dilogo o showInputDialog() e suas variaes so:

static String showInputDialog(Component componentePai, Object mensagem):


mostra uma caixa de entrada com com o ttulo Input, uma caixa de texto para a entrada
de dados e os botes OK e Cancel.
static String showInputDialog(Component componentePai, Object mensagem,
String titulo, int tipoDaMensagem): mostra uma caixa de entrada como a anterior,

53

com a possibilidade de inserir um ttulo e selecionar o tipo da mensagem, que vai definir o
cone a ser apresentado, que pode ser: ERROR_MESSAGE, INFORMATION_MESSAGE,
WARNING_MESSAGE, QUESTION_MESSAGE, ou PLAIN_MESSAGE.

static Object showInputDialog(Component componentePai, Object mensagem,


String titulo, int tipoDaMensagem, Icon icone, Object[] valoresSelec,
Object valorSelecInicial): tem as mesmas opes que o anterior, porm, permite
inserir um cone e, atravs da criao de um objeto do tipo Object, apresenta os valores
em uma lista, podendo ainda ter o valor inicial setado por valorSelecInicial.

Figura 3.11. Caixa de dilogo de seleo de arquivos

A quinta aba apresenta um boto que, ao ser clicado, abre uma caixa de dilogo de arquivos,
como mostra a figura 3.11. A classe JFileChooser fornece mtodos para apresentar essa caixa
de dilogo e configur-la conforme as necessidades. Semelhante s outras caixas de dilogo, essa
tambm apresentada na forma modal, tendo que fecha-la antes de continuar a utilizao da
aplicao que a chamou.
No exemplo apresentado criado um objeto abreArquivo, do tipo JFileChooser, em primeiro
lugar. Aps setado o diretrio a ser mostrado inicialmente, atravs do mtodo
setCurrentDirectory(), passando como parmetro um objeto do tipo File. Alm do diretrio,
foi setado o nome do arquivo inicial da busca, atravs do mtodo setSelectedFile(), que
tambm precisa de um objeto do tipo File como parmetro. No foi utilizado no exemplo, mas,
se for necessrio permitir a seleo mltipla de arquivos, possvel utilizar o mtodo
setMultiSelectionEnabled(true). Para abrir a caixa de dilogo, basta chamar o mtodo
showOpenDialog(), tendo como valor de retorno um inteiro que representa o boto que foi
pressionado (0 para Open e 1 para Cancel). Da mesma forma, se for desejvel abrir uma caixa de
dilogo para Salvar arquivo, ao invs de Abrir, basta utilizar o showSaveDialog(). No
exemplo, foi utilizada a varivel retorno para ser posteriormente mostrada no label
LabelArquivo1.

54

Esse retorno pode ser testado utilizando o JFileChooser.APPROVE_OPTION, no caso de ter sido
clicado o boto Open e JFileChooser.CANCEL_OPTION, no caso de ter sido clicado o boto
Cancel. No exemplo, se for clicado no boto Open, atribudo ao objeto arquivoSelec, do tipo
File, o retorno do mtodo getSelectedFile(), que traz o arquivo que foi selecionado na caixa
de dilogo. Se existir a situao de mltipla seleo de arquivos, o mtodo a ser utilizado o
getSelectedFiles(), que retorna um arranjo de objetos do tipo File. Aps, o nome desse
arquivo foi mostrado no label LabelArquivo2, atravs do mtodo getName(). Caso tenha sido
clicado no boto Cancel, esse mesmo label apresenta uma mensagem que no foi selecionado
nenhum arquivo.

Figura 3.12. Caixa de dilogo de seleo de cores

A sexta e ltima aba apresenta um boto que, ao ser clicado, abre uma caixa de dilogo de
seleo de cores, mostrado na figura 3.12. A classe JColorChooser a responsvel por essa
tarefa. No exemplo, foi criado um objeto abreCor a partir dessa classe e depois foi aberta a caixa
de dilogo a partir do mtodo showDialog(), tendo que passar como parmetro o seu ttulo e a
sua cor inicial. O retorno desse mtodo foi atribudo a um objeto c, do tipo Color, para depois ser
utilizado na determinao da cor do label, atravs do mtodo setForeground().

3.9 Menus e reas de Texto


O Swing apresenta suporte a menus a partir das classes JMenuBar, JMenu, JMenuItem,
JCheckBoxMenuItem e JRadioButtonMenuItem. Para criar um menu no necessrio ter um
gerenciador de layout especfico, sendo normalmente inserido no prprio frame. A barra de menu
apresentada, normalmente, no topo do frame, com os nomes para cada menu suspenso que, ao
55

serem clicados, podem abrir itens de menu, com aes diretas, ou submenus, que abrem outros
menus suspensos direita, contendo itens de menu ou at mesmo outros submenus.
Os itens de menu podem ser mostrados de diversas formas: com uma imagem associada, com
teclas de atalho, com teclas aceleradoras, na forma de caixa de seleo ou boto de rdio. Ao
serem clicados, os itens de menu disparam eventos de ao, como um boto, por exemplo.
Referente s teclas de atalho, so utilizados mnemnicos para realizar essa funo, que sublinham
um caracter para cada item de menu e so ativados utilizando a tecla Alt + caracter sublinhado.
Quanto s teclas aceleradoras, possvel relacionar uma combinao de teclas, ou uma tecla de
funo, aos itens de menu, como Ctrl + C, Alt + R ou F3.
Para demonstar a utilizao da maioria das funes possveis em um menu, o exemplo a seguir
apresenta uma barra de menu com itens que manipulam uma rea de texto. Uma rea de texto
semelhante aos objetos da classe JTextField, mas permite a entrada de mais que uma linha de
texto, podendo utilizar a tecla Enter para passar de uma linha para outra. A classe responsvel por
esse componente a JTextArea, permitindo especificar o nmero de linhas e colunas na criao
dos seus objetos.
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class TesteDeMenu extends JFrame implements ActionListener
{
private JRadioButtonMenuItem RBFontes[],RBCores[];
private JCheckBoxMenuItem CBNegritoItalico[];
private Color cores[]= {Color.black, Color.red,
Color.blue, Color.orange, Color.green};
private JTextArea AreaTexto;
private ButtonGroup grupoFontes, grupoCores;
public TesteDeMenu()
{
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e){System.exit(0);}});
setSize(400,180);
setLocation(200,150);
setTitle("Menus e reas de Texto");
JMenuBar BarraMenu = new JMenuBar();
setJMenuBar(BarraMenu);
// criao do menu Arquivo
JMenu menuArquivo = new JMenu("Arquivo");
menuArquivo.setMnemonic('A');
JMenuItem itemNovo = new JMenuItem("Novo...", new ImageIcon("novo.gif"));
itemNovo.setMnemonic('N');
JMenuItem itemAbrir= new JMenuItem("Abrir...",new ImageIcon("abrir.gif"));
itemAbrir.setMnemonic('b');
itemAbrir.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O,
InputEvent.CTRL_MASK));;
JMenuItem itemSalvar= new JMenuItem("Salvar",new ImageIcon("salvar.gif"));
itemSalvar.setMnemonic('S');
itemSalvar.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S,
InputEvent.CTRL_MASK));;
JMenuItem itemSair= new JMenuItem("Sair");

56

itemSair.setMnemonic('r');
itemSair.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R,
InputEvent.ALT_MASK));;
menuArquivo.add(itemNovo);
menuArquivo.add(itemAbrir);
menuArquivo.addSeparator();
menuArquivo.add(itemSalvar);
menuArquivo.addSeparator();
menuArquivo.add(itemSair);
BarraMenu.add(menuArquivo);
itemNovo.addActionListener(this);
itemAbrir.addActionListener(this);
itemSalvar.addActionListener(this);
itemSair.addActionListener(this);
// criao do menu Editar
JMenu menuEditar = new JMenu("Editar");
menuEditar.setMnemonic('E');
JMenuItem itemRecortar = new JMenuItem("Recortar...",
new ImageIcon("recortar.gif"));
itemRecortar.setMnemonic('t');
itemRecortar.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X,
InputEvent.CTRL_MASK));;
JMenuItem itemCopiar = new JMenuItem("Copiar...",
new ImageIcon("copiar.gif"));
itemCopiar.setMnemonic('b');
itemCopiar.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C,
InputEvent.CTRL_MASK));;
JMenuItem itemColar = new JMenuItem("Colar...",
new ImageIcon("colar.gif"));
itemColar.setMnemonic('S');
itemColar.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V,
InputEvent.CTRL_MASK));;
menuEditar.add(itemRecortar);
menuEditar.add(itemCopiar);
menuEditar.add(itemColar);
BarraMenu.add(menuEditar);
itemRecortar.addActionListener(this);
itemCopiar.addActionListener(this);
itemColar.addActionListener(this);
// criao do menu Formatar
JMenu menuFormatar = new JMenu("Formatar");
menuFormatar.setMnemonic('F');
// criao do submenu Cor
String nomesCores[]= {"Preto", "Vermelho", "Azul", "Laranjado", "Verde"};
JMenu menuCor = new JMenu("Cor");
menuCor.setMnemonic('C');
RBCores = new JRadioButtonMenuItem[nomesCores.length];
grupoCores = new ButtonGroup();
for (int i = 0; i < nomesCores.length; i++)
{
RBCores[i] = new JRadioButtonMenuItem(nomesCores[i]);
menuCor.add(RBCores[i]);
grupoCores.add(RBCores[i]);
RBCores[i].addActionListener(this);
}
RBCores[0].setSelected(true);
menuFormatar.add(menuCor);

57

menuFormatar.addSeparator();
// criao do submenu Fonte
String nomesFontes[] = {"SansSerif", "Monospaced", "Serif"};
JMenu menuFonte = new JMenu("Fonte");
menuFonte.setMnemonic('n');
RBFontes = new JRadioButtonMenuItem[nomesFontes.length];
grupoFontes = new ButtonGroup();
for (int i = 0; i < RBFontes.length; i++)
{
RBFontes[i] = new JRadioButtonMenuItem(nomesFontes[i]);
menuFonte.add(RBFontes[i]);
grupoFontes.add(RBFontes[i]);
RBFontes[i].addActionListener(this);
}
RBFontes[0].setSelected(true);
menuFonte.addSeparator();
String CBItalicoNegrigoItens[] = {"Negrito", "Itlico"};
CBNegritoItalico = new JCheckBoxMenuItem[CBItalicoNegrigoItens.length];
for (int i = 0; i < CBItalicoNegrigoItens.length; i++)
{
CBNegritoItalico[i] = new JCheckBoxMenuItem(CBItalicoNegrigoItens[i]);
menuFonte.add(CBNegritoItalico[i]);
CBNegritoItalico[i].addActionListener(this);
}
menuFormatar.add(menuFonte);
BarraMenu.add(menuFormatar);
// criao do menu Ajuda
JMenu menuAjuda = new JMenu("Ajuda");
menuAjuda.setMnemonic('u');
JMenuItem itemSobre = new JMenuItem("Sobre a Aplicao...");
itemSobre.setMnemonic('S');
menuAjuda.add(itemSobre);
BarraMenu.add(menuAjuda);
itemSobre.addActionListener(this);
AreaTexto = new JTextArea(5, 40);
AreaTexto.setForeground(Color.black);
AreaTexto.setFont(new Font("SansSerif", Font.PLAIN, 14));
AreaTexto.setLineWrap(true);
Container P = getContentPane();
P.add(new JScrollPane(AreaTexto));
}
public void actionPerformed(ActionEvent evt)
{
if (evt.getSource() instanceof JMenuItem)
{
String item = evt.getActionCommand();
if (item == "Novo...")
JOptionPane.showMessageDialog(this, "Opao Novo no disponvel!",
"Alerta", JOptionPane.WARNING_MESSAGE);
else if (item == "Abrir...")
JOptionPane.showMessageDialog(this, "Opao Abrir no disponvel!",
"Alerta", JOptionPane.WARNING_MESSAGE);
else if (item == "Salvar")
JOptionPane.showMessageDialog(this, "Opao Salvar no disponvel!",
"Alerta", JOptionPane.WARNING_MESSAGE);
else if (item == "Sair")

58

System.exit(0);
else if (item == "Recortar...")
AreaTexto.cut();
else if (item == "Copiar...")
AreaTexto.copy();
else if (item == "Colar...")
AreaTexto.paste();
else if (item == "Sobre a Aplicao...")
JOptionPane.showMessageDialog(this,
"Este um exemplo de utilizao de menus",
"Sobre", JOptionPane.PLAIN_MESSAGE);
else
{
int Tipo = Font.PLAIN;
if (CBNegritoItalico[0].isSelected())
Tipo += Font.BOLD;
if (CBNegritoItalico[1].isSelected() )
Tipo += Font.ITALIC;
AreaTexto.setFont(new Font(AreaTexto.getFont().getName(), Tipo, 14));
for (int i = 0; i < RBCores.length; i++)
if (evt.getSource() == RBCores[i])
{
AreaTexto.setForeground(cores[i]);
break;
}
for (int i = 0; i < RBFontes.length; i++ )
if (evt.getSource() == RBFontes[i])
{
AreaTexto.setFont(new Font(RBFontes[i].getText(), Tipo, 14));
break;
}
repaint();
}
}
}
public static void main(String args[])
{
TesteDeMenu fr = new TesteDeMenu();
fr.setVisible(true);
}
}

Figura 3.13. Manipulao de uma rea de texto a partir de menus

59

A figura 3.13 mostra a execuo da aplicao, notando que no foi inserido nenhum painel no
frame, tendo sido setada a barra de menu para o frame e inserida a rea de texto diretamente em
um continer. Para criar uma rea de texto necessrio, primeiramente, criar um objeto do tipo
JTextArea e passar os parmetros para determinar o nmero de linhas e o nmero de colunas
desejado. Aps, alguns mtodos podem ser utilizados para configurar a rea: o setForeground()
indica a cor do texto; o setFont() determina o tipo, tamanho e formato de fonte; o
setLineWrap() determina se o texto vai mudar de linha ao chegar no final da rea definida. Para
que o texto possa ser mostrado com barras de rolagem, caso este seja maior que a rea visvel,
necessrio inserir o objeto rea de texto em um objeto JScrollPane e aps inseri-lo no continer.
Dois outros mtodos so teis: o setWrapStyleWord(), que faz a quebra da linha ao final da
palavra se o parmetro for true, ou ignora o final da palavra para a quebra da linha, se o
parmetro for falso, e; o setTabSize(), que determina, em seu parmetro, o nmero de colunas
utilizados para a tabulao.

Figura 3.14. As opes existentes no menu

Para criar o menu mostrado na figura 3.14, foi necessrio seguir vrios passos. No exemplo, antes
de tudo, foi criado o objeto BarraMenu, do tipo JMenuBar, para depois ser passado como
parmetro pelo mtodo setJMenuBar(), que responsvel pela insero do menu no frame.
Aps foram inseridos os vrios menus que compem a barra de menu. Para a criao do menu
Arquivo foi criado um objeto menuArquivo, do tipo JMenu e setado um mnemnico, que ir
sublinhar o caracter desejado e servir de tecla de atalho, atravs do mtodo setMnemonic().
Os itens de menu so adicionados a seguir, a partir da criao de objetos do tipo JMenuItem,
permitindo a definio de imagens a serem mostradas juntamente com os itens. Para cada item foi
setada uma tecla de atalho a partir do setMnemonic() e, para alguns deles, foram associadas
teclas aceleradoras atravs do mtodo setAccelerator(), tendo que passar como parmetro um
objeto do tipo KeyStroke, que identifica o caracter e a tecla de controle utilizados para fazer a
combinao. Tendo definidos todos itens de menu, suas teclas de atalho e aceleradoras, estes
foram adicionados ao menu menuArquivo, e este foi adiconado barra de menu BarraMenu.
Percebe-se a existncia de linhas separatrias entre os itens, criadas pelo mtodo
addSeparator(). Como os itens de menu respondem a eventos de ao, foi setado um ouvinte
de eventos para cada um, a partir do addActionListener. Os mesmos passos foram seguidos
para criar os menus menuEditar e menuAjuda.
A criao do menuFormatar segue basicamente os mesmos passos, mas eles possuem, no lugar
de itens de menu comuns, itens que abrem submenus, que contm outros itens especiais (caixas

60

de seleo e botes de rdio). Assim, no menu Formatar foram inseridos dois submenus: Cor e
Fonte. Para a criao do menu Cor foi definido um objeto menuCor, do tipo JMenu, e foram
adicionados seis itens de menu a partir do arranjo RBCores, do tipo JRadioButtonMenuItem. Por
se tratar de botes de rdio, foi necessrio adicion-los tambm ao grupo grupoCores, do tipo
ButtonGroup. Antes de adicionar o menuCor ao menuFormatar, foi setado o boto de rdio que
inicia selecionado, pelo mtodo setSelected().
Para a criao do menu Fonte foi definido um objeto menuFonte, tambm do tipo JMenu, e foram
adicionados: um grupo de botes de rdio, seguindo os mesmos passos j apresentados, uma
linha separatria, e dois itens do tipo caixa de seleo, feitos a partir do arranjo
CBNegritoItalico, do tipo JCheckBoxMenuItem. Ao final, o menuFonte foi adicionado ao
menuFormatar, e esse, por sua vez, foi adicionado barra de menu. Da mesma forma que os
itens de menu normais, tembm foi setado um ouvinte de eventos para cada um, a partir do
addActionListener.
Como j comentado, para o tratamento dos eventos, foi utilizada a interface ActionListener e
implementado o mtodo actionPerformed() que, a partir do getActionCommand(), permite a
comparao do que foi clicado com o texto do item de menu especfico. Como as opes Novo,
Abrir e Salvar no possuem uma efetiva implementao, foi apresentada uma mensagem para
cada uma delas. O item Sair encerra a aplicao. Os itens do menu Editar simplesmente
executam os mtodos cut(), copy() e paste(), do objeto AreaTexto. O item Sobre tambm
mostra apenas uma mensagem. Caso o item selecionado for algum dos constantes no menu
Formatar, ento so utilizados mtodos como o setFont() e o setForeground(), para realizar
as operaes desejadas, sendo confirmadas a partir do repaint().

3.10 Tratamento de Eventos Especiais


Alm dos eventos gerados por componentes de interface com o usurio, vistos at aqui, existem
eventos especiais que podem ser ativados a qualquer hora, e no precisam estar associados a
algum componente especfico. As prximas sees explicitam trs desses tipos de eventos: de
foco, de janela, de mouse e de teclado.
3.10.1 Eventos de Foco
Existem componentes que podem receber foco e outros no. Receber foco significa possuir
prioridade sobre os outros componentes na digitao de teclas. Por exemplo, se um boto possuir
o foco, no momento que for pressionada a barra de espaos, este ser o escolhido. Da mesma
forma, se uma caixa de texto possuir o foco, quando forem digitados caracteres, nela que eles
sero mostrados. Portanto, se o componente puder realizar algum tipo de ao advindo do
pressionamento de teclas, ento, ele pode obter foco, caso contrrio, no. Logicamente, em um
frame pode haver apenas um componente com foco, mas ele pode perder o foco se for
pressionada a tecla Tab ou se um outro componente que pode receber foco for clicado com o
mouse. Isso se existitem, no frame, outros componentes que podem receber foco.
O componente que possui o foco mostra visualmente essa situao, como: um boto apresenta
um retngulo pontilhado e uma caixa de texto apresenta o cursor piscando na rea destinada
digitao. possvel mudar o foco via programao a qualquer momento, atravs do mtodo
requestFocus(), mas s ir funcionar em resposta a um evento qualquer.
61

Como padro, os componentes do Swing so percorridos, pela tecla Tab, da esquerda para a
direita e de cima para baixo, dentro do continer. Essa ordem conhecida como Ordem de
tabulao, e o exemplo a seguir foi criado para realizar a verificao dessa ordem.
import
import
import
import

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

public class TesteDeFoco extends JFrame


{
private JTextField TextoUm;
private JTextField TextoDois;
private JTextField TextoTres;
private JTextField TextoQuatro;
private JButton BotaoUm;
private JButton BotaoDois;
private JButton BotaoTres;
private JButton BotaoQuatro;
public TesteDeFoco()
{
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e){System.exit(0);}});
setSize(300,170);
setLocation(200,200);
setTitle("Teste de Foco");
Container P = getContentPane();
P.setLayout(new GridLayout(2,1));
JPanel PainelFocoCima = new JPanel();
TextoUm = new JTextField("Texto Um",10);
PainelFocoCima.add(TextoUm);
TextoDois = new JTextField("Texto Dois",10);
PainelFocoCima.add(TextoDois);
BotaoUm = new JButton("Boto Um");
PainelFocoCima.add(BotaoUm);
BotaoDois = new JButton("Boto Dois");
PainelFocoCima.add(BotaoDois);
Border bordaPainelCima = BorderFactory.createEtchedBorder();
PainelFocoCima.setBorder(bordaPainelCima);
P.add(PainelFocoCima);
JPanel PainelFocoBaixo = new JPanel();
TextoTres = new JTextField("Texto Trs",10);
PainelFocoBaixo.add(TextoTres);
TextoQuatro = new JTextField("Texto Quatro",10);
PainelFocoBaixo.add(TextoQuatro);
BotaoTres = new JButton("Boto Trs");
PainelFocoBaixo.add(BotaoTres);
BotaoQuatro = new JButton("Boto Quatro");
PainelFocoBaixo.add(BotaoQuatro);
Border bordaPainelBaixo = BorderFactory.createEtchedBorder();
PainelFocoBaixo.setBorder(bordaPainelBaixo);
P.add(PainelFocoBaixo);
}
public static void main(String[] args)
{

62

JFrame fr = new TesteDeFoco();


fr.setVisible(true);
}
}

Figura 3.15. Sentido da Ordem de Tabulao

As legendas inseridas na figura 3.15 mostram o sentido natural seguido pelos componentes do
Swing. Se existir um continer dentro de outro, no momento que entrar no continer interno, ir
ser seguida a ordem padro at o seu ltimo componente, s ento voltar a percorrer os
componentes do continer externo. possvel alterar essa ordem atravs do mtodo
setNextFocusableComponent(). Por exemplo, para passar o foco do objeto TextoUm
diretamente para o TextoTres, basta implementar o cdigo:
TextoUm.setNextFocusableComponent(TextoTres);

Nesse caso, aps o TextoUm viria o TextoTres, e depois retornaria o sentido normal, ou seja:
TextoDois, BotaoUm, etc., a no ser que se altere novamente a ordem.
Como visto anteriormente, o requestFocus() permite alterar o foco, mas apenas em resposta a
algum evento. Isso bastante til se for necessrio testar o contedo de uma caixa de texto e,
caso no esteja correto, emitir uma mensagem e no permitir a sada da caixa, como no exemplo
a seguir.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class FocoAlterado extends JFrame implements FocusListener
{
private JTextField TextoUm;
private JTextField TextoDois;
public FocoAlterado()
{
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e){System.exit(0);}});
setSize(300,70);
setLocation(200,200);
setTitle("Alterando o Foco");
Container P = getContentPane();
JPanel PainelFoco = new JPanel();
TextoUm = new JTextField("Texto Um",10);
PainelFoco.add(TextoUm);

63

TextoDois = new JTextField("Texto Dois",10);


PainelFoco.add(TextoDois);
P.add(PainelFoco);
TextoUm.addFocusListener(this);
}
public void focusLost(FocusEvent evt)
{
Component origem = evt.getComponent();
if (origem == TextoUm && !evt.isTemporary())
if (TextoUm.getText().equals(""))
{
JOptionPane.showMessageDialog(this, "O valor deve ser digitado!",
"Ateno", JOptionPane.ERROR_MESSAGE);
TextoUm.requestFocus();
}
}
public void focusGained(FocusEvent evt) { }
public static void main(String[] args)
{
JFrame fr = new FocoAlterado();
fr.setVisible(true);
}
}

Figura 3.16. Teste de entrada de dados em uma caixa de texto

A figura 3.16 mostra o que acontece se for feita a tentativa de sair da primeira caixa de texto sem
digitar nada nela. Para que isso seja possvel, necessrio implementar os mtodos da interface
FocusListener, focusLost() e focusGained(), que so invocados no momento que a origem
do evento ganhar ou perder o foco. O parmetro FocusEvent uma classe que apresenta alguns
mtodos importantes, como o getComponent(), que informa quem recebeu ou perdeu o foco e o
isTemporary(), que informa se a mudana de foco foi permanente ou temporria, podendo ser,
por exemplo, na ativao de uma outra janela e posterior retorno janela atual.
No exemplo, para o objeto TextoUm, foi adicionado o ouvinte de eventos a partir do
addFocusListener(). No mtodo focusLost() foi feito o teste se a origem do evento foi o
TextoUm e se no foi uma perda de foco temporria. Caso seja verdadeiro e o contedo da caixa
de texto esteja vazio, mostrada uma mensagem e devolvido o foco ao prprio TextoUm, no
permitindo, dessa forma, sair da caixa de texto sem a digitao de algo. Como no foi realizada

64

nenhuma ao no ganho de foco, o mtodo focusGained() ficou vazio, lembrando a


obrigatoriedade de se implementar todos os mtodos de uma interface.
3.10.2 Eventos de Janela
Da mesma forma que os componentes, as janelas tambm possuem eventos possveis de
acontecer. A classe JFrame o tipo de janela mais utilizado em Java, possuindo uma barra de
ttulo e uma borda que se adaptam a plataforma onde o aplicativo est sendo executado. Isso
significa que so incorporados recursos da GUI daquela plataforma especfica.
Quando as janelas, incluindo o JFrame, gerarem algum evento, deve haver um ouvinte de eventos
baseado na interface WindowListener para seu tratamento, e alguns mtodos podem ser
implementados, como o caso do trecho de cdigo a seguir, que tem sido colocado nos exemplos
vistos at aqui, com a funo de fechar o frame. O mtodo windowClosing() executado no
momento que clicado no boto especfico para fechar a janela da plataforma corrente, sendo
necessrio para isso encerrar a aplicao com o mtodo System.exit(0).
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e){System.exit(0);}});

Alm do mtodo windowClosing(), outros seis mtodos podem ser implementados. So eles:

windowActivated(): ocorre quando

windowDeactivated():

a janela se torna ativa.

ocorre quando a janela se torna inativa, provavelmente na

ativao de outra janela.

windowOpened(): ocorre

windowClosed(): ocorre quando a janela fechada. A diferena desse mtodo para


windowClosing() que esse ltimo pode evitar que a janela seja fechada, enquanto
windowClosed() executado aps o fechamento da janela.

windowIconified(): ocorre quando

windowDeiconified():

quando a janela aberta.


o
o

a janela minimizada.

ocorre quando a janela restaurada.

O exemplo a seguir mostra a primeira maneira de implementao de alguns mtodos da interface


WindowListener.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class EventosEmJanelas extends JFrame
{
public EventosEmJanelas()
{
addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
JOptionPane.showMessageDialog(null, "O frame ser fechado...");

65

System.exit(0);
}
public void windowOpened(WindowEvent e)
{
setTitle("Aberto");
}
public void windowIconified(WindowEvent e)
{
setTitle("Minimizado");
}
public void windowDeiconified(WindowEvent e)
{
setTitle("Restaurado");
}
});
setSize(300,70);
setLocation(200,200);
}
public static void main(String[] args)
{
JFrame fr = new EventosEmJanelas();
fr.setVisible(true);
}
}

Figura 3.17. Manipulao de eventos em janelas

Percebe-se que a estrutura adotada na maioria dos exemplos vistos at aqui foi seguida,
acrescentando-se apenas os mtodos windowOpened(), na abertura do frame,
windowIconified(), no ato de minimizar o frame, e windowDeiconified(), no ato de restaurar
o frame. O resultado, apresentado na figura 3.17, mostra que foi feita uma alterao no ttulo do
frame nesses mtodos. O mtodo windowClosing(), antes de finalizar a aplicao, mostra uma
mensagem alertando o usurio que isso ir acontecer. Nota-se que os demais mtodos no foram
implementados, pois nesse tipo de implementao no necessrio.
A segunda maneira de realizar as mesmas tarefas mostrada no exemplo a seguir.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class EventosEmJanelasSegundaForma extends JFrame
implements WindowListener
{
public EventosEmJanelasSegundaForma()

66

{
addWindowListener(this);
setSize(300,70);
setLocation(200,200);
}
public void windowClosing(WindowEvent e)
{
JOptionPane.showMessageDialog(null, "O frame ser fechado...");
System.exit(0);
}
public void windowOpened(WindowEvent e)
{
setTitle("Aberto");
}
public void windowIconified(WindowEvent e)
{
setTitle("Minimizado");
}
public void windowDeiconified(WindowEvent e)
{
setTitle("Restaurado");
}
public void windowClosed(WindowEvent e) { }
public void windowActivated(WindowEvent e) { }
public void windowDeactivated(WindowEvent e){ }
public static void main(String[] args)
{
JFrame fr = new EventosEmJanelasSegundaForma();
fr.setVisible(true);
}
}

A execuo a mesma, mas a forma escolhida para a programao diferente. Observe que, em
primeiro lugar, utilizou-se o implements WindowListener, e aps foi realizada a implementao
dos mtodos, tornando-se obrigatria, dessa forma, que todos os mtodos estejam presentes,
inclusive aqueles que no tem nenhum cdigo interno.
3.10.3 Eventos de Mouse
Qualquer ao do mouse pode ser capturada como sendo um evento especfico, porm, na
maioria das vezes, essas aes j so tratadas pelos componentes que esto sendo manipulados.
Por exemplo, se for clicado em um boto, o mtodo a ser implementado o
actionPerformed(), da interface ActionListener, no sendo necessrio tratar exclusivamente
o clique do mouse. Porm, existem situaes que necessitam da implementao de linhas de
cdigo que respondam a eventos de mouse, e quando isso acontece, os mtodos da interface
MouseListener e MouseMotionListener devem ser implementados, tendo como parmetro um

67

objeto do tipo MouseEvent, que contm as informaes necessrias para o tratamento, como as
coordenadas x e y de onde o evento ocorreu, por exemplo.
A interface MouseListener possui cinco mtodos possveis de serem implementados. So eles:

mouseClicked(): ocorre quando h o pressionamento do mouse, com qualquer boto, e


sua liberao sem o movimento do cursor.

mousePressed(): ocorre

mouseReleased(): ocorre quando h a liberao de algum boto do mouse aps ter


havido o pressionamento deste.

mouseEntered(): ocorre quando o cursor do mouse entra na rea definida por um


componente especfico.

mouseExited():

quando h o pressionamento de algum boto do mouse.

ocorre quando o cursor do mouse sai da rea definida por um


componente especfico.

J a interface MouseMotionListener se preocupa mais com os eventos de movimento do mouse.


Os dois mtodos exitentes so:

mouseMoved():

ocorre quando h o movimento do cursor do mouse em um componente

especfico.

mouseDragged(): ocorre quando h o pressionamento (mousePressed()) de um boto do


mouse e posterior movimentao.

A fim de demonstrar o funcionamento do tratamento de eventos de mouse, o exemplo a seguir


traz uma implementao para todos os mtodos de cada uma das duas interfaces.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class EventosDeMouse extends JFrame
implements MouseListener, MouseMotionListener
{
private JLabel Mensagem;
private JButton BotaoOK;
public EventosDeMouse()
{
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e){System.exit(0);}});
addMouseListener(this);
addMouseMotionListener(this);
setSize(400,100);
setLocation(200,200);
setTitle("Eventos de Mouse");
Container P = getContentPane();
P.setLayout(new BorderLayout());
JPanel PainelEMCentro = new JPanel();

68

BotaoOK = new JButton("OK");


PainelEMCentro.add(BotaoOK);
P.add(PainelEMCentro,"Center");
JPanel PainelEMSul = new JPanel();
Mensagem = new JLabel();
PainelEMSul.add(Mensagem);
P.add(PainelEMSul,"South");
BotaoOK.addMouseListener(this);
}
public void mouseClicked(MouseEvent e)
{
String botaoPressionado =e.getButton() == 1 ? "esquerdo" :
(e.getButton() == 2 ? "do meio" : "direito");
Mensagem.setText("Boto " + botaoPressionado +
" CLICADO nas cordenadas x = " + e.getX() + " y = " + e.getY());
}
public void mousePressed(MouseEvent e)
{
String botaoPressionado =e.getButton() == 1 ? "esquerdo" :
(e.getButton() == 2 ? "do meio" : "direito");
Mensagem.setText("Boto " + botaoPressionado +
" PRESSIONADO nas cordenadas x = " + e.getX() + " y = " + e.getY());
}
public void mouseReleased(MouseEvent e)
{
String botaoPressionado =e.getButton() == 1 ? "esquerdo" :
(e.getButton() == 2 ? "do meio" : "direito");
Mensagem.setText("Boto " + botaoPressionado +
" LIBERADO nas cordenadas x = " + e.getX() + " y = " + e.getY());
}
public void mouseEntered(MouseEvent e)
{
Mensagem.setText("Mouse ENTROU no FRAME");
if (e.getSource() == BotaoOK)
{
Mensagem.setText("Mouse ENTROU no BOTO");
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
}
}
public void mouseExited(MouseEvent e)
{
Mensagem.setText("Mouse SAIU do FRAME");
if (e.getSource() == BotaoOK)
{
Mensagem.setText("Mouse SAIU no BOTO");
setCursor(Cursor.getDefaultCursor());
}
}

// mensagem no perceptvel

public void mouseMoved(MouseEvent e)


{
Mensagem.setText("Cursor MOVIDO para x = " + e.getX() +

69

" y = " + e.getY());


}
public void mouseDragged(MouseEvent e)
{
Mensagem.setText("Cursor ARRASTADO para x = " + e.getX() +
" y = " +e.getY());
}
public static void main(String[] args)
{
JFrame fr = new EventosDeMouse();
fr.setVisible(true);
}
}

Figura 3.18. Manipulao de eventos de mouse

Apenas uma das mensagens, das vrias existentes, est sendo mostrada na figura 3.18. Antes de
tudo, as duas interfaces esto sendo utilizadas, atravs do implements MouseListener,
MouseMotionListener. Atravs do addMouseListener() e do addMouseMotionListener() foi
setado o frame como sendo ouvinte de eventos dele mesmo. Para que o boto BotaoOK tambm
pudesse responder aos eventos de clique, foi adicionado um ouvinte de eventos para ele. O
resultado que, para cada um dos mtodos implementados, uma mensagem mostrada no label
Mensagem, que fica no painel situado na parte sul do frame. Em algumas situaes, porm,
algumas mensagens no podem ser vistas porque a mensagem de outro evento a sobrepe, como
o caso de quando se entra no frame, onde a mensagem sobreposta por aquela emitida pelo
mtodo mouseMoved().
Os mtodos mouseClicked(), mousePressed() e mouseReleased() simplesmente atualizam o
label com: a mensagem de qual boto foi pressionado, informao adquirida pelo mtodo
getButton(), que retorna um inteiro (1- boto esquerdo, 2- boto do meio e 3- boto direito); a
ao realizada, se o boto foi clicado, pressionado ou liberado; e as coordenadas x e y, adquiridas
pelos mtodos getX() e getY(). Como o boto tambm possui um ouvinte de eventos, a
mensagem tambm atualizada quando o evento ocorre sobre ele. Percebe-se que as coordenadas
x e y so especficas do boto.
Nos mtodos mouseEntered() e mouseExited() h um tratamento especial para a ocorrncia do
evento no boto. Quando o evento de entrada ou sada ocorre no frame, apenas uma mensagem
adequada mostrada, porm, quando esse tipo de evento ocorre no boto, alm da mensagem,
alterado o cursor para HAND_CURSOR na entrada e para o cursor padro na sada. Isso feito a
partir do mtodo setCursor(), que tem como parmetro um objeto do tipo Cursor, onde,
atravs do getPredefinedCursor(), possvel setar um dos cursores pr-definidos. Alguns
desses tipos de cursor so mostrados na tabela 3.1.

70

DEFAULT_CURSOR
HAND_CURSOR
WAIT_CURSOR
TEXT_CURSOR
CROSSHAIR_CURSOR
MOVE_CURSOR
N_RESIZE_CURSOR

(norte) ou S_RESIZE_CURSOR (sul)

SW_RESIZE_CURSOR

(sul- leste) ou NE_RESIZE_CURSOR (norte-leste)

SE_RESIZE_CURSOR

(sul-leste) ou NW_RESIZE_CURSOR (norte-leste)

E_RESIZE_CURSOR

(leste) ou W_RESIZE_CURSOR (oeste)

Tabela 3.1. Exemplos de cursor existentes na plataforma Windows

Por fim, durante a movimentao sobre o frame, com ou sem o boto do mouse pressionado, uma
mensagem mostrada, indicando o posicionamento. Os mtodos responsveis so o
mouseMoved() e o mouseDragged(). Percebe-se que esse tipo de mensagem no aparece quando
se passa em cima do boto. Isso ocorre porque no foi adicionado um ouvinte de eventos de
movimento (addMouseMotionListener()) ao boto.
3.10.4 Eventos de Teclado
Da mesma forma que o mouse, qualquer evento gerado pelo teclado pode ser tratado, mas isso s
necessrio em situaes em que o evento ocorrido no esteja associado a um componente
especfico. No mesmo exemplo utilizado para os eventos de mouse, um boto, para ser
presssionado, pode ser clicado o mouse sobre ele, ou pode ser pressionada a barra de espaos
quando o foco est sobre ele. Nesse caso, o evento a ser tratado no algum especfico de
teclado, e sim o evento especfico para o boto. Nos casos especficos de tratamento de eventos
de teclado, a interface utilizada a KeyListener, onde existem trs mtodos possveis de serem
implementados, todos eles recebendo um objeto do tipo KeyEvent como parmetro. So eles:

keyPressed():

keyReleased():

ocorre quando h o pressionamento de qualquer tecla.


ocorre quando h a liberao de qualquer tecla, ocorrida aps o seu

pressionamento.

keyTyped():

ocorre quando h o pressionamento de qualquer tecla que no seja uma tecla


de ao, como o Home, End, Caps Lock, Shift, Alt, etc.

O funcionamento dos eventos de teclado possveis demonstrado no exemplo a seguir, que


simplesmente mostra a tecla, ou combinao de teclas que foi pressionada ou liberada.
71

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class EventosDeTeclado extends JFrame implements KeyListener
{
private JLabel Mensagem;
private int tecla = 0;
private String teclaPressed = null;
private char teclaTyped;
private boolean entrouPressed;
private boolean combinacao;
public EventosDeTeclado()
{
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e){System.exit(0);}});
addKeyListener(this);
setSize(250,100);
setLocation(300,250);
setTitle("Eventos de Teclado");
Container P = getContentPane();
Mensagem = new JLabel();
P.add(Mensagem);
}
public void keyPressed(KeyEvent e)
{
tecla = e.getKeyCode();
teclaPressed = e.getKeyText(tecla);
entrouPressed = true;
switch (tecla){
case KeyEvent.VK_SHIFT: teclaPressed = "Shift"; break;
case KeyEvent.VK_CONTROL: teclaPressed = "Control"; break;
case KeyEvent.VK_ALT: teclaPressed = "Alt"; break;
case KeyEvent.VK_RIGHT: teclaPressed = "Direita"; break;
case KeyEvent.VK_LEFT: teclaPressed = "Esquerda"; break;
case KeyEvent.VK_UP: teclaPressed = "Cima"; break;
case KeyEvent.VK_DOWN: teclaPressed = "Baixo"; break;
}
if (tecla == KeyEvent.VK_A && e.isShiftDown())
{
combinacao = true;
teclaPressed = "Shift + A";
}
if (tecla == KeyEvent.VK_A && e.isControlDown())
{
combinacao = true;
teclaPressed = "Control + A";
}
if (tecla == KeyEvent.VK_A && e.isAltDown())
{
combinacao = true;
teclaPressed = "Alt + A";
}
Mensagem.setText("Tecla " + tecla + " - " + teclaPressed +" PRESSIONADA");

72

}
public void keyReleased(KeyEvent e)
{
if (entrouPressed)
{
Mensagem.setText("Tecla " + tecla + " - " + teclaPressed + " LIBERADA");
combinacao = false;
}
else
Mensagem.setText("Tecla " + teclaTyped + " LIBERADA");
}
public void keyTyped(KeyEvent e)
{
if (!combinacao)
{
teclaTyped = e.getKeyChar();
entrouPressed = false;
Mensagem.setText("Tecla " + teclaTyped +
}
}

" PRESSIONADA");

public static void main(String[] args)


{
JFrame fr = new EventosDeTeclado();
fr.setVisible(true);
}
}

Figura 3.19. Manipulao de eventos de teclado

Um label Mensagem inserido no frame (figura 3.19) indica qual tecla ou combinao foi
pressionada ou liberada. Para que isso seja possvel, necessrio implementar os trs mtodos da
interface KeyListener. No exemplo, algumas variveis foram declaradas a fim de utilizar nos
trs mtodos, j que, em algumas situaes, a mensagem de um sobreporia aquela emitida por
outro mtodo. No keyPressed() a varivel tecla armazena o cdigo inteiro da tecla
pressionada, a partir do getKeyCode(), e a varivel teclaPressed armazena a descrio da tecla
pressionada, a partir do getKeyText(). No caso de se querer testar uma tecla especfica,
necessrio testar o cdigo para ver se ele igual a alguma das constantes definidas na classe
KeyEvent, sempre iniciadas por VK_. No exemplo, foi feito isso simplesmente para colocar uma
descrio em portugus de algumas teclas na varivel teclaPressed. Aps, foi verificada a
ocorrncia, e atualizada a varivel teclaPressed, das combinaes de teclas Shift+A,
Control+A e Alt+A, atravs dos mtodos isShiftDown(), isControlDown() e isAltDown(),
respectivamente. A varivel entrouPressed setada para true sempre que for executado o
mtodo keyPressed() e a varivel combinacao setada para true sempre que forem

73

pressionadas as combinaes anteriormente citadas. Ao final, mostrado no label o cdigo e a


descrio da tecla ou combinao pressionada.
No mtodo keyTyped() a varivel teclaTyped obtm a tecla que foi pressionada, atravs do
getKeyChar(), lembrando que apenas teclas que no so de ao ativam esse mtodo. A varivel
entrouPressed setada para false para indicar a entrada no keyTyped(). Ao final, mostrada
a tecla que foi pressionada. Tudo isso somente feito se no tiver sido pressionada uma
combinao de teclas anteriormente, controlada pela varivel combinao.
O mtodo keyReleased() executado aps o keyPressed() ou o keyTyped() tiver sido
executado. Por isso a existncia da varivel entrouPressed, para dar mensagens diferentes na
liberao das teclas.
Adicionalmente, existe ainda o mtodo isActionKey(), que retorna true se a tecla pressionada
for uma tecla de ao e false caso contrrio.

3.11 Aplicaes MDI, Menus Flutuantes e Barra de Ferramentas


Em Java, uma aplicao MDI (Mutilple Document Interface Interface de Mltiplos
Documentos) caracterizada pela existncia de um frame principal, ou frame pai, que pode
conter vrias outros frames internos, ou frames filhos. As operaes de manipulao do frame
principal acarretam em efeitos nos frames internos. A ao de fechar, por exemplo, faz com que
os frames internos que esto abertos tambm sejam finalizados.
A rea de ao de um frame interno o prprio frame principal, no podendo ultrapassar os seus
limites. Isso significa que, se um frame interno for maximizado, ele vai ocupar o espao
delimitado pelo frame principal, esteja ele ocupando o espao que for da tela. Da mesma forma,
ao minimizar um frame interno, este vai ficar localizado no rodap do frame principal.
Para que se possa criar uma rea apta manipulao de frames internos, deve-se trabalhar com
um objeto da classe JDesktopPane e inserir um objeto da classe JInternalFrame para cada
frame interno que se deseja criar.
A aplicao mostrada a seguir apresenta, alm do exemplo da aplicao MDI, a utilizao de uma
barra de ferramentas e de menus flutuantes. Uma barra de ferramentas criada a partir da classe
JToolBar, e nada mais do que um conjunto de botes que realizam aes, normalmente
utilizada para criar acessos rpidos s principais tarefas da aplicao. Os menus flutuantes,
criados a partir da classe JPopupMenu e comumente chamados de pop-up, so menus suspensos
ativados normalmente pelo clique do boto direito do mouse, e podem aparecer em qualquer
parte da rea que lhe foi destinada. Os itens de menu de um menu flutuante podem ter as mesmas
caractersticas de um menu normal: ser apresentados na forma de caixa de seleo ou boto de
rdio, com imagem associada, com teclas de atalho e teclas aceleradoras.
import
import
import
import

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

public class AplicacaoMDI extends JFrame implements ActionListener


{

74

private
private
private
private
private
private
private

JDesktopPane DPane;
JPopupMenu Menu;
JButton abreFrameUm;
JButton abreFrameDois;
JButton sair;
JInternalFrame IFrameUm;
JInternalFrame IFrameDois;

public AplicacaoMDI()
{
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e){System.exit(0);}});
setSize(500,400);
setLocation(100,50);
setTitle("Aplicao MDI com Barra de Ferramentas e Menu Flutuante");
//criao do menu
JMenuBar BarraMenu = new JMenuBar();
setJMenuBar(BarraMenu);
JMenu menuArquivo = new JMenu("Arquivo");
menuArquivo.setMnemonic('A');
JMenuItem itemAbrirUm = new JMenuItem("Abrir Frame Interno Um...",
new ImageIcon("EstrelaUm.gif"));
itemAbrirUm.setMnemonic('U');
JMenuItem itemAbrirDois= new JMenuItem("Abrir Frame Interno Dois...",
new ImageIcon("EstrelaDois.gif"));
itemAbrirDois.setMnemonic('D');
JMenuItem itemSair= new JMenuItem("Sair",
new ImageIcon("Sair.gif"));
itemSair.setMnemonic('r');
itemSair.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R,
InputEvent.ALT_MASK));;
menuArquivo.add(itemAbrirUm);
menuArquivo.add(itemAbrirDois);
menuArquivo.addSeparator();
menuArquivo.add(itemSair);
BarraMenu.add(menuArquivo);
itemAbrirUm.addActionListener(this);
itemAbrirDois.addActionListener(this);
itemSair.addActionListener(this);
//criao da barra de ferramentas
JToolBar barra = new JToolBar();
abreFrameUm = new JButton(new ImageIcon("EstrelaUm.gif"));
abreFrameUm.setToolTipText("Abre o Frame Interno Um");
abreFrameDois = new JButton(new ImageIcon("EstrelaDois.gif"));
abreFrameDois.setToolTipText("Abre o Frame Interno Dois");
sair = new JButton(new ImageIcon("Sair.gif"));
sair.setToolTipText("Encerra a aplicao");
barra.add(abreFrameUm);
barra.add(abreFrameDois);
barra.addSeparator();
barra.add(sair);
abreFrameUm.addActionListener(this);
abreFrameDois.addActionListener(this);
sair.addActionListener(this);
Container P = getContentPane();
P.setLayout(new BorderLayout());
P.add(barra,"North");

75

// criao da rea para insero de frames internos


DPane = new JDesktopPane();
DPane.putClientProperty("JDesktopPane.dragMode", "outline");
P.add(DPane,"Center");
}
public void actionPerformed(ActionEvent evt)
{
Object origem = evt.getSource();
String item = evt.getActionCommand();
if (item == "Abrir Frame Interno Um..." || origem == abreFrameUm)
{
IFrameUm = new JInternalFrame("Frame Interno Um",
true, true, true, true);
IFrameUm.setSize(250,150);
IFrameUm.setLocation(50,50);
IFrameUm.setFrameIcon(new ImageIcon("EstrelaUm.gif"));
IFrameUm.setVisible(true);
JButton BotaoFechar = new JButton("Fechar");
BotaoFechar.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
IFrameUm.setClosed(true);
}
catch (PropertyVetoException exc) { }
}
});
Menu = new JPopupMenu();
JMenuItem itemTitulo = new JMenuItem("Alterar Ttulo");
Menu.add(itemTitulo);
itemTitulo.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String retorno = JOptionPane.showInternalInputDialog(IFrameUm,
"Digite novo ttulo", "Entrada",
JOptionPane.QUESTION_MESSAGE);
if (retorno != null)
IFrameUm.setTitle(retorno);
try {
IFrameUm.setSelected(true);
}
catch (PropertyVetoException exc) { }
}
});
Menu.addSeparator();
JMenuItem itemFechar = new JMenuItem("Fechar");
Menu.add(itemFechar);
itemFechar.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
IFrameUm.setClosed(true);
}
catch (PropertyVetoException exc) { }
}
});
IFrameUm.addMouseListener(new MouseAdapter() {
public void mouseReleased(MouseEvent e) {
if (e.isPopupTrigger())

76

Menu.show(e.getComponent(), e.getX(), e.getY());


}
});
Container C = IFrameUm.getContentPane();
C.setLayout(new BorderLayout());
C.add(BotaoFechar,"South");
DPane.add(IFrameUm);
try {
IFrameUm.setSelected(true);
}
catch (PropertyVetoException exc) { }
}
else if (item == "Abrir Frame Interno Dois..." || origem == abreFrameDois)
{
IFrameDois = new JInternalFrame("Frame Interno Dois",
false, true, false, false);
IFrameDois.setSize(250,150);
IFrameDois.setLocation(150,150);
IFrameDois.setFrameIcon(new ImageIcon("EstrelaDois.gif"));
IFrameDois.setVisible(true);
JButton BotaoFechar = new JButton("Fechar");
BotaoFechar.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
IFrameDois.setClosed(true);
}
catch (PropertyVetoException exc) { }
}
});
Container C = IFrameDois.getContentPane();
C.setLayout(new BorderLayout());
C.add(BotaoFechar,"South");
DPane.add(IFrameDois);
try {
IFrameDois.setSelected(true);
}
catch (PropertyVetoException exc) { }
}
else if (item == "Sair" || origem == sair)
System.exit(0);
}
public static void main(String args[])
{
AplicacaoMDI fr = new AplicacaoMDI();
fr.setVisible(true);
}
}

77

Figura 3.20. Aplicao MDI Barra de Menu

A primeira parte do exemplo mostra a criao da barra de menu do frame principal, j adiantando
que os frames internos tambm podem conter barras de menu individuais, o que no o caso do
exemplo. A barra de menu BarraMenu, objeto da classe JMenuBar, definida como barra de
menu do frame principal atravs do setJMenuBar(), e criado um nico menu nessa barra, o
menuArquivo, onde so adicionados os itens de menu apresentados na figura 3.20. O processo de
criao dos itens de menu segue o j visto em sees anteriores.

Figura 3.21. Aplicao MDI Barra de Ferramentas

Aps, a barra de ferramentas mostrada na figura 3.21 criada, e isso feito de maneira simples, a
partir do objeto barra, da classe JToolBar. Ao criar esse objeto, todas as caractersticas
referentes a uma barra de ferramentas so assimiladas, sendo necessrio apenas inserir botes
com imagens atravs do mtodo add(). O tamanho de cada boto proporcional ao tamanho da
imagem e cada um dos botes vai ter um comportamento normal, sendo necessrio adicionar um
ouvinte de eventos (addActionListener()) a eles para virem a executar aes posteriormente.
Na figura, tambm possvel verificar a existncia de uma dica de ferramenta, que aparece
quando o cursor posicionado sobre um componente, para o boto sair, inserido em cada boto
a partir do mtodo setToolTipText(). bom lembrar que qualquer componente que possui
como superclasse a classe JComponent pode possuir uma dica de ferramenta. O separador
existente entre os dois primeiros botes e o ltimo foi adicionado pelo mtodo addSeparator().
Ao final, o objeto barra includo na parte norte do frame.

78

Figura 3.22. Aplicao MDI Mobilidade da Barra de Ferramentas

Entre as caractersticas particulares de uma barra de ferramentas, uma que se destaca a que est
sendo mostrada na figura 3.22, caracterizada pela sua mobilidade. A barra de ferramentas pode
ser arrastada para qualquer uma das bordas do frame, ou ainda pode ser destacada do frame,
sendo criado um frame especfico para ela. Nesse caso, se esse frame for fechado, a barra volta ao
seu lugar de origem.

79

Figura 3.23. Aplicao MDI Frames Internos

Para que seja inserida a capacidade de receber frames internos, como mostra a figura 3.23,
criando assim uma aplicao MDI, necessrio adicionar ao continer um objeto da classe
JDesktopPane(). Foi isso que ocorreu na criao do objeto DPane, que, ao ser adicionado ao
continer, tornou possvel a criao de frames internos.
O mtodo putClientProperty() utilizado em seguida referente ao arrastar dos frames
internos. Como padro, toda vez que se tentar movimentar um frame interno, este redesenhado
a todo momento, enquanto estiver sendo arrastado. Isso pode causar desagrado a usurios que no
tenham um bom equipamento, principalmente no que diz respeito ao vdeo, pois o desempenho
pode no ser satisfatrio. Para evitar isso, o mtodo chamado faz com que, no ato de arrastar,
apenas o contorno aparea e o frame s seja redesenhado na posio final desejada. O Windows,
por exemplo, tem esse procedimento como padro no arrastar de janelas.
No exemplo, os frames internos somente sero criados se um evento ocorrer, seja pela chamada
do item de menu especfico, ou atravs da barra de ferramentas. Ento, no mtodo
actionPerformed(), se for selecionado o item do menu Abrir Frame Interno Um..., ou se
for clicado o primeiro boto da barra de ferramentas, ser mostrrado o primeiro frame interno.
Para isso, foi criado um objeto IFrameUm a partir da classe JInternalFrame, passando cinco
parmetros, seguindo a sintaxe:
JInternalFrame(String titulo,
boolean redimensionar,
boolean fechar,
boolean maximizar,
boolean minimizar)

80

Como todos os parmetro foram passados como true, o frame incorporou todas as
funcionalidades permitidas a ele. Aps, como qualquer outro frame, ele foi configurado atravs
de alguns mtodos:

setSize():

setLocation():

setFrameIcon(): insere

setVisible():

determina o tamanho do frame interno.


determina a localizao do frame interno dentro do frame principal.
um cone no frame interno.

torna o frame interno visvel.

O boto BotaoFechar foi criado, j adicionando um ouvinte de eventos e implementando o


cdigo para fechar o frame interno. O mtodo setClosed() responsvel por fechar o frame
interno, mas necessrio tratar a exceo PropertyVetoException, do pacote java.beans,
pois o frame pode ter problemas na ao de fechar, por algum motivo, e, nesse caso, se a exceo
no for tratada, alm de no fechar, a aplicao seria abortada. O Java tem muito disso, quando a
operao crtica e pode resultar na finalizao forada da aplicao, ele exige o tratamento da
exceo. Se isso no for feito, no possvel executar o mtodo.

Figura 3.24. Aplicao MDI Menu Flutuante

Para esse frame interno, e apenas esse, foi criado um menu flutuante a partir do objeto Menu, da
classe JPopupMenu (figura 3.24). Cada item de menu criado e adicionado ao menu flutuante da

81

mesma maneira que ocorre em um menu normal. No exemplo, no foi criado nenhum menu
muito elaborado, tendo apenas dois itens: itemTitulo e itemFechar. O primeiro tem como ao
a alterao do ttulo do frame pelo setTitle() a partir do retorno do que for digitado na caixa de
dilogo de entrada interna showInternalInputDialog(). Normalmente, quando se utilizam
frames internos, tambm so usadas caixas de dilogo internas. Elas so iguais s normais, mas,
alm do nome, que recebe o termo Internal, permitem criar caixas de dilogo com as mesmas
caractersticas dos frames internos, no sendo frames modais e possuem atuao dentro da rea
definida pelo frame principal.
No ato de fechar a caixa de dilogo, definindo o novo ttulo, o frameUm no volta a ficar
selecionado. Para isso, foi utilizado o mtodo setSelected(), necessitando tambm do
tratamento da exceo PropertyVetoException, pois pode ser que haja alguma rejeio nessa
ao.
O segundo item, o itemFechar, simplesmente executa o mtodo setClosed(), da mesma forma
que foi feito no boto BotaoFechar.
Com os itens criados, necessrio mostrar o menu de alguma forma e isso feito atravs do
mtodo show(). A questo a ser resolvida : onde ele ir ser mostrado? Como a inteno fazer
com que a rea de atuao desse menu flutuante seja somente o frame interno IFrameUm, nele
que foi adicionado um ouvinte de eventos baseado na interface MouseListener e implementado
o mtodo mouseReleased(). Isso porque o menu flutuante vai ser mostrado quando ocorrer uma
ao do mouse. No cdigo da implementao, foi utilizado o mtodo isPopupTrigger() para
verificar se o boto que foi clicado o correspondente ao boto padro para abrir menus
flutuantes da plataforma atual, no caso do Windows, o boto direito. Os parmetros do mtodo
show() envolvem o componente sobre o qual o menu flutuante ir aparecer e as coordenadas do
clique do mouse, que onde o menu flutuante ir ser desenhado
Por fim, criado um continer dentro do frame IFrameUm para receber o boto na parte inferior, o
frame adicionado ao DPane, rea destinada a receber os frames internos e utilizado o
setSelected() para selecionar o frame.
Ainda no actionPerformed(), caso o item do menu selecionado for o Abrir Frame Interno
Dois... ou se for clicado o segundo boto da barra de ferramentas, ser criado o segundo frame
interno (objeto IFrameDois). Os procedimentos de criao e configurao so os mesmos, mas
esse frame mais simples, possuindo o boto fechar e no possuindo o menu flutuante. Tambm
foi setado para false as opes de redimensionar, minimizar e maximizar.
Por fim, se o item do menu selecionado for o Sair ou se for clicado o terceiro boto da barra de
ferramentas, a aplicao ser finalizada, no interessando se existem frames internos abertos ou
no.

3.12 Aplicao com Vrios Frames


Existem situaes em que o estilo de aplicao MDI no aplicvel, e nem desejado. Nesses
casos, as aplicaes devem trabalhar com um frame principal que abre outros frames normais,
no internos, que possuem suas reas de atuao dentro da plataforma utilizada, e no no frame

82

principal, como acontece com os frames internos. O exemplo a seguir ilustra essa situao, com a
criao de dois frames a partir de dois botes localizados no frame principal.
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class VariosFrames extends JFrame implements ActionListener
{
private JButton abreFrameUm;
private JButton abreFrameDois;
private JFrame FrameDois;
public VariosFrames()
{
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e){System.exit(0);}});
setSize(300,200);
setLocation(150,150);
setTitle("Criando Frames");
JPanel painelVF = new JPanel();
abreFrameUm = new JButton("Criar Frame Um");
abreFrameDois = new JButton("Criar Frame Dois");
painelVF.add(abreFrameUm);
painelVF.add(abreFrameDois);
abreFrameUm.addActionListener(this);
abreFrameDois.addActionListener(this);
Container P = getContentPane();
P.add(painelVF);
}
public void actionPerformed(ActionEvent evt)
{
Object origem = evt.getSource();
if (origem == abreFrameUm)
{
FrameUm frame = new FrameUm();
frame.show();
}
if (origem == abreFrameDois)
{
FrameDois = new JFrame();
FrameDois.setTitle("Frame Dois");
FrameDois.setSize(200,100);
FrameDois.setLocation(350,230);
JPanel painelFDois = new JPanel();
painelFDois.setLayout(new BorderLayout());
JButton Fecha = new JButton("Fechar");
painelFDois.add(Fecha,"South");
Container P = FrameDois.getContentPane();
P.add(painelFDois);
Fecha.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
FrameDois.dispose();
}
});
FrameDois.show();

83

}
}
public static void main(String args[])
{
VariosFrames fr = new VariosFrames();
fr.setVisible(true);
}
}
class FrameUm extends JFrame implements ActionListener
{
private JButton Fecha;
public FrameUm()
{
setSize(200,100);
setLocation(50,230);
setTitle("Frame Um");
JPanel painelFUm = new JPanel();
painelFUm.setLayout(new BorderLayout());
Fecha = new JButton("Fechar");
painelFUm.add(Fecha,"South");
Fecha.addActionListener(this);
Container P = getContentPane();
P.add(painelFUm);
}
public void actionPerformed(ActionEvent evt)
{
if (evt.getSource() == Fecha)
{
dispose();
}
}
}

Figura 3.25. Aplicao normal com criao de outros frames

Os dois frames criados tem o mesmo aspecto (figura 3.25), com posicionamento diferente, mas a
criao de cada um diferente. Em primeiro lugar, no frame principal, foram inseridos dois
botes no painel painelVF: abreFrameUm e abreFrameDois. O tratamento do evento de clicar do

84

primeiro boto simplesmente cria uma instncia da classe FrameUm, chamada frame, e mostra
atravs do show().
A classe FrameUm um frame normal, que possui, em seu construtor, a definio do tamanho,
localizao e ttulo, insero de um painel com um boto que, ao ser clicado, executa o mtodo
dispose() para finalizar o frame.
O segundo boto (abreFrameDois) tambm cria uma instncia de um frame, chamada
mas faz isso internamente, sem criar uma classe a parte. Dependendo da
complexidade do frame, isso pode ser um pouco complicado de se fazer, ou pelo menos, o cdigo
fica um pouco mais confuso. Talvez seja uma melhor idia construir uma classe para cada frame
a ser criado.

FrameDois,

Como as duas instncias de frame foram criadas dentro do frame principal, no momento que este
for finalizado, automaticamente os outros frames tambm sero.

3.13 Tabelas
Existem aplicaes que necessitam apresentar dados na forma de tabelas, como o caso de
aplicaes com banco de dados. Em Java, a classe JTable a responsvel pela tarefa de
tratamento de dados em tabelas, permitindo a manipulao de linhas e colunas. As tabelas criadas
a partir dessa classe so extremamente poderosas, possuindo muitos recursos para seu manuseio.
Apesar da complexidade, relativamente fcil criar uma tabela funcional, com um
comportamento pr-definido, como mostra o exemplo a seguir, que cria uma tabela simples.
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class TabelaFormaUm extends JFrame implements ActionListener
{
private JButton BSair;
public TabelaFormaUm()
{
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e){System.exit(0);}});
setSize(500,200);
setLocation(100,50);
setTitle("Tabela - Forma Um");
Container P = getContentPane();
P.setLayout(new BorderLayout());
// criao da tabela
String[] colunas = new String []{"Referncia", "Descrio", "Estoque"};
Object[][] linhas = new Object [][] {
{"01.015", "Televisor 15 polegadas", new Float(50)},
{"03.098", "Geladeira 300 litros", new Float(30)},
{"14.055", "Forno microondas", new Float(15)},
{"08.078", "DVD porttil", new Float(85)},
{"05.150", "Freezer vertical", new Float(25)},
{"10.004", "Aparelho de Som 300W", new Float(60)}};
JTable tabela = new JTable(linhas, colunas);
JScrollPane rolagemTabela = new JScrollPane(tabela);

85

P.add(rolagemTabela,"Center");
// criao do painel de baixo
JPanel pBaixo = new JPanel();
BSair = new JButton("Sair");
pBaixo.add(BSair);
P.add(pBaixo,"South");
BSair.addActionListener(this);
}
public void actionPerformed(ActionEvent evt)
{
Object origem = evt.getSource();
if (origem == BSair)
{
System.exit(0);
}
}
public static void main(String args[])
{
TabelaFormaUm fr = new TabelaFormaUm();
fr.setVisible(true);
}
}

Figura 3.26. Uma tabela simples

A execuo do exemplo apresenta a tabela da figura 3.26. A criao dela foi baseada em um
arranjo bidimensional, e no em um modelo de tabela, como o usual e mais indicado, visto no
exemplo posterior. Os nomes das colunas foram definidos em um arranjo String chamado
colunas. Os dados da tabela so armazenados em um arranjo bidimensional do tipo Object
chamado linhas. O arranjo do tipo Object pelo fato de que possvel ter muitos tipos de
objeto em uma coluna, como um JComboBox, por exemplo.
Aps definir os arranjos, base da construo da tabela, esta criada com a passagem dos
parmetros linhas e colunas, sendo depois inserida em um JScrollPane, para perimitir a
existncia de barras de rolagem, e este, por fim, sendo inserido no continer.
No painel de baixo inserido o boto BSair no painel pBaixo, que possui a tarefa de finalizar a
aplicao.

86

Na execuo, algumas caractersticas so pr-definidas, como:

cabealhos das colunas formatados automaticamente.

largura das colunas distribudas igualmente.

permisso para digitao dos dados, sendo que, se o valor no couber na clula,
reticncias (...) so apresentadas, indicando essa situao.

redimensionamento das colunas, bastando posicionar o cursor na linha separatria de duas


colunas, no cabealho, e arrastar para o local desejado.

seleo de linhas, permitindo a seleo de mltiplas linhas, com a tecla Shift, e de


linhas intercaladas, com a tecla Ctrl.

no caso de existncia de barras de rolagem, apenas os dados da tabela so movimentados,


permanecendo o cabealho em seu lugar de origem.

troca de colunas, onde uma coluna pode ser trocada com outra atravs do ato de arrastarsoltar, com o mouse posicionado no cabealho da coluna desejada.

3.13.1 Modelos de Tabela


Apesar de fcil de ser criada, geralmente a maneira apresentada no primeiro exemplo no a
mais indicada para criao de tabelas. Para que se possa ter maior controle sobre a tabela,
necessrio criar um modelo de tabela, que se responsabilizar em manipular os dados. Tais
modelos so implementados pela interface TableModel (AbstractTableModel e
DefaultTableModel). O exemplo a seguir cria uma tabela com caractersticas particulares,
baseado no DefaultTableModel.
import
import
import
import

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

public class TabelaFormaDois extends JFrame implements ActionListener


{
private JButton btnExcluir;
private JButton btnIncluir;
private JButton btnMostrar;
private JTextField texto;
private JTable tabela;
private int incCod = 0;
public TabelaFormaDois()
{
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e){System.exit(0);}});
setTitle("Tabela - Forma Dois");
setSize(430,250);
setLocation(100,50);
Container P = getContentPane();
P.setLayout(new BorderLayout());

87

String[] tipos = {"Sim","No"};


JComboBox cbAtivo = new JComboBox(tipos);
tabela = new JTable();
tabela.setModel(new DefaultTableModel(
new Object [][] { },
new String [] {
"ID", "Nome", "Sobrenome", "Limite", "Ativo"
}
));
tabela.getColumnModel().getColumn(0).setPreferredWidth(20);
tabela.getColumnModel().getColumn(0).setResizable(false);
tabela.getColumnModel().getColumn(1).setPreferredWidth(150);
tabela.getColumnModel().getColumn(1).setResizable(true);
tabela.getColumnModel().getColumn(2).setPreferredWidth(150);
tabela.getColumnModel().getColumn(2).setResizable(true);
tabela.getColumnModel().getColumn(3).setPreferredWidth(60);
tabela.getColumnModel().getColumn(3).setResizable(true);
tabela.getColumn(tabela.getColumnName(4)).setCellEditor
(new DefaultCellEditor(cbAtivo));
tabela.getColumnModel().getColumn(4).setPreferredWidth(50);
tabela.getColumnModel().getColumn(4).setResizable(true);
tabela.getTableHeader().setReorderingAllowed(false);
tabela.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
JScrollPane rolagemTabela = new JScrollPane(tabela);
P.add(rolagemTabela,"Center");
// criao do Painel de baixo
JPanel PTabSul = new JPanel();
btnIncluir = new JButton("Incluir");
PTabSul.add(btnIncluir);
btnExcluir = new JButton("Excluir");
PTabSul.add(btnExcluir);
btnMostrar = new JButton("Mostrar");
PTabSul.add(btnMostrar);
texto = new JTextField("Nome Selecionado");
PTabSul.add(texto);
P.add(PTabSul, "South");
btnExcluir.addActionListener(this);
btnIncluir.addActionListener(this);
btnMostrar.addActionListener(this);
}
public void actionPerformed(ActionEvent evt)
{
Object origem = evt.getSource();
if (origem == btnIncluir)
{
DefaultTableModel dtm = (DefaultTableModel)tabela.getModel();
dtm.addRow(new Object[]{
new Integer(++incCod),
"Cliente " + incCod,
"Endereo " + incCod,
new Double(999.99),
"Sim"
});
}
if (origem == btnExcluir)
{

88

int linhas[] = tabela.getSelectedRows();


DefaultTableModel dtm = (DefaultTableModel)tabela.getModel();
for(int i = (linhas.length - 1); i >= 0; i--)
dtm.removeRow(linhas[i]);
}
if (origem == btnMostrar)
{
if (tabela.getSelectedRow()>=0)
texto.setText(tabela.getValueAt
(tabela.getSelectedRow(),1).toString());
}
}
public static void main(String args[]) {
TabelaFormaDois fr = new TabelaFormaDois();
fr.setVisible(true);
}
}

Figura 3.27. Uma tabela baseada no DefaultTableModel

A figura 3.26 apresenta o resultado da execuo aps clicar em alguns botes. A tabela foi criada
normalmente, baseada no JTable. Aps isso, foi setado o modelo pelo mtodo setModel(), cujo
parmetro a criao de um objeto DefaultTableModel, iniciando com um arranjo
bidimensional vazio e um arranjo String com os nomes das colunas. Nenhum dado
apresentado inicialmente porque isso uma tarefa do boto Incluir.
Para cada coluna foi configurado o seu tamanho, a partir do mtodo setPreferredWidth() e se
redimensinvel ou no, a partir do mtodo setResizable(). A coluna Ativo diferente das
demais, pois apresenta um caixa de seleo. Para que isso seja possvel, foi definido um objeto
cbAtivo, do tipo JComboBox, que, posteriormente, foi inserido na tabela a partir do mtodo
setCellEditor().
As

colunas

deixaram

de ser passveis de reorganizao a partir do mtodo


setReorderingAllowed(), setado para false. O mtodo setAutoResizeMode() configura o
modo de redimensionamento automtico das colunas da tabela, sendo que o AUTO_RESIZE_OFF
desliga esse redimensionamento. Os outros modos existentes so:

89

AUTO_RESIZE_NEXT_COLUMN: redimensiona apenas a prxima coluna.


AUTO_RESIZE_SUBSEQUENT_COLUMNS:

redimensiona todas as colunas subseqentes, sendo

o padro.

AUTO_RESIZE_LAST_COLUMN: redimensiona apenas a ltima coluna.

AUTO_RESIZE_ALL_COLUMNS: redimensiona todas

as colunas da tabela.

Aps, a tabela inserida em um JScrollPane, para perimitir a existncia de barras de rolagem, e


este, por fim, inserido no continer.
O painel de baixo contm trs botes e uma caixa de texto. O primeiro boto, Incluir, ao ser
clicado, utiliza o mtodo getModel() para criar o objeto dtm, do tipo DefaultTableModel. Tal
objeto possui o mtodo addRow(), que usado para inserir uma linha na tabela, sempre com os
mesmos campos, apenas mudando a numerao, controlada pela varivel inteira incCod. O
segundo boto, Excluir, tambm cria um objeto dtm, alm de utilizar o getSelectedRows()
para alimentar o arranjo int linhas com as linhas selecionadas. Um for percorrendo as linhas
selecionadas foi feito para exclu-las a partir do mtodo removeRow(). Por fim, o terceiro boto,
Mostrar, mostra na caixa de texto o contedo da clula 1 (Nome) da linha selecionada
(getSelectedRow()). Isso capturado a partir do mtodo getValueAt().
3.13.2 Modelo AbstractTableModel
A classe DefaultTableModel uma classe com mtodos bsicos para trabalhar com os dados da
JTable. Uma opo mais avanada criar uma classe prpria, estendendo a classe
AbstractTableModel, que fornece diversos mtodos prontos, exceto:

public Object getValueAt(int row, int col):

retorna o objeto contido na clula

determinado por row e col.

public int getRowCount():

public int getColumnCount():

retorna o nmero de linhas da tabela.


retorna o nmero de colunas da tabela.

A classe criada o prprio modelo da tabela e os mtodos apresentados devem ser


implementados, obrigatoriamente. Muitos outros mtodos existem, e eles podem ser sobrepostos
para realizar as aes desejadas para a tabela especfica. Por exemplo, o mtodo
getColumnName() atribuir os nomes A, B, C, etc. aos nomes das colunas, a no ser que ele seja
sobreposto para que atribua nomes significativos.
Assim, necessrio sobrepor os mtodos existentes na classe AbstractTableModel da melhor
forma possvel, para que atenda s necessidades do modelo especfico da tabela que ser
implementada. Na verdade, uma vez tendo o modelo bem elaborado, possvel utiliza-lo na
criao de vrias tabelas. O cdigo a seguir implementa vrias sobreposies de mtodos para
exemplificar a criao de um modelo e de uma tabela baseada nesse modelo.
import javax.swing.*;
import javax.swing.table.*;

90

import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class TabelaFormaTres extends JFrame implements ActionListener
{
private JButton btnExcluir;
private JButton btnIncluir;
private JButton btnMostrar;
private JButton btnAlterar;
private JButton btnMostrarClasse;
private JTextField texto;
private JTable tabela;
private int incCod = 0;
private ModeloTabela modelo;
public TabelaFormaTres()
{
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e){System.exit(0);}});
setTitle("Tabela - Forma Trs");
setSize(600,250);
setLocation(100,50);
Container P = getContentPane();
P.setLayout(new BorderLayout());
// criao de um arranjo sem tamanho definido para insero
// dinmica de objetos
ArrayList dados = new ArrayList();
// criao de um arranjo para os ttulos no cabealho
String[] colunas = new String[] { "ID", "Nome", "Sobrenome",
"Limite", "Ativo" };
// criao de um arranjo para identificar se a clula editvel ou no
boolean[] edicao = {false, true, true, false, true};
// Insero da primeira linha da tabela
dados.add(new Object[]{
new Integer(++incCod),
"Cliente " + incCod,
"Endereo " + incCod,
new Double(999.99),
new Boolean(true)
});
// criao da tabela baseada no modelo ModeloTabela
modelo = new ModeloTabela(dados, colunas, edicao);
tabela = new JTable(modelo);
tabela.getColumnModel().getColumn(0).setPreferredWidth(50);
tabela.getColumnModel().getColumn(0).setResizable(false);
tabela.getColumnModel().getColumn(1).setPreferredWidth(200);
tabela.getColumnModel().getColumn(1).setResizable(true);
tabela.getColumnModel().getColumn(2).setPreferredWidth(200);
tabela.getColumnModel().getColumn(2).setResizable(true);
tabela.getColumnModel().getColumn(3).setPreferredWidth(80);
tabela.getColumnModel().getColumn(3).setResizable(true);
tabela.getColumnModel().getColumn(4).setPreferredWidth(55);
tabela.getColumnModel().getColumn(4).setResizable(true);
tabela.getTableHeader().setReorderingAllowed(false);
tabela.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
tabela.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

91

JScrollPane rolagemTabela = new JScrollPane(tabela);


P.add(rolagemTabela,"Center");
// criao do Painel de baixo
JPanel PTabSul = new JPanel();
btnIncluir = new JButton("Incluir");
PTabSul.add(btnIncluir);
btnExcluir = new JButton("Excluir");
PTabSul.add(btnExcluir);
btnMostrar = new JButton("Mostrar");
PTabSul.add(btnMostrar);
btnAlterar = new JButton("Alterar");
PTabSul.add(btnAlterar);
btnMostrarClasse = new JButton("Classe");
PTabSul.add(btnMostrarClasse);
texto = new JTextField(15);
PTabSul.add(texto);
P.add(PTabSul, "South");
btnExcluir.addActionListener(this);
btnIncluir.addActionListener(this);
btnMostrar.addActionListener(this);
btnAlterar.addActionListener(this);
btnMostrarClasse.addActionListener(this);
}
public void actionPerformed(ActionEvent evt)
{
Object origem = evt.getSource();
if (origem == btnIncluir)
{
modelo.addRow(new Object[]{
new Integer(++incCod),
"Cliente " + incCod,
"Endereo " + incCod,
new Double(999.99),
new Boolean(true)
});
}
if (origem == btnExcluir)
{
modelo.removeRow(tabela.getSelectedRow());
}
if (origem == btnMostrar)
{
if (tabela.getSelectedRow()>=0)
texto.setText(modelo.getValueAt(tabela.getSelectedRow(),
tabela.getSelectedColumn()).toString());
}
if (origem == btnAlterar)
{
if (tabela.getSelectedRow()>=0)
modelo.setValueAt(texto.getText(),tabela.getSelectedRow(),
tabela.getSelectedColumn());
}
if (origem == btnMostrarClasse)
{
if (tabela.getSelectedRow()>=0)
texto.setText(modelo.getColumnClass(

92

tabela.getSelectedColumn()).toString());
}
}
public static void main(String args[])
{
TabelaFormaTres fr = new TabelaFormaTres();
fr.setVisible(true);
}
}
class ModeloTabela extends AbstractTableModel
{
private ArrayList linhas = null;
private String[] colunas = null;
private boolean[] colEditavel;
public ModeloTabela(ArrayList lin, String[] col, boolean[] editavel)
{
setLinhas(lin);
setColunas(col);
colEditavel = editavel;
}
public ArrayList getLinhas()
{
return linhas;
}
public void setLinhas(ArrayList dados)
{
linhas = dados;
}
public String[] getColunas()
{
return colunas;
}
public void setColunas(String[] nomes)
{
colunas = nomes;
}
public int getColumnCount()
{
return colunas.length;
}
public int getRowCount()
{
return linhas.size();
}
public String getColumnName(int numCol)
{
return colunas[numCol];

93

}
public boolean isCellEditable(int numCol)
{
return colEditavel[numCol];
}
public Object getValueAt(int numLin, int numCol)
{
Object[] linha = (Object[])getLinhas().get(numLin);
return linha[numCol];
}
public void setValueAt(Object dado, int numLin, int numCol)
{
if (isCellEditable(numCol))
{
Object[] linha = (Object[])getLinhas().get(numLin);
linha[numCol] = dado;
fireTableDataChanged();
}
}
public void addRow(Object[] dados)
{
getLinhas().add(dados);
fireTableDataChanged();
}
public void removeRow(int numLin)
{
getLinhas().remove(numLin);
fireTableDataChanged();
}
public Class getColumnClass(int numCol)
{
Object[] linha = (Object[])getLinhas().get(0);
return linha[numCol].getClass();
}
}

94

Figura 3.28. Uma tabela baseada no modelo criado a partir do AbstractTableModel

Antes de tudo, importante entender a classe ModeloTabela, que derivada de


AbstractTableModel. O contedo das linhas armazenado em um objeto linhas, do tipo
ArrayList. Um ArrayList permite armazenar qualquer tipo de objeto de uma forma dinmica,
ou seja, no necessrio determinar o tamanho dele na sua declarao. Assim, ser possvel
inserir ou excluir linhas a qualquer momento.
Dois outros arranjos so criados: colunas, do tipo String, que armazena o nome das colunas, a
ser mostrado no cabealho da tabela e; colEditavel, do tipo boolean, que armazena true ou
false, conforme a coluna possa ser editvel ou no.
Os primeiros quatro mtodos realizam o tratamento dos dados dos arranjos linhas e colunas. So
eles:

public void setLinhas(ArrayList dados):

public ArrayList getLinhas():

public void setColunas(String[] nomes): alimenta o

public String[] getColunas():

alimenta o arranjo das linhas

retorna o arranjo das linhas.


arranjo das colunas.

retorna o arranjo das colunas.

O contrutor da classe recebe trs parmetros: um ArrayList, para iniciar a tabela com as linhas
desejadas; um arranjo String, que so os nomes das colunas, e; um arranjo boolean, com a
indicao da possibilidade de edio de cada uma das colunas. No momento da instanciao em
alguma aplicao, esses dados devem ser passados para que a tabela tenha uma situao inicial.
Como explicado anteriormente, os nomes das colunas no seriam atribudos se no fosse
sobreposto o mtodo getColumnName(), que retorna exatamente o contedo atribudo ao arranjo
colunas. Alm disso, os dois mtodos obrigatrios getRowCount()e getColumnCount() so
implementados, retornando o nmero de linhas e colunas do modelo.
Os demais mtodos implementados so:

95

public boolean isCellEditable(int numCol):

retorna true se a coluna numCol for

editvel, e false, caso contrrio.

public Object getValueAt(int numLin, int numCol): Implementao


Obtm o valor contido na clula de coordenadas numLin, numCol.

public void setValueAt(Object dado, int numLin, int numCol): define um


novo valor para a clula de coordenadas numLin, numCol, se esta for editvel (testado a
partir do mtodo isCellEditable()). Percebe-se que, aps inserido o objeto na clula,
invocado o mtodo fireTableDataChanged(), que tem a funo de realizar a efetiva

obrigatria.

alterao dos dados da tabela.

public void addRow(Object[] dados):

inclui uma linha na tabela a partir de um

arranjo de objetos.

public void removeRow(int numLin):

public Class getColumnClass(int numCol):


coluna numCol.

exclui a linha numLin da tabela.


retorna a classe do objeto contido na

A criao da tabela baseada nesse modelo, que resulta na aplicao mostrada na figura 3.28,
feita na classe TabelaFormaTres. O ArrayList dados criado e adicionado a ele apenas uma
nica linha, que um arranjo de vrios objetos de tipos diferentes. Alm de dados, o arranjo
colunas criado e alimentado com os nomes das colunas da tabela; e o arranjo edicao criado
com a indicao se cada coluna editvel ou no.
Tais arranjos so passados como parmetro na criao do objeto da classe ModeloTabela,
explicado anteriormente, chamado modelo, e este serve como parmetro na criao da JTable.
Aps, como no exemplo anterior, so definidos os tamanhos de cada coluna
(setPreferredWidth()), e se elas so redimensionveis ou no (setResizable()). Tambm
igualmente ao exemplo anterior, as colunas deixam de ser reorganizveis, a partir do mtodo
setReorderingAllowed(), setado para false, e configurado o modo de redimensionamento
automtico das colunas da tabela, a partir do mtodo setAutoResizeMode().
Adicionalmente, o setSelectionMode() determina que s possvel selecionar uma linha por
vez
(SINGLE_SELECTION).
Os
outros
dois
valores
possveis
so:
MULTIPLE_INTERVAL_SELECTION, que permite a seleo de uma ou mais linhas, de forma
contgua ou no, e; SINGLE_INTERVAL_SELECTION, que permite a seleo de uma ou mais linhas,
desde que seja de forma contgua.
A tabela criada , ento, jogada em um JScrollPane e esse no continer. Aps, os botes
Incluir, Excluir, Mostrar, Alterar e Classe so inseridos, alm do JTextField texto. As
aes desses botes foram implementadas no ActionPerformed:

Incluir:

utiliza o mtodo addRow() do modelo para incluir uma nova linha no final da

tabela.

96

Excluir: utiliza o mtodo removeRow() do modelo para excluir a linha que est
selecionada, capturada a partir do mtodo getSelectedRow().

Mostrar:

mostra o contedo da clula no campo texto, caso haja uma linha selecionada.
Isso feito pelo mtodo getValueAt(), passando como parmetro o nmero da linha
(getSelectedRow()) e coluna (getSelectedColumn()) referente clula selecionada.

Alterar: Se houver linha selecionada, o contedo da clula selecionada alterado pelo


valor contido no campo texto, a partir do mtodo setValueAt().

Classe: utiliza o mtodo getSelectedColumn() para capturar a classe da clula


selecionada, mostrando no campo texto.

3. Banco de Dados: Conectividade Utilizando JDBC


A pa
import
import
import
import
import
import

javax.swing.*;
java.awt.*;
java.awt.event.*;
java.util.*;
java.sql.*;
javax.swing.border.*;

public class CriaTabelas extends JFrame implements ActionListener


{
private JButton btnExcluir;
private JButton btnIncluir;
private JButton btnLimpar;
private JButton btnConectar;
private JButton btnDesconectar;
private JButton btnCriar;
private JTextField nomeCampo;
private JTextField tipoCampo;
private JTextField fonteDados;
private JTextField usuario;
private JPasswordField senha;
private JTextField nomeTabela;
private JList lista;
private Vector campos;
private JLabel lblCon;
private Connection con;
private String chavePrimaria;
public CriaTabelas()
{
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e){System.exit(0);}});
setTitle("Wizard para criao de tabelas de BD");
setSize(500,320);
setLocation(100,100);
Container P = getContentPane();
P.setLayout(new BorderLayout());
campos = new Vector();

97

// criao do primeiro painel


JPanel PNorte = new JPanel();
PNorte.setLayout(new BorderLayout());
JPanel PNorteNorte = new JPanel();
PNorteNorte.add(new JLabel("Fonte de Dados"));
fonteDados = new JTextField(13);
PNorteNorte.add(fonteDados);
PNorteNorte.add(new JLabel("Usurio"));
usuario = new JTextField(7);
PNorteNorte.add(usuario);
PNorteNorte.add(new JLabel("Senha"));
senha = new JPasswordField(5);
PNorteNorte.add(senha);
PNorte.add(PNorteNorte,"North");
JPanel PNorteCentro = new JPanel();
btnConectar = new JButton("Conectar Banco");
btnConectar.addActionListener(this);
PNorteCentro.add(btnConectar);
lblCon = new JLabel("No Conectado");
PNorteCentro.add(lblCon);
btnDesconectar = new JButton("Desconectar Banco");
btnDesconectar.addActionListener(this);
PNorteCentro.add(btnDesconectar);
PNorte.add(PNorteCentro,"Center");
P.add(PNorte, "North");
// criao do segundo painel
JPanel PCentro = new JPanel();
PCentro.add(new JLabel("Nome da Tabela"));
nomeTabela = new JTextField(10);
PCentro.add(nomeTabela);
lista = new JList();
lista.setVisibleRowCount(8);
lista.setFixedCellWidth(200);
lista.setFixedCellHeight(15);
lista.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
PCentro.add(new JScrollPane(lista));
btnCriar = new JButton("Criar Tabela");
btnCriar.addActionListener(this);
PCentro.add(btnCriar);
btnLimpar = new JButton("Limpar lista");
btnLimpar.addActionListener(this);
PCentro.add(btnLimpar);
Border borda = BorderFactory.createEtchedBorder();
PCentro.setBorder(borda);
P.add(PCentro, "Center");
// criao do terceiro painel
JPanel PSul = new JPanel();
PSul.add(new JLabel("Nome"));
nomeCampo = new JTextField(10);
PSul.add(nomeCampo);
PSul.add(new JLabel("Tipo"));
tipoCampo = new JTextField(10);
PSul.add(tipoCampo);
btnIncluir = new JButton("Incluir");
PSul.add(btnIncluir);
btnExcluir = new JButton("Excluir");
PSul.add(btnExcluir);

98

P.add(PSul, "South");
btnExcluir.addActionListener(this);
btnIncluir.addActionListener(this);
}
public void actionPerformed(ActionEvent evt)
{
Object origem = evt.getSource();
if (origem == btnConectar)
{
String sFonte = "jdbc:odbc:" + fonteDados.getText().trim();
String sUsuario = usuario.getText().trim();
String sSenha = senha.getText().trim();
try {
System.setProperty("jdbc.drivers","sun.jdbc.odbc.JdbcOdbcDriver");
con = DriverManager.getConnection(sFonte, sUsuario, sSenha);
JOptionPane.showMessageDialog(this,
"Banco conectado com sucesso!",
"Mensagem", JOptionPane.WARNING_MESSAGE);
lblCon.setText("Conectado");
}catch (SQLException eSQL) {
// excees de SQL
eSQL.printStackTrace();
JOptionPane.showMessageDialog(this,
"Falha na conexo com o banco!\n" +
"Mensagem: " + eSQL.getMessage(),
"Erro", JOptionPane.ERROR_MESSAGE);
}catch (Exception e) {
// demais excees
e.printStackTrace();
JOptionPane.showMessageDialog(this,
"Falha na conexo com o banco!\n" +
"Mensagem: " + e.getMessage(),
"Erro", JOptionPane.ERROR_MESSAGE);
}
}
if (origem == btnDesconectar)
{
try {
con.close();
lblCon.setText("Desconectado");
}catch (SQLException eSQL) {
// excees de SQL
eSQL.printStackTrace();
JOptionPane.showMessageDialog(this,
"No foi possvel desconectar o banco!\n" +
"Mensagem: " + eSQL.getMessage(),
"Erro", JOptionPane.ERROR_MESSAGE);
}
}
if (origem == btnIncluir)
{
String item = nomeCampo.getText() + " " + tipoCampo.getText();
if (campos.isEmpty())
{
JOptionPane.showMessageDialog(this,
"O primeiro campo ser a chave primria da tabela",

99

"Mensagem", JOptionPane.WARNING_MESSAGE);
chavePrimaria = nomeCampo.getText();
}
campos.addElement(item);
lista.setListData(campos);
}
if (origem == btnExcluir)
{
if (lista.getSelectedIndex()>= 0)
{
campos.removeElementAt(lista.getSelectedIndex());
lista.setListData(campos);
}
}
if (origem == btnLimpar)
{
campos.removeAllElements();
lista.setListData(campos);
}
if (origem == btnCriar)
{
String itens = campos.toString();
itens = itens.substring(1,itens.length()-1);
String sentencaSQL = "CREATE TABLE " +
nomeTabela.getText().trim() + " (" + itens +
", PRIMARY KEY (" + chavePrimaria + "))" ;
try{
Statement st = con.createStatement();
st.executeUpdate(sentencaSQL);
JOptionPane.showMessageDialog(this,
"Tabela criada com sucesso!",
"Mensagem", JOptionPane.WARNING_MESSAGE);
}catch (SQLException eSQL) {
eSQL.printStackTrace();
JOptionPane.showMessageDialog(this,
"No foi possvel criar a tabela!\n" +
"Mensagem: " + eSQL.getMessage(),
"Erro", JOptionPane.ERROR_MESSAGE);
}
}
}
public static void main(String args[])
{
CriaTabelas fr = new CriaTabelas();
fr.setVisible(true);
}
}

100

A
import
import
import
import
import
import

javax.swing.*;
java.awt.*;
java.awt.event.*;
java.sql.*;
java.util.*;
javax.swing.table.*;

public class Consulta extends JFrame implements ActionListener


{
private JButton btnSair;
private JButton btnPesqNome;
private JButton btnPesqCod;
private JTextField nome;
private JTextField codigo;
private Connection con;
private ModeloTabelaBD modelo;
private JTable tabela;
private Statement sentenca;
private ResultSet registros;
public Consulta()
{
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e){System.exit(0);}});
setTitle("Consulta a Banco de Dados");
setSize(500,320);
setLocation(100,100);
Container P = getContentPane();
P.setLayout(new BorderLayout());
// conecta o banco
con = conectaBanco("jdbc:odbc:ODBCBancoExemplo", null, null);
// criao do primeiro painel
JPanel PNorte = new JPanel();

101

PNorte.setLayout(new BorderLayout());
JPanel PNorteNorte = new JPanel();
PNorteNorte.add(new JLabel("Digite nome"));
nome = new JTextField(13);
PNorteNorte.add(nome);
btnPesqNome = new JButton("Pesquisar por nome");
PNorteNorte.add(btnPesqNome);
btnPesqNome.addActionListener(this);
PNorte.add(PNorteNorte,"North");
JPanel PNorteCentro = new JPanel();
PNorteCentro.add(new JLabel("Digite cdigo"));
codigo = new JTextField(7);
PNorteCentro.add(codigo);
btnPesqCod = new JButton("Pesquisar por cdigo");
PNorteCentro.add(btnPesqCod);
PNorte.add(PNorteCentro,"Center");
btnPesqCod.addActionListener(this);
P.add(PNorte, "North");
// criao da tabela
// criao de um array para insero dinmica de objetos
ArrayList dados = new ArrayList();
// criao de um array para os ttulos no cabealho
String[] colunas = new String[] { "Cdigo", "Nome", "Endereo"};
// criao de um array para identificar se a clula editvel ou no
boolean[] edicao = {false, false, false};
// seleciona todos os registros da tabela Clientes e joga no ArrayList
try {
String sentencaSQL = "SELECT * FROM Clientes ORDER BY Codigo";
sentenca = con.createStatement();
registros = sentenca.executeQuery(sentencaSQL);
boolean proximoRegistro = registros.next();
if (!proximoRegistro)
{
JOptionPane.showMessageDialog(this,
"Nenhum registro foi encontrado!",
"Mensagem", JOptionPane.WARNING_MESSAGE);
}
else
do {
dados.add(new Object[]{
new Integer(Integer.parseInt(registros.getString("Codigo"))),
registros.getString("Nome"),
registros.getString("Endereco")
});
} while (registros.next());
sentenca.close();
}catch (SQLException eSQL) {
eSQL.printStackTrace();
JOptionPane.showMessageDialog(this,
"No foi possvel carregar os dados!\n" +
"Mensagem: " + eSQL.getMessage(),
"Erro", JOptionPane.ERROR_MESSAGE);
}
// criao da tabela baseada no modelo ModeloTabelaBD
modelo = new ModeloTabelaBD(dados, colunas, edicao);
tabela = new JTable(modelo);
tabela.getColumnModel().getColumn(0).setPreferredWidth(50);

102

tabela.getColumnModel().getColumn(0).setResizable(false);
tabela.getColumnModel().getColumn(1).setPreferredWidth(200);
tabela.getColumnModel().getColumn(1).setResizable(true);
tabela.getColumnModel().getColumn(2).setPreferredWidth(240);
tabela.getColumnModel().getColumn(2).setResizable(true);
tabela.getTableHeader().setReorderingAllowed(false);
tabela.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
tabela.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
JScrollPane rolagemTabela = new JScrollPane(tabela);
P.add(rolagemTabela, "Center");
// criao do terceiro painel
JPanel PSul = new JPanel();
btnSair = new JButton("Sair");
PSul.add(btnSair);
P.add(PSul, "South");
btnSair.addActionListener(this);
}
public void actionPerformed(ActionEvent evt)
{
Object origem = evt.getSource();
if (origem == btnPesqNome)
{
Selecao("SELECT * FROM Clientes WHERE NOME LIKE '%" +
nome.getText() + "%' ORDER BY NOME");
}
if (origem == btnPesqCod)
{
Selecao("SELECT * FROM Clientes WHERE CODIGO = " +
codigo.getText() + " ORDER BY CODIGO");
}
if (origem == btnSair)
{
try {
con.close();
System.exit(0);
}catch (SQLException eSQL) {
// excees de SQL
eSQL.printStackTrace();
JOptionPane.showMessageDialog(this,
"No foi possvel desconectar o banco!\n" +
"Mensagem: " + eSQL.getMessage(),
"Erro", JOptionPane.ERROR_MESSAGE);
}
}
}
public void Selecao(String sentencaSQL)
{
// apaga todas as linhas da tabela
for (int i= modelo.getRowCount()-1; i >= 0; i--)
modelo.removeRow(i);
try {
sentenca = con.createStatement();
registros = sentenca.executeQuery(sentencaSQL);
boolean proximoRegistro = registros.next();
if (!proximoRegistro)

103

{
JOptionPane.showMessageDialog(this,
"Nenhum registro foi encontrado!",
"Mensagem", JOptionPane.WARNING_MESSAGE);
}
else
do {
modelo.addRow(new Object[]{
new Integer(Integer.parseInt(registros.getString("Codigo"))),
registros.getString("Nome"),
registros.getString("Endereco")
});
} while (registros.next());
sentenca.close();
}catch (SQLException eSQL) {
eSQL.printStackTrace();
JOptionPane.showMessageDialog(this,
"No foi possvel carregar os dados!\n" +
"Mensagem: " + eSQL.getMessage(),
"Erro", JOptionPane.ERROR_MESSAGE);
}
}
public Connection conectaBanco(String sFonte,String sUsuario,String sSenha)
{
Connection conexao = null;
try {
System.setProperty("jdbc.drivers","sun.jdbc.odbc.JdbcOdbcDriver");
conexao = DriverManager.getConnection(sFonte, sUsuario, sSenha);
}catch (SQLException eSQL) {
// excees de SQL
eSQL.printStackTrace();
JOptionPane.showMessageDialog(this,
"Falha na conexo com o banco!\n" +
"Mensagem: " + eSQL.getMessage(),
"Erro", JOptionPane.ERROR_MESSAGE);
}catch (Exception e) {
// demais excees
e.printStackTrace();
JOptionPane.showMessageDialog(this,
"Falha na conexo com o banco!\n" +
"Mensagem: " + e.getMessage(),
"Erro", JOptionPane.ERROR_MESSAGE);
}
return conexao;
}
public static void main(String args[])
{
Consulta fr = new Consulta();
fr.setVisible(true);
}
}
class ModeloTabelaBD extends AbstractTableModel
{
private ArrayList linhas = null;

104

private String[] colunas = null;


private boolean[] colEditavel;
public ModeloTabelaBD(ArrayList lin, String[] col, boolean[] editavel)
{
setLinhas(lin);
setColunas(col);
colEditavel = editavel;
}
public ArrayList getLinhas()
{
return linhas;
}
public void setLinhas(ArrayList dados)
{
linhas = dados;
}
public String[] getColunas()
{
return colunas;
}
public void setColunas(String[] nomes)
{
colunas = nomes;
}
public int getColumnCount()
{
return colunas.length;
}
public int getRowCount()
{
return linhas.size();
}
public String getColumnName(int numCol)
{
return colunas[numCol];
}
public boolean isCellEditable(int numCol)
{
return colEditavel[numCol];
}
public Object getValueAt(int numLin, int numCol)
{
Object[] linha = (Object[])getLinhas().get(numLin);
return linha[numCol];
}
public void setValueAt(Object dado, int numLin, int numCol)

105

{
if (isCellEditable(numCol))
{
Object[] linha = (Object[])getLinhas().get(numLin);
linha[numCol] = dado;
fireTableDataChanged();
}
}
public void addRow(Object[] dados)
{
getLinhas().add(dados);
fireTableDataChanged();
}
public void removeRow(int numLin)
{
getLinhas().remove(numLin);
fireTableDataChanged();
}
public Class getColumnClass(int numCol)
{
Object[] linha = (Object[])getLinhas().get(0);
return linha[numCol].getClass();
}
}

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

106

import
import
import
import

java.awt.event.*;
java.sql.*;
java.util.*;
javax.swing.table.*;

public class Cadastro extends JFrame implements ActionListener


{
private JButton btnSair;
private JButton btnIncluir;
private JButton btnAlterar;
private JButton btnExcluir;
private JButton btnPesqNome;
private JTextField nome;
private Connection con;
private ModeloTabelaBD modelo;
private JTable tabela;
private Statement sentenca;
private ResultSet registros;
public Cadastro()
{
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e){System.exit(0);}});
setTitle("Consulta a Banco de Dados");
setSize(500,320);
setLocation(100,100);
Container P = getContentPane();
P.setLayout(new BorderLayout());
// conecta o banco
con = conectaBanco("jdbc:odbc:ODBCBancoExemplo", null, null);
// criao do primeiro painel
JPanel PNorte = new JPanel();
PNorte.setLayout(new FlowLayout());
PNorte.add(new JLabel("Digite nome"));
nome = new JTextField(13);
PNorte.add(nome);
btnPesqNome = new JButton("Pesquisar");
PNorte.add(btnPesqNome);
btnPesqNome.addActionListener(this);
P.add(PNorte, "North");
// criao da tabela
// criao de um array para insero dinmica de objetos
ArrayList dados = new ArrayList();
// criao de um array para os ttulos no cabealho
String[] colunas = new String[] { "Cdigo", "Nome", "Endereo"};
// criao de um array para identificar se a clula editvel ou no
boolean[] edicao = {false, false, false};
// criao da tabela baseada no modelo ModeloTabelaBD
modelo = new ModeloTabelaBD(dados, colunas, edicao);
tabela = new JTable(modelo);
tabela.getColumnModel().getColumn(0).setPreferredWidth(50);
tabela.getColumnModel().getColumn(0).setResizable(false);
tabela.getColumnModel().getColumn(1).setPreferredWidth(200);
tabela.getColumnModel().getColumn(1).setResizable(true);
tabela.getColumnModel().getColumn(2).setPreferredWidth(240);
tabela.getColumnModel().getColumn(2).setResizable(true);
tabela.getTableHeader().setReorderingAllowed(false);

107

tabela.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
tabela.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
JScrollPane rolagemTabela = new JScrollPane(tabela);
P.add(rolagemTabela, "Center");
// criao do terceiro painel
JPanel PSul = new JPanel();
btnIncluir = new JButton("Incluir");
btnAlterar = new JButton("Alterar");
btnExcluir = new JButton("Excluir");
btnSair = new JButton("Sair");
PSul.add(btnIncluir);
PSul.add(btnAlterar);
PSul.add(btnExcluir);
PSul.add(btnSair);
P.add(PSul, "South");
btnIncluir.addActionListener(this);
btnAlterar.addActionListener(this);
btnExcluir.addActionListener(this);
btnSair.addActionListener(this);
}
public void actionPerformed(ActionEvent evt)
{
Object origem = evt.getSource();
if (origem == btnPesqNome)
{
Selecao("SELECT * FROM Clientes WHERE NOME LIKE '%" +
nome.getText() + "%' ORDER BY NOME");
}
if (origem == btnIncluir)
{
FrameCadastro frame = new FrameCadastro(con, null, null, null, 'I');
frame.show();
}
if (origem == btnAlterar)
{
if (tabela.getSelectedRow()>=0)
{
FrameCadastro frame = new FrameCadastro(con,
modelo.getValueAt(tabela.getSelectedRow(),0).toString(),
modelo.getValueAt(tabela.getSelectedRow(),1).toString(),
modelo.getValueAt(tabela.getSelectedRow(),2).toString(), 'A');
frame.show();
}
else
JOptionPane.showMessageDialog(this,
"No existe registro selecionado!\n",
"Mensagem", JOptionPane.WARNING_MESSAGE);
}
if (origem == btnExcluir)
{
try {
if (JOptionPane.showConfirmDialog(null,"Confirma Excluso?",
"Confirmao", JOptionPane.YES_NO_OPTION,
JOptionPane.WARNING_MESSAGE) == 0)
{
sentenca = con.createStatement();

108

String sentencaSQL ="DELETE FROM Clientes WHERE Codigo= " +


modelo.getValueAt(tabela.getSelectedRow(),0).toString();
sentenca.executeUpdate(sentencaSQL);
sentenca.close();
Selecao("SELECT * FROM Clientes WHERE NOME LIKE '%" +
nome.getText() + "%' ORDER BY NOME");
}
}catch (SQLException eSQL) {
eSQL.printStackTrace();
JOptionPane.showMessageDialog(this,
"No foi possvel realizar a operao!\n" +
"Mensagem: " + eSQL.getMessage(),
"Erro", JOptionPane.ERROR_MESSAGE);
}
}
if (origem == btnSair)
{
try {
con.close();
System.exit(0);
}catch (SQLException eSQL) {
// excees de SQL
eSQL.printStackTrace();
JOptionPane.showMessageDialog(this,
"No foi possvel desconectar o banco!\n" +
"Mensagem: " + eSQL.getMessage(),
"Erro", JOptionPane.ERROR_MESSAGE);
}
}
}
public void Selecao(String sentencaSQL)
{
// apaga todas as linhas da tabela
for (int i= modelo.getRowCount()-1; i >= 0; i--)
modelo.removeRow(i);
try {
sentenca = con.createStatement();
registros = sentenca.executeQuery(sentencaSQL);
boolean proximoRegistro = registros.next();
if (!proximoRegistro)
{
JOptionPane.showMessageDialog(this,
"Nenhum registro foi encontrado!",
"Mensagem", JOptionPane.WARNING_MESSAGE);
}
else
do {
modelo.addRow(new Object[]{
new Integer(Integer.parseInt(registros.getString("Codigo"))),
registros.getString("Nome"),
registros.getString("Endereco")
});
} while (registros.next());
sentenca.close();
}catch (SQLException eSQL) {
eSQL.printStackTrace();

109

JOptionPane.showMessageDialog(this,
"No foi possvel carregar os dados!\n" +
"Mensagem: " + eSQL.getMessage(),
"Erro", JOptionPane.ERROR_MESSAGE);
}
}
public Connection conectaBanco(String sFonte,String sUsuario,String sSenha)
{
Connection conexao = null;
try {
System.setProperty("jdbc.drivers","sun.jdbc.odbc.JdbcOdbcDriver");
conexao = DriverManager.getConnection(sFonte, sUsuario, sSenha);
}catch (SQLException eSQL) {
// excees de SQL
eSQL.printStackTrace();
JOptionPane.showMessageDialog(this,
"Falha na conexo com o banco!\n" +
"Mensagem: " + eSQL.getMessage(),
"Erro", JOptionPane.ERROR_MESSAGE);
}catch (Exception e) {
// demais excees
e.printStackTrace();
JOptionPane.showMessageDialog(this,
"Falha na conexo com o banco!\n" +
"Mensagem: " + e.getMessage(),
"Erro", JOptionPane.ERROR_MESSAGE);
}
return conexao;
}
public static void main(String args[])
{
Cadastro fr = new Cadastro();
fr.setVisible(true);
}
}
class FrameCadastro extends JFrame implements ActionListener
{
private JButton OK;
private JButton Cancelar;
private JTextField txtCodigo;
private JTextField txtNome;
private JTextField txtEndereco;
private Connection conexao;
private char TipoOperacao;
public FrameCadastro(Connection con, String Cod, String Nome,
String Endereco, char Tipo)
{
conexao = con;
TipoOperacao = Tipo;
setSize(250,140);
setLocation(220,190);
Container P = getContentPane();
JPanel painelFC = new JPanel();

110

painelFC.setLayout(new FlowLayout());
painelFC.add(new JLabel("Cdigo"));
txtCodigo = new JTextField(15);
txtCodigo.setText(Cod);
if (Tipo == 'A')
{
txtCodigo.setEditable(false);
setTitle("Alterao");
}
else
setTitle("Incluso");
painelFC.add(txtCodigo);
painelFC.add(new JLabel("Nome"));
txtNome = new JTextField(15);
txtNome.setText(Nome);
painelFC.add(txtNome);
painelFC.add(new JLabel("Endereo"));
txtEndereco = new JTextField(15);
txtEndereco.setText(Endereco);
painelFC.add(txtEndereco);
OK = new JButton("OK");
Cancelar = new JButton("Cancelar");
painelFC.add(OK);
painelFC.add(Cancelar);
OK.addActionListener(this);
Cancelar.addActionListener(this);
P.add(painelFC,"Center");
}
public void actionPerformed(ActionEvent evt)
{
if (evt.getSource() == OK)
{
if (txtCodigo.getText().trim().equals("") ||
txtNome.getText().trim().equals(""))
{
JOptionPane.showMessageDialog(this,
"Campos Cdigo e Nome devem ser preenchidos!\n",
"Erro", JOptionPane.ERROR_MESSAGE);
}
else
{
try {
Statement sentenca = conexao.createStatement();
String sentencaSQL = null;
if (TipoOperacao == 'I')
sentencaSQL = "INSERT INTO Clientes (" +
"Codigo, Nome, Endereco) "+
"VALUES ("+
Integer.parseInt(txtCodigo.getText())+", '"+
txtNome.getText() + "', '" +
txtEndereco.getText()+"')";
else
sentencaSQL = "UPDATE Clientes SET Nome = '" +
txtNome.getText() + "', Endereco = '" +
txtEndereco.getText()+"' WHERE Codigo = " +
Integer.parseInt(txtCodigo.getText());

111

sentenca.executeUpdate(sentencaSQL);
sentenca.close();
dispose();
}catch (SQLException eSQL) {
eSQL.printStackTrace();
JOptionPane.showMessageDialog(this,
"No foi possvel realizar a operao!\n" +
"Mensagem: " + eSQL.getMessage(),
"Erro", JOptionPane.ERROR_MESSAGE);
}
}
}
if (evt.getSource() == Cancelar)
{
dispose();
}
}
}

D
D
d

3. AWT Avanado
Imagens e desenhos mais complexos no podem ser feitos a partir da classe Graphics.
necessrio utilizar pacotes existentes na API Java 2D, que permite produzir desenhos de mais alta
qualidade.

112

3.14 Java 2D
O Java 2D apresenta pacotes de classes com mtodos para desenhos grficos com um nvel maior
de complexidade. Alguns desses pacotes: java.awt.image, java.awt.geom, java.awt.print,
java.awt.Graphics2D. Com o Java 2D possvel produzir uma variedade maior de figuras
geomtricas, com padres diferentes de preenchimento, alm de ter controle sobre os desenhos
criados, podendo move-los, gira-los ou alonga-los.

3.15 Imagens
A classe Image a responsvel pelo carregamento de imagens armazenadas em disco. Novam
d

113

Bibliografia
Cesta, Andr Augusto. Tutorial: A Linguagem de Programao JAVA. Instituto de
Computao. UNICAMP, 1996. Disponvel em http://www.dcc.unicamp.br
Davis, Stephen R. Aprenda Java agora. 2.ed. Rio de Janeiro : Campus, 1997. 401p.
Deitel, Harvey M. Java : como programar. 3.ed. Porto Alegre : Bookman, 2001. 1201p.
Flanagan, David. Java : o guia essencial. Rio de Janeiro : Campus, 2000. 718 p.
Lemay, Laura; Cadenhead, Rogers. Aprenda em 21 dias Java 2. Rio de Janeiro : Campus,
1999. 661p.
Schtzer, Waldeck; Massago, Sadao. Programao Java. Departamento de Matemtica
Universidade Federal de So Carlos UFSCar. 1999. Disponvel em:
http://www2.dm.ufscar.br/~waldeck/curso/java/

Sites de Interesse
www.java.sun.com - Site ofical do Java.
www.javafree.com.br - Comunidade de desenvolvedores Java.
www.portaljava.com.br - Comunidade de desenvolvedores Java.

114

Você também pode gostar