2016-02-11 6 views
1

Итак, у меня есть 2 класса под названием Viewer и PaintWindow. В моем случае класс Viewer действует как контроллер, в то время как я использую класс PaintWindow для рисования вещей на JPanel.Как получить Keyevent из другого класса?

Теперь я пытаюсь собрать небольшую игру, но я не понимаю, как реализовать KeyListener, чтобы иметь возможность контролировать игру. Я хочу, чтобы слушатель перечислил ключевой случай, чтобы я мог решить, что произойдет. Это как мой код выглядит следующим образом:

Viewer:

public void run() { 
    System.out.println("Viewer Run"); 
    cloud1 = new ImageIcon("src/images/cloud.png"); 
    cloud2 = new ImageIcon("src/images/cloud.png"); 
    background1 = new ImageIcon("src/images/background.png"); 
    playerStill = new ImageIcon("src/images/still.png"); 
    playerRight = new ImageIcon("src/images/right.png"); 
    playerLeft = new ImageIcon("src/images/left.png"); 


    paintWindow = new PaintWindow(background1); 
    paintWindow.showImage(playerStill, 30, 370); 
    paintWindow.addKeyListener(new KeyTimerListener()); 
    paintWindow.startAlarm(); 



} 
/* 
* Lyssnar på vad som händer när man trycker en viss knapp 
*/ 
private class KeyTimerListener implements KeyListener { 

    @Override 
    public void keyPressed(KeyEvent e) { 
     int keyCode = e.getKeyCode(); 
     if(keyCode == 37){ 
      System.out.print("Left"); 
     } 
     else if (keyCode == 39){ 
      System.out.print("Right"); 
     } 
     else if (keyCode == 32){ 
      System.out.print("JUMP"); 
     } 

    } 

    @Override 
    public void keyReleased(KeyEvent e) { 
    } 

    @Override 
    public void keyTyped(KeyEvent e) { 
    } 
} 

}

Это часть моего класса PaintWindow:

public void addKeyListener(KeyListener listener){ 
    this.listener.add(listener); 
} 
private class AT extends Thread { 
    KeyEvent keyevent; 
    public void run() { 
     try { 
      Thread.sleep(1); 
     }catch(InterruptedException e) { 

     } 
     for(KeyListener al : listener) { 
      al.keyPressed(keyevent);//<----------------------------- 
      } 
     thread = null; 
    } 
} 


public void startAlarm() { 
    if(thread==null) { 
     thread = new AT(); 
     thread.start(); 
    } 
} 

я получаю исключение NullPointer как мой KeyEvent нулевой. Конечно, я мог бы определить его как конкретный ключ, но мне это действительно не помогает.

Что я пропустил?

+0

Какой _Component_ является PaintWindow? – Berger

+0

@Berger Что вы имеете в виду? PaintWindow - это просто класс, который создает фрейм и JPanel и рисует на нем с помощью объектов Graphics. – Baxtex

+0

Пользовательский объект не получает никаких ключевых событий, _java.awt.Component_ делает, или вы можете зарегистрировать глобальный слушатель, см .: http://stackoverflow.com/questions/5344823/how-can-i-listen-for- key-presses-in-java-swing-through-all-components – Berger

ответ

1

Забудьте о KeyListener, так как PaintWindow не получит событие нажатия клавиши, не будучи java.awt.Component.

Вместо этого добавьте этот код в методе run():

KeyboardFocusManager.getCurrentKeyboardFocusManager() 
       .addKeyEventDispatcher(new KeyEventDispatcher() { 
        @Override 
        public boolean dispatchKeyEvent(final KeyEvent e) { 

         // we only want PRESSED events 
         if(e.getID() == KeyEvent.KEY_PRESSED){ 


          int keyCode = e.getKeyCode(); 
          if(keyCode == 37){ 
           System.out.print("Left"); 
          } 
          else if (keyCode == 39){ 
           System.out.print("Right"); 
          } 
          else if (keyCode == 32){ 
           System.out.print("JUMP"); 
          } 
         } 
         return false; 
        } 
       }); 

Это будет прослушивать все ключевые события в вашем приложении.

Более подробная информация в этом разделе:

How can I listen for key presses (within Java Swing) across all components?

+0

Это сработало, спасибо. Это обычная практика, которую следует использовать? Я довольно часто использовал ActionListeners и недавно научился использовать обратный вызов и наблюдателей, но эти методы не могут использоваться, когда я хочу keyPressed, если сам компонент не является java.awt.Component. Я предполагаю, что JPanels - это такой компонент, поэтому почему он работал для меня раньше, когда у меня были классы, расширяющие JPanel? – Baxtex

+0

Да JPanel - это компонент, поэтому в этом случае проблем нет. Если ваш объект не может принимать события, вам необходимо прослушивать более высокий уровень с помощью KeyboardFocusManager, который отвечает за управление активной и сфокусированной Windows_, а также для диспетчеризации фокуса и событий для всех компонентов. Я, честно говоря, не мог сказать, есть ли более распространенная практика, чем эта, когда KeyListener нельзя использовать. – Berger

0

Я думаю, что ваша проблема в том, что вы не проходите ни одного слушателя. Попробуйте создать экземпляр KeyTimerListener и добавить его. public void addKeyListener(new KeyTimerListener()){ this.listener.add(listener);

 Смежные вопросы

  • Нет связанных вопросов^_^