Pergunta
Estou um pouco familiarizado com a forma como o KeyAdapter
Java funciona, e estou obtendo resultados inesperados com o seguinte código usando KeyAdapter
. O problema ocorre quando uma tecla é pressionada enquanto outra chave já está pressionado, independentemente de isKeyPressed()
é chamado.
Nota: Eu sei que isso é um monte de código, e peço desculpas. Eu tentei o melhor que pude para isolá-lo, e eu acho que reside principalmente em torno dos comentários no método keyHandler
abaixo (como puts keyHandler()
as chaves atualmente pressionados em keysHeld
). Esperemos que os comentários completos são úteis.
keyHandler:
ArrayList keysHeld = new ArrayList<KeyEvent>();
private void keyHandler()
{
KeyAdapter keyListnr = new KeyAdapter()
{
public void keyPressed(KeyEvent e)
{
int keyCode = e.getKeyCode();
int index = 0;
boolean found = false;
while(!found && index<keysHeld.size()) //While not already found, and end of ArrayList not reached
{
System.out.print("errorCheck: keysHeld: "+keysHeld+", "+(Object)keyCode+" "); //PRINT
if(keysHeld.get(index) == (Object)keyCode)
{
System.out.println("found"); //PRINT
found = true; //This key is already recognized as held
}
else
{
System.out.println("not found"); //PRINT
//This key is not recognized as held
}
}
if(!found) //If key must be added to keysHeld
{
keysHeld.add(keyCode); //Add to list of held keys
}
System.out.println(keysHeld.toString()); //PRINT ArrayList of all held keys
} //end of keyPressed
public void keyReleased(KeyEvent e) //similar in concept to keyPressed
{
int keyCode = e.getKeyCode();
int index = 0;
boolean found = false;
while(!found && index < keysHeld.size())
{
if(keysHeld.get(index) == (Object)keyCode)
{
keysHeld.remove(index); //remove key from keysHeld
found = true;
}
else
{
index++;
}
}
System.out.println(keysHeld.toString()); //PRINT ArrayList of all held keys
} //end of keyReleased
};
addKeyListener( keyListnr );
}
isKeyHeld:
public boolean isKeyHeld(int e)
{
int keyCode = e;
Object key = (Object)keyCode;
if(!keysHeld.isEmpty())
{
int index = 0;
while(index<keysHeld.size())
{
if(keysHeld.get(index) == key)
{
return true;
}
index++;
}
}
return false;
}
saída consola: (realizada leftarrow [37], e em seguida, pressionado rightArrow [39])
[37]
errorCheck: keysHeld: [37], 39 not found
errorCheck: keysHeld: [37], 39 not found
errorCheck: keysHeld: [37], 39 not found
errorCheck: keysHeld: [37], 39 not found
...
Solução
pontos Um par de:
- Você não está povoando sua matriz
keysHeld
com instâncias deKeyEvent
, mas com autoBoxedInteger
objetos derivados dos códigos de teclaint
. - Você precisa incrementar sua variável
index
se você quer sair do loopwhile
emkeyPressed
- Você não deve usar
==
para comparar os doisObjects
em seu loopwhile
Você pode testar com algo parecido com o seguinte:
if(keysHeld.get(index++).equals(new Integer(keyCode))
Outras dicas
Ao manusear várias chaves, é melhor usar o método keyReleased(KeyEvent)
:. Torna mais fácil para lidar com múltiplas combinações de teclas durante uma liberação chave
O que eu notei foi que, quando dentro do keyPressed()
, eu só iria começar a capturar um personagem-chave. Em um keyReleased
, eu era capaz de capturar vários personagens (como Ctrl - V ).