Alinhamento de botão [Resolvido]

Bom dia,

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.

[]s

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.

Na minha opinião o melhor conteúdo sobre layout managers é este da Sun: http://download.oracle.com/javase/tutorial/uiswing/layout/visual.html

E um layout manager muito bom para criar layout na mão é MigLayout: http://www.miglayout.com/

QuickStart do MigLayout: http://www.miglayout.com/QuickStart.pdf

Bom dia,

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?

Ex: containerJPanel.add(botaoFechar, FIRST_LINE_START);

De acordo com as posições abaixo:

-------------------------------------------------
|FIRST_LINE_START   PAGE_START     FIRST_LINE_END|
|                                                |
|                                                |
|LINE_START           CENTER             LINE_END|
|                                                |
|                                                |
|LAST_LINE_START     PAGE_END       LAST_LINE_END|
-------------------------------------------------

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.

Obrigado pela ajuda até o momento.

[]s

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í.

Bom dia,

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);
    }

}

Obrigado pelas dicas e pela paciencia.

[]s

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.

GridBagConstraints posicaoGrid = new GridBagConstraints(); posicaoGrid.anchor = GridBagConstraints.FIRST_LINE_START; posicaoGrid.weightx = 1.0; posicaoGrid.weighty = 1.0;

Bom dia,

Deu certo aqui, com sua ultima dica, agora vou passar para as janelas mais complicadas.

Obrigado :slight_smile:

[]s