Como saber se um botão está pressionado

22 respostas
R

Fala galera do Guj…

Existe algum evento para JButton que me diga se o botão está pressionado… ou seja não quero saber se ele foi pressionado… mas se ele está pressionado… por exemplo a cada clique em um botão eu vou somar 1 para uma variavel qq, mas se o clique for longo eu preciso ir somando um enquanto o usuário não solta o botão, como se fosse um loop pelo tempo que ele segurou o clique em um botão…

Alguem sabe como se faz isso

Valeu…

22 Respostas

E

tente JButton.isSelected()

R

Valeu Edu4rd0… mas não é bem isso, deixa eu explicar melhor, eu preciso fazer uma contagem enquanto o usuário estiver pressionando o mouse sobre um botão e não só se ele esta selecionado…

Exemplo um usuáaio aperta o mouse sobre um JButton mas leva 10 segundos para soltar o botão, eu preciso que enquanto ele não solte o botão do mouse eu vou somando um a uma variavel…

E

entao, faça algo do tipo:

while (botao.isSelected() ) {
// faz algo
}

acho que dentro desse while vc deveria fazer uma checagem pra ver quando tempo se passou, talvez um novo while

long inicio = System.currentTimeMillis();

while( botao.isSelected() ) {
 while ( System.currentTimeMillis() == ( inicio += 1000 ) ) {
  ++a; // incrementando
 }
}

enfim… acho que é por aih

R

Edu4rd0 - Valeu pela ajuda eu dei um outro jeito usando Threads...

ficou assim;
Quando o usuário clica no botão eu seto a variavel botaoPressed para true, e chamo uma thread que vai ficar num loop enquanto a variavel botaoPressed for verdadeira, então quando ele solta o botão do mouse lança o evento mouseReleased que para o loop da thread...

btnUp.addMouseListener(new MouseAdapter(){
			@Override
			public void mousePressed(MouseEvent e) {
				botaoPressed = true;
				qtdCliques = 0;
				(new ThreadIncrementa()).start();
			}

			@Override
			public void mouseReleased(MouseEvent e) {
				botaoPressed = false;
				qtdCliques = 0;
			}
		});
B

Achei esse tópico antigo então decidi usa-lo para não ter que criar outro.

Tentei usar a idéia do eduardo dos while, mas minha aplicação esta travando quando tento isso. O meu problema é ter alguma função que retorne se uma tecla esta em hold, eu estou implementando um jogo e eu não quero que o usuário possa fazer hold em exclusivamente duas teclas.

Gostaria de saber se existe alguma função em java que ajude a saber se uma tecla esta sendo segurada.

João Pedro

B

Ninguém pode dar um help aqui?

L

Oi,

Se escutar o KeyListener das teclas… resolveria?

Tchauzin!

B

Isso seria implementar os métodos keyPressed, keyReleased, keyTyped, para que eu possa saber o estado em que a tecla se encontra?

Tipo o meu código esta com a idéia pronta a única coisa que não funciona é o que acima foi dito pelo Eduardo o botao.isSelected() era uma função dessas para saber se a tecla esta em hold que eu preciso.

Muito obrigado pela ajuda estive esperando bastante tempo por uma resposta.

João Pedro

L

Bruto_JPO:
Isso seria implementar os métodos keyPressed, keyReleased, keyTyped, para que eu possa saber o estado em que a tecla se encontra?

Oi,

Exatamente…

Tchauzin!

B

Foi uma ótima idéia a de implementar esta interface, eu já tinha ouvido falar dela, mas teoria e prática são coisas distantes então esta assim:

/** Key Listener interface implementation */
        
        public void keyPressed( KeyEvent e ){
        	mPressed = true;
        	int time = 0;
        	while( time < 50 ){
        		time++;
        	}
        	 if ( mPressed && time == 50 ){
                   mHold = true;
          }        	
        }
        
        public void keyTyped( KeyEvent e ){
        	mKeyTyped = true;
        	System.out.println( "mTyped is true" );
        }
        
        public void keyReleased( KeyEvent e ){
        	mKeyUp = true;
        	System.out.println( "mkeyUp is true" );
        }

Eu tenho três variavéis boolean que ficam em true caso uma das ações seja verdadeira. Tentei implementar a idéia a cima de que se o cara apertou o botão e passou uma fração de tempo a tecla esta em hold, mas por algum motivo que eu não estou sabendo qual é ele sempre entra naquele laço e deixa o mHold em true, parece até que ele só esta checando se o tempo passou e não se o o botão ainda esta pressionado. Tentei também deixar o while assim:

while ( mPressed ){
   time++;
}

Mas assim ele fica em um laço infinito e não sai deste trecho.

Então agora só preciso de uma idéia que me ajude a pegar o hold, porque implementar estas interfaces realmente me ajudou.

L

Oi,

Teoricamente o keyReleased será realizado quando soltar a tela pressionada. Então, você poderia fazer.:

public void keyPressed( KeyEvent e ){   
        mPressed = true;                  
       }   
         
       public void keyTyped( KeyEvent e ){   
        mKeyTyped = true;   
        System.out.println( "mTyped is true" );   
       }   
         
       public void keyReleased( KeyEvent e ){   
        mPressed = false; 
       }

Quando você deixar pressionada a tecla, a variavel boolean ficará sendo true, e quando soltar a tecla, a variavel boolean ficará false.

Tchauzin!

B

Sim agora eu posso saber os estados através desta variável boolean, quando ela for true quer dizer que a tecla esta sendo pressionada e se ela for false quer dizer que ela esta na posição inicial de solta.

O problema é que o estado de estar segurando a tecla é entre estas duas ações. Estou trabalhando duro para tentar pegar a fração de tempo que o usuário ficou apertando a tecla. Se o mPressed for true e tiver se passado uma quantia determinada de tempo eu queria colocar o mHold em true dai eu teria a certeza de que o usuário esta segurando a tecla o problema é que esta bem trabalhoso saber o tempo que a tecla demorou para voltar ao estado inicial. Tentei usar um while simples que incrementava uma variável inteira.

int time = 0; while ( mPressed ){ time++; if ( time == 5 ){ mPressed = false; mHold = true; break; } }

Mas isso não funciona na prática então vou tentar usar novamente o tempo do sistema, com o método System.currentTimeMillis(), mas acho que também não vai funcionar porque eu já havia testado antes. Na prática o ideal seria não permitir que a tecla ficasse em hold e que esta pudesse ser apenas Typed, isso seria a melhor solução vou trabalhar nisso o dia todo espero que mais pessoas como a Lina apareçam para me dar uma mão.

João Pedro

L

Oi,

Quando entrar no pressed, você pode receber uma variavel Date. e no Released você receberá outra.
Diminua uma data da outra e saberá o tempo…

Tchauzin!

B
Creio que foi isto que me sugeriu a fazer:
public void keyPressed( KeyEvent e ){
        	mPressed = true;
        	long timePressed = System.currentTimeMillis();
        	}
        }
        
        public void keyTyped( KeyEvent e ){
        	mKeyTyped = true;
           }
        }
        public void keyReleased( KeyEvent e ){
               	mPressed = false;
        	long timeReleased = System.currentTimeMillis();
           }
        }

Foi uma boa idéia só que há uma coisa muito estranha acontecendo, eu fiz isto e estava tentando estipular uma fração de tempo, colocando se este intervalo de tempo entre a ação de pressionar e soltar a tecla fosse por exemplo maior que 0.500 então o hold seria true. Então tentei comparar com zero só para testar e percebi que da true, quer dizer que a subtração dos dois tempos esta dando zero e exatamente zero porque testei com outros valores e da verdadeiro somente para zero.

long timeElapsed = timePressed - timeReleased;

        if ( timeElapsed == 0 ){
            	 mHold = true;
            	 
            	 System.out.println( timeElapsed );
            	  
             }

Não sei porque esta dando exatamente zero, se os dois métodos são chamados em momentos distintos no sistema, e eles sendo zero eu não tenho como estipular os milisegundos que normalmente leva-se para pressionar e soltar uma tecla, eu tenho quase certeza que este tempo é a metade de um segundo ou seja 0.500 milisegundos já tentei comparar com este valor, mas não funcionou.

L

Oi,

O que acontece no seu código, é que o time está se sobreescrendo.
Dessa forma, a unica maneira seria assim.:

int	
inicial_pressed = 0,
final_pressed = 0,
time_final	= 0;

public void keyPressed(KeyEvent e) {

	mPressed = true;

	if (inicial_pressed == 0){
		inicial_pressed	=	new Date().getSeconds(); // Esse método é deprecated, pode usar o System.Current
	}
	else {
		final_pressed = new Date().getSeconds(); // Esse método é deprecated, pode usar o System.Current
	}
}
		  
public void keyReleased(KeyEvent e)  {  
	
	mPressed = false;				
	time_final	=	(final_pressed - inicial_pressed);
	System.out.print(time_final);
}

Tchauzin!

B

Bem agora já estou conseguindo saber se esta em true o hold isso é ótimo, muito obrigado. A única coisa que não deu certo foi estipular um tempo pro hold, porque o time_final vai aumentando de acordo com o tempo da aplicação, então eu tentei fazer assim:

if( keyCode == KeyEvent.KEYCODE_K && mTimeFinal > 0.1 ) { mHold = true; mPunching = false; }

Bem tudo isto até agora é para que o personagem do meu jogo faça a operação de socar, sendo assim a variável mPunching fica em true, como estou querendo pegar o hold eu coloco essa variável que define se ele pode socar em false, ele só podera socar se ficar apertando o botão continuamente. O jogo esta sendo feito na plataforma android e quanto ao keyCode e KeyEvent não tem mistério estou simplesmente pegando quando o cara apertar a tecla “K”.

Depois que se passa 0.1 o cara não consegue mais socar e fica assim tipo depois que eu seto o mPunching em false uma vez mesmo que eu continue a rodar a aplicação ele não faz mais a ação de socar, vou trabalhar em uma função que resete esse valor porque o que eu quero é que o cara soque quando apertar o botão varias vezes e quando acontecer o hold ele desfira um único soco e volte ao seu estado normal e não fique “socando o ar” ( estado de hold permanente ).

O mTimeFinal deveria devolver realmente os segundos que o cara ficou apertando a tecla. Por exemplo: 2, ou 1. Como o tempo do sistema aumenta ele começa devolvendo 1 ou 2 depois 3 e 4 e assim sucessivamente. Se eu conseguir pegar o tempo real ai sim eu creio que posso criar uma faixa de 1 segundo entre cada vez que o usuário pressionar uma tecla e colocar o mHold em true.

Mais uma vez obrigado pela ajuda.

K

Oi, vi esse tópico e resolvi usa-lo, apesar da minha dúvida ser bem mais básica que a dos anteriores.
Tenho que colocar uma imagem em primeiro plano caso o botão referente aquela imagem (que já está na janela, só que em tamanho menor) for pressionado.
Sou iniciante em JAVA, e fiz de uma maneira que achei a mais simples: fiz um while e quando o botão fosse pressionado a imagem aparecia, mas não deu certo.
Alguma dica?

K
Boom, preciso que a imagem já chamada fique maior quando o botão for pressionado.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;

import javax.swing.ImageIcon;  
import javax.swing.JFrame;  
import javax.swing.JLabel;  

public class BotaoComando extends JFrame implements ActionListener {
	JButton botaoComando;
	String pedindoComando = "@@@,a?,&";
	char[] comandoChar = pedindoComando.toCharArray();  
	int[] comandoInteiro = new int[comandoChar.length];
	JLabel label;  
	
	DriverSerial driver;// = new DriverSerial ("comandoInteiro");   
	
    public BotaoComando()
 
    {
        super(" Controle ");
 
        Container tela = getContentPane();
        tela.setLayout(null);
        
        botaoComando = new JButton ("Controle TV");
        botaoComando.setBounds(180, 30, 100, 40);
        ImageIcon img = (new ImageIcon("C:/Katarina/Controle/controle.jpg")); 
        
        if(img == null)
        {
        	System.out.println("erro");
        }              
        
        label = new JLabel(img);
        label.setBounds(80,80,290,290);
                
        tela.add(botaoComando);
        tela.add(label);
        this.setSize(600,440); 
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setVisible(true); 
       
        botaoComando.addActionListener((ActionListener) this);
                       
        botaoComando.setToolTipText("Clique neste botão "
				+ "para usar o controle.");
        
        driver = new DriverSerial("Controle TV"); 
        driver.open();
        
   }
    
    private boolean ImageIcon(String string) {
		// TODO Auto-generated method stub
		return false;
	}

    public void actionPerformed(ActionEvent e) 
    {	 
	  for (int cont = 0; cont >= comandoInteiro.length; cont++)
      {
    	  System.out.println (comandoInteiro[0]);
      }
     	//System.out.println("Testando código");
    	driver.sendBytes(comandoInteiro); 
    }
 
    public static void main(String args[]) 
    {
       	new BotaoComando();      	
    }


 }
Alguma dica, alguém pode me ajudar?
R

opa tem esta classe ai:

DriverSerial

fiquei afim de ver funcionando.

K

E ai Raghy, algum erro?

R

ta faltando esta classe DriverSerial

no seu programa… podes mostrar?
ou precisa biblioteca?
o que é isto ? DriverSerial ?

obrigado…

sugiro que olhem meu jogo de memoria…

www.raghyjose.net/memoria.php

tem o uso destas bibliotecas de mouse. valeu galera!

K

Oii, a Driver serial é um objeto que chama uma outra classe, entende?
Esse código é uma implementação de uma Comunicação serial (dai a classe Driver), quando o driver é chamado, está chamando a comunicação.

Deu pra entender? Num sei explicar direito…
Obrigada.

Criado 10 de junho de 2005
Ultima resposta 25 de out. de 2010
Respostas 22
Participantes 6