![]() |
|
Introdução
Na era da Web, quase passa desapercebido a importância das aplicações Desktop e sua enorme variedade de aplicativos para diversos sistemas operacionais. O desafio e construir aplicações Desktop que possam ser executadas nestes diversos sistemas operacionais, sem que tenhamos que reescrever o sistema.
No Portal Java(http://www.portaljava.com), em pesquisa on-line aparece um resultado que sinaliza a importância as aplicações Desktop.

Neste tutorial vamos introduzir os conceitos de Java Swing, que constitui um importante conjunto de API's para construção de robustas Interfaces Gráficas com o Usuários.
JFC e Swing
Quando a linguagem Java 1.0
foi lançada, ela continha uma biblioteca de classes que a
SUN
chamou de AWT(Abstract Window Tool-kit –
ferramentas de
janela abstratas) para programação GUI
básica.
A Netscape em 1996 criou uma biblioteca
GUI chamada
de IFC-Internet Foudation Classes. A SUN trabalhou junto com a Netscape
para aperfeiçoar e criou uma biblioteca de interface de
usuário com o nome código de
“Swing”, que
alguns chamaram de “conjunto Swing”.
JFC é abreviatura de Java
Foundation Classes,
que abrangem um grupo das características para construir
Interfaces Gráficas com o Usuários (GUIs) e
adição de ricas funcionalidades e
interatividade
com aplicações Java.
Swing é um kit de ferramentas
GUI e faz parte da JFC.
Swing não é um
substituto completo do
AWT, simplesmente fornece à interface de usuário
componentes mais capazes
Galeria de componentes Swing:
![]() |
JApplet |
![]() |
Borders |
![]() |
JButton |
![]() |
JCheckBox |
![]() |
JCheckBoxMenuItem |
![]() |
JColorChooser |
![]() |
JComboBox |
| ImageIcon | |
![]() |
JDialog |
![]() |
JFileChooser |
![]() |
JInternalFrame |
![]() |
JLabel |
![]() |
JList |
![]() |
JMenu |
![]() |
JMenuBar |
![]() |
JOptionPane |
![]() |
JPopupMenu |
![]() |
JRadioButton |
![]() |
JRadioButtonMenuItem |
![]() |
JScrollBar |
![]() |
JScrollPane |
![]() |
JSlider |
![]() |
JSplitPane |
![]() |
JTabbedPane |
![]() |
JTable |
![]() |
JTextArea |
![]() |
JTextField |
![]() |
JToggleButton |
![]() |
JToolBar |
![]() |
JToolTip |
![]() |
JTree |
API Swing
A API Swing é poderosa,
flexível e imensa, que possui pacotes públicos,
cada um
com sua própria finalidade distinta:
javax.swing
Pacote swing de alto nível,
consiste
primariamente de componentes, adaptadores, modelos padrão de
componentes e interface.
javax.swing.border
O pacote border declara a interface
Border e classes, que define especifico estilo de borda.
javax.swing.colorchooser
O pacote colorchooser contem suporte de
para classes para componentes color chooser .
javax.swing.event
O pacote de event é para
eventos e listeners
específicos Swing. Adiciona ao java.awt.event
types,
componentes Swing podem gerar seus próprios tipos de eventos.
javax.swing.filechooser
O pacote filechooser contem classes de
suporte para componentes de seleção de arquivos.
javax.swing.plaf
Plug-in look-and-feel (PLAF) pacote que contém Interfaces com usuário(UI) classes (delegadas) que implementam diferentes look-and-feel aspects para componentes Swing. Há também alguns pacotes de PLAF sob a hierarquia.
javax.swing.table
O pacote table contem suporte para
interfaces e e classes para o componente Swing table.
javax.swing.text
O pacote text contem classes de suporte
para o framework do Swing de documento.
javax.swing.text.html
O pacote text.html contem classes de
suporte para HTML versão 3.2 interpretador e
analisador.
javax.swing.text.rtf
O pacote text.rtf contem classes de
suporte para um básico interpretados Rich Text
Format (RTF).
javax.swing.tree
O pacote tree contem interface e classes
para o componente tree do Swing.
javax.swing.undo
O pacote undo provê classes de
suporte para implementar a capacidade de fazer/desfazer nos GUI.
javax.accessibility
O pacote de acessibilidade da JFC
é incluido
nas classes Swing. Entretanto, seu uso não será
discutido
aqui.
Componentes Swing
O widget é um termo sem
tradução que designa componentes de interface
gráfica com o usuário (GUI). Qualquer item de uma
interface gráfica é chamada de widget, por
exemplo:
janelas, botões, menus ítens de menus,
ícones,
barras de rolagem, etc.
O pacote de acessibilidade da JFC
é
incluído nas classes Swing. Entretanto, seu uso
não
será discutido aqui.
![]() |
| Hierarquia de componentes similares ao AWT |
![]() |
| Hierarquia de componentes novos no Swing |
Usando componentes Swing na construção de interfaces com o usuário.
O exemplo AloMundo Swing, foi criado uma interface com o usuário usando componentes do pacote javax.swing.
Código:
import javax.swing.*;
public class AloMundoSwing {
/**
* Cria um GUI e o exibe. Para thread safety,
* este metodo podera invocar para uma thread
* de disparo de evento(event-dispatching thread).
*/
private static void criaExibeGUI() {
//Faz com que tenha uma decoracao de janela
JFrame.setDefaultLookAndFeelDecorated(true);
//Cria e organiza a janela
JFrame frame = new JFrame("AloMundoSwing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Adiciona o rotulo "Alo Mundo".
JLabel label = new JLabel("Alo Mundo");
frame.getContentPane().add(label);
//Exibe a janela
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
//Agenda um trabalho para o event-dispatching thread:
//cria e exibe uma aplicacao GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
criaExibeGUI();
}
});
}
}
Resultado:

Este é um simple
exemplos de
aplicação Swing que pode ser escrito. No
código do
programa Swing temos:
1. Importar os pacotes pertinentes:
2. Posicionando o container top-level.
3. Exibição do container.
4. Thread-safe.
import java.awt.*;
import java.awt.event.*;
Estes dois pacotes são
requeridos por que os
componentes Swing usam a infra-estrutura AWT, incluindo o modelo de
eventos. O modelo de eventos governa como um componente reage a um
evento semelhante a um clique de botão ou o movimento de
mouse.
Para fazer o programa fechar, quando o
botão
Close [x] é clicado, incluímos o
código:
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
O exemplo AloMundoSwing tem um
único container top-level, um JFrame.
Implementando uma
instância da classe Jframe, um frame é uma janela,
por
padrão, tem ornamentos semelhantes a bordas,
títulos,
botões com ícones para fechar a janela.
Aplicações tipicamente GUI usam um frame no
mínimo.
O código a seguir, mostra
como um frame é construído e exibido:
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("HelloWorldSwing");
...
frame.pack();
frame.setVisible(true);
A exceção dos
containes top-level, semelhantes a um Jframe, todos os componentes
descendentes da classe JComponent. HelloWorldSwing usa um
JComponent descendente chamado JLabel, que exibe um texto Hello World.
As duas próximas linhas de código,
constrói e
adiciona um componente JLabel num frame:
JLabel label = new JLabel("Hello World");
frame.getContentPane().add(label);
Pode parecer estranho, mas
é recomendado utilizar o código a seguir para que
as
aplicações GUI não tenham problemas de
threas-safety que podem parar a interface antes de aparecer a
exibição.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
/* cria e exibe o GUI */
}
});
Look e Feel
Swing permite que seja especificado um look and feel para os usuários do programas--Java, GTK+, Windows, e assim por diante.
Código
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class AplicacaoSwing implements ActionListener {
private static String labelPrefix = "Numero de cliques de botao: ";
private int numClicks = 0;
final JLabel label = new JLabel(labelPrefix + "0 ");
//Especifica o look and feel para usar. Valores validos:
//null (usa o padrao), "Metal", "System", "Motif", "GTK+"
final static String LOOKANDFEEL = "System";
public Component createComponents() {
JButton button = new JButton("Eu sou um botao Swing!");
button.setMnemonic(KeyEvent.VK_I);
button.addActionListener(this);
label.setLabelFor(button);
/*
* Um facil caminho para colocar um espaco entre o container top-level
* que contem e para colocar JPanel contido
* tem uma borda vazia (empty).
*/
JPanel pane = new JPanel(new GridLayout(0, 1));
pane.add(button);
pane.add(label);
pane.setBorder(BorderFactory.createEmptyBorder(
30, //top
30, //left
10, //bottom
30) //right
);
return pane;
}
public void actionPerformed(ActionEvent e) {
numClicks++;
label.setText(labelPrefix + numClicks);
}
private static void initLookAndFeel() {
String lookAndFeel = null;
if (LOOKANDFEEL != null) {
if (LOOKANDFEEL.equals("Metal")) {
lookAndFeel = UIManager.getCrossPlatformLookAndFeelClassName();
} else if (LOOKANDFEEL.equals("System")) {
lookAndFeel = UIManager.getSystemLookAndFeelClassName();
} else if (LOOKANDFEEL.equals("Motif")) {
lookAndFeel = "com.sun.java.swing.plaf.motif.MotifLookAndFeel";
} else if (LOOKANDFEEL.equals("GTK+")) { //novo a partir da versao 1.4.2
lookAndFeel = "com.sun.java.swing.plaf.gtk.GTKLookAndFeel";
} else {
System.err.println("Valor inesperado de especifico LOOKANDFEEL: "
+ LOOKANDFEEL);
lookAndFeel = UIManager.getCrossPlatformLookAndFeelClassName();
}
try {
UIManager.setLookAndFeel(lookAndFeel);
} catch (ClassNotFoundException e) {
System.err.println("Nao pode encontrar classe especifica para o look and feel:"
+ lookAndFeel);
System.err.println("Voce incluiu a biblioteca L&F library no class path?");
System.err.println("Usa o padrao look and feel.");
} catch (UnsupportedLookAndFeelException e) {
System.err.println("Nao pode ser especificado um look and feel ("
+ lookAndFeel
+ ") nesta plataforma.");
System.err.println("Uso do padrao look and feel.");
} catch (Exception e) {
System.err.println("Nao pode obter especifico look and feel ("
+ lookAndFeel
+ "), por alguma razao .");
System.err.println("Uso do padrao look and feel.");
e.printStackTrace();
}
}
}
/**
* Cria um GUI e o exibe. Para thread safety,
* este metodo podera invocar para uma thread
* de disparo de evento(event-dispatching thread).
*/
private static void criaExibeGUI() {
//Inicializa o look and feel.
initLookAndFeel();
//Faz com se tenha janelas com decoracoes agradaveis.
JFrame.setDefaultLookAndFeelDecorated(true);
//Cria e organiza janela.
JFrame frame = new JFrame("AplicacaoSwing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
AplicacaoSwing app = new AplicacaoSwing();
Component contents = app.createComponents();
frame.getContentPane().add(contents, BorderLayout.CENTER);
//Exibe a janela.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
//Agenda um trabalho para o event-dispatching thread:
//cria e exibe uma aplicacao GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
criaExibeGUI();
}
});
}
}
Resultado:
![]() |
![]() |
A parte de código a
seguir, mostra como AplicacaoSwing especifica de que maneira
deve
ser usado o Java look and feel:
String lookAndFeel = null;
...
lookAndFeel = UIManager.getCrossPlatformLookAndFeelClassName();
...
try {
UIManager.setLookAndFeel(lookAndFeel);
} catch (Exception e) { }
...// Cria e exibe um GUI...
Construção de Botões e Rótulos.
Como a maioria dos GUIs, a
AplicacaoSwing GUI contem um botão e um
rótulo(label). O código a seguir, inicializa o
botão:
JButton button = new Jbutton("Eu sou um
botao Swing!");
button.setMnemonic('i');
button.addActionListener(/*...cria um
action listener...*/);
A primeira linha cria o
botão. A segunda
marca a letra "i" um mnemônico para o usuário
poder usar e
simular um clique do botão. Por exemplo, no Java
look and
feel, tipicamente é a tecla “Alt-i” que
faz isto. A
terceira linha registra para fornecer o evento (event handler) para o
clique do botão.
Onde as variáveis são declaradas e inicializadas os rotulos.
private static String labelPrefix = "Numero de cliques de botao: ";
private int numClicks =
0;
Código de
inicialização do GUI
final JLabel label = new
JLabel(labelPrefix + "0 ");
label.setLabelFor(button);
label.setText(labelPrefix + numClicks);
Adicionando um Componente ao Container
O programa AplicacaoSwing, agrupa o label e o botão no container (um JPanel) antes de adicionar o componente no frame. A seguir o código de inicialização do container:
Código:
Resultado:
A primeira linha cria um container e atribui um gerenciador de layout- no objeto determina o tamanho e posição de cada componente e adiciona para o container. O código new GridLayout(0,1) cria um gerenciador de layout que força o conteúdo do container's ser exibido numa unica coluna, com cada componente que tem o mesmo tamanho.
JPanel pane = new JPanel(new GridLayout(0, 1));
pane.add(button);
pane.add(label);
pane.setBorder(BorderFactory.createEmptyBorder(...);
Nestas duas linhas adiciona o botão e label no container. A
última linha adiciona uma borda.
Para adição de
bordas ao painel, o
código cria e ajusta uma borda que forneça algum
espaço vazio em torno do container - 30 pixels extras no
top, e 10 pixels extras a esquerda( left), direita(right) no
rodapé (bottom).
Adicionando bordas ao Redor dos Componentes
Código:
Resultado:

pane.setBorder(BorderFactory.createEmptyBorder(
30, //top
30, //left
10,
//bottom
30)
//right);
O código adiciona uma borda.
Para adição de
bordas ao painel, o
código cria e ajusta uma borda que forneça algum
espaço vazio em torno do container - 30 pixels extras no
top, e 10 pixels extras a esquerda( left), direita(right) no
rodapé (bottom).
Bordas tem características
herdadas do
JPanel da classe Jcomponent. Um objeto Border não
é
um JComponent; isto é, usa um ou mais JComponents
para
pintar o componente borda.
Handling Events
Cada vez que o usuário
digita um caráter ou aperta um botão do mouse, um
evento
ocorre. Todo o objeto pode ser notificado do evento. Todo o
objeto tem que implementar apropriadamente a interface e registra um
event listener na apropriada fonte do evento.
A classe AplicacaoSwing implementa um
event handler
para o clique do botão(action events). Observe o
código a
seguir:
public class AplicacaoSwing implements ActionListener {
...
JButton button = new Jbutton("Eu sou um
botao Swing!");
button.addActionListener(this);
....
public
void actionPerformed(ActionEvent e) {
numClicks++;
label.setText(labelPrefix + numClicks);
}
}
Cada event handler requer três partes no código:
1. Na declaração para a
classe event
handler, uma linha de código especifica na classe a
implementação da interface listener ou
extende a
classe que implementa a interface listener. Por exemplo:
public class MinhaClasse implements ActionListener {

Em geral, para detectar os
cliques do botão do usuário na tela(ou
equivalente no
teclado), um programa tem que ter um objeto que implemente a interface
ActionListener . O programa pode registrar que o objeto no action
listener no botão (a fonte do evento), usa o
método
addActionListener. Onde o usuário clicar com
botão na
tela que dispara o evento.
Este resultado na
invocação do action
listener's do método actionPerformed(o único
método na interface ctionListener). O simples argumento para
o
método no objeto ActionEvent que dá
sobre o evento
e na fonte do evento.
Os componentes Swing podem gerar muitos tipos de eventos.
Alguns eventos e suas associado no Event
Listeners:
| Ação do resultado do evento | Tipo Listener |
| Clique do usuário no botão, pressiona Enter quando um campo de texto, ou item menu de seleção | ActionListener |
| Usuário fecha um frame(janela principal) | WindowListener |
| Usuário preciona um botão do mouse quando o cursor passa sobre um componente | MouseListener |
| Usuário move o mouse sobre um componente. | MouseMotionListener |
| O componente torna-se visível | ComponentListener |
| O componente recebe o foco do teclado | FocusListener |
| Mudança de seleção na tabela ou lista | ListSelectionListener |
| Variação de uma propriedade no componente semelhante a um texto no label. | PropertyChangeListener |
Conversor de temperatura
Esta é uma simples ferramenta de conversão. O usuário entre com uma dad temperatura em graus Celsius e clica no botão Converter. Um label exibe a temperatura equivalente e graus Fahrenheit.
Código:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ConversaoCelsius implements ActionListener {
JFrame converterFrame;
JPanel converterPanel;
JTextField tempCelsius;
JLabel celsiusLabel, fahrenheitLabel;
JButton convertTemp;
public ConversaoCelsius() {
//Cria e organiza janela.
converterFrame = new JFrame("Converte graus Celsius para Fahrenheit");
converterFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
converterFrame.setSize(new Dimension(120, 40));
//Cria e constroi o painel.
converterPanel = new JPanel(new GridLayout(2, 2));
//Adiciona o widgets.
adicionaWidgets();
//Marca padrao o o botao
converterFrame.getRootPane().setDefaultButton(convertTemp);
//Adiciona o painel na janela
converterFrame.getContentPane().add(converterPanel, BorderLayout.CENTER);
//Exibe a janela.
converterFrame.pack();
converterFrame.setVisible(true);
}
/**
* Cria e adciona o widgets.
*/
private void adicionaWidgets() {
//Cria widgets.
tempCelsius = new JTextField(2);
celsiusLabel = new JLabel("Graus Celsius", SwingConstants.LEFT);
convertTemp = new JButton("Converte");
fahrenheitLabel = new JLabel("Graus Fahrenheit", SwingConstants.LEFT);
//Listen para evento do botao Converte
convertTemp.addActionListener(this);
//Adiciona widgets para container.
converterPanel.add(tempCelsius);
converterPanel.add(celsiusLabel);
converterPanel.add(convertTemp);
converterPanel.add(fahrenheitLabel);
celsiusLabel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
fahrenheitLabel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
}
public void actionPerformed(ActionEvent event) {
//Parse degrees Celsius as a double and convert to Fahrenheit.
int tempFahr = (int)((Double.parseDouble(tempCelsius.getText()))
* 1.8 + 32);
fahrenheitLabel.setText(tempFahr + " Graus Fahrenheit");
}
/**
* Cria um GUI e o exibe. Para thread safety,
* este metodo podera invocar para uma thread
* de disparo de evento(event-dispatching thread).
*/
private static void criaExibeGUI() {
//Faz com se tenha janelas com decoracoes agradaveis.
JFrame.setDefaultLookAndFeelDecorated(true);
ConversaoCelsius converter = new ConversaoCelsius();
}
public static void main(String[] args) {
//Agenda um trabalho para o event-dispatching thread:
//cria e exibe uma aplicacao GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
criaExibeGUI();
}
});
}
}
Resultado:

Vamos examinar o código
para ver como ConversaoCelsius analisa o número
que entrou
no JTextField.
Primeirot, este código
constroe um JTextField:
JTextField tempCelsius = null;
...
tempCelsius = new JtextField(5);
O argumento inteiro que é
passado no
construtuor do JTextField --5 no exemplo—indica o numero de
colunasno campo. Este número é usado junto com o
metrics
fornecido pela pela fonte para calcular a largura preferida do campo,
que é usada por layout managers. Este número
não
limita o número de caracteres que o usuário pode
entrar.
Nós queremos executar a
conversão quando o usuário clicar um
botão ou
pressionar ENTER no campo do texto. Para fazer assim,
nós
adicionamos um action event ao campo para o botão
convertTemp e
do texto tempCelsius.
convertTemp.addActionListener(this);
tempCelsius.addActionListener(this);
...
public void actionPerformed(ActionEvent
event) {
//Analisa graus Celsius para um double e converte
para Fahrenheit.
int tempFahr =
(int)((Double.parseDouble(tempCelsius.getText()))
* 1.8 + 32);
fahrenheitLabel.setText(tempFahr + " Fahrenheit");
}
O código event-handling entra no método actionPerformed. Chama o método do getText no campo do texto, tempCelsius, para recuperar os dados dentro dele. Em seguida usa o método parseDouble para analisar/converter o texto para um número de ponto flutuante e precisão dupla antes de converter a temperatura e transformar num resultado inteiro. Finalmente, chama o método do setText no fahrenheitLabel para fazer um label indicar a temperatura convertida.
Gerenciadores de Layout
FlowLayout
O gerenciador de layout de “fluxo” apenas posiciona os componentes em fila, um após o outro, cada qual com suas dimensões mínimas. O FlowLayout imita o fluxo de textos, e pode alinhar os componentes à direita, à esquerda, ou centraliza-los dentro do container. O uso mais comum deste layout é para preencher uma linha com maior quantidade possível de componentes, por exemplo em barras de ferramentas ou de status.
BorderLayout
BorderLayoutO BorderLayout
posiciona os componentes nas “bordas” do container,
deixando a maior parte de sua área disponível
para o
componente inserido no centro. Cada borda é identificado por
um
ponto cardeal(NORTH,SOUTH, EAST, WEST). Apenas um componente
será visível em cada borda, expandindo-se na
altura ou
largura para ocupar toda a borda do container, porém
assumindo o
valor mínimo na outra dimensão.
Note que esta
disposição reflete o
padrão na maioria das aplicações
desktop, como
processadores de texto ou programas de desenho: uma barra de
ferramentas ao norte, uma barra de status ao sul, opcionalmente outras
barras de ferramentas ao leste e oeste, e uma área de
edição ao centro.
Demo BorderLayout
Código:
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class DemoBorderLayout {
public static boolean RIGHT_TO_LEFT = false;
public static void addComponentsToPane(Container pane) {
if (!(pane.getLayout() instanceof BorderLayout)) {
pane.add(new JLabel("O Container não usa BorderLayout!"));
return;
}
if (RIGHT_TO_LEFT) {
pane.setComponentOrientation(
java.awt.ComponentOrientation.RIGHT_TO_LEFT);
}
JButton button = new JButton("Boatao 1 (PAGINA_INICIAR)");
pane.add(button, BorderLayout.PAGE_START);
//Faz a centralização de um grande componente, deste que
//tipico do uso de BorderLayout.
button = new JButton("Boatao 2 (CENTRO)");
button.setPreferredSize(new Dimension(200, 100));
pane.add(button, BorderLayout.CENTER);
button = new JButton("Boatao 3 (INICIAR_LINHA)");
pane.add(button, BorderLayout.LINE_START);
button = new JButton("NOME-LONGO Boatao 4 (FIM_PAGINA)");
pane.add(button, BorderLayout.PAGE_END);
button = new JButton("5 (FIM_LINHA)");
pane.add(button, BorderLayout.LINE_END);
}
/**
* Cria um GUI e o exibe. Para thread safety,
* este metodo podera invocar para uma thread
* de disparo de evento(event-dispatching thread).
*/
private static void createAndShowGUI() {
//Faz com que tenha uma decoracao de janela.
JFrame.setDefaultLookAndFeelDecorated(true);
//Cria e organiza a janela.
JFrame frame = new JFrame("DemoBorderLayout");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Organiza o conteudo no painel.
addComponentsToPane(frame.getContentPane());
//Uso do conteudo do painel por padrão o BorderLayout. No need for
//setLayout(new BorderLayout());
//Exibe janela.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
//Agenda um trabalho para o event-dispatching thread:
//cria e exibe uma aplicacao GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
Resultado:

GridLayout
O GridLayout organiza os
componentes em uma “grade” ou tabela com
número de
linhas e colunas pré-fixado no momento da sua
criação. Todas as células possuem o
mesmo tamanho,
e são expandidas igualmente para ocupar a área
total
disponível no container. Caso haja menos componentes do que
células, o espaço das células
vázias
é distribuído entre os componentes; mas podem
ficar
células vázias nas últimas colunas da
última linha.
O GridLayout é adequado
quando se deseja que
um grupo de componentes (ex.? Um grupo de botões) tenha
dimensões uniformes, como na caixa de ferramentas de um
programa
de desenho ou par de botões “OK” e
“Cancelar” de um diálogo.
Demo GridLayout
Código:
import java.awt.*;
import javax.swing.*;
public class DemoGridLayout {
public final static boolean RIGHT_TO_LEFT = false;
public static void addComponentsToPane(Container pane) {
if (RIGHT_TO_LEFT) {
pane.setComponentOrientation(
ComponentOrientation.RIGHT_TO_LEFT);
}
pane.setLayout(new GridLayout(0,2));
pane.add(new JButton("Botoao 1"));
pane.add(new JButton("Botoao 2"));
pane.add(new JButton("Botoao 3"));
pane.add(new JButton("Botao Nome-Longo 4"));
pane.add(new JButton("5"));
}
/**
* Cria um GUI e o exibe. Para thread safety,
* este metodo podera invocar para uma thread
* de disparo de evento(event-dispatching thread).
*/
private static void createAndShowGUI() {
//Faz com que tenha uma decoracao de janela.
JFrame.setDefaultLookAndFeelDecorated(true);
//Cria e organiza a janela.
JFrame frame = new JFrame("DemoGridLayout");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Organiza o conteudo no painel.
addComponentsToPane(frame.getContentPane());
//Exibe janela.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
//Agenda um trabalho para o event-dispatching thread:
//cria e exibe uma aplicacao GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
Resultado:

GridBagLayout
Com nome estranho(“saco
de grades”), o GridBagLayout é o mais poderoso e o
mais
flexível dos gerenciadores fornecidos com o J2EE. Ele imita
em
linhas gerais o funcionamento de uma tabela HTML, em que um componente
pode ocupar várias células, ou seja, se estender
por
várias colunas e linhas.
Os componentes podem ser expandidos para
ocupar toda
a área das suas células, ou serem alinhados em
qualquer
posição do conjunto de células. Linhas
e colunas
assumem as dimensões do maior componente, mas é
necessário que tenham todas o mesmo tamanho. E algumas
células podem ser configuradas para ocuparem toda a
área
disponível no container.
Este layout tem como base a utilização de um GridBagConstraints para cada componente inserido. É este objeto que proporcionará a liberdade que queremos com o layout. A GridBagConstraints é uma classe que não possui métodos, ela servirá simplesmente para armazenar as informações para cada componente adicionado. Vamos dar uma olhada nas propriedades da classe:
anchor: Essa propriedade é utilizada somente quando o tamanho do componente é menor que a área que lhe foi concedida. Normalmente, queremos que nosso componente ocupe toda a área disponível, mas em casos especiais, não podemos redimensionar os componentes. Sendo assim, o layout precisa saber em que posição da célula deixará o componente. Os valores para esse campo são de dois tipos: Absolutos (CENTER, NORTH, NORTHEAST, EAST, SOUTHEAST, SOUTH, SOUTHWEST, WEST, e NORTHWEST) e Relativos (PAGE_START, PAGE_END, LINE_START, LINE_END, FIRST_LINE_START, FIRST_LINE_END, LAST_LINE_START and LAST_LINE_END). O valor padrão é CENTER.
fill: Determina como
redimensionar o componente. Valores possíveis para esta
propriedade são:
NONE: Não redimensiona o componente
HORIZONTAL: Redimensiona horizontalmente, fazendo com que o mesmo ocupe
toda a área horizontal na célula
VERTICAL: Redimensiona verticalmente, fazendo com que o mesmo ocupe
toda a área vertical na célula
BOTH: Redimensiona para ambas as direções.
Valor padrão é NONE
gridx e gridy
Especificam a
posição X,Y para adicionar o componente.
Não
é necessário alterar seus valores, pois seu valor
padrão é a constante RELATIVE e portanto o layout
adicionará após o último componente
que foi
colocado.
- gridx: Permite especificar qual a posição
absoluta horizontalmente que o componente será adicionado.
- gridy: Permite especificar qual a posição
absoluta verticalmente que o componente será adicionado.
gridheight e gridwidth
Especificam o tamanho do
componente baseado em células. É com essa
propriedade que
você indicará que um componente seu
ocupará duas
células, ou ocupurá tantas quanto forem
necessárias para ir até o final da tela.
Lembrem-se
é células e não pixels
Nestes valores podem ser utilizadas duas
constantes:
REMAINDER e RELATIVE. REMAINER fará com que o componente se
estique até a última célula.
Já o RELATIVE
fará com que o componente ocupe todas as casas com
excessão da última.
- gridheight: Especifica o número de células que
o
componente ocupará verticalmente. Valor padrão
é 1.
- gridwidth: Especifica o número de células que o
componente ocupará horizontalmente. Valor padrão
é
1.
insets
Indica as distãncias entre os componentes do layout. Um Insets possui valores para as 4 direções, cima, baixo, direita e esquerda. Permitindo com isso muita flexibilidade no gerenciador. Valor padrão é new Insets(0, 0, 0, 0)
weight
Essas propriedades especificam
um percentual de crescimento da célula, não do
componente, quando a mesma precisa ser redimensionada. É
dito
isso, pois se o componente não pode se redimensionar, pois a
propriedade fill do constraint afirma isso, o componente não
vai
sofrer as alterações, mas a célula
irá
aumentar.
Com este layout é possível informar que uma
célula
redimensionará 75% e o outra 25%, portanto o primeiro
componente
receberá 3 vezes mais tamanho do que o segundo.
O valor padrão é
0 e os valores percentuais são dados em casas decimais, por
exemplo: 0.03 é igual a 3%, 1.00 é igual a 100% e
por
aí vai.
- weightx:
Peso em x.
Especifica um peso no redimensionamento. Este peso será
utilizado para um cálculo que o layout faz para determinar
quais
as células irão redimensionar horizontalmente,
quais
não irão, e quais aumentarão mais que
os outros.
- weighty:
Peso em y.
Especifica um peso no redimensionamento. Este peso será
utilizado para um cálculo que o layout faz para determinar
quais
as células irão redimensionar verticalmente,
quais
não irão, e quais aumentarão mais que
os
outros.
ipadx e ipady
Determina um adicional nas
bordas internas do componenete. Essa propriedade modifica o tamanho
mínimo de cada componente. O tamanho mínimo
será o
ipad + o valor mínimo do componente.
- ipadx: Valor para ser adicionado horizontalmente.
- ipady: Valor para ser adicionado verticalmente.
Podemos afirmar com segurança que qualquer disposição de componentes pode ser configurada em um GridBagLayout. Por outro lado, a quantidade de constraints(propriedades e restrições de layout) possível para cada componente também deu a este gerenciador a fama de ser difícil de programar.
Demo GridBagLayout
Código:
import java.awt.*;
import javax.swing.JButton;
import javax.swing.JFrame;
public class DemoGridBagLayout {
final static boolean shouldFill = true;
final static boolean shouldWeightX = true;
final static boolean RIGHT_TO_LEFT = false;
public static void addComponentsToPane(Container pane) {
if (RIGHT_TO_LEFT) {
pane.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
}
JButton button;
pane.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
if (shouldFill) {
//altura natural, largura maxima.
c.fill = GridBagConstraints.HORIZONTAL;
}
button = new JButton("Botao 1");
if (shouldWeightX) {
c.weightx = 0.5;
}
c.gridx = 0;
c.gridy = 0;
pane.add(button, c);
button = new JButton("Botao 2");
c.gridx = 1;
c.gridy = 0;
pane.add(button, c);
button = new JButton("Botao 3");
c.gridx = 2;
c.gridy = 0;
pane.add(button, c);
button = new JButton("Botao 4 - Nome-Longo");
c.ipady = 40; //faz o componente no alto.
c.weightx = 0.0;
c.gridwidth = 3;
c.gridx = 0;
c.gridy = 1;
pane.add(button, c);
button = new JButton("5");
c.ipady = 0; //esvazia por padrao
c.weighty = 1.0; //requisita um espaco vertical extra.
c.anchor = GridBagConstraints.PAGE_END; //espaco em baixo.
c.insets = new Insets(10,0,0,0); //top padding
c.gridx = 1; //alinhamento do botao 2.
c.gridwidth = 2; //2 colunas largas.
c.gridy = 2; //terceira linha.
pane.add(button, c);
}
/**
* Cria um GUI e o exibe. Para thread safety,
* este metodo podera invocar para uma thread
* de disparo de evento(event-dispatching thread).
*/
private static void createAndShowGUI() {
//Faz com que tenha uma decoracao de janela.
JFrame.setDefaultLookAndFeelDecorated(true);
//Cria e organiza a janela.
JFrame frame = new JFrame("DemoGridBagLayout");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Organiza o conteudo no painel.
addComponentsToPane(frame.getContentPane());
//Exibe janela.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
//Agenda um trabalho para o event-dispatching thread:
//cria e exibe uma aplicacao GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
Resultado:

NullLayout
Na verdade o Null Layout não é um gerenciador de layout, mas sim a ausência de qualquer gerenciador (equivalente a definir a propriedade layout do container com o valor null). O resultado é que , no IDE, componentes podem ser posicionados à vontade na área de desenho; eles permanerão na posição onde foram colocados e com as dimensões indicadas pelo desenvolvedor.
AbsoluteLayout
O AbsoluteLayout não é um gerenciador padrão do Java, mas uma adição do NetBeans; seu uso requer que o pacote modules/ext/AbsoluteLayout.jar seja copiado para a estação do usuário e configurado no classpath. Ele funciona como um Null Layout, co a diferença de que as dimensões do container são calculadas corretamente, permitindo o uso do método pack() (com o Null Layout, o resultado são dimensões [0,]). Porém, AbsoluteLayout apresenta todas as desvantagens do Null Layout, portanto também, não é recomendado para uso geral.
Demo Swing Fases da Lua
OBS: É necessário que os arquivos *.gif estejam no mesmo diretório do arquivo fonte FasesDaLua.java.
Transfira para seu computador o Arquivo_fotos.zip que contem os arquivos *.gif.
Código:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.net.URL;
public class FasesDaLua implements ActionListener {
final static int NUM_IMAGES = 8;
final static int START_INDEX = 3;
ImageIcon[] images = new ImageIcon[NUM_IMAGES];
JPanel mainPanel, selectPanel, displayPanel;
JComboBox phaseChoices = null;
JLabel phaseIconLabel = null;
public FasesDaLua() {
//Cria a selecao das faaes e exibe no painel.
selectPanel = new JPanel();
displayPanel = new JPanel();
//Adiciona varios widgets para o sub-painel.
addWidgets();
//Cria um painel contendo dois sub-paineis.
mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.PAGE_AXIS));
mainPanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
//Adiciona e seleciona painel de exibicao para o painel principal.
mainPanel.add(selectPanel);
mainPanel.add(displayPanel);
}
/*
* Obtem a imagem e organiza o widgets.
*/
private void addWidgets() {
//Obtem a imagem e coloca no array de ImageIcons.
for (int i = 0; i < NUM_IMAGES; i++) {
images[i] = createImageIcon("image" + i + ".jpg");
}
/*
* Cria um rotulo para exibir as imagens das fases da lua e
* coloca uma bordar ao redor desta.
*/
phaseIconLabel = new JLabel();
phaseIconLabel.setHorizontalAlignment(JLabel.CENTER);
phaseIconLabel.setVerticalAlignment(JLabel.CENTER);
phaseIconLabel.setVerticalTextPosition(JLabel.CENTER);
phaseIconLabel.setHorizontalTextPosition(JLabel.CENTER);
phaseIconLabel.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createLoweredBevelBorder(),
BorderFactory.createEmptyBorder(5,5,5,5)));
phaseIconLabel.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createEmptyBorder(0,0,10,0),
phaseIconLabel.getBorder()));
//Cria um combo box com cada selecao da fase lunar.
String[] phases = { "Nova", "Maximo Crescente", "Primeiro Quarto",
"Waxing Gibbous", "Cheia", "Waning Gibbous",
"Terceiro Quarto", "Crescente" };
phaseChoices = new JComboBox(phases);
phaseChoices.setSelectedIndex(START_INDEX);
//Exibe a primeira imagem.
phaseIconLabel.setIcon(images[START_INDEX]);
phaseIconLabel.setText("");
//Adiciona uma borda em volta do painel de selecao.
selectPanel.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder("Selecione uma Fase"),
BorderFactory.createEmptyBorder(5,5,5,5)));
//Adiciona borda em vola do painel de exibicao.
displayPanel.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder("Exibe Fases"),
BorderFactory.createEmptyBorder(5,5,5,5)));
//Adiciona fases da lua no combo box para selecionar imagem no painel e rotulo da imagem.
displayPanel.add(phaseIconLabel);
selectPanel.add(phaseChoices);
//Listen para o events do combo box.
phaseChoices.addActionListener(this);
}
public void actionPerformed(ActionEvent event) {
if ("comboBoxChanged".equals(event.getActionCommand())) {
//Update the icon to display the new phase.
phaseIconLabel.setIcon(images[phaseChoices.getSelectedIndex()]);
}
}
/** Retorna um ImageIcon, ou null se o path for invalido. */
protected static ImageIcon createImageIcon(String path) {
java.net.URL imageURL = FasesDaLua.class.getResource(path);
if (imageURL == null) {
System.err.println("Caminho nao encontrado: "
+ path);
return null;
} else {
return new ImageIcon(imageURL);
}
}
/**
* Cria um GUI e o exibe. Para thread safety,
* este metodo podera invocar para uma thread
* de disparo de evento(event-dispatching thread).
*/
private static void criaExibeGUI() {
//Make sure we have nice window decorations.
JFrame.setDefaultLookAndFeelDecorated(true);
//Cria uma nova instancia de FasesDaLua.
FasesDaLua phases = new FasesDaLua();
//Cria e organiza a janela.
JFrame lunarPhasesFrame = new JFrame("Fases da Lua");
lunarPhasesFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
lunarPhasesFrame.setContentPane(phases.mainPanel);
//Exibe janela.
lunarPhasesFrame.pack();
lunarPhasesFrame.setVisible(true);
}
public static void main(String[] args) {
//Agenda um trabalho para o event-dispatching thread:
//cria e exibe uma aplicacao GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
criaExibeGUI();
}
});
}
}
Resultado:

Demo Look Feel
Código:
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class LFDemo extends JFrame{
private UIManager.LookAndFeelInfo[] looks = UIManager.getInstalledLookAndFeels();
private JLabel lbLabel01 = new JLabel("Nome :");
private JLabel lbLabel02 = new JLabel("E-mail :");
private JTextField jtTexto01 = new JTextField( 10 );
private JTextField jtTexto02 = new JTextField( 10 );
private JButton jbOk = new JButton("Enviar");
private JButton jbLim = new JButton("Limpar");
private JRadioButton[] escolha = new JRadioButton[ looks.length ];
private ButtonGroup grupo = new ButtonGroup();
public static void main( String[] args ){
LFDemo lfd = new LFDemo();
lfd.setVisible(true);
}
public LFDemo(){
super("Selecione um LF");
Container c = getContentPane();
// Usa o gerenciador FlowLayout(fluxo)
c.setLayout ( new FlowLayout());
c.add(lbLabel01);
c.add(jtTexto01);
c.add(lbLabel02);
c.add(jtTexto02);
c.add(jbOk);
c.add(jbLim);
ItemSelecionado iselect = new ItemSelecionado();
for (int i = 0; i < looks.length; i++){
escolha[i] = new JRadioButton( looks[i].getName() );
escolha[i].addItemListener( iselect );
grupo.add( escolha[i] );
c.add( escolha[i] );
}
escolha[2].setSelected( true );
setDefaultCloseOperation( EXIT_ON_CLOSE );
setSize(200,250);
}
public void atualiza(int i){
try {
UIManager.setLookAndFeel(looks[i].getClassName());
SwingUtilities.updateComponentTreeUI(this);
}catch(Exception e) {
e.printStackTrace();
}
}
private class ItemSelecionado implements ItemListener {
public void itemStateChanged( ItemEvent e) {
for (int i=0; i < escolha.length; i++){
if (escolha[i].isSelected())
atualiza(i);
}
}
}
}
Resultado:
![]() |
Autores: Carlos Fernando Gonçalves e Marli Esprega Gonçalves (Antares Information Systems)