Estou com problema para posicionar um botão. O fato é que, não sei, quem deve ser responsavel por definir sua posição. O código segue abaixo, posteriormente, a imagem.
import java.awt.Dimension;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
/**
*
* @author Kaos
*/
public class PainelSobreRodape extends JPanel {
public PainelSobreRodape() {
super();
this.inicializaComponentes();
}
private void inicializaComponentes() {
Dimension dimensao = new Dimension(380, 35);
this.setPreferredSize(dimensao);
this.setBorder(BorderFactory.createEtchedBorder());
}
}
Na imagem abaixo, os JPanel’s podem ser observados, através de suas bordas. Adotei esse recurso, de borda marcada, para auxiliar durante o desenvolvimento.
Dúvidas:
Qual componente é responsável pelo alinhamento do botão?
Como realizar esse alinhamento?
Perdoem a pergunta “simples”, é que nunca fiz telas com conteudo “na unha”, e está bem complicado pra mim.
Na verdade o responsável pelo alinhamento dos componentes é o layout manager do container.
No caso do JFrame, os componentes são adicionados no content pane, que utiliza por padrão o BorderLayout. O BorderLayout pode posicionar até cinco componentes, posicionados ao NORTH, SOUTH, EAST, WEST e CENTER. No seu frame os paineis estão adicionados ao NORTH, CENTER e SOUTH. Neste layout manager os componentes são redimensionados para ocupar todo o espaço disponível.
Já no caso do JPanel, o layout manager padrão é FlowLayout, que vai posicionando os componentes um ao lado do outro respeitando o preferred size de cada componente, quando não houver mais espaço para armazenar componentes na linha, ele passa a posicionar os componentes na linha de baixo.
Mas enfim, existem diversos layout managers para fazer o posicionamento e dependendo de cada caso, você pode escolher o que se encaixa melhor as suas necessidades.
Só pra entender, fiz a modificação abaixo, nas linhas 21 e 22. Pelo que entendi, qualquer objeto, dessa classe ao ser instanciado, estaria usando o GridBagLayout. É isso mesmo?
import java.awt.Dimension;
import java.awt.GridBagLayout;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
/**
*
* @author Kaos
*/
public class PainelSobreTitulo extends JPanel {
public PainelSobreTitulo() {
super();
this.inicializaComponentes();
}
private void inicializaComponentes() {
Dimension dimensao = new Dimension(380, 45);
this.setPreferredSize(dimensao);
this.setBorder(BorderFactory.createEtchedBorder());
GridBagLayout layout = new GridBagLayout();
this.setLayout(layout);
}
}
No caso de adicionar um componente, teria que usar o metodo “add”, conforme ex abaixo?
Nota: Coloquei todos os links, passados nos favoritos, do meu navegador. E vou ler, com mais cuidado amanhã, pois preciso dominar esse conceito. E nesse momento to dormindo aqui ja.
Vixi, o GridBagLayout é um dos mais chatos de aprender porque tem muitos parâmetros que podem ser configurados. Mas vamos lá.
Bom, as palavras corretas não seriam exatamente estas. Quem usa o layout manager é o container, e ele define como os componentes adicionados devem ser posicionados dentro do container. Já os componentes adicionados podem usar outros layout managers. Por exemplo, dentro do JFrame, eu posso ter 3 JPanels, cada um utilizando um layout manager diferente.
[quote=KaosBr]No caso de adicionar um componente, teria que usar o metodo “add”, conforme ex abaixo?
Ex: containerJPanel.add(botaoFechar, FIRST_LINE_START);[/quote]
Alguns layout managers como o GridBagLayout utilizam constraints para ajudar a configurar o posicionamento, essa constraint deve ser passada no segundo parâmetro do método “add”. No caso de GridBagLayout é a classe GridBagConstraints que define as configurações de posicionamento dos componentes.
Para utilizá-la basta criar um objeto do tipo GridBagConstraints e alterar os atributos diretamente, pois são públicos.
Basicamente o GridBagLayout monta um grid na tela e dependendo das constraints passadas, ele vai posicionando os componentes por este grid.
Ex.:[code]GridBagConstraints cons = new GridBagConstraints();
cons.anchor = GridBagConstraints.CENTER; //Indica em que parte da célula o componente ficará ancorado. Pode ser utilizado NORTH, SOUTH, WEST, EAST, CENTER, e combinações como NORTHWEST, SOUTHEAST, etc.
cons.fill = GridBagConstraints.NONE; //Define como o componente deve ser redimensionado para ocupar o espaço da célula, que pode ser redimensionado horizontalmente (HORIZONTAL), verticalmente (VERTICAL), para ambos lados (BOTH) ou não redimensionar (NONE).
cons.gridx = GridBagConstraints.RELATIVE; //Define o índice que o componente vai ocupar na horizontal (eixo x). Pode ser passado um valor inteiro com o índice específico, ou então passar a constante RELATIVE, que faz com que seja adicionado na posição imediatamente posterior ao último componente adicionado.
cons.gridy = GridBagConstraints.RELATIVE; //Mesmo que o acima, porém para o eixo y.
cons.gridwidth = 1; //Define quantas colunas (span) o componente deve ocupar no eixo x. Pode ser usada a constante REMAINDER para definir que o componente é o último de sua linha (REMAINDER atuaria como uma quebra de linha).
cons.gridheight = 1; //Mesmo que o acima, porém para o eixo y.
cons.insets = new Insets(0, 0, 0, 0); //Define o external padding, ou seja o espaço ao redor do componente, seria um tipo de borda ezterna.
cons.weightx = 0.0; //Recebe um double que determina o crescimento das células horizontalmente (eixo x). Geralmente eu seto como 1.0 para ocupar todo o espaço, ou 0.0 para respeitar o preferred size.
cons.weighty = 0.0; //Mesmo que o acima, porém para o eixo y.
cons.ipadx = 0; //Define o internal padding do componente horizontalmente, ou seja, se o width do preferred size do meu componente é 20 e eu especificar o ipadx como 10, o preferred size ficará em 30. Basicamente serve para fazer com que o componente cresca.
cons.ipady = 0; //Mesmo que o acima, porém para o eixo y.
panel.add(component, cons); //Por fim, adiciona o componente[/code]
Mas não é necessário especificar todos os atributos toda vez que for usar o GridBagConstraints. Neste exemplo que eu passei eu simulei os valores que já vem por padrão no GridBagConstraints. Geralmente eu só especifico os primeiros citados. Se o posicionamento padrão atender, não há por que especificar tudo.
Bom, estou com um sono desgraçado e nem eu estou entendo mais o que estou escrevendo. Qualquer coisa posta aí.
Fiz um teste aqui com GridBagLayout, mas sem sucesso, agora em um painel que contem o titulo da janela. Sem layout algum, a posição do JLabel no JPanel, é no centro. E apos, o codigo abaixo não houve mudança.
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JPanel;
/**
*
* @author Kaos
*/
public class PainelSobreTitulo extends JPanel {
public PainelSobreTitulo() {
super();
this.inicializaComponentes();
}
private void inicializaComponentes() {
Dimension dimensao = new Dimension(380, 45);
this.setPreferredSize(dimensao);
this.setBorder(BorderFactory.createRaisedBevelBorder());
GridBagLayout layout = new GridBagLayout();
this.setLayout(layout);
JLabel titulo = new JLabel("Sistema");
Font fonte = new Font(Font.SANS_SERIF, Font.PLAIN, 24);
titulo.setFont(fonte);
GridBagConstraints posicaoGrid = new GridBagConstraints();
posicaoGrid.anchor = GridBagConstraints.FIRST_LINE_START;
this.add(titulo, posicaoGrid);
}
}
O label está na posição que deveria estar, o problema é que o grid está muito pequeno e centralizado na tela. Para ter o efeito que deseja, é preciso setar o weight, para que as células do grid cresçam.