的哈克解決方法是調用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
添加一個KeyBinding
即JButton
對於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
_...但我不喜歡KeyBindings_:使用它們有什麼問題? – Reimeus
他們有點混亂(我的品味)......而所有關於如何使用它們的教程都過於複雜。 – RookieCookie
-1瞭解推薦的方法並堅持不使用它 - 聳聳肩,這是你浪費時間... – kleopatra