Вопрос

Я несколько незнаком с тем, как работает Java KeyAdapter работает, и я получаю неожиданные результаты со следующим кодом, использующим KeyAdapter.Проблема возникает, когда клавиша нажата, в то время как другая клавиша уже удерживается нажатой, независимо от того, isKeyPressed() называется.

Примечание:Я знаю, что это большой объем кода, и я приношу свои извинения.Я сделал все, что мог, чтобы изолировать это, и я думаю, что это связано в первую очередь с комментариями в keyHandler приведенный ниже метод (как keyHandler() помещает нажатые в данный момент клавиши в keysHeld).Надеюсь, подробные комментарии окажутся полезными.

Манипулятор с ключами:

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 );
}

исКейХелд:

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;
}

Консольный вывод:(удерживая левую стрелку [37], а затем нажав правую стрелку[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
...
Это было полезно?

Решение

Пара моментов:

  • Вы не заполняете свой keysHeld массив с экземплярами KeyEvent, но с автоматической упаковкой Integer объекты , производные от int Коды ключей.
  • Вам нужно увеличить свой index переменная, если вы хотите выйти из while петля в keyPressed
  • Вы не должны использовать == чтобы сравнить эти два Objects в вашем while петля

Вы можете протестировать что-то вроде следующего:

    if(keysHeld.get(index++).equals(new Integer(keyCode))

Другие советы

При работе с несколькими ключами лучше всего использовать keyReleased(KeyEvent) способ:это упрощает обработку нескольких комбинаций клавиш во время отпускания клавиши.

Что я заметил, так это то, что когда внутри keyPressed(), У меня получилось бы запечатлеть только одного ключевого персонажа.На keyReleased, я смог запечатлеть несколько символов (таких как CTRL-V).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top