2016-02-11 2 views
1

J'ai donc 2 classes appelées Viewer et PaintWindow. Dans mon cas, la classe Viewer agit comme un contrôleur alors que j'utilise ma classe PaintWindow pour peindre des choses sur un JPanel.Comment obtenir un Keyevent d'une autre classe?

Maintenant j'essaie de mettre en place un petit jeu mais je ne comprends pas comment implémenter le KeyListener pour pouvoir contrôler le jeu. Ce que je veux, c'est qu'un auditeur écoute un keyEvent pour que je puisse décider de ce qui va se passer. Voici comment mon code ressemble à:

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

}

Ceci est une partie de ma classe 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(); 
    } 
} 

je reçois une exception nullpointer comme mon KeyEvent est nul. Bien sûr, je pourrais le définir comme étant une clé spécifique, mais cela ne m'aide pas vraiment ici.

Qu'est-ce que j'ai manqué?

+0

Quel genre de _Component_ est PaintWindow? – Berger

+0

@Berger Que voulez-vous dire? PaintWindow est juste une classe qui crée un cadre et JPanel et peint à l'aide d'objets graphiques. – Baxtex

+0

Un objet personnalisé ne reçoit aucun événement clé, _java.awt.Component_ fait, ou vous pouvez enregistrer un écouteur global, voir: http://stackoverflow.com/questions/5344823/how-can-i-listen-for- key-presses-dans-java-swing-across-all-components – Berger

Répondre

1

Oubliez vos KeyListener, puisque PaintWindow ne recevront aucune événement clé, ne pas être un java.awt.Component.

Au lieu de cela, ajoutez ce code dans votre méthode 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; 
        } 
       }); 

Cela écoutera tous les événements clés de votre application.

Plus d'informations sur ce sujet:

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

+0

Cela a fonctionné, merci. Est-ce une pratique courante qui devrait être utilisée? J'ai beaucoup utilisé les ActionListeners avant et j'ai récemment appris comment utiliser le rappel et les observateurs, mais ces méthodes ne sont pas quelque chose qui peut être utilisé quand je veux keyPressed si le composant lui-même n'est pas un composant java.awt.Component. Je suppose que JPanels est un tel composant, alors pourquoi cela a-t-il fonctionné pour moi avant quand j'avais des cours prolongeant JPanel? – Baxtex

+0

Oui JPanel est un composant, donc pas de problème dans ce cas. Si votre objet n'est pas capable de recevoir des événements, vous devez écouter à un niveau supérieur avec KeyboardFocusManager, qui est responsable de la gestion de Windows_ active et ciblée, ainsi que de la répartition des événements et des focus pour tous les composants. Honnêtement, je ne pourrais pas dire s'il y a une pratique plus courante que celle-ci, quand KeyListener ne peut pas être utilisé. – Berger

0

Je pense que votre problème est que vous ne transmettez pas de clé d'écoute. Essayez d'instancier votre KeyTimerListener et ajoutez-le. public void addKeyListener(new KeyTimerListener()){ this.listener.add(listener);