2013-05-13 45 views
6

我想在JPanel類中使用KeyListener按下其中一個箭頭鍵時執行某些操作。這裏是我的代碼:Keylistener不適用於JPanel

public class TestPanel extends JPanel implements KeyListener{ 

    public TestPanel(){ 
     this.addKeyListener(this); 
     this.setFocusable(true); 
     this.requestFocusInWindow(); 
    } 

    public void keyPressed(KeyEvent e) { 
     if (e.getKeyCode() == KeyEvent.VK_RIGHT) { 
      System.out.println("Right"); 

     } 

     if (e.getKeyCode() == KeyEvent.VK_LEFT) { 
      System.out.println("Left"); 
     } 

    } 

    public void keyTyped(KeyEvent e) {} 
    public void keyReleased(KeyEvent e) {} 
} 

我的主要方法,這增加了面板的新實例框架和顯示。我是否需要將Keylistener添加到JFrame?在我的情況下,這將是困難和低效的,所以我想盡可能使它與這個JPanel一起工作。任何人都知道我在做什麼錯了?

編輯:鍵綁定的代碼無法正常工作或:

public class GamePanel extends JPanel implements ActionListener{ 

//Constructor 
public GamePanel(){ 

    setupKeyBinding(); 
    this.setFocusable(true); 
    this.requestFocusInWindow(); 


} 

private void setupKeyBinding() { 
    int condition = JComponent.WHEN_IN_FOCUSED_WINDOW; 
    InputMap inMap = getInputMap(condition); 
    ActionMap actMap = getActionMap(); 

    inMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), "Left"); 
    actMap.put("Left", new leftAction()); 
} 

private class leftAction extends AbstractAction { 

     public void actionPerformed(ActionEvent e) { 
      System.out.println("test"); 
     } 
} 

public void actionPerformed(ActionEvent e) { 
    //some other game info 
} 
} 

誰能告訴我,爲什麼這不工作要麼? (我的第二個動作偵聽器是爲我的遊戲需要的其他東西)

+0

另一個想法可能是製作一個內部類,並使用類似於:「this.addKeyListener(內部類/匿名內部類);」 – ObedMarsh 2013-05-13 21:00:10

+0

可能重複的[java keylistener not called](http://stackoverflow.com/questions/8482268/java-keylistener-not-called) – 2013-05-13 21:17:45

回答

9

如果您搜索此問題,您會看到它已被詢問並已被多次解決。

  • KeyListeners需要在關注的組件上工作。一種解決方案是先讓組件成爲焦點後的焦點。
  • 然而,長時間拍攝更好的是使用鍵綁定。谷歌教程就此。

請查看我對this question的回答,瞭解更多信息,包括許多血淋淋的細節。

+0

謝謝,我會研究關鍵綁定,但對於這個問題,我已經看過各種解決方案,不能看到我在做什麼不同。我認爲我是通過使用requestFocusInWindow() – user2373733 2013-05-13 21:19:00

+3

來實現的,焦點行爲因平臺而異;此外,如果有其他_any_其他可聚焦組件,那麼'KeyListener'在這方面將會很脆弱。 – trashgod 2013-05-13 21:26:09

+0

@ user2373733密鑰綁定是要走的路。只需放下你的KeyListener:它會爲你節省一些時間並避免將來的錯誤。 – 2013-05-13 21:30:10

4

僅供參考,我已經使用您的方法創建了一個示例;雖然它起作用,但它也暗示了代碼中其他地方的焦點問題。 Key Bindings避免這種情況,如here所示。

附錄:這是我的工作密鑰綁定。

private static class TestPanel extends JPanel { 

    private static final String LEFT = "Left"; 
    private Action left = new AbstractAction(LEFT) { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      System.out.println(LEFT); 
     } 
    }; 
    private static final String RIGHT = "Right"; 
    private Action right = new AbstractAction(RIGHT) { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      System.out.println(RIGHT); 
     } 
    }; 

    public TestPanel() { 
     this.getInputMap().put(
      KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), LEFT); 
     this.getActionMap().put(LEFT, left); 
     this.getInputMap().put(
      KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), RIGHT); 
     this.getActionMap().put(RIGHT, right); 
    } 
} 

原始SSCCE:

import java.awt.EventQueue; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

/** 
* @see https://stackoverflow.com/a/16531380/230513 
*/ 
public class Test { 

    private void display() { 
     JFrame f = new JFrame("Test"); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.add(new TestPanel()); 
     f.pack(); 
     f.setLocationRelativeTo(null); 
     f.setVisible(true); 
    } 

    private static class TestPanel extends JPanel implements KeyListener { 

     public TestPanel() { 

      this.addKeyListener(this); 
      this.setFocusable(true); 
      this.requestFocusInWindow(); 
     } 

     @Override 
     public void keyPressed(KeyEvent e) { 
      if (e.getKeyCode() == KeyEvent.VK_RIGHT) { 
       System.out.println("Right"); 
      } 

      if (e.getKeyCode() == KeyEvent.VK_LEFT) { 
       System.out.println("Left"); 
      } 
     } 

     @Override 
     public void keyTyped(KeyEvent e) { 
     } 

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

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       new Test().display(); 
      } 
     }); 
    } 
} 
+1

啊謝謝,我不知道什麼可能是重點。我在測試時將所有其他面板都添加到了我的框架中,以確保沒有任何干擾。我現在正嘗試使用鍵綁定,儘管我在新東西中遇到了一些麻煩 – user2373733 2013-05-13 21:27:41

+0

您可以試試這個最簡單的[示例](http://stackoverflow.com/a/7457102/230513)。 – trashgod 2013-05-13 21:34:28

+0

是的,這是我試過的例子:( – user2373733 2013-05-13 22:02:11

1

我必須做兩件事情:我添加comp.setFocusable(真);到監聽關鍵事件的組件comp,並且我添加了comp.requestFocus();對每個導致comp失去焦點的行動。

相關問題