Programação JAVA
Programação JAVA
1. Programação Visual Básica
1. Programação Visual Básica
A Interface Gráfica com o Usuário, também conhecido como GUI
-A Interface Gráfica com o Usuário, também conhecido como GUI -
Graphical User Interface
Graphical User Interface
,,
em Java, é feita através de bibliotecas de classes, sendo que a primeira a surgir foi a AWT
em Java, é feita através de bibliotecas de classes, sendo que a primeira a surgir foi a AWT
((
Abstract Window Toolki
Abstract Window Toolki
t). A AWT surgiu já na versão 1.0, mas se tornou confiável a partir da
t). A AWT surgiu já na versão 1.0, mas se tornou confiável a partir da
versão 1.1. A maneira como as classes dessa biblioteca trabalham garante a criação dos
versão 1.1. A maneira como as classes dessa biblioteca trabalham garante a criação dos
elementos da interface de usuário seguindo o comportamento destinado às ferramentas GUI
elementos da interface de usuário seguindo o comportamento destinado às ferramentas GUI
nativas de cada plataforma (Windows, Mac, Solaris, ...).
nativas de cada plataforma (Windows, Mac, Solaris, ...).
Alguns exemplos destes elementos são: botões, listas, menus, componentes de textos, containers
Alguns exemplos destes elementos são: botões, listas, menus, componentes de textos, containers
(janelas e barras de menus), caixas de diálogo para abrir ou salvar arquivos, além de elementos
(janelas e barras de menus), caixas de diálogo para abrir ou salvar arquivos, além de elementos
para manipulação de imagens, fontes e cores.
para manipulação de imagens, fontes e cores.
A portabilidade de plataforma funcionava bem em aplicações simples, mas aplicações que
A portabilidade de plataforma funcionava bem em aplicações simples, mas aplicações que
envolviam elementos mais complexos, como menus e barras de rolagem, por exemplo,
envolviam elementos mais complexos, como menus e barras de rolagem, por exemplo,
apresentavam diferenças de comportamento conforme a plataforma. O que aconteceu foi que as
apresentavam diferenças de comportamento conforme a plataforma. O que aconteceu foi que as
aplicações visuais feitas em Java não se pareciam, e nem tinham as mesmas funcionalidades, com
aplicações visuais feitas em Java não se pareciam, e nem tinham as mesmas funcionalidades, com
as aplicações convencionais de cada plataforma.
as aplicações convencionais de cada plataforma.
A partir da versão 2 do Java, a JFC (Java Foundation Classes) apresentou novos recursos para a
A partir da versão 2 do Java, a JFC (Java Foundation Classes) apresentou novos recursos para a
construção da GUI das aplicações, o que melhorou muito os problemas de portabilidade. São
construção da GUI das aplicações, o que melhorou muito os problemas de portabilidade. São
eles:
eles:
•
•
Java 2D: novas funções para desenhos e gráficos.
Java 2D: novas funções para desenhos e gráficos.
••
Drag & Drop: clicar, arrastar, copiar e colar.
Drag & Drop: clicar, arrastar, copiar e colar.
••
Swing: biblioteca de classes extensão da AWT, onde são apresentados novos
Swing: biblioteca de classes extensão da AWT, onde são apresentados novos
componentes de interface e o que é conhecido por
componentes de interface e o que é conhecido por
look and feel
look and feel
, que é uma adaptação
, que é uma adaptação
perfeita da GUI ao sistema operacional específico de desenvolvimento.
perfeita da GUI ao sistema operacional específico de desenvolvimento.
É bom salientar que o Swing não substitui o AWT, mas é o kit de ferramentas GUI mais utilizado
É bom salientar que o Swing não substitui o AWT, mas é o kit de ferramentas GUI mais utilizado
para desenvolvimento de aplicações visuais. O AWT continua existindo, mantendo a mesma
para desenvolvimento de aplicações visuais. O AWT continua existindo, mantendo a mesma
arquitetura criada para o Java versão 1.1.
arquitetura criada para o Java versão 1.1.
O Swing possui muito mais recursos, além de garantir maior portabilidade e, em boa parte dos
O Swing possui muito mais recursos, além de garantir maior portabilidade e, em boa parte dos
casos, é mais fácil de usar. Isso não significa que ou se utiliza AWT ou se utiliza Swing,
casos, é mais fácil de usar. Isso não significa que ou se utiliza AWT ou se utiliza Swing,
normalmente o que acontece é que elementos das duas bibliotecas são utilizados conjuntamente
normalmente o que acontece é que elementos das duas bibliotecas são utilizados conjuntamente
nas aplicações.
nas aplicações.
Referente a criação das aplicações, exitem muitas ferramentas que auxiliam na produção de
Referente a criação das aplicações, exitem muitas ferramentas que auxiliam na produção de
interfaces de usuário gráficas, mas não se comparam a ferramentas para plataformas específicas,
interfaces de usuário gráficas, mas não se comparam a ferramentas para plataformas específicas,
como Delphi e VisualBasic, que são voltadas exclusivamente para esse fim. Boa parte da
como Delphi e VisualBasic, que são voltadas exclusivamente para esse fim. Boa parte da
elaboração da interface da aplicação tem que ser feita manualmente, o que exige bastante
elaboração da interface da aplicação tem que ser feita manualmente, o que exige bastante
trabalho.
trabalho.
1.1
1.1 Frames
Frames
Na AWT, a janela de mais alto nível de uma aplicação (não está contida dentro de nenhuma
Na AWT, a janela de mais alto nível de uma aplicação (não está contida dentro de nenhuma
outra) é denominada
outra) é denominada
FrameFrame. No Swing, existe uma versão chamada
. No Swing, existe uma versão chamada
JFrameJFrame, que é
, que é
derivada/estendida da classe
derivada/estendida da classe
FrameFrame, possuindo alguns poucos métodos adicionais relacionados à
, possuindo alguns poucos métodos adicionais relacionados à
manipulação da disposição visual dos frames .Todos os outros métodos são derivados da classe
manipulação da disposição visual dos frames .Todos os outros métodos são derivados da classe
Frame
Frame
. Um frame pode conter diversos outros componentes da GUI.
. Um frame pode conter diversos outros componentes da GUI.
Para se definir um frame básico baseado em AWT, deve-se:
Para se definir um frame básico baseado em AWT, deve-se:
•
•
Importar o pacote
Importar o pacote
java.awt.*java.awt.*..
••
Estender a classe
Estender a classe
FrameFrame..
••
Ter um método
Ter um método
main()main()para criar o objeto a partir do operador
para criar o objeto a partir do operador
newnew..
••
Torná-lo visível.
Torná-lo visível.
Assim, o código a seguir resulta no frame apresentado na figura 1.1.
Assim, o código a seguir resulta no frame apresentado na figura 1.1.
import java.awt.*;
import java.awt.*;
public class FrameUm extends Frame
public class FrameUm extends Frame
{
{
public static void main (String[] args)
public static void main (String[] args)
{
{
FrameUm fr = new FrameUm();
FrameUm fr = new FrameUm();
fr.setVisible(true); fr.setVisible(true); } } } }
Para torná-lo visível, é possível utilizar
Para torná-lo visível, é possível utilizar
fr.show();fr.show();no lugar de
no lugar de
fr.setVisible(true);fr.setVisible(true);..
Percebe-se que não é possível fechá-lo utilizando o botão fechar. Por enquanto, ela deve ser
Percebe-se que não é possível fechá-lo utilizando o botão fechar. Por enquanto, ela deve ser
encerrada forçando a finalização do processo (ex.: finalizar tarefa no Windows, ou terminar
encerrada forçando a finalização do processo (ex.: finalizar tarefa no Windows, ou terminar
processo na ferramenta específica de desenvolvimento).
processo na ferramenta específica de desenvolvimento).
Figura 1.1. Frame FrameUm Figura 1.1. Frame FrameUm
O frame criado não possui tamanho definido, nem título ou posicionamento. Para personalizar o
O frame criado não possui tamanho definido, nem título ou posicionamento. Para personalizar o
frame é necessário inserir um método construtor com as instruções necessárias. Exemplo:
frame é necessário inserir um método construtor com as instruções necessárias. Exemplo:
import java.awt.*;
import java.awt.*;
public class FrameDois extends Frame
public class FrameDois extends Frame
{
{
public
public
FrameDois() //construtorFrameDois() //construtor{
{
setTitle("Frame
setTitle("Frame Dois"); Dois"); // // título título do do FrameFrame
setSize(300,
setSize(300, 200); 200); // // largura: largura: 300 300 pixels pixels altura: altura: 200 200 pixelspixels
setResizable(false); // não permite o redimensionamento
como Delphi e VisualBasic, que são voltadas exclusivamente para esse fim. Boa parte da
como Delphi e VisualBasic, que são voltadas exclusivamente para esse fim. Boa parte da
elaboração da interface da aplicação tem que ser feita manualmente, o que exige bastante
elaboração da interface da aplicação tem que ser feita manualmente, o que exige bastante
trabalho.
trabalho.
1.1
1.1 Frames
Frames
Na AWT, a janela de mais alto nível de uma aplicação (não está contida dentro de nenhuma
Na AWT, a janela de mais alto nível de uma aplicação (não está contida dentro de nenhuma
outra) é denominada
outra) é denominada
FrameFrame. No Swing, existe uma versão chamada
. No Swing, existe uma versão chamada
JFrameJFrame, que é
, que é
derivada/estendida da classe
derivada/estendida da classe
FrameFrame, possuindo alguns poucos métodos adicionais relacionados à
, possuindo alguns poucos métodos adicionais relacionados à
manipulação da disposição visual dos frames .Todos os outros métodos são derivados da classe
manipulação da disposição visual dos frames .Todos os outros métodos são derivados da classe
Frame
Frame
. Um frame pode conter diversos outros componentes da GUI.
. Um frame pode conter diversos outros componentes da GUI.
Para se definir um frame básico baseado em AWT, deve-se:
Para se definir um frame básico baseado em AWT, deve-se:
•
•
Importar o pacote
Importar o pacote
java.awt.*java.awt.*..
••
Estender a classe
Estender a classe
FrameFrame..
••
Ter um método
Ter um método
main()main()para criar o objeto a partir do operador
para criar o objeto a partir do operador
newnew..
••
Torná-lo visível.
Torná-lo visível.
Assim, o código a seguir resulta no frame apresentado na figura 1.1.
Assim, o código a seguir resulta no frame apresentado na figura 1.1.
import java.awt.*;
import java.awt.*;
public class FrameUm extends Frame
public class FrameUm extends Frame
{
{
public static void main (String[] args)
public static void main (String[] args)
{
{
FrameUm fr = new FrameUm();
FrameUm fr = new FrameUm();
fr.setVisible(true); fr.setVisible(true); } } } }
Para torná-lo visível, é possível utilizar
Para torná-lo visível, é possível utilizar
fr.show();fr.show();no lugar de
no lugar de
fr.setVisible(true);fr.setVisible(true);..
Percebe-se que não é possível fechá-lo utilizando o botão fechar. Por enquanto, ela deve ser
Percebe-se que não é possível fechá-lo utilizando o botão fechar. Por enquanto, ela deve ser
encerrada forçando a finalização do processo (ex.: finalizar tarefa no Windows, ou terminar
encerrada forçando a finalização do processo (ex.: finalizar tarefa no Windows, ou terminar
processo na ferramenta específica de desenvolvimento).
processo na ferramenta específica de desenvolvimento).
Figura 1.1. Frame FrameUm Figura 1.1. Frame FrameUm
O frame criado não possui tamanho definido, nem título ou posicionamento. Para personalizar o
O frame criado não possui tamanho definido, nem título ou posicionamento. Para personalizar o
frame é necessário inserir um método construtor com as instruções necessárias. Exemplo:
frame é necessário inserir um método construtor com as instruções necessárias. Exemplo:
import java.awt.*;
import java.awt.*;
public class FrameDois extends Frame
public class FrameDois extends Frame
{
{
public
public
FrameDois() //construtorFrameDois() //construtor{
{
setTitle("Frame
setTitle("Frame Dois"); Dois"); // // título título do do FrameFrame
setSize(300,
setSize(300, 200); 200); // // largura: largura: 300 300 pixels pixels altura: altura: 200 200 pixelspixels
setResizable(false); // não permite o redimensionamento
setLocation(200,
setLocation(200, 100); 100); // // x: x: 200 200 pixels pixels y: y: 100 100 pixelspixels
}
}
public static void main (String[] args)
public static void main (String[] args)
{
{
FrameDois fr = new FrameDois();
FrameDois fr = new FrameDois();
fr.setVisible(true); fr.setVisible(true); } } } }
A figura 1.2 mostra o resultado da execução, um frame com largura 300 x 200 pixels
A figura 1.2 mostra o resultado da execução, um frame com largura 300 x 200 pixels
((
setSize()setSize()), com o título “Frame Dois” (
), com o título “Frame Dois” (
setTitle()setTitle()), que não permite redimensionamento
), que não permite redimensionamento
((
setResizable()setResizable()).
).
Figura 1.2. Frame FrameDois Figura 1.2. Frame FrameDois
Além disso, o
Além disso, o
setLocation()setLocation()realiza o posicionamento em tela do frame, seguindo o sistema de
realiza o posicionamento em tela do frame, seguindo o sistema de
coordenadas do Java (figura 1.3), medidas em pixels, conforme a resolução atual da tela. No
coordenadas do Java (figura 1.3), medidas em pixels, conforme a resolução atual da tela. No
exemplo, o frame fica posicionado em 2
exemplo, o frame fica posicionado em 200 pixels para x
00 pixels para x e 100 pixels para
e 100 pixels para y.
y.
(0 ,0) (0 ,0) xx y y (x, y) (x, y)
Figura 1.3. Sistema de coordenadas do Java Figura 1.3. Sistema de coordenadas do Java
Conforme já mencionado, o frame ainda não pode ser fechado. Para que isso aconteça é
Conforme já mencionado, o frame ainda não pode ser fechado. Para que isso aconteça é
necessário ter uma maneira de se ter a notificação de quando ele é fechado. A partir da
necessário ter uma maneira de se ter a notificação de quando ele é fechado. A partir da
manipulação desse evento, mostrado no exemplo a seguir, é possível fechar o frame. É necessário
manipulação desse evento, mostrado no exemplo a seguir, é possível fechar o frame. É necessário
importar o pacote
importar o pacote
java.awt.event.*java.awt.event.*para manipular eventos do AWT. O modelo de eventos e
para manipular eventos do AWT. O modelo de eventos e
os demais eventos de janela serão vistos em seções posteriores.
os demais eventos de janela serão vistos em seções posteriores.
import java.awt.*;
import java.awt.event.*;
public class FrameTres extends Frame {
public FrameTres() //construtor {
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e){System.exit(0);}}); setTitle("Frame Três"); // título do Frame
setSize(300, 200); // largura: 300 pixels altura: 200 pixels setResizable(false); // não permite o redimensionamento
setLocation(200, 100); // x: 200 pixels y: 100 pixels }
public static void main (String[] args) {
FrameTres fr = new FrameTres(); fr.setVisible(true);
} }
Ainda em relação ao posicionamento, dependendo da resolução da tela onde o frame será aberto,
pode se ter situações bem desagradáveis, como, por exemplo, o frame ser aberto e ficar com parte
fora da tela. É necessário então posicionar o frame em coordenadas que independam da resolução
utilizada. O exemplo a seguir abrirá um frame com a metade do tamanho da tela, posicionado no
centro, respeitando a resolução.
import java.awt.*;
import java.awt.event.*;
public class FrameQuatro extends Frame {
public FrameQuatro() //construtor {
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e){System.exit(0);}}); Toolkit tk = Toolkit.getDefaultToolkit();
Dimension d = tk.getScreenSize(); setSize(d.width / 2, d.height / 2); setLocation(d.width / 4, d.height / 4); Image img = tk.getImage("icone.gif"); setIconImage(img);
setTitle("Frame Quatro"); setResizable(false);
}
public static void main (String[] args) {
FrameQuatro fr = new FrameQuatro(); fr.setVisible(true);
} }
Para que seja possível essa tarefa de posicionamento conforme a resolução de vídeo, é necessário
obter informações do sistema operacional, e isso é feito através da classe
Toolkit, método
getScreenSize(), cujos dados são jogados em um objeto da classe
Dimension, que armazena a
altura e largura nos campos
d.widthe
d.height. Por exemplo, se a resolução de vídeo for
800x600, o
d.widthfica com 800 e o
d.heightfica com 600. Tendo esses valores, é possível
utilizar em métodos como o
setLocation()e o
setSize(), como foi feito no exemplo. Além
método
getImage(), para carregar a imagem (extensão
.gif) e jogar em um objeto da classe
Image, para depois setar o ícone através do
setIconImage().
O mesmo exemplo pode ser feito baseado na biblioteca Swing, classe
JFrame, mudando apenas a
derivação e importando o pacote
javax.swing.*, assim:
import java.awt.*;import java.awt.event.*; import javax.swing.*;
public class FrameQuatro extends JFrame {
... }
Os exemplos apresentados nas próximas seções criarão frames baseado na classe
JFrame.
1.2 Mostrando Textos e Linhas no Frame
Para que seja possível mostrar textos em um frame é necessário criar um objeto baseado na classe
Graphics
, que será responsável pelo gerenciamento da área gráfica a ser desenhada, controlando
cores, tipos de fontes, etc. A classe
Componentpossui um método
paint()que aceita um objeto
Graphicscomo parâmetro. Esse método, na classe de origem, não faz nada, por isso ele deve ser
sobrescrito com a chamada de métodos que realizam operações de escrita, pintura, desenho, etc.
Para efetuar a sobreposição do método
paint()deve-se ter o cabeçalho:
public void paint(Graphics g)
A partir disso, métodos como
drawString()e
drawLine()podem ser utilizados, como no
exemplo a seguir. O resultado é apresentado na figura 1.4.
import java.awt.*;
import java.awt.event.*; import javax.swing.*;
public class MostrandoTextos extends JFrame {
public MostrandoTextos() {
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e){System.exit(0);}}); Toolkit tk = Toolkit.getDefaultToolkit();
Dimension d = tk.getScreenSize(); int screenHeight = d.height;
int screenWidth = d.width;
setSize(d.width / 2, d.height / 2); setLocation(d.width / 4, d.height / 4); setTitle("Escrevendo Textos");
setResizable(false); }
public void paint (Graphics g) {
g.drawString("Estou escrevendo no frame", 40, 50); g.drawLine(40, 60, 200, 60);
int i = 30; while (i < 150) {
g.drawString("Estou escrevendo no frame", 40+i, 50+i); g.drawLine(40+i, 60+i, 200+i, 60+i);
i+=30; }
}
public static void main (String[] args) {
MostrandoTextos fr = new MostrandoTextos(); fr.setVisible(true);
} }
Figura 1.4. Frame MostrandoTextos
O método
drawString(String s, int x, int y)realiza a mostragem de um texto em uma
posição definida por
xe
y. O método
drawLine(int x1, int y1, int x2, int y2)desenha
uma linha que inicia nas coordenadas
x1,y1e termina nas coordenadas
x2,y2.
1.3 Cores
O método
setColor()seleciona a cor que é utilizada para todas as operações de desenho dentro
do contexto gráfico ou componente. Um parâmetro
Colordefine a cor a ser usada, sendo que as
treze cores padrão, apresentadas na tabela 1.1, estão definidas na classe
java.awt.Color.
black(preto)
magenta(magenta)
blue
(azulo)
orange(laranja)
cyan
(ciano)
pink(rosa)
darkGray
(cinza-escuro)
red(vermelho)
gray
(cinza)
white(branco)
lightGray
(cinza-claro)
Tabela 1.1. Cores definidas em java.awt.Color
Além das cores pré-definidas, pode-se criar novas cores baseadas no conteúdo RGB
(red-vermelho, green-verde, blue-azul), expressos por inteiros de 0 a 255. O exemplo a seguir
apresenta a criação de objetos coloridos em um frame. O resultado é apresentado na figura 1.5.
import java.awt.*;
import java.awt.event.*; import javax.swing.*;
public class Cores extends JFrame {
public Cores() {
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e){System.exit(0);}}); setSize(400, 200);
setLocation(200, 100); setTitle("Cores"); }
public void paint (Graphics g) { g.setColor(Color.blue); g.drawString("Cor Azul", 50, 50); g.setColor(Color.green); g.drawLine(50, 60, 220, 60); g.setColor(Color.red); g.drawRect(50,70,100,30); g.setColor(new Color(0,128,128)); g.fillRect(50,110,100,30); }
public static void main (String[] args) {
Cores fr = new Cores(); fr.setVisible(true); }
}
O método
drawRect(int x, int y, int width, int height)desenha um retângulo com a
cor definida em
setColor(), iniciando nas coordenadas
x,y, tendo uma largura
widthe uma
altura
height. O método
fillRect(int x, int y, int width, int height)faz a mesma
coisa, mas preenche o retângulo.
1.4 Fontes
O método responsável por definir o tipo de fonte desejado é o
setFont(), que precisa de um
objeto criado, baseado na classe
Font, definindo assim o nome da fonte, o seu estilo e seu
tamanho. O nome pode ser qualquer fonte suportada pelo sistema operacional específico; o estilo
pode ser:
PLAIN– regular,
BOLD– negrito e
ITALIC– itálico, sendo possível combinar os estilos
utilizando o operador
+; o tamanho pode ser qualquer valor que represente o tamanho em pontos
da fonte. Exemplo:
import java.awt.*;
import java.awt.event.*; import javax.swing.*;
public class Fontes extends JFrame {
public Fontes() {
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e){System.exit(0);}}); setSize(400,130);
setTitle("Tipos de Fonte"); }
public void paint (Graphics g) {
g.setColor(Color.blue);
Font f = new Font("SansSerif", Font.ITALIC, 16); g.setFont(f);
g.drawString("Fonte SansSerif itálico tamanho 16", 20, 50); g.setFont(new Font("Monospaced", Font.BOLD + Font.ITALIC, 14));
g.drawString("Fonte Monospaced negrito e itálico tamanho 14", 20, 80); g.setFont(f);
g.drawString("Novamente Fonte SansSerif itálico tamanho 16", 20, 110); }
public static void main (String[] args) {
Fontes fr = new Fontes(); fr.setVisible(true);
} }
A figura 1.6 mostra o resultado. Percebe-se que não é necessário criar explicitamente um objeto
do tipo
Font(objeto
f), podendo ser possível criá-lo no próprio argumento do
setFont(). Se a
fonte for utilizada várias vezes no decorrer da aplicação, torna-se útil a criação do objeto
explicitamente.
Figura 1.6. Frame Fontes
Em termos de portabilidade, deve-se tomar cuidado quanto a fontes que não existem em alguns
sistemas operacionais. O ideal é trabalhar com fontes comuns em sistemas operacionais
diferentes. O modelo do AWT define cinco fontes disponíveis em qualquer sistema operacional.
São elas:
Serif,
Monospaced,
SansSerif,
Dialoge
DialogInput.
1.5 Outras Formas Geométricas
Além das formas já apresentadas, existem várias outras possíveis, a maioria com a opção de
preenchimento ou não, a partir da precedência de
drawou
fill. O exemplo a seguir tem como
resultado o frame apresentado na figura 1.7.
import java.awt.*;
import java.awt.event.*; import javax.swing.*;
public class FormasGeometricas extends JFrame {
public FormasGeometricas() {
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e){System.exit(0);}}); setSize(460,140);
setTitle("Formas Geométricas"); }
public void paint (Graphics g) { g.setColor(Color.red); g.drawRoundRect(10,30,80,40,30,30); g.fillRoundRect(10,80,80,40,30,30); g.setColor(Color.yellow); g.draw3DRect(100,30,80,40,true); g.fill3DRect(100,80,80,40,false); g.setColor(Color.blue); g.drawOval(190,30,80,40); g.fillOval(190,80,80,40); g.setColor(Color.darkGray); g.drawArc(280,30,80,40,90,270); g.fillArc(280,80,80,40,90,270); g.setColor(Color.magenta); int ValoresX[] = {370,450,410,370}; int ValoresY[] = {30,30,70,30}; g.drawPolygon(ValoresX,ValoresY,3); int ValoresX2[] = {370,450,410,370}; int ValoresY2[] = {80,80,120,80}; g.fillPolygon(ValoresX2,ValoresY2,3);
}
public static void main (String[] args) {
FormasGeometricas fr = new FormasGeometricas(); fr.setVisible(true);
} }
Figura 1.7. Frame Fontes
Várias formas geométricas foram desenhadas no frame. Funcionamento de cada método:
• drawRoundRect(int x, int y, int width, int height, int arcWidth, int
arcHeight)
: Desenha um retângulo com cantos arredondados, iniciando nas coordenadas
x,y, tendo uma largura
widthe uma altura
height, e cantos definidos por
arcWidthe
arcHeight.
• fillRoundRect(int x, int y, int width, int height, int arcWidth, int
arcHeight)
: Idem a
drawRoundRect, mas preenche o retângulo.
• draw3DRect(int x, int y, int width, int height, boolean raised)
: Desenha
um retângulo 3D, iniciando nas coordenadas
x,y, tendo uma largura
widthe uma altura
height, e um valor lógico para indicar a aparência do 3D.
• fill3DRect(int x, int y, int width, int height, boolean raised)
: Idem a
draw3DRect
, mas preenche o retângulo.
• drawOval(int x, int y, int width, int height)
: Desenha uma forma oval,
baseado nas coordenadas do retângulo que inicia em
x,y, tendo uma largura
widthe uma
altura
height.
• fillOval(int x, int y, int width, int height)
: Idem a
drawOval, mas preenche
a forma oval.
• drawArc(int x, int y, int width, int height, int startAngle, int
arcAngle)
: Desenha um arco, baseado nas coordenadas do retângulo que inicia em
x,y,
tendo uma largura
widthe uma altura
height, mostrando apenas a linha que vai do
ângulo
startAngleaté o ângulo
arcAngle.
• fillArc(int x, int y, int width, int height, int startAngle, int
• drawPolygon(int[] xPoints, int[] yPoints, int nPoints)
: Desenha um
polígono, baseado nas coordenadas dos arranjos
x,y.
• fillPolygon(int[] xPoints, int[] yPoints, int nPoints)
:
Idem
a
drawPolygon
, mas preenche o arco.
1.6 Imagens
A classe
Imageé a responsável pelo carregamento de imagens armazenadas em disco.
Novamente, é necessário utilizar um objeto do tipo
Toolkitpara obter uma imagem, através do
método
getImage(), e depois jogar em um objeto do tipo
Image. O exemplo a seguir mostra a
maneira de se preencher um frame com as imagens lado a lado. A figura 1.8 mostra o resultado.
import java.awt.*;
import java.awt.event.*; import javax.swing.*;
public class Imagens extends JFrame {
public Imagens() //construtora {
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e){System.exit(0);}}); setSize(400,200);
setTitle("Imagens"); }
public void paint (Graphics g) {
Image ima = Toolkit.getDefaultToolkit().getImage("LogoJava.gif"); int larguraTela = 400;
int alturaTela = 200;
int larguraImagem = ima.getWidth(this); int alturaImagem = ima.getHeight(this); g.drawImage(ima,4,23,null);
for (int i = 0; i <= larguraTela / larguraImagem; i++) for (int j = 0; j <= alturaTela / alturaImagem; j++)
if (i + j > 0)
g.copyArea(4,23,larguraImagem, alturaImagem, i * larguraImagem, j * alturaImagem); }
public static void main (String[] args) {
Imagens fr = new Imagens(); fr.setVisible(true);
} }
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
imgnas coordenadas
x,y, para depois ser copiada lado a lado, através do método
copyArea(int x, int y, int width, int height, int dx, int dy), que copia o
conteúdo da área que começar nas coordenadas
x,ycom largura
widthe altura
height, em um
local a uma distância
dx,dy. Para realizar essa tarefa, foi necessário descobrir o tamanho da
imagem, através
getWidth()e do
getHeight().
1.7 Contêiners
Contêiners servem de repositório de outros componentes, como botões, por exemplo. Alguns
exemplos de contêiners:
JFrame,
JPanele
JApplet. Um
JFrameé uma janela de mais alto nível;
um
JPanelé um contêiner usado para agrupar componentes, normalmente dentro de um
JFrame;
um
JAppletpermite a execução em navegadores da Web. Pode-se desenhar algo diretamente no
frame ou definir um contêiner, como um painel, por exemplo, e desenhar nele. Não é considerada
uma boa prática de programação desenhar diretamente no frame, pois ele foi projetado para ser
contêiner de componentes específicos, como barras de menu, por exemplo. Os painéis devem ser
utilizados para agrupar outros componentes. Exemplo de adição de um painel a um frame:
import java.awt.*;
import java.awt.event.*; import javax.swing.*;
class Painel extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawString("Estou escrevendo em um painel", 100, 50); }
}
public class EscrevendoEmPainel extends JFrame {
public EscrevendoEmPainel() {
{public void windowClosing(WindowEvent e){System.exit(0);}}); setSize(400,130); setTitle("Painel"); Container P = getContentPane(); P.add(new Painel()); }
public static void main (String[] args) {
EscrevendoEmPainel fr = new EscrevendoEmPainel(); fr.setVisible(true);
} }
Figura 1.9. Contêiner do tipo painel
O resultado pode ser conferido na figura 1.9. Para desenhar algo em um painel, deve-se criar uma
classe derivada de
JPanele sobrepor o método
paintComponent(), que está definido na classe
JComponent, e recebe um parâmetro do tipo
Graphics. Tal método é chamado automaticamente
toda vez que a janela é redesenhada, como na criação e no redimensionamento. Se, por algum
motivo, se desejar redesenhar o conteúdo no painel, o método a ser chamado é o
repaint(), que
se encarrega de executar novamente o
paintComponent(). O
super.paintComponent(g)faz
com que o método da superclasse seja executado também. Isso normalmente é feito em
sobreposições de métodos, quando se deseja criar algo a mais que o método definido na
superclasse. A criação de uma classe derivada de
JFrameé feita a seguir, e um objeto
Containeré criado para depois adicionar (
add) o painel. O método
getContentPane()retorna a área de
conteúdo do frame para que possa ser adicionado o painel.
1.8 Gerenciadores de Layout
Os gerenciadores de layout controlam o dimensionamento e posicionamento dos componentes
dentro de contêiners, sendo que cada contêiner possui um gerenciador padrão, mas pode ser
alterado através da chamada ao método
setLayout()do contêiner específico. Por exemplo, o
gerenciador padrão do
JPanelé o
FlowLayout, que coloca os componentes em um tamanho
pré-definido da esquerda para a direita e de cima para baixo no contêiner. Outros gerenciadores de
layout existentes:
GridLayout,
BorderLayout,
BoxLayoute
GridBagLayout.
1.8.1 Gerenciador FlowLayout
Para que seja possível verificar a diferença entre alguns deles, exemplos são demonstrados nas
próximas seções, começando exatamente pelo gerenciador
FlowLayout, padrão do
JPanel. Nos
exemplos, são definidos objetos botão a partir da classe
JButton.
import java.awt.*;import java.awt.event.*; import javax.swing.*;
class PainelFlow extends JPanel { public PainelFlow() { setLayout(new FlowLayout()); add(new JButton("Um")); add(new JButton("Dois")); add(new JButton("Três")); add(new JButton("Quatro")); add(new JButton("Cinco")); } }
public class GerenciadorFlowLayout extends JFrame {
public GerenciadorFlowLayout() {
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e){System.exit(0);}}); setSize(200,90); setLocation(150,150); setTitle("FlowLayout"); Container P = getContentPane(); P.add(new PainelFlow()); }
public static void main (String[] args) {
GerenciadorFlowLayout fr = new GerenciadorFlowLayout(); fr.setVisible(true);
} }
Figura 1.10. Gerenciador de Layout FlowLayout
Como o
FlowLayouté o gerenciador padrão do
JPanel, não seria necessário setar o layout
através do
setLayout(new FlowLayout());. O alinhamento dos componentes fica centralizado
e, caso algum compontnte não caiba em uma linha, é jogado para a linha seguinte, como mostra a
figura 1.10. É possível alterar o alinhamento, passando-o como parâmetro na determinação do
layout (
LEFT,
RIGHTou
CENTER), assim:
setLayout(new FlowLayout(FlowLayout.RIGHT));
O
GridLayouté um gerenciador que organiza os componentes em linhas e colunas espaçadas
regularmente. Exemplo:
import java.awt.*;
import java.awt.event.*; import javax.swing.*;
class PainelGrid extends JPanel { public PainelGrid() { setLayout(new GridLayout(3,2)); add(new JButton("Um")); add(new JButton("Dois")); add(new JButton("Três")); add(new JButton("Quatro")); add(new JButton("Cinco")); } }
public class GerenciadorGridLayout extends JFrame {
public GerenciadorGridLayout() {
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e){System.exit(0);}}); setSize(200,150); setLocation(150,150); setTitle("GridLayout"); Container P = getContentPane(); P.add(new PainelGrid()); }
public static void main (String[] args) {
GerenciadorGridLayout fr = new GerenciadorGridLayout(); fr.setVisible(true);
} }
Figura 1.11. Gerenciador de Layout GridLayout
O tamanho de cada componente é redimensionado automaticamente, como mostra a figura 1.11,
podendo ficar espaços vazios. É necessário definir o número de linhas e colunas no
setLayout()
. Os componentes são adicionados a partir da posição na parte superior esquerda da
grade, seguindo para a direita até preencher a linha e passar para baixo.
Também é possível espaçar os componentes horizontal e verticalmente. Nesse caso, na definição
do layout, deve-se passar esses valores também. O layout abaixo, por exemplo, define
5pixels de
espaçameno horizontal e
8pixels de espaçamento vertical:
setLayout(new GridLayout(3,2,5,8));1.8.3 Gerenciador BorderLayout
Existem gerenciadores mais interessantes, como o
BorderLayout, que organiza os objetos em
locais determinados por
NORTH,
SOUTH,
EAST,
WESTe
CENTER. Exemplo:
import java.awt.*;import java.awt.event.*; import javax.swing.*;
class PainelBorder extends JPanel { public PainelBorder() { setLayout(new BorderLayout()); add(new JButton("Um"),BorderLayout.NORTH); add(new JButton("Dois"),BorderLayout.SOUTH); add(new JButton("Três"),BorderLayout.EAST); add(new JButton("Quatro"),BorderLayout.WEST); add(new JButton("Cinco"),BorderLayout.CENTER); } }
public class GerenciadorBorderLayout extends JFrame {
public GerenciadorBorderLayout() {
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e){System.exit(0);}}); setSize(300,150); setLocation(150,150); setTitle("BorderLayout"); Container P = getContentPane(); P.add(new PainelBorder()); }
public static void main (String[] args) {
GerenciadorBorderLayout fr = new GerenciadorBorderLayout(); fr.setVisible(true);
} }
Figura 1.12. Gerenciador de Layout GridLayout
Na figura 1.12 se observa o resultado da aplicação, com um botão em cada localização geográfica
dentro do painel. O
BorderLayouté o gerenciador padrão para os contêiners
JWindowe
JFrame.
Não é necessário ter todas as localizações preenchidas. Se alguma das localizações (norte, sul,
leste ou oeste) não for ocupada, as demais ocupam o lugar da(s) omitida(s). Porém, se a
localização central não for ocupada, ela ficará vazia.
Na definição do layout é possível determinar o espaçamento horizontal e vertical entre as
localizações. O layout abaixo, por exemplo, define
5pixels de espaçameno horizontal e
8pixels
de espaçamento vertical:
setLayout(new BorderLayout(5,8));
1.8.4 Gerenciador BoxLayout
Os gerenciadores de layout foram criados ainda na versão 1.0 do Java. O Swing possui apenas
um gerenciador de layout de uso geral, chamado
BoxLayout, sendo mais utilizado para criar
barras de ferramentas, podendo inserir componentes em apenas uma linha ou uma coluna. Ao
invés de utilizar o
BoxLayoutdiretamente, pode-se usar um outro contêiner do Swing chamado
Box, como no exemplo a seguir.
import java.awt.*;
import java.awt.event.*; import javax.swing.*;
class PainelBox extends JPanel { public PainelBox() { add(Box.createHorizontalGlue()); add(new JButton("Um")); add(Box.createHorizontalGlue()); add(new JButton("Dois")); add(Box.createHorizontalStrut(10)); add(new JButton("Três")); add(Box.createHorizontalStrut(30)); add(new JButton("Quatro")); add(Box.createHorizontalGlue()); add(new JButton("Cinco")); add(Box.createHorizontalGlue()); } }
{
public GerenciadorBoxLayout() {
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e){System.exit(0);}}); setSize(500,100); setLocation(150,150); setTitle("BoxLayout"); Container b = Box.createHorizontalBox(); getContentPane().add(b,BorderLayout.CENTER); b.add(new PainelBox()); }
public static void main (String[] args) {
GerenciadorBoxLayout fr = new GerenciadorBoxLayout(); fr.setVisible(true);
} }
Figura 1.13. Gerenciador de Layout BoxLayout
Observa-se, na figura 1.13, que os botões não ficaram distanciados uniformemente. Isso porque
dois métodos foram utilizados: o
createHorizontalGlue(), que determina um espaçamento
variável, conforme o tamanho da janela e o
createHorizontalStrut(), que determina um
espaçamento fixo, determinado pelo seu parâmetro.
1.8.5 Gerenciador GridBagLayout
O gerenciador
GridBagLayouté bastante flexível, permitindo posicionamento dos componentes
em relação aos outros. Assim, é possível criar praticamente qualquer tipo de layout. Por ser mais
flexível, é também mais difícil de ser utilizado. O construtor não possui argumentos e a aparência
do layout é controlada pela classe
GridBagConstraints. Os componentes gerenciados devem
estar associados a um objeto
GridBagConstraints, que possui campos, mostrados na tabela 1.1,
para controle dos componentes.
Campo
Descrição
int gridx, gridy
Utilizado para controlar o posicionamento dos componentes
na grade do layout.
int weightx, weighty
Utilizado para especificar um percentual de aumento do local
destinado aos componentes, que irão aumentar também se
estiverem expandidos.
int fill
Utilizado para expandir o componente a fim de preencher o
espaço reservado a ele.
componente irá se espalhar.
int anchor
Utilizado para controlar a posição do componente, caso ele
não esteja espalhado.
int ipadx, ipady
Utilizado para controlar o aumento do tamanho mínimo dos
componente.
Insets insets
Utilizado para controlar o afastamento entre componentes.
Tabela 1.1. Campos da classe GridBagConstraints
A utilização desses campos são demonstradas através de exemplos. O primeiro deles mostra um
GridBagLayout
com cinco botões inseridos em posições determinadas pelo
gridxe
gridy.
import java.awt.*;import java.awt.event.*; import javax.swing.*;
class PainelGridBag extends JPanel {
GridBagConstraints restricoes = new GridBagConstraints(); public PainelGridBag() { setLayout(new GridBagLayout()); addGridBag(new JButton("Um"), 1, 0); addGridBag(new JButton("Dois"), 0, 1); addGridBag(new JButton("Três"), 1, 1); addGridBag(new JButton("Quatro"), 2, 1); addGridBag(new JButton("Cinco"), 1, 2); }
void addGridBag(Component objeto, int x, int y) { restricoes.gridx = x; restricoes.gridy = y; add(objeto, restricoes); } }
public class GerenciadorGridBagLayout extends JFrame {
public GerenciadorGridBagLayout() {
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e){System.exit(0);}}); setSize(270,130); setLocation(150,150); setTitle("GridBagLayout"); Container P = getContentPane(); P.add(new PainelGridBag()); }
public static void main (String[] args) {
GerenciadorGridBagLayout fr = new GerenciadorGridBagLayout(); fr.setVisible(true);
} }
Figura 1.13. Gerenciador de Layout GridBagLayout com cinco botões
O resultado, mostrado na figura 1.13, apresenta cinco botões inseridos em coordenadas que
indicam a presença de três linhas por três colunas (0, 1 e 2). O tamanho da grade é definido por
essas coordenadas, sendo possível, por isso, ter quantas colunas e linhas se desejar. O método
addGridBag()
criado serve para auxiliar na definição dos valores que os campos de controle do
GridBagConstraintsirão assumir.
Para que os botões preencham toda a área do painel é necessário definir, no construtor, a restrição
fill
para
BOTHe os campos
weigthxe
weigthypara
1, assim:
public PainelGridBag() { setLayout(new GridBagLayout()); restricoes.weightx = 1.0; restricoes.weighty = 1.0; restricoes.fill = GridBagConstraints.BOTH; addGridBag(new JButton("Um"), 1, 0); addGridBag(new JButton("Dois"), 0, 1); addGridBag(new JButton("Três"), 1, 1); addGridBag(new JButton("Quatro"), 2, 1); addGridBag(new JButton("Cinco"), 1, 2); }Figura 1.14. Gerenciador de Layout GridBagLayout ocupando todo espaço disponível
O resultado é o preenchimento de todo painel, como mostra a figura 1.14. O
fillainda pode ser
definido como:
HORIZONTAL, preenchendo o espaço horizontal disponível;
VERTICAL,
preenchendo o espaço vertical disponível e;
NONE, não preenchendo o espaço disponível. Os
campos
weigthxe
weigthydevem receber um valor diferente de zero, pois o preenchimento não
ocorre se esse valor for igual a zero, que é o valor default.
É possível realizar um espalhamento dos componentes em mais do que uma linha e/ou coluna.
Para isso, é necessário combinar os valores de
gridxe
gridycom a determinação da altura (em
número de linhas) e largura (em número de colunas) através dos campos
gridwidthe
gridheight, assim:
public PainelGridBag() { setLayout(new GridBagLayout()); restricoes.weightx = 1.0; restricoes.weighty = 1.0; restricoes.fill = GridBagConstraints.BOTH; restricoes.gridwidth = 3; addGridBag(new JButton("Um"), 0, 0); restricoes.gridwidth = 1; addGridBag(new JButton("Dois"), 0, 1); addGridBag(new JButton("Três"), 1, 1); restricoes.gridheight = 2; addGridBag(new JButton("Quatro"), 2, 1); restricoes.gridheight = 1; addGridBag(new JButton("Cinco"), 0, 2); addGridBag(new JButton("Seis"), 1, 2); }Figura 1.15. Gerenciador de Layout GridBagLayout utilizando espalhamento
Percebe-se, pelo resultado apresentado na figura 1.15, que o botão
Umocupou três colunas e uma
linha, enquanto o botão
Quatroocupou duas linhas e uma coluna. No momento que o número de
colunas/linhas é definido, todos os componentes utilizarão esse tamanho de espaço daí pra diante,
a não ser que este seja redefinido.
É possível também definir o tamanho dos componentes através do peso atribuído aos campos
weigthx
e
weigthy, como no exemplo:
public PainelGridBag() { setLayout(new GridBagLayout()); restricoes.weighty = 1.0; restricoes.fill = GridBagConstraints.BOTH; restricoes.weightx = 0.2; addGridBag(new JButton("Um"), 0, 0); restricoes.weightx = 0.6; addGridBag(new JButton("Dois"), 1, 0); restricoes.weightx = 1.5; addGridBag(new JButton("Três"), 2, 0); restricoes.weightx = 4.0; addGridBag(new JButton("Quatro"), 3, 0); }Figura 1.16. Gerenciador de Layout GridBagLayout com determinação de pesos
Para que o exemplo fique igual ao apresentado na figura 1.16, é necessário mudar o
setSize()do frame para
(400,60). Os botões ficam dispostos em uma única linha, com tamanhos
diferentes, determinados pela atribuição de seus respectivos pesos, sabendo-se que o valor
específico do peso não é o que importa, e sim as proporções relativas entre os botões e o tamanho
do painel.
O aumento do tamanho de alguns componentes pode ser feito pelos campos
ipadxe
ipady, que
especificam valores de aumento vertical e horizontal. Além disso, é possível fixar uma posição
do componente, dentro do espaço reservado a ele, desde que ele não esteja espalhado em mais
que uma coluna e/ou linha. Isso é feito através do
anchor. Exemplo:
public PainelGridBag() { setLayout(new GridBagLayout()); addGridBag(new JButton("Um"), 1, 0); restricoes.ipadx=10; restricoes.ipady=10; addGridBag(new JButton("Dois"), 0, 1); restricoes.ipadx=0; restricoes.ipady=0; restricoes.anchor = GridBagConstraints.SOUTHEAST; addGridBag(new JButton("Três"), 1, 1); restricoes.ipadx=10; restricoes.ipady=10; restricoes.anchor = GridBagConstraints.CENTER; addGridBag(new JButton("Quatro"), 2, 1); restricoes.ipadx=0; restricoes.ipady=0; addGridBag(new JButton("Cinco"), 1, 2); }
Figura 1.17. Gerenciador de Layout GridBagLayout com aumento do tamanho e posicionamento de componentes
Novamente, para que o exemplo fique igual ao da figura 1.17, é necessário alterar o
setSize()do frame para
(270,130). Percebe-se que o tamanho dos componentes
Doise
Quatrofoi
aumentado, sendo mantido o tamanho mínimo do botão
Três. Para esse mesmo botão
Trêsfoi
especificado um posicionamento fixo no canto inferior direito, dentro de sua área definida. O
concedida. O valor padrão é
concedida. O valor padrão é
CENTERCENTER, e os outros valores possíveis são:
, e os outros valores possíveis são:
NORTHNORTH,,
NORTHEASTNORTHEAST,,
EASTEAST,,
SOUTHEAST
SOUTHEAST
,,
SOUTHSOUTH,,
SOUTHWESTSOUTHWEST,,
WESTWEST, e
, e
NORTHWESTNORTHWEST..
Através do campo
Através do campo
insetsinsetsé possível indicar as distâncias entre os componentes do layout. Uma
é possível indicar as distâncias entre os componentes do layout. Uma
classe
classe
InsetsInsetspossui valores para as quatro direções: cima, baixo, direita e esquerda, dando
possui valores para as quatro direções: cima, baixo, direita e esquerda, dando
muita flexibilidade ao layout. O valor padrão é
muita flexibilidade ao layout. O valor padrão é
(0, 0, 0, 0)(0, 0, 0, 0). Exemplo:
. Exemplo:
public PainelGridBag() public PainelGridBag() { { setLayout(new GridBagLayout()); setLayout(new GridBagLayout()); restricoes.weightx = 1.0; restricoes.weightx = 1.0; restricoes.weighty = 1.0; restricoes.weighty = 1.0; restricoes.fill = GridBagConstraints.BOTH; restricoes.fill = GridBagConstraints.BOTH;
restricoes.insets = new Insets(3,3,3,3);
restricoes.insets = new Insets(3,3,3,3);
addGridBag(new JButton("Um"), 1, 0); addGridBag(new JButton("Um"), 1, 0); addGridBag(new JButton("Dois"), 0, 1); addGridBag(new JButton("Dois"), 0, 1); addGridBag(new JButton("Três"), 1, 1); addGridBag(new JButton("Três"), 1, 1); addGridBag(new JButton("Quatro"), 2, 1); addGridBag(new JButton("Quatro"), 2, 1); addGridBag(new JButton("Cinco"), 1, 2); addGridBag(new JButton("Cinco"), 1, 2); } }
Figura 1.18. Gerenciador de Layout GridBagLayout utilizando Insets Figura 1.18. Gerenciador de Layout GridBagLayout utilizando Insets
A figura 1.18 mostra que cada componente ganhou um espaço adicional de três pixels para cada
A figura 1.18 mostra que cada componente ganhou um espaço adicional de três pixels para cada
uma das direções: cima, baixo, direita e esquerda.
uma das direções: cima, baixo, direita e esquerda.
1.8.6
1.8.6 Layouts Compostos
Layouts Compostos
Normalmente, ao querer criar um determinado layout, a utillização de um gerenciador apenas não
Normalmente, ao querer criar um determinado layout, a utillização de um gerenciador apenas não
é suficiente. É necessário, então, combinar os diferentes layouts, como no exemplo a seguir.
é suficiente. É necessário, então, combinar os diferentes layouts, como no exemplo a seguir.
import java.awt.*; import java.awt.*; import java.awt.event.*; import java.awt.event.*; import javax.swing.*; import javax.swing.*;
class PainelComposto extends JPanel
class PainelComposto extends JPanel
{ { public PainelComposto() public PainelComposto() { { setLayout(new BorderLayout()); setLayout(new BorderLayout());
add(new JTextField("Digite seu texto aqui"),BorderLayout.NORTH);
add(new JTextField("Digite seu texto aqui"),BorderLayout.NORTH);
add(new PainelTipoFlow(),BorderLayout.SOUTH); add(new PainelTipoFlow(),BorderLayout.SOUTH); } } } }
class PainelTipoFlow extends JPanel
class PainelTipoFlow extends JPanel
{
public PainelTipoFlow() public PainelTipoFlow() { { setLayout(new FlowLayout()); setLayout(new FlowLayout()); add(new JButton("Um")); add(new JButton("Um")); add(new JButton("Dois")); add(new JButton("Dois")); add(new JButton("Três")); add(new JButton("Três")); add(new JButton("Quatro")); add(new JButton("Quatro")); add(new JButton("Cinco")); add(new JButton("Cinco")); } } } }
public class LayoutsCompostos extends JFrame
public class LayoutsCompostos extends JFrame
{ { public LayoutsCompostos() public LayoutsCompostos() { { addWindowListener(new WindowAdapter() addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e){System.exit(0);}});
{public void windowClosing(WindowEvent e){System.exit(0);}});
setSize(400,120); setSize(400,120); setLocation(150,150); setLocation(150,150); setTitle("Layouts Compostos"); setTitle("Layouts Compostos"); Container P = getContentPane(); Container P = getContentPane(); P.add(new PainelComposto()); P.add(new PainelComposto()); } }
public static void main (String[] args)
public static void main (String[] args)
{
{
LayoutsCompostos fr = new LayoutsCompostos();
LayoutsCompostos fr = new LayoutsCompostos();
fr.setVisible(true); fr.setVisible(true); } } } }
Figura 1.17. Layouts Compostos – BorderLayout e
Figura 1.17. Layouts Compostos – BorderLayout e FlowLayoutFlowLayout
A figura 1.17 mostra que o painel com layout
A figura 1.17 mostra que o painel com layout
FlowLayoutFlowLayoutfoi inserido na localização sul do
foi inserido na localização sul do
painel com layout
painel com layout
BorderLayoutBorderLayout. Isso é uma prática bastante comum para se alcançar layouts
. Isso é uma prática bastante comum para se alcançar layouts
com disposição de componentes que satisfaçam aos objetivos da aplicação. A localização do
com disposição de componentes que satisfaçam aos objetivos da aplicação. A localização do
centro ficou vazia porque isso é uma característica do
centro ficou vazia porque isso é uma característica do
BorderLayoutBorderLayout: não expandir as outras
: não expandir as outras
localizações se a do centro estiver vazia.
localizações se a do centro estiver vazia.
2. Interface Gráfica com o Usuário e a Manipulação de Eventos
2. Interface Gráfica com o Usuário e a Manipulação de Eventos
Os componentes de uma Interface Gráfica com o Usuário (GUI) são baseados em eventos, os
Os componentes de uma Interface Gráfica com o Usuário (GUI) são baseados em eventos, os
quais são gerados na interação do usuário com a interface. Alguns exemplos de eventos possíveis:
quais são gerados na interação do usuário com a interface. Alguns exemplos de eventos possíveis:
mover/clicar o mouse, clicar em um botão, fechar o frame, digitar um texto em um campo de
mover/clicar o mouse, clicar em um botão, fechar o frame, digitar um texto em um campo de
edição, etc. É necessário, então, realizar uma manipulação dos eventos gerados. As próximas
edição, etc. É necessário, então, realizar uma manipulação dos eventos gerados. As próximas
seções descrevem o modelo de manipulação de eventos AWT a partir de alguns elementos GUI
seções descrevem o modelo de manipulação de eventos AWT a partir de alguns elementos GUI
simples.
simples.
2.1
2.1 O Modelo de Manipulação de Eventos AWT
O Modelo de Manipulação de Eventos AWT
É muito comum encontrar, em linguagens de programação visuais, o tratamento dos eventos que
É muito comum encontrar, em linguagens de programação visuais, o tratamento dos eventos que
são gerados por seus componentes visuais. Com Java não é diferente, tanto na biblioteca AWT,
são gerados por seus componentes visuais. Com Java não é diferente, tanto na biblioteca AWT,
quanto na biblioteca Swing, existem classes para manipulação de eventos. A maneira como essa
quanto na biblioteca Swing, existem classes para manipulação de eventos. A maneira como essa
manipulação acontece não é tão simples como nas linguagens Delphi e Visual Basic, exigindo
manipulação acontece não é tão simples como nas linguagens Delphi e Visual Basic, exigindo
que haja a designação de pelo menos um (pode ter mais que um) objeto
que haja a designação de pelo menos um (pode ter mais que um) objeto
ouvinte de eventos
ouvinte de eventos
, que
, que
deve ser um objeto de uma classe que implemente a interface ouvinte (
deve ser um objeto de uma classe que implemente a interface ouvinte (
listener interfacelistener interface). O
). O
objeto deve efetuar convenientemente a resposta desejada ao evento. É necessário lembrar que as
objeto deve efetuar convenientemente a resposta desejada ao evento. É necessário lembrar que as
interfaces possuem métodos
interfaces possuem métodos
abstractabstractpara serem redefinidos pelas classes que as
para serem redefinidos pelas classes que as
implementarem. Além disso, “todos” os métodos
implementarem. Além disso, “todos” os métodos
abstractabstractdevem
devem ser
ser redefinidos.
redefinidos. O
O registro
registro
desses ouvintes é feito em objetos conhecidos como
desses ouvintes é feito em objetos conhecidos como
origem do evento
origem do evento
, como um botão, por
, como um botão, por
exemplo. A origem envia objetos eventos para o(s) ouvinte(s) na ocorrência de um evento, e
exemplo. A origem envia objetos eventos para o(s) ouvinte(s) na ocorrência de um evento, e
esse(s) usa(m) essa informação para determinar o que será feito em reação ao evento.
esse(s) usa(m) essa informação para determinar o que será feito em reação ao evento.
Um exemplo de registro de um objeto ouvinte
Um exemplo de registro de um objeto ouvinte
painelpainelem um objeto de origem
em um objeto de origem
botãobotão::
MeuPainel painel = new MeuPainel();
MeuPainel painel = new MeuPainel();
Jbutton botao = new Jbutton(“OK”);
Jbutton botao = new Jbutton(“OK”);
botao.addActionListener(painel); botao.addActionListener(painel);
seguindo a sintaxe:
seguindo a sintaxe:
ObjetoOrigem.addEventListener(ObjetoOuvinte); ObjetoOrigem.addEventListener(ObjetoOuvinte);Assim, o objeto
Assim, o objeto
painelpainelé notificado sempre que um evento ocorrer em
é notificado sempre que um evento ocorrer em
botaobotao, como o clique,
, como o clique,
por exemplo. No exemplo, a classe onde o objeto ouvinte
por exemplo. No exemplo, a classe onde o objeto ouvinte
painelpainelé registrado deve implementar
é registrado deve implementar
a interface
a interface
ActionListenerActionListenere definir o método
e definir o método
actionPerformed()actionPerformed(), que recebe um objeto
, que recebe um objeto
ActionEvent
ActionEvent
como parâmetro. Assim:
como parâmetro. Assim:
public class MeuPainel extends Jpanel implements ActionListener
public class MeuPainel extends Jpanel implements ActionListener
{
{
...
...
public void actionPerformed(ActionEvent evt)
public void actionPerformed(ActionEvent evt)
{
{
//código para a reação ao evento
//código para a reação ao evento
}
}
}
}
2.2
2.2 Eventos em Botões
Eventos em Botões
O exemplo a seguir apresenta um painel com três botões, sendo que o próprio painel é definido
O exemplo a seguir apresenta um painel com três botões, sendo que o próprio painel é definido
como ouvinte para monitorar os eventos que podem acontecer nos botões.
como ouvinte para monitorar os eventos que podem acontecer nos botões.
import java.awt.*; import java.awt.*; import java.awt.event.*; import java.awt.event.*; import javax.swing.*; import javax.swing.*;
class PainelEventosBotao extends JPanel implements ActionListener
class PainelEventosBotao extends JPanel implements ActionListener
{
{
private JButton BotaoVerde;
private JButton BotaoVerde;
private JButton BotaoPreto;
private JButton BotaoBranco; public PainelEventosBotao() {
BotaoVerde = new JButton("Verde"); BotaoPreto = new JButton("Preto"); BotaoBranco = new JButton("Branco"); add(BotaoVerde); add(BotaoPreto); add(BotaoBranco); BotaoVerde.addActionListener(this); BotaoPreto.addActionListener(this); BotaoBranco.addActionListener(this); }
public void actionPerformed(ActionEvent evt) {
Object origem = evt.getSource(); Color cor = getBackground(); if (origem == BotaoVerde)
cor = Color.green;
else if (origem == BotaoPreto) cor = Color.black;
else if (origem == BotaoBranco) cor = Color.white;
setBackground(cor); repaint();
} }
public class TesteEventosBotao extends JFrame {
public TesteEventosBotao() {
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e){System.exit(0);}}); setSize(400,130);
setTitle("Eventos em Botões"); Container P = getContentPane(); P.add(new PainelEventosBotao()); }
public static void main(String[] args) {
JFrame fr = new TesteEventosBotao(); fr.setVisible(true);
} }
Figura 2.1. Eventos em objetos JButton
Na criação do painel, três botões foram adicionados a ele. Logo após, foi determinado que o
próprio painel (
this) seria o ouvinte das ações dos três botões. O método
actionPerformed()é
o único método da interface
ActionListener, por isso apenas ele deve ser implementado. Esse
método recebe como parâmetro um objeto do tipo
ActionEvent, que fornece informações sobre
o evento ocorrido, sendo o local para implementar as ações a serem realizadas. A classe
TesteEventosBotao
adiciona o painel com os botões.
2.3 Eventos em Caixas de Texto
O exemplo a seguir apresenta um painel com duas caixas de texto do tipo
JTextFielde uma do
tipo
JPasswordField. O objeto ouvinte definido foi o próprio painel e, quando for dado um
Enter em qualquer uma das caixas, o conteúdo digitado irá aparecer em uma caixa de mensagens.
import java.awt.*;
import java.awt.event.*; import javax.swing.*;
class PainelEventosCaixaTexto extends JPanel implements ActionListener {
private JTextField Codigo; private JTextField Nome;
private JPasswordField Senha; public PainelEventosCaixaTexto() {
Codigo = new JTextField(3); add(Codigo);
Nome = new JTextField("Digite seu nome"); add(Nome);
Senha = new JPasswordField(10); add(Senha);
Codigo.addActionListener(this); Nome.addActionListener(this); Senha.addActionListener(this); }
public void actionPerformed(ActionEvent evt) {
Object origem = evt.getSource(); if (origem == Codigo)
JOptionPane.showMessageDialog(null,"Código = "+ evt.getActionCommand()); else if (origem == Nome)
JOptionPane.showMessageDialog(null,"Nome = "+ evt.getActionCommand()); else if (origem == Senha)
JOptionPane.showMessageDialog(null,"Senha = "+ evt.getActionCommand()); }
}
public class TesteEventosCaixaTexto extends JFrame {
public TesteEventosCaixaTexto() {
{public void windowClosing(WindowEvent e){System.exit(0);}}); setSize(300,70);
setLocation(300,350);
setTitle("Eventos em Caixas de Texto"); Container P = getContentPane();
P.add(new PainelEventosCaixaTexto()); }
public static void main(String[] args) {
JFrame fr = new TesteEventosCaixaTexto(); fr.setVisible(true);
} }
Figura 2.2. Eventos em objetos JTextField e JPasswordField
A figura 2.1 mostra o que acontece se for digitado algo em código e logo a seguir for pressionada
a tecla Enter. Novamente, o método
actionPerformed()foi sobreposto e, no momento que for
pressionado o Enter, o
getSource()pega o objeto onde está o foco naquele momento e mostra
em uma caixa de mensagens, criada a partir do método
showMessageDialog(), pertencente à
classe
JOptionPane.
2.4 Utilizando Eventos para Alterar o Aspecto Visual da Aplicação
O Look and Feel é a aparência que sua aplicação irá tomar, definindo a forma como seus
componentes serão mostrados na tela. Ao utilizar componentes da biblioteca Swing, o aspecto
visual é determinado pelo estilo Metal, mas existem outros, e a alteração é feita através do
método
UIManager.setLookAndFeel(), passando como parâmetro o aspecto visual desejado,
localizados em pacotes diferentes:
•
Aspecto Metal:
javax.swing.plaf.metal.MetalLookAndFeel•
Aspecto Windows:
com.sun.java.swing.plaf.windows.WindowsLookAndFeel •Aspecto Motif:
com.sun.java.swing.plaf.motif.MotifLookAndFeel•
Aspecto GTK:
com.sun.java.swing.plaf.gtk.GTKLookAndFeel •Aspecto Mac:
javax.swing.plaf.mac.MacLookAndFeelLogo após, é necessário chamar o método
SwingUtilities.updateComponentTreeUIpara
atualizar todo o conjunto de componentes.
import java.awt.*;
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 {