Domanda
Non ho familiarità con il modo in cui funziona Java KeyAdapter
e sto ottenendo risultati imprevisti con il seguente codice usando KeyAdapter
. Il problema si verifica quando si preme un tasto mentre è già premuto un altro tasto, indipendentemente dal fatto che sia chiamato isKeyPressed ()
.
Nota: so che questo è un sacco di codice e mi scuso. Ho fatto del mio meglio per isolarlo e penso che risieda principalmente nei commenti nel metodo keyHandler
di seguito (in che modo keyHandler ()
inserisce i tasti attualmente premuti in < code> keysHeld ). Speriamo che i commenti approfonditi siano utili.
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;
}
Output della console: (tieni premuto leftArrow [37], quindi premi 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
...
Soluzione
Un paio di punti:
- Non stai popolando il tuo array
keysHeld
con istanze diKeyEvent
, ma con oggettiInteger autoBoxed derivati ??dall'oggetto int
keyCodes. - È necessario incrementare la variabile
index
se si desidera uscire dal ciclomentre
inkeyPressed
- Non dovresti usare
==
per confrontare i dueOggetti
nel tuomentre
loop
Puoi provare con qualcosa di simile al seguente:
if(keysHeld.get(index++).equals(new Integer(keyCode))
Altri suggerimenti
Quando si gestiscono più chiavi, è meglio usare il metodo keyReleased (KeyEvent)
: semplifica la gestione di più combinazioni di tasti durante il rilascio di una chiave.
Quello che ho notato è che all'interno del keyPressed ()
, avrei potuto catturare solo un carattere chiave. Su un keyReleased
, sono stato in grado di catturare più caratteri (come CTRL - V ).