2017-12-07 6 views
0

Ich versuche, meine keyPressed-Methode aufzurufen, die ich in meinem Konstruktor für ein Spiel, das ich mache, um ein Objekt verschieben zu lassen, erstellt habe. Ich habe ActionListener und KeyListener in der Hauptklasse implementiert.Java Implementieren von ActionListener-Methoden in Constructor

Ist das überhaupt möglich? Ich habe versucht, die Methode von this.keyPressed(KeyEvent e) aufrufen, aber ich weiß nicht, wie Sie e initialisieren.

Was wäre der beste Weg, um so etwas zu tun?

Timer timer = new Timer(DELAY, this); 
public Game(Main game) { 

    this.game = game; 
    gamePanel = new GamePanel(); 
    buttonPanel = new JPanel(); 
    buttonPanel.add(startButton); 

    this.addKeyListener(this); 
    this.setFocusable(true); 
    this.setFocusTraversalKeysEnabled(false); 
    this.getContentPane().add(gamePanel, BorderLayout.CENTER); 
    this.getContentPane().add(buttonPanel, BorderLayout.PAGE_END); 
    this.setSize(1000, 1000); 
    this.setVisible(true); 





    } 

} 

@Override 
public void keyTyped(KeyEvent e) { 
    // TODO Auto-generated method stub 

} 

@Override 
public void keyPressed(KeyEvent e) { 

    switch (e.getKeyCode()) { 
    case KeyEvent.VK_UP: 
     game.move("u"); 
     break; 

    case KeyEvent.VK_DOWN: 
     game.move("d"); 
     break; 

    case KeyEvent.VK_RIGHT: 
     game.move("r"); 
     break; 

    case KeyEvent.VK_LEFT: 
     game.move("l"); 
     break; 
    } 
} 
@Override 
public void actionPerformed(ActionEvent e) { 

    Object src = e.getSource(); 

    if (src == timer) { 
     game.updateBoard(); 
     if (game.gameEnded()) { 
      timer.stop(); 
      } 
     repaint(); 

    } else if (src == startButton) { 

     if (timer.isRunning()) { 
      timer.stop(); 
     } else { 
      timer.stop(); 
     } 
    } 
} 

Antwort

1

Das Problem ist hier:

while(!game.gameEnded()) { 
    game.updateBoard(); 
    KeyEvent e = null; 
    this.keyPressed(e); 
} 

Wenn Ihr Konstruktor mit dem Swing-Ereignis-Dispatching-Thread, blockiert sie es, und kein Ereignis daher versendet werden können genannt wird.

Der korrekte Weg sollte eine javax.swing.Timer verwenden, die eine ActionEvent periodisch zündet.

int period = 1000;//fire ActionEvent every second 
Timer timer = new Timer(period,new ActionListener(){ 
    public void actionPerformed(ActionEvent e){ 
     //do your stuff, for example 
     game.updateBoard(); 
    } 
}); 
timer.start(); 

Sie sollten nicht die Methoden in Eventlistener selbst aufrufen, da sie alle durch die Event-Dispatching-Thread behandelt werden sollte.

+0

Dank @Judger, das war hilfreich. Soll ich den Timer nach dem Erstellen automatisch starten? Ich überschreibe 'actionPerformed (ActionEvent e) .' Zu Beginn der Klasse' Timer timer = new Timer (DELAY, this) 'habe ich einen Timer global erstellt. 'Ich rufe dies auch in der ersten Zeile meiner' actionPerformed (ActionEvent e) 'Methode' Objekt src = e.getSource(); ' – user5402

+0

Ich habe gerade die Frage mit den Änderungen bearbeitet. Würde so etwas funktionieren? – user5402

+0

Ich glaube nicht, dass Sie Ihr 'Timer'-Objekt so instanziieren können, indem Sie' this' als ein Argument verwenden. Sie sollten es im Konstruktor initialisieren. – Judger