Pegar coordenadas do click do mouse no Jpanel

53 respostas
Filipe_A

Ola ,espero que alguem possa me ajudar…

Estou começando a desenvolver um projeto, e preciso pegar o click do mouse no panel e
comparar com um local especifico no mesmo.
Caso a pessoa clique nesse local a imagem do panel será trocada… se não, não…

Obrigado.

53 Respostas

dionat4n

Fazer isso é uma péssima técnica!

Você deve adicionar a imagem num painel apenas para a imagem, e adicionar esse painel da imagem em outro painel da sua aplicação.

JPainel são containers, interfaces gráficas em Java se baseam em containers.

Filipe_A

Opa, realmente eu nao tenho muita noção ainda…
vou tentar implementar isso aqui…

valeu.

F
seuPanel.addMouseListener(new MouseAdapter(){
   public void mouseCliked(MouseEvent e){
     int x=e.getX();
     int y=e.getY();
  }
 }
);
Filipe_A

Ola flaryon, valeu pela ajuda.
Com isso eu pego as coordenadas do mouse certo…

Mas e o local onde eu quero que ele click? Como vou fazer pra especificar…

Tipo se eu rodar o programa e dar os clicks no panel e mandar exibir o x e y …talvez eu possa assim
achar as coordenadas do panel onde será preciso ser clicado…

Vou tentar aqui valeu, muito obrigado.

F

então…isso teoricamente é mais fácil de fazer…

basta vc criar um par de variáveis auxiliares que guardem o local que você quer …Imagine o seuPanel como sendo um plano cartesiano, onde o canto superior esquerdo é o ponto de coordenadas (0,0), o canto superior direito (x,0),
o canto inferior esquedo (0,y) e por fim o canto inferior direito (x,y)…de posse disse você pode fazer o seguinte:

logo dentro do código que lhe passei vc pode inseriir o seguinte código:

if(x<=10&&x>=5&&y<=10&&y>=5){
    System.out.println("As coordenadas são: x:"+x+" , y:"+y);
}

esse código define um quadrado de lado 5, se o usuário clicar dentro desse quadrado , exclusivamente neste quadrado, vai imprimir na tela as coordenadas X e Y do click do mouse.

espero que tenha dado pra entender!

Marky.Vasconcelos

Se voce tiver a posição e o tamanho da imagem no JPanel voce pode atraves do mouse saber qual imagem que esta no lugar. Com um pouco de matematica é claro.

Marky.Vasconcelos

flaryon:
então…isso teoricamente é mais fácil de fazer…

basta vc criar um par de variáveis auxiliares que guardem o local que você quer …Imagine o seuPanel como sendo um plano cartesiano, onde o canto superior esquerdo é o ponto de coordenadas (0,0), o canto superior direito (x,0),
o canto inferior esquedo (0,y) e por fim o canto inferior direito (x,y)…de posse disse você pode fazer o seguinte:

logo dentro do código que lhe passei vc pode inseriir o seguinte código:

if(x<=10&&x<=5&&y<=10&&y<=5){
    System.out.println("As coordenadas são: x:"+x+" , y:"+y);
}

esse código define um quadrado de lado 5, se o usuário clicar dentro desse quadrado , exclusivamente neste quadrado, vai imprimir na tela as coordenadas X e Y do click do mouse.

espero que tenha dado pra entender!

Era isso que eu queria dizer… mas o código tem um pequeno erro.

if( (x<=10 && x>=5) && (y<=10 && y>=5)){
    System.out.println("As coordenadas são: x:"+x+" , y:"+y);
}
F

de fato!!! já alterei!!!

=)

Filipe_A

Então eu entendi o que vcs disseram …

Mas não ta dando certo aqui.

public PEMPanel() {

		setLayout(null);

		add(b1);
		add(b2);

		Insets insets = getInsets();
		Dimension size = b1.getPreferredSize();
		b1.setBounds(860 + insets.left, 560 + insets.top, size.width,
				size.height);
		b2.setBounds(950 + insets.left, 560 + insets.top, size.width,
				size.height);

		b1.addActionListener(this);
		b2.addActionListener(this);

		carregarImagem(contador_imagens); 

		addMouseListener(new MouseAdapter() {

			public void mouseCliked(MouseEvent e) {
				int x = e.getX();
				System.out.println(x);
				int y = e.getY();
				System.out.println(y);
			}
		});

	}

Tipo esse é o Panel… mas diz que o metodo não esta sendo usado e tb não imprime o x e y.
podem verificar pra mim,
Obrigado.

F

Dexa eu ver se entendi de fato: Vc quer que imprima a coordenada X e Y qd vc clciar em uma área específica do seu Painel…eh isso?

F

aparentemente estpa tudo correto…qd vc clica no panel o que acontece?

Filipe_A

Não é isso… deixa eu explicar melhor.

De fato eu quero trocar a imagem do panel quando clicar em um lugar especifico no panel.

Eu só fiz isso como teste pra mim ter o x e y do local que foi clicado.
Mas acontece que não ta funcionando, não ta imprimindo nada.

Bem é isso…valeu mais uma vez.

F

qd vc quer alterar uma imagem em um painel vc tem q redesenhá-la…

seuPanel.revalidate();

coloca isso após o me´todo que faz trocar a imagem!!!

Filipe_A

Tipo esse é o construtor a classe ja esta estendida para Jpanel.
valeu.

Marky.Vasconcelos

Mostre a classe inteira.

Filipe_A

Bom vou mostrar o que eu ja fiz ate agora.

public class PEMPanel extends JPanel implements ActionListener {

	private Image imagem;
	private String[] colecao_imagens = { "inicial", "imagem_um", "imagem_dois" };
	private int contador_imagens = 0;
	private static final String LOCAL_IMAGENS = "Extras/Img/";

	private Clip clip;
	private String[] colecao_sons = { "som_um", "som_dois" };
	private int contador_sons = 0;
	private static final String LOCAL_SONS = "Extras/Sons/";

	JButton b1 = new JButton("avançar");
	JButton b2 = new JButton("menu");
	JButton b3 = new JButton("sair");

	public PEMPanel() {

		setLayout(null);

		add(b1);
		add(b2);

		Insets insets = getInsets();
		Dimension size = b1.getPreferredSize();
		b1.setBounds(860 + insets.left, 560 + insets.top, size.width,
				size.height);
		b2.setBounds(950 + insets.left, 560 + insets.top, size.width,
				size.height);

		b1.addActionListener(this);
		b2.addActionListener(this);

		carregarImagem(contador_imagens);

		addMouseListener(new MouseAdapter() {
			public void mouseCliked(MouseEvent e) {
				int x = e.getX();
				System.out.println(x);
				int y = e.getY();
				System.out.println(y);
			}
		});

	}

	public void actionPerformed(ActionEvent e) {
		Object source = e.getSource();

		if (source == b1) {

			if (contador_imagens < 3 && contador_sons < 2) {

				carregarImagem(contador_imagens);
				repaint();

				carregarSom(contador_sons);
				tocaSom();
			}

			else {

				contador_imagens = 0;
				contador_sons = 0;

				carregarImagem(contador_imagens);
				repaint();
			}

		}

		else if (source == b2) {

			contador_imagens = 0;
			contador_sons = 0;

			carregarImagem(contador_imagens);
			repaint();

		}
	}

	public void paintComponent(Graphics g) {
		super.paintComponents(g);
		if (imagem != null)
			g.drawImage(imagem, 0, 0, null);
	}

	public void carregarImagem(int posImagem) {

		try {
			imagem = ImageIO.read(new File(LOCAL_IMAGENS
					+ colecao_imagens[posImagem] + ".gif"));
		} catch (IOException e) {
			e.printStackTrace();
		}
		contador_imagens++;

	}

	public void carregarSom(int posSom) {

		File soundFile = new File(LOCAL_SONS + colecao_sons[posSom] + ".wav");
		AudioInputStream sound = null;

		try {
			sound = AudioSystem.getAudioInputStream(soundFile);
		} catch (UnsupportedAudioFileException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		DataLine.Info info = new DataLine.Info(Clip.class, sound.getFormat());
		try {
			clip = (Clip) AudioSystem.getLine(info);
		} catch (LineUnavailableException e) {
			e.printStackTrace();
		}

		try {
			clip.open(sound);
		} catch (LineUnavailableException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		contador_sons++;

	}

	public void tocaSom() {
		clip.start();
	}

}

Espero que possa me ajudar.
To començando agora e sei que deve ter muita coisa errada no codigo.

E as coordenadas que eu não to conseguindo pegar…visualizar.

Obrigado.

F

eh, eu sei, percebi depois… =p~~~
vc adicionou a linha q escrevi?

F

no fim do método paintComponent adiciona

this.repaint();

não creio que deva solucionar o problema de imprimir as coordenadas…Aparentemente seu código está correto

Filipe_A

Então ainda continuo sem as coordenadas.

Devo informar tb que esse mesmo panel esta adicionado ao frame.
Pq ainda naum consegui adiciona- lo em outro panel.
Pq quando tentei não deu certo.

Será que pode ser por isso?

Obrigado.

F

eh bem provável, já q não está imprimindo as coordenadas!

muda a cor do seu Panel para saber se ele está sendo adicionado no Frame…

Filipe_A

O setBackground(), que vc se refere?

Eu alterei mas não apereceu a cor, será que é pq ja tem a imagem
no panel…

valeu flaryon.

Marky.Vasconcelos

é mouse ‘clicked’ não ‘cliked’

addMouseListener(new MouseAdapter() {  
             public void mouseCliked(MouseEvent e) {  //Errado.. aqui voce só criou um método com esse nome mas ele não vai ser chamado
                 int x = e.getX();  
                 System.out.println(x);  
                 int y = e.getY();  
                 System.out.println(y);  
             }  
         });
public void mouseClicked(MouseEvent e){//correto
F

se vc alterou a cor do seuPanel, e qd mandou visualizar o Form, não apareceu uma área com a cor q vc setou é pq o panel não está dentro do Form…adicione o panel ao Form!!!

Filipe_A

Valeu Mark_Ameba…era o nome mesmo…rss

Agora vou poder dar continuidade aqui.

F

por um ‘c’…aheuaehauea

Filipe_A

flaroyn eu adicionei meu panel ao frame na minha outra classe.
Fiz assim.

public PEMFrame() {

		
		Toolkit kit = Toolkit.getDefaultToolkit();
		Dimension dimensaoTela = kit.getScreenSize();

		int larguraTela = dimensaoTela.width;
		int alturaTela = dimensaoTela.height;

		setBounds(larguraTela / 6, alturaTela / 6, LARGURA_FRAME, ALTURA_FRAME);

		PEMPanel panel = new PEMPanel();
		add(panel);

	}

Esta correto?
Como eu poderia adicionar o panel em outro panel e depois ao frame?

Obrigado mais uma vez

Marky.Vasconcelos

Por isso eu coloco @Override nos métodos que estou sobreescrevendo… se estiver errado o nome o compilador reclama que não existe este método para sobreescrever.

F

da mesma forma

JPanel Panel1 = new JPanel();
 JPanel Panel2= new JPanel();
  Panel1.add(Panel2);
 JFrame form = new JFrame();
 form.add(Panel1);
F

esqueci de mencionar que deve ser dimensionado o tamando dos Paineis com o método

setpreferredSize(new Dimension(suaLargura,suaAltura));
Marky.Vasconcelos

Outra coisa…

public void paintComponent(Graphics g) {  
         super.paintComponents(g);  
         if (imagem != null)  
             g.drawImage(imagem, 0, 0, null);  
     }

Não trabalhe com o Graphics direto por que voce vai ter resultados estranhos.

Crie uma copia e trabalhe com o Graphics2D

public void paintComponent(Graphics g) {  
         super.paintComponents(g);  
         Graphics2D g2d = (Graphics2D) g.create();//Criando a copia
         if (imagem != null)  
             g2d.drawImage(imagem, 0, 0, null);  
         g2d.dispose();//liberando para ser desenhada
     }

E quais problemas voce esta tendo agora?

Se esse Panel voce quer que seja o fundo inteiro do JFrame voce pode simplesmente no frame ao invés de add(panel), coloque setContentPane(panel)
Mas nesse caso um método add no frame iria chamar o add desse Panel que talvez seja algo que voce queira.

Filipe_A

Mark_Ameba vc postou

addMouseListener(new MouseAdapter() {    
            public void mouseCliked(MouseEvent e) {  //Errado.. aqui voce só criou um método com esse nome mas ele não vai ser chamado  
                int x = e.getX();    
                System.out.println(x);    
                int y = e.getY();    
                System.out.println(y);    
            }    
        });

Falou ser errado mas funcionou aqui…
Como assim vc quis dizer? eu não entendi.

Obrigado.

dionat4n

Vocês gostam de passar trabalho!

Coloque a imagem num panel que contenha só a imagem, e coloque o evento sobre esse panel!

F

o correto é mouseClicked e não mouseCliked!

dionat4n

flaryon:
da mesma forma

JPanel Panel1 = new JPanel(); JPanel Panel2= new JPanel(); Panel1.add(Panel2); JFrame form = new JFrame(); form.add(Panel1);

Você está adicionando um painel vazio, nao vai exibir nada mesmo.
Tu precisa adicionar o painel principal no teu frame.getContentPane().add( painel );

Marky.Vasconcelos

Filipe A.:
Mark_Ameba vc postou

addMouseListener(new MouseAdapter() {    
            public void mouseCliked(MouseEvent e) {  //Errado.. aqui voce só criou um método com esse nome mas ele não vai ser chamado  
                int x = e.getX();    
                System.out.println(x);    
                int y = e.getY();    
                System.out.println(y);    
            }    
        });

Falou ser errado mas funcionou aqui…
Como assim vc quis dizer? eu não entendi.

Obrigado.

Funcionou mesmo? Quando voce clicou ele mostrou as coordenadas?

O correto é mouseClicked e voce colocou mouseCliked… o que eu quis dizer é que voce simplesmente criou um novo método dentro dessa classe que nunca vai ser chamado.

Filipe_A

Aham eu ja corrigi aqui é que postei errado.

Filipe_A

Não Pessoal ta exibindo aqui sim…

Ta blz…

agora tenho que implementar outras coisas.

Tipo vou ter que desabilitar os botões enquanto o som estiver tocando
Pra pessoa não avançar de tela.

Se alguem poder dar uma ajuda.

Tambem vou modificar o meu codigo com as dicas que recebi e ver como irá ficar.

Obrigado, estão me ajudando bastante.

Marky.Vasconcelos

No caso do som.
Se voce tocar o som na Thread principal toda sua aplicação já vai ficar desabilitada até o som terminar.

Filipe_A

Nossa não sei nada de Thread vou ter que da uma pesquisada.

Mas o som vai continuar carregando dentro da minha classe PEMPanel?

valeu!

Marky.Vasconcelos

Sim… é ele que vai travar a Thread ele vai ficar carregando e tocando o som. Quando ele acabar o processo continua.

Agora que vi… voce é de prudente… um dos lugares que mais gosto… eu vou ir pra ai nesse mes ainda.

Filipe_A

Sim eu moro em prudente desde sempre …

Aqui é bem bacana sim , tranquilo .

Vc costuma vir sempre?

flw =)

Filipe_A

Tentei adicionar meu panel em outro.
Mas aparece só panel sem nada, sem botoes sem imagem…

fiz deste jeito:

Panel panel2 = new JPanel();
panel2.setPreferredSize(new Dimension(LARGURA_FRAME, ALTURA_FRAME));

PEMPanel panel = new PEMPanel();
panel2.add(panel);

setContentPane(panel2);

Por que será que isto acontece?

Obrigado mais uma vez.

Marky.Vasconcelos

Voce não precisa adicionar seu Panel em outro… voce já pode usar o panel com a imagem como argumento para o setContentPane

Eu costuma ir bastante… pelo menos uma vez a cada 3 semanas… agor ato indo menos… mas ainda acho legal ai.

Filipe_A

Opa Blz … eu pensei que precisava de outro.

Valeu!

Filipe_A

Eu estou tentando o esquema da Thread aqui…
Eu mudei algumas coisa no meu codigo, Criei uma classe apenas pra som.

É nela que devo implementar a Thread ? Eu começei fazer alguma coisa já …veja como ficou:

public class ClassSound implements Runnable {

	private Clip clip;
	private static final String LOCAL_SONS = "Extras/Sons/";
	private String[] colecao_sons = { "som_um", "som_dois" };

	public ClassSound() {

	}

	public void carregarSom(int pos) {

		File soundFile = new File(LOCAL_SONS + colecao_sons[pos] + ".wav");
		AudioInputStream sound = null;

		try {
			sound = AudioSystem.getAudioInputStream(soundFile);
		} catch (UnsupportedAudioFileException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		DataLine.Info info = new DataLine.Info(Clip.class, sound.getFormat());
		try {
			clip = (Clip) AudioSystem.getLine(info);
		} catch (LineUnavailableException e) {
			e.printStackTrace();
		}

		try {
			clip.open(sound);
		} catch (LineUnavailableException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	public void tocarSom() {
		clip.start();

	}
	
	public Clip getClip(){
		return this.clip;
	}

	@Override
	public void run() {
		clip.start();
		
	}
}

Bom é mais ou menos isso que deve ser feito ?

Obrigado

Que lugar vc fica quando vem pra prudente ?

Marky.Vasconcelos

É… assim mesmo que deveria ficar… e para invocar voce pode ter em algum lugar algo assim.

ClassSound sound = new ClassSound();
new Thread(sound).start();//Aqui ele começa a tocar em outra Thread.

Cara… eu sempre esqueço o nome do bairro… mas conhecem lá como vila operaria coisa assim… eu sei que é no meio do caminho para o shopping e para o centro.

Voce é de qual faculdade?

Filipe_A

ok

Filipe_A

Então mas no caso no thread.start() ,

Ele não vai tocar o som já ou vai ? e tb não vai desabilitar os botões etc …

Eu estive lendo sobre thread mas não entendi muito bem pq sempre tinham exemplos de mais de uma thread,
e no caso eu so teria uma…

tipo to meio perdido ainda se puder dar uma ajuda.

obrigado.

Então eu sei onde fica.

Eu moro perto da Torre da Band não sei se vc conhece…

Eu estudo na FATEC abriu faz pouco tempo aqui, curso Analise e Desenvolvimento de Sistemas.
=)

Marky.Vasconcelos

Pra falar a verdade quando falei sobre Thread é que como estava ele não ia desabilitar os botões mas ia travar o processo. E também é uma boa hora para aprender a trabalhar com Threads.

no começo do run voce bote desabilitar os botoes e no final voce pode habilitalos.

Não sei onde é essa torre não =/
Voce sai pra onde por ai? Eu quando vo to sempre pelo Bon Giovani(Coisa assim esqueci o nome xD) e adoro ir no Sichas comer um lanche de madrugada.

Filipe_A

Então eu estava vendo aqui eu acho que da pra fazer tb usando o

sound.getClip().isActive… e assim verificar se o som ta tocando ou não.

mas to tentando aqui ainda.

Então qualquer lugar que me chamarem eu to indo hsuahsuahus … barzinho, shopping etc.
Entao o sichas é otimo, ja fui lah algumas vezes.

Marky.Vasconcelos

Voce pode de tempos em tempos fazer isso

botao.setEnabled(!sound.getClip().isActive());
Filipe_A

Mas eu vou ter que implementar um listener não é ?

Tipo adiciono um no panel pra ele ver se o som ta tocando ou não e assim
abilitar ou desabilitar o botão.

Valeu!

Marky.Vasconcelos

Procure sobre o padrão Observer… voce vai entender mais fácil.

Criado 1 de abril de 2009
Ultima resposta 3 de abr. de 2009
Respostas 53
Participantes 4