Java KeyAdapter
I am somewhat unfamiliar with how the Java KeyAdapter
works, and am getting unexpected results with the following code using KeyAdapter
. The problem occurs when a key is pressed while another key is already held down, regardless of whether isKeyPressed()
is called.
Note: I know this is a lot of code, and I apologize. I tried the best I could to isolate it, and I think it resides primarily around the comments in the keyHandler
method below (how keyHandler()
puts the keys currently pressed into keysHeld
). Hopefully the thorough comments are helpful.
keyHandler:
ArrayList keysHeld = new ArrayLi开发者_JAVA技巧st<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;
}
Console output: (held leftArrow[37], and then pressed 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
...
A couple points:
- You aren't populating your
keysHeld
array with instances ofKeyEvent
, but with autoBoxedInteger
objects derived from theint
keyCodes. - You need to increment your
index
variable if you want to get out of thewhile
loop inkeyPressed
- You shouldnt use
==
to compare the twoObjects
in yourwhile
loop
You can test with something like the following:
if(keysHeld.get(index++).equals(new Integer(keyCode))
When handling multiple keys, it's best to use the keyReleased(KeyEvent)
method: it makes it easier to handle multiple key combinations during a key release.
What I've noticed was that when inside the keyPressed()
, I would only get to capture one key character. On a keyReleased
, I was able to capture multiple characters (such as CTRL-V).
精彩评论