سؤال

أنا لست على دراية إلى حد ما بكيفية عمل 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 );
}

هوKeyHeld:

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