2012-12-22 30 views
1

當我在JPanel之間切換時,KeyListener沒有響應(由於未獲得焦點),所以出現問題。Java KeyListener在切換後沒有響應JPanels

我有Google'd這個,知道要解決這個問題我需要使用KeyBindings,但我不喜歡KeyBindings。所以我想知道,有沒有其他方法?

這裏是JPanel的初始化代碼有一個反應遲鈍的KeyListener:

public void init() 
{ 
    setFocusable(true); 
    requestFocusInWindow(); 
    requestFocus(); 
    addMouseListener(new MouseInput()); 
    addMouseMotionListener(new MouseInput()); 
    addMouseWheelListener(new MouseInput()); 
    addKeyListener(new KeyInput(p)); 

    t = new Timer(10, this); 
    t.start(); 
} 

隨意問更多的代碼樣本,如果你需要!

+3

_...但我不喜歡KeyBindings_:使用它們有什麼問題? – Reimeus

+0

他們有點混亂(我的品味)......而所有關於如何使用它們的教程都過於複雜。 – RookieCookie

+0

-1瞭解推薦的方法並堅持不使用它 - 聳聳肩,這是你浪費時間... – kleopatra

回答

6

的哈克解決方法是調用requestFocusInWindow()JPanel,以確保它具有焦點爲KeyListener/KeyAdapter被加上了Componnet後,這應該只能被稱爲(但可以肯定我的組件具有焦點我把它稱爲JFrame後通過revalidate()repaint())刷新例如:

public class MyUI { 

    //will switch to the gamepanel by removing all components from the frame and adding GamePanel 
    public void switchToGamePanel() { 
     frame.getContentPane().removeAll(); 

     GamePanel gp = new GamePanel();//keylistener/keyadapter was added to Jpanel here 

     frame.add(gp);//add component. we could call requestFocusInWindow() after this but to be 98% sure it works lets call after refreshing JFrame 

     //refresh JFrame 
     frame.pack(); 
     frame.revalidate(); 
     frame.repaint(); 

     gp.requestFocusInWindow(); 
    } 

} 
class GamePanel extends JPanel { 

     public GamePanel() { 
      //initiate Jpanel and Keylistener/adapter 
     } 

} 

但是你應該使用Swing KeyBinding S(+1至@Reimeus評論)。

有一個在這裏閱讀,以熟悉他們:

現在,您已經閱讀,讓顯示的另一個例子,以幫助澄清(儘管甲骨文的工作做得很好)

如果我們想爲某個JComponent添加一個KeyBindingJButton對於Esc您應該這樣做:

void addKeyBinding(JComponent jc) { 
     jc.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, false), "esc pressed"); 
     jc.getActionMap().put("esc pressed", new AbstractAction() { 
      @Override 
      public void actionPerformed(ActionEvent ae) { 
       System.out.println("Esc pressed"); 
      } 
     }); 

     jc.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, true), "esc released"); 
     jc.getActionMap().put("esc released", new AbstractAction() { 
      @Override 
      public void actionPerformed(ActionEvent ae) { 
       System.out.println("Esc released"); 
      } 
     }); 
} 

上面的方法將被稱爲像:

JButton b=..;//create an instance of component which is swing 

addKeyBinding(b);//add keybinding to the component 

請注意:

1)您將不需要同時KeyBindings,我只是展示瞭如何讓不同的國家重點和採取適當的行動使用Keybindings

2)該方法將增加一個Keybinding將被只要Esc鍵被按壓和部件是在具有焦點的窗口被激活,則可以通過指定另一InputMap即改變該:

jc.getInputMap(JComponent.WHEN_FOCUSED).put(..);//will only activated when component has focus