Mover JPanel em tempo de execução

5 respostas
Sergio_Junior

Bom dia, olhando o titulo parece ser algo facil, porem não é… pelo menos não pra mim.
É o seguinte, tenho um programa que vai adicionando componentes JPanel na tela, em uma ordem, um do lado do outro até tem 7 lado a lado, ai vai pra linha de baixo e faz a mesma coisa.
Até ai tudo bem, vide codigo1.
O meu problema é o seguinte, esses JPanel terão que respeitar uma ordem crescente. E o usuario quem ira defini-los. Então como eu faço pra que ele fique na ordem de acordo com o numero que o usuario digita?
Consigo fazer eles serem criados de boa (codigo2), porem ficam na ordem de criação, e não a ordem crescente. Alguem pode me dar uma luz?

codigo1
nesse codigo, ele cria as mesas na ordem, a variavel “mesaCriada” é iniciada em 0, e vai crescendo de acordo com as mesas que são criadas, até 27 (numero maximo de mesas).

int xMesa = 5;
        int yMesa = 5;
        int xLblMesa = 5;
        if (mesaCriada < 28) {
            int posicao;
            if (mesaCriada == 0) {
                xMesa = 5;
                yMesa = 5;
            } else if (mesaCriada < 7) {
                xMesa = 5 + (mesaCriada * 135);
                yMesa = 5;
                xLblMesa = 5 + (mesaCriada * 15);
            } else if (mesaCriada < 14) {
                posicao = mesaCriada - 7;
                xMesa = 5 + (posicao * 135);
                yMesa = 130;
                xLblMesa = 5 + (mesaCriada * 15);
            } else if (mesaCriada < 21) {
                posicao = mesaCriada - 14;
                xMesa = 5 + (posicao * 135);
                yMesa = 255;
                xLblMesa = 5 + (mesaCriada * 15);
            } else if (mesaCriada < 28) {
                posicao = mesaCriada - 21;
                xMesa = 5 + (posicao * 135);
                yMesa = 380;
                xLblMesa = 5 + (mesaCriada * 15);
            }
        } else {
            javax.swing.JOptionPane.showMessageDialog(null, "Limite de Mesas criadas");
            System.out.println("limite " + mesaCriada);

            return;
        }

codigo2 - Como podemos ver, estou adicionando um JPanel e dentro dele um JLabel ambos com tamanhos fixos. Esses componantes são add dentro de um JDesktopPane que se chama “maeprincipal”. E add um listener pra eventos quando clicar naquele JLabel.

JLabel lblMesa = new JLabel();
        JPanel pnMesa = new JPanel();


 pnMesa.setLayout(null);
        pnMesa.add(lblMesa);

     //AQUI TEM VARIAS CONFIGURAÇÕES DO LABEL INSIGNIFICANTES PARA O TOPICO
        lblMesa.setText("MESA: " + mesa);
        lblMesa.setPreferredSize(new java.awt.Dimension(118, 99));
        pnMesa.add(lblMesa);
        lblMesa.setBounds(5, 5, 120, 110);

        pnMesa.setBounds(xMesa, yMesa, 130, 120);
        mesaCriada++;

        maeprincipal.add(pnMesa);

        lblMesa.addMouseListener(new java.awt.event.MouseAdapter() {
            @Override
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                BotaoMesa(evt, mesa, lblMesa);
            }
        });

5 Respostas

H

@Sergio_Junior, tudo bom?

tenho um programa que vai adicionando componentes JPanel na tela, em uma ordem, um do lado do outro até tem 7 lado a lado, ai vai pra linha de baixo e faz a mesma coisa.

Nesse caso, você pode usar o GridLayout e, para ordernar as mesas, criar uma classe que implemente Comparable. Segue um código que fiz de exemplo:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collections;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;

public class MesaTeste extends JFrame {

	private JPanel contentPane;

	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					MesaTeste frame = new MesaTeste();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	public MesaTeste() {

		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 744, 551);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(new BorderLayout(0, 0));

		JPanel painelPrincipal = new JPanel();
		contentPane.add(painelPrincipal, BorderLayout.CENTER);
		painelPrincipal.setLayout(new GridLayout(4, 7, 10, 10));

		JPanel painelBotao = new JPanel();
		contentPane.add(painelBotao, BorderLayout.SOUTH);

		JButton btnAlterar = new JButton("Alterar n\u00FAmero das mesas");
		painelBotao.add(btnAlterar);
		ArrayList<Mesa> mesas = new ArrayList<Mesa>();
		
		// Cria as mesas
		for (int numeroMesa = 1; numeroMesa <= 28; numeroMesa++) {
			Mesa m = new Mesa(numeroMesa);
			m.setMouseAdapter(new MouseAdapter() {
				@Override
				public void mouseClicked(MouseEvent evt) {
					botaoMesa(evt, m);
				}
			});
			mesas.add(m);
		}

		// Adiciona as mesas em ordem
		for (Mesa mesa : mesas) {
			painelPrincipal.add(mesa.getPanel());
		}

		btnAlterar.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				// Inverte a ordem das mesas, para demonstrar o Collections.sort
				for (int novoNumero = 28, indice = 0; novoNumero >= 1; novoNumero--, indice++) {
					mesas.get(indice).setNumeroMesa(novoNumero);
				}
				// Remove todas as mesas do painel
				painelPrincipal.removeAll();
				// Ordena as mesas
				Collections.sort(mesas);
				// Readiciona as mesas
				for (Mesa mesa : mesas) {
					painelPrincipal.add(mesa.getPanel());
				}
			}
		});
	}

	public void botaoMesa(MouseEvent evt, Mesa mesa) {
		System.out.println(String.format("Mesa clicada %d", mesa.getNumeroMesa()));
	}

}

class Mesa implements Comparable<Mesa> {
	private JPanel panel;
	private int numeroMesa;
	private JLabel label;
	private MouseAdapter mouseAdapter;

	public MouseAdapter getMouseAdapter() {
		return mouseAdapter;
	}

	public void setMouseAdapter(MouseAdapter mouseAdapter) {
		this.mouseAdapter = mouseAdapter;
		panel.addMouseListener(mouseAdapter);
	}

	public Mesa(int numeroMesa) {
		this.numeroMesa = numeroMesa;
		panel = new JPanel();
		panel.setBorder(new LineBorder(Color.BLACK));

		label = new JLabel();

		label.setBounds(0, 0, 46, 14);
		label.setText(String.format("Mesa %d", numeroMesa));
		panel.add(label);
	}

	public JPanel getPanel() {
		return panel;
	}

	public void setPanel(JPanel panel) {
		this.panel = panel;
	}

	public int getNumeroMesa() {
		return numeroMesa;
	}

	public void setNumeroMesa(int numeroMesa) {
		this.numeroMesa = numeroMesa;
		this.label.setText(String.format("Mesa %d", numeroMesa));
	}

	@Override
	// Usado pelo Collections.sort
	public int compareTo(Mesa outraMesa) {
		if (this.getNumeroMesa() < outraMesa.getNumeroMesa()) {
			return -1;
		}
		if (this.getNumeroMesa() > outraMesa.getNumeroMesa()) {
			return 1;
		}
		return 0;
	}
}

Se entendi errado, me avise.
Abcs!

Sergio_Junior

Então cara… Na verdade não é isso… Colocar os componentes eu consigo…
Porem eles serão adicionados conforme a necessidade. Por exemplo: garçom vai na mesa 3, e abre a mesa, então adiciona ela no sistema, depois vai na mesa 5, adiciona ela, assim ele esta na sequencia certa, pois ele atendeu na sequencia. só que se por exemplo, depois ele ir na mesa 1, ela ficara por ultimo, ficando fora de ordem, então teria que mover a mesa 1 pro começo, e colocar as mesas 3 e 5 a frente.

Abraço

D

São 27 mesas no total, entao:

ArrayList<Integer> numeros = new ArrayList<>(); // Uma lista vazia , sera usado depois
JLabel[] lblMesas = new JLabel[27];
for (int i = 0; i < 27; i++) {
    lblMesas[i] = new JLabel();
    lblMesas[i].setBounds;
    lblMesas[i].setVisible(false); // Esconde
    pnMesa.add(lblMesas[i]);
}

Neste momento não há mesas, mas graficamente existem e estão escondidas.

Ao digitar um numero:

numeros.add(numeroDigitadoPeloUsuario);
for (int i = 0; i < 27; i++) {
    if (i < numeros.getSize()) {
        lblMesas[i].setText(numeros.get(i)); // atualiza o label
        lblMesas[i].setVisible(true); // exibe
    } else {
        lblMesas[i].setVisible(false); // esconde
    }
}
H

Agora entendi :slight_smile:, o GridLayout não suporta ocultar os JPanels sem que eles ocupem espaço, eles tem que ser removidos e adicionados somente quando “em atendimento”, segue o código atualizado:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;

public class MesaTeste extends JFrame {

	private JPanel contentPane;
	private JTextField inputMesa;

	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					MesaTeste frame = new MesaTeste();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	public MesaTeste() {

		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 744, 551);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(new BorderLayout(0, 0));

		JPanel painelPrincipal = new JPanel();
		contentPane.add(painelPrincipal, BorderLayout.CENTER);
		painelPrincipal.setLayout(new GridLayout(4, 7, 10, 10));

		JPanel painelBotao = new JPanel();
		contentPane.add(painelBotao, BorderLayout.SOUTH);

		inputMesa = new JTextField();
		painelBotao.add(inputMesa);
		inputMesa.setColumns(10);

		JButton btnAtender = new JButton("Atender Mesa");
		painelBotao.add(btnAtender);
		ArrayList<Mesa> mesas = new ArrayList<Mesa>();

		// Cria as mesas
		for (int numeroMesa = 1; numeroMesa <= 28; numeroMesa++) {
			Mesa m = new Mesa(numeroMesa);
			m.setMouseAdapter(new MouseAdapter() {
				@Override
				public void mouseClicked(MouseEvent evt) {
					botaoMesa(evt, m);
				}
			});
			mesas.add(m);
		}

		btnAtender.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				// TODO: Tratar se mesa já não está sendo atendida 
				int indiceMesa = Integer.parseInt(inputMesa.getText()) - 1;
				mesas.get(indiceMesa).setEmAtemdimento(true);
				
				painelPrincipal.removeAll();
				
				for (Mesa mesa : mesas) {
					if(mesa.isEmAtemdimento()){
						painelPrincipal.add(mesa.getPanel());
					}
				}
				
				int paineisVazios = 28 - painelPrincipal.getComponentCount();

				// Adiciona um dummy space, para forçar o layout 4 x 7
				for(int i = 0; i < paineisVazios; i++){
					painelPrincipal.add(new JPanel());
				}
				
				painelPrincipal.revalidate();
				painelPrincipal.repaint();
			}
		});
	}

	public void botaoMesa(MouseEvent evt, Mesa mesa) {
		System.out.println(String.format("Mesa clicada %d", mesa.getNumeroMesa()));
	}
}

class Mesa {
	private JPanel panel;
	private int numeroMesa;
	private JLabel label;
	private MouseAdapter mouseAdapter;
	private boolean emAtemdimento;
	
	public Mesa(int numeroMesa) {
		this.numeroMesa = numeroMesa;

		panel = new JPanel();
		panel.setBorder(new LineBorder(Color.BLACK));

		label = new JLabel();

		label.setBounds(0, 0, 46, 14);
		label.setText(String.format("Mesa %d", numeroMesa));
		panel.add(label);
	}

	public boolean isEmAtemdimento() {
		return emAtemdimento;
	}

	public void setEmAtemdimento(boolean emAtemdimento) {
		this.emAtemdimento = emAtemdimento;
	}

	public MouseAdapter getMouseAdapter() {
		return mouseAdapter;
	}

	public void setMouseAdapter(MouseAdapter mouseAdapter) {
		this.mouseAdapter = mouseAdapter;
		panel.addMouseListener(mouseAdapter);
	}
	public JPanel getPanel() {
		return panel;
	}

	public int getNumeroMesa() {
		return numeroMesa;
	}
}

Adicionando mesas 1 e 5:

Adicionando mesa 3:

Sergio_Junior

Obrigado Lucas,
Bom, ja implementei uma outra maneira pra fazer isso.
Porem estou com outra duvida, estou usando um array para armazenar os JPanels, e depois organizo eles com Collections.sort… Porém, ele só atualiza depois que sai da função e volta novamente. Então não estou conseguindo atualizar na hora. Sabe o que pode ser isso?

Criado 29 de março de 2016
Ultima resposta 31 de mar. de 2016
Respostas 5
Participantes 3