Вы находитесь на странице: 1из 16

Trabalhando com Layouts

1 Introdução
Em um Panel podemos inserir componentes para criarmos nossa janela.
Para posicionar nossos componentes usaremos ferramenta poderosa do Java,
LAYOUT. Os layouts organizam nossos componentes de maneira inteligente,
poupando tempo de programação, já que o próprio layout calcula o tamanho e
reorganização dos componentes caso nossa janela aumente ou diminua de
tamanho.

1.1 Border Layout


http://java.sun.com/docs/books/tutorial/uiswing/layout/border.html

Todos os Content Panes são inicializados com Border Layout. Um


Content Pene é um Panel que faz parte de um contêiner de componentes.
O Border Layout divide nosso Panel em 5 regiões, onde a região central
é a mais importante. Quando colocamos um componente na região central,
esse ocupa todo o espaço vazio do nosso Panel independente do valor que
atribuímos ao tamanho desse componente. Quem controla isso é o layout e
caso nossa janela mude de tamanho, o componente que está na região central
será redimensionado.

1.2 Box Layout


http://java.sun.com/docs/books/tutorial/uiswing/layout/box.html

Esse layout organiza os componentes em uma coluna ou linha,


depende de como estiver configurado.
1.3 Card Layout
http://java.sun.com/docs/books/tutorial/uiswing/layout/card.html

Esse layout nos ajuda a implementar uma área que contem diferentes
componentes a cada momento. Esse layout, por exemplo, pode ser controlado
por uma ComboBox, onde o estado dessa combo determina qual será o
conjunto de componentes mostrados pelo Card Layout.

1.4 Flow Layout


http://java.sun.com/docs/books/tutorial/uiswing/layout/flow.html

Esse é o layout padrão do JPanel. Simplesmente ordena os


componentes em uma linha e quando não há mais espaço, uma nova linha é
criada.

1.5 GridBag Layout


http://java.sun.com/docs/books/tutorial/uiswing/layout/gridbag.html

Esse layout é sofisticado e flexível. Permite alinhar, distanciar,


configurar mudanças de tamanho etc. É um dos mais utilizados para
organização de componentes em janelas com grande quantidade e variedade
de componentes.

1.6 Grid Layout


http://java.sun.com/docs/books/tutorial/uiswing/layout/grid.html
O Grid Layout simplesmente divide os componentes em linhas e
colunas.

1.7 Spring Layout


http://java.sun.com/docs/books/tutorial/uiswing/layout/spring.html

É um layout flexível e desenvolvido para construtores de layout.

2 Configurando um layout
Podemos modificar o layout do componente usando o método
setLayout().

public class FramePrincipal extends JFrame {

public FramePrincipal() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(400, 300);
setLocationRelativeTo(null);

Panel panelPrincipal = new Panel();


panelPrincipal.setLayout(new GridBagLayout());
}
}

3 Praticando o Border Layout


Quando criamos um JFrame, seu Content Pane já vem configurado
com Border Layout. Caso precisarmos configurar um Border Layout em
JPanel, basta chamar o método setLayout() passando o objeto do layout.
public class FramePrincipal extends JFrame {

public FramePrincipal() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(400, 300);
setLocationRelativeTo(null);

Panel panelPrincipal = new Panel();


panelPrincipal.setLayout(new BorderLayout());
}
}

Como mostrado na figura abaixo, podemos ver como o layout é


dividido em 5 regiões, sendo que a região central sempre ocupa o maior
espaço possível.

Irei usar como exemplo uma janela com um JPanel e um JToolBar. O


JToolBar é interessante nesse caso por ter uma integração interessante com o
Border Layout. Se posicionarmos o toolbar em uma das laterais, poderemos
clicar e arrastar o componente para fora ou para outra posição do layout.
Como já vimos, sempre que quisermos inserir um componente em um
contêiner usamos o método add(), mas dependendo do layout utilizado,
podemos passar parâmetros para configurar o layout para cada componente
individualmente.
No caso do Border Layout podemos usar as constantes da classe
BorderLayout: PAGE_START, LINE_START, PAGE_END, LINE_END e
CENTER. Quando inserimos um componente usando o método add()
passando apenas o componente, ou seja, sem passar em qual posição
queremos posiciona-lo, esse componente será colocado na região central.

public class FramePrincipal extends JFrame {

public FramePrincipal() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(400, 300);
setLocationRelativeTo(null);

Panel panelPrincipal = new Panel();


panelPrincipal.setBackground(Color.DARK_GRAY);
add(panelPrincipal);

JToolBar toolBar = new JToolBar();


toolBar.add(new JButton("Teste"));
add(toolBar, BorderLayout.PAGE_START);
}
}

Notem que o panelPrincipal é inserido sem passar a posição, mas seria


o mesmo do que chamar o método add() passando BorderLayout.CENTER
como segundo parâmetro.
No segundo caso, passamos PAGE_START como segundo parâmetro,
ou seja, posicionando o toolbar na parte superior da tela.
Tente arrastar o toolbar para outra posição do layout ou para fora.

4 Praticando GridBag Layout


Esse layout tem muito mais funcionalidades do que o Border Layout e
sua configuração não é feita através de simples constantes, mas sim,
utilizando um objeto da classe GridBagConstraints.
Iremos utilizar esse layout no Panel que está inserido no centro de
nossa janela, para isso temos que modificar seu layout para GridBagLayout,
já que como vimos anteriormente, um Panel vem configurado como Floy
Layout.

public class FramePrincipal extends JFrame {

public FramePrincipal() {
...

Panel panelPrincipal = new Panel();


panelPrincipal.setLayout(new GridBagLayout());

add(panelPrincipal);
}
}
Muito bom, agora que temos nosso layout configurado vamos fazer
algumas experiências.
Vamos primeiro adicionar alguns componentes para possibilitar o
cadastro de clientes com nome, telefone e CPF.

public class FramePrincipal extends JFrame {

private JTextField _fieldNome = null;


private JTextField _fieldTelefone = null;
private JTextField _fieldCPF = null;

public FramePrincipal() {
...

Panel panelPrincipal = new Panel();


panelPrincipal.setLayout(new GridBagLayout());

panelPrincipal.add(new JLabel("Nome:"));
_fieldNome = new JTextField(15);
panelPrincipal.add(_fieldNome);

panelPrincipal.add(new JLabel("Telefone:"));
_fieldTelefone = new JTextField(15);
panelPrincipal.add(_fieldTelefone);

panelPrincipal.add(new JLabel("CPF:"));
_fieldCPF = new JTextField(15);
panelPrincipal.add(_fieldCPF);

add(panelPrincipal);
}
}

Hum... não ficou muito bom. Isso acontece porque quando inserimos
componentes em um GridBagLayout sem configurar o layout para ele, os
componentes são organizados em uma linha apenas e como não é possível
desenhar todos os componentes em uma linha por falta de espaço,
automaticamente os JTextFields são configurados para seu tamanho mínimo.
Caso precisarmos modificar o tamanho mínimo para o componente iremos
usar o método setMinimumSize().
Se você expandir a tela, os componentes serão desenhados em seu
tamanho normal.

4.1 Posicionando os componentes (gridx / gridy)


Como já comentei anteriormente, para configurar o layout precisamos
criar um objeto da classe GridBagConstraints. Essa classe possui vários
atributos que servem para configurar o layout, dois desses atributos são o
gridx e gridy que usaremos para posicionar nossos componentes em linhas e
colunas imaginárias como mostrado no diagrama abaixo.

(x,y) Eixo X de 0  n

0,0 1,0 2,0 3,0


Eixo Y de 0  n

0,1 1,1 2,1 3,1


0,2 1,2 2,2 3,2
0,3 1,3 2,3 3,3
Seguindo esse diagrama poderemos posicionar nossos componentes da
seguinte forma: lable “Nome” na posição 0 , 0; field “Nome” na posição 1 , 0;
label “Telefone” na posição 0 , 1 e assim por diante.

public class FramePrincipal extends JFrame {

public FramePrincipal() {
...

Panel panelPrincipal = new Panel();


panelPrincipal.setLayout(new GridBagLayout());

GridBagConstraints gbc = new GridBagConstraints();

gbc.gridx = 0;
gbc.gridy = 0;
panelPrincipal.add(new JLabel("Nome:"), gbc);

_fieldNome = new JTextField(15);


gbc.gridx = 1;
gbc.gridy = 0;
panelPrincipal.add(_fieldNome, gbc);

gbc.gridx = 0;
gbc.gridy = 1;
panelPrincipal.add(new JLabel("Telefone:"), gbc);

_fieldTelefone = new JTextField(15);


gbc.gridx = 1;
gbc.gridy = 1;
panelPrincipal.add(_fieldTelefone, gbc);

gbc.gridx = 0;
gbc.gridy = 2;
panelPrincipal.add(new JLabel("CPF:"), gbc);

_fieldCPF = new JTextField(15);


gbc.gridx = 1;
gbc.gridy = 2;
panelPrincipal.add(_fieldCPF, gbc);

add(panelPrincipal);
}
}

Como estamos utilizando o mesmo objeto GridBagConstraints para


todos os posicionamentos, as configurações que fizemos para os componentes
anteriores continuam para o componente atual. Temos que prestar atenção,
pois caso configuremos uma propriedade do layout no componente anterior e
não queremos que essa seja usada no componente atual, teremos que
reconfigurá-la.

4.2 Distância entre componentes (Insets)


Para configurar a distância entre componentes usaremos a propriedade
Insets. Com essa propriedade podemos configurar a distância entre o
componente e o limite do grid.
É bom ressaltar que não é a distância entre os componentes, e sim, a
distância entre o componente e o limite do grid. Como configuramos para
cada componente, se configurarmos 10px do lado direito de um componente e
10px do lado esquerdo de um componente posicionado do lado direito do
primeiro, iremos ter uma distância total de 20px entre os dois componentes.
Para usar a propriedade Insets, teremos que criar um objeto da classe
Insets passando em seu construtor as quatro distâncias seguindo a seqüência:
superior, esquerda, inferior e direita.
Observe o código.
public class FramePrincipal extends JFrame {

public FramePrincipal() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(400, 300);
setLocationRelativeTo(null);

JToolBar toolBar = new JToolBar();


toolBar.add(new JButton("Teste"));

add(toolBar, BorderLayout.PAGE_START);

Panel panelPrincipal = new Panel();


panelPrincipal.setLayout(new GridBagLayout());

GridBagConstraints gbc = new GridBagConstraints();

gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(10, 10, 10, 10);
panelPrincipal.add(new JLabel("Nome:"), gbc);

_fieldNome = new JTextField(15);


gbc.gridx = 1;
gbc.gridy = 0;
gbc.insets = new Insets(10, 0, 10, 10);
panelPrincipal.add(_fieldNome, gbc);

gbc.gridx = 0;
gbc.gridy = 1;
gbc.insets = new Insets(0, 10, 10, 10);
panelPrincipal.add(new JLabel("Telefone:"), gbc);

_fieldTelefone = new JTextField(15);


gbc.gridx = 1;
gbc.gridy = 1;
gbc.insets = new Insets(0, 0, 10, 10);
panelPrincipal.add(_fieldTelefone, gbc);

gbc.gridx = 0;
gbc.gridy = 2;
gbc.insets = new Insets(0, 10, 10, 10);
panelPrincipal.add(new JLabel("CPF:"), gbc);

_fieldCPF = new JTextField(15);


gbc.gridx = 1;
gbc.gridy = 2;
gbc.insets = new Insets(0, 0, 10, 10);
panelPrincipal.add(_fieldCPF, gbc);

add(panelPrincipal);
}
}
4.3 Alinhando os lables (anchor)
Como os componentes têm tamanhos diferentes, os grids são ajustados
automaticamente com a largura do maior componente da coluna e com a
altura do maior componente na linha.
A propriedade anchor é usada quando o componente não ocupa todo o
espaço do grid e com ele podemos posicionar nosso componente em uma das
seguintes posições:

FIRST_LINE_START PAGE_START FIRST_LINE_END


LINE_START CENTER LINE_END
LAST_LINE_START PAGE_END LAST_LINE_END
Irei posicionar os labels no final da linha usando a constante
LINE_END. Observe o código.

public class FramePrincipal extends JFrame {

public FramePrincipal() {
...

Panel panelPrincipal = new Panel();


panelPrincipal.setLayout(new GridBagLayout());

GridBagConstraints gbc = new GridBagConstraints();

gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(10, 10, 10, 10);
gbc.anchor = GridBagConstraints.LINE_END;
panelPrincipal.add(new JLabel("Nome:"), gbc);

_fieldNome = new JTextField(15);


gbc.gridx = 1;
gbc.gridy = 0;
gbc.insets = new Insets(10, 0, 10, 10);
gbc.anchor = GridBagConstraints.CENTER;
panelPrincipal.add(_fieldNome, gbc);

gbc.gridx = 0;
gbc.gridy = 1;
gbc.insets = new Insets(0, 10, 10, 10);
gbc.anchor = GridBagConstraints.LINE_END;
panelPrincipal.add(new JLabel("Telefone:"), gbc);

_fieldTelefone = new JTextField(15);


gbc.gridx = 1;
gbc.gridy = 1;
gbc.insets = new Insets(0, 0, 10, 10);
gbc.anchor = GridBagConstraints.CENTER;
panelPrincipal.add(_fieldTelefone, gbc);

gbc.gridx = 0;
gbc.gridy = 2;
gbc.insets = new Insets(0, 10, 10, 10);
gbc.anchor = GridBagConstraints.LINE_END;
panelPrincipal.add(new JLabel("CPF:"), gbc);

_fieldCPF = new JTextField(15);


gbc.gridx = 1;
gbc.gridy = 2;
gbc.insets = new Insets(0, 0, 10, 10);
gbc.anchor = GridBagConstraints.CENTER;
panelPrincipal.add(_fieldCPF, gbc);

add(panelPrincipal);
}
}

4.4 Inserindo dois botões


Supondo que precisaremos de dois botões, um para processar os dados
e outro para limpar os campos, e queremos que esses botões fiquem
centralizados em relação a tela, iremos usar para isso um panel auxiliar
configurado como Flow Layout que é o padrão.
Iremos inicialmente posicionar nosso panel logo abaixo no label CPF,
ou seja, na posição 0, 3. Usaremos ainda, dois outras propriedades: fill e
gridwidth.
Nesse novo panel, poderemos inserir os botões sem se preocupar com
como iremos centralizá-los, já que o Flow Layout tem como característica
principal posicionar os componentes sempre no centro horizontal.
Além disso, para melhorar a visualização da ocupação do panel, iremos
modificar para cinza escuro o fundo do panel onde colocaremos os botões.

4.5 Forçando o componente a ocupar todo o espaço (fill)


Com a propriedade fill podemos forçar um componente, menor do que
a área do grid, a ocupar todo o espaço horizontal e/ou vertical. As constantes
que podemos utilizar para isso são: HORIZONTAL, VERTICAL e BOTH.
Vou adicionar um novo panel para colocar os botões e configura-lo para
ocupar todo o espaço horizontal do grid. Observe o código.

public class FramePrincipal extends JFrame {

public FramePrincipal() {
...
Panel panelPrincipal = new Panel();
panelPrincipal.setLayout(new GridBagLayout());

GridBagConstraints gbc = new GridBagConstraints();

...

JPanel panelBotões = new JPanel();


panelBotões.setBackground(Color.DARK_GRAY);

gbc.gridx = 0;
gbc.gridy = 3;
gbc.insets = new Insets(0, 10, 10, 10);
gbc.anchor = GridBagConstraints.CENTER;
gbc.fill = GridBagConstraints.HORIZONTAL;
panelPrincipal.add(panelBotões, gbc);

add(panelPrincipal);
}
}
Agora precisamos configurar para que o panel ocupe duas colunas e
inserir os botões.

4.6 Ocupando linhas e colunas (gridwidth e gridheight)


Com a propriedade gridwidth (largura) podemos configurar quantas
colunas, ou quantas células na horizontal, iremos usar para exibir o
componente. De forma similar, a propriedade gridheight (altura) pode ser
usada para configurar quantas linhas, ou quantas células na vertical, serão
usadas para exibir nosso componente.
No nosso caso, iremos usar a propriedade gridwidth com valor 2 para o
panel, o que significa que o componente irá utilizar duas colunas.
Observe o código.

public class FramePrincipal extends JFrame {

public FramePrincipal() {
...

Panel panelPrincipal = new Panel();


panelPrincipal.setLayout(new GridBagLayout());

GridBagConstraints gbc = new GridBagConstraints();

...

JPanel panelBotões = new JPanel();


panelBotões.setBackground(Color.DARK_GRAY);

gbc.gridx = 0;
gbc.gridy = 3;
gbc.insets = new Insets(0, 10, 10, 10);
gbc.anchor = GridBagConstraints.CENTER;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridwidth = 2;
panelPrincipal.add(panelBotões, gbc);
add(panelPrincipal);
}
}

4.7 Outras propriedades


Existe ainda mais quatro propriedades: ipadx, ipady, weightx e weighty.
As propriedades ipadx e ipady são usadas para aumentar a parte interna dos
componentes, já as propriedades weightx e weighty são usadas para
dimensionar o quanto de espaço restante do panel certo componente irá
ocupar. Seu valor varia entre 0 e 1, assim, se colocarmos 1 para weightx e
weighty e fill igual a BOTH no panelBotões ele irá ocupar todo espaço vazio
do panelPrincipal. Observe na imagem.

Expanda a janela para ver o que acontece. :D


4.8 Inserindo os botões
Agora, para finalizar, podemos inserir dois botões no panelBotões.
Observe e analise o código completo.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Panel;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JToolBar;

public class FramePrincipal extends JFrame {

private JTextField _fieldNome = null;


private JTextField _fieldTelefone = null;
private JTextField _fieldCPF = null;

public FramePrincipal() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(400, 300);
setLocationRelativeTo(null);

JToolBar toolBar = new JToolBar();


toolBar.add(new JButton("Teste"));

add(toolBar, BorderLayout.PAGE_START);

Panel panelPrincipal = new Panel();


panelPrincipal.setLayout(new GridBagLayout());

GridBagConstraints gbc = new GridBagConstraints();

gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(10, 10, 10, 10);
gbc.anchor = GridBagConstraints.LINE_END;
panelPrincipal.add(new JLabel("Nome:"), gbc);

_fieldNome = new JTextField(15);


gbc.gridx = 1;
gbc.gridy = 0;
gbc.insets = new Insets(10, 0, 10, 10);
gbc.anchor = GridBagConstraints.CENTER;
panelPrincipal.add(_fieldNome, gbc);

gbc.gridx = 0;
gbc.gridy = 1;
gbc.insets = new Insets(0, 10, 10, 10);
gbc.anchor = GridBagConstraints.LINE_END;
panelPrincipal.add(new JLabel("Telefone:"), gbc);

_fieldTelefone = new JTextField(15);


gbc.gridx = 1;
gbc.gridy = 1;
gbc.insets = new Insets(0, 0, 10, 10);
gbc.anchor = GridBagConstraints.CENTER;
panelPrincipal.add(_fieldTelefone, gbc);

gbc.gridx = 0;
gbc.gridy = 2;
gbc.insets = new Insets(0, 10, 10, 10);
gbc.anchor = GridBagConstraints.LINE_END;
panelPrincipal.add(new JLabel("CPF:"), gbc);

_fieldCPF = new JTextField(15);


gbc.gridx = 1;
gbc.gridy = 2;
gbc.insets = new Insets(0, 0, 10, 10);
gbc.anchor = GridBagConstraints.CENTER;
panelPrincipal.add(_fieldCPF, gbc);

JPanel panelBotões = new JPanel();

panelBotões.add(new JButton("Processar"));
panelBotões.add(new JButton("Limpar"));

gbc.gridx = 0;
gbc.gridy = 3;
gbc.insets = new Insets(0, 10, 10, 10);
gbc.anchor = GridBagConstraints.CENTER;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridwidth = 2;
panelPrincipal.add(panelBotões, gbc);

add(panelPrincipal);
}
}

Maiores informações na página:


http://java.sun.com/docs/books/tutorial/uiswing/layout/gridbag.html

Вам также может понравиться