如下面例子講解java
下面代碼,沒有添加按鈕的時候,綁定keyListener事件的myframe能夠正常得到鍵盤事件,代碼以下:ide
import java.awt.*; import java.awt.event.*; import javax.swing.*; @SuppressWarnings("serial") public class Test extends JFrame implements KeyListener { public Test() { setLayout(new FlowLayout()); addKeyListener(this); } public static void main(String[] args) { Test myframe = new Test(); myframe.setSize(400, 300); myframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); myframe.setVisible(true); } @Override public void keyPressed(KeyEvent event) { // TODO 自動生成的方法存根 switch (event.getKeyCode()) { case KeyEvent.VK_UP: System.out.println("up"); break; case KeyEvent.VK_DOWN: System.out.println("down"); break; case KeyEvent.VK_LEFT: System.out.println("left"); break; case KeyEvent.VK_RIGHT: System.out.println("right"); break; } } @Override public void keyReleased(KeyEvent e) { // TODO 自動生成的方法存根 } @Override public void keyTyped(KeyEvent e) { // TODO 自動生成的方法存根 } }
可是當添加按鈕btn以後, 綁定keyListener事件的myframe沒法得到鍵盤事件,代碼以下:this
import java.awt.*; import java.awt.event.*; import javax.swing.*; @SuppressWarnings("serial") public class Test extends JFrame implements KeyListener { JButton btn=new JButton("button"); public Test() { setLayout(new FlowLayout()); getContentPane().add(btn); addKeyListener(this); } public static void main(String[] args) { Test myframe = new Test(); myframe.setSize(400, 300); myframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); myframe.setVisible(true); } @Override public void keyPressed(KeyEvent event) { // TODO 自動生成的方法存根 switch (event.getKeyCode()) { case KeyEvent.VK_UP: System.out.println("up"); break; case KeyEvent.VK_DOWN: System.out.println("down"); break; case KeyEvent.VK_LEFT: System.out.println("left"); break; case KeyEvent.VK_RIGHT: System.out.println("right"); break; } } @Override public void keyReleased(KeyEvent e) { // TODO 自動生成的方法存根 } @Override public void keyTyped(KeyEvent e) { // TODO 自動生成的方法存根 } }
經過谷歌查找後才知道spa
添加button後,焦點在button上了,而不是在myframe上code
綁定keyListener事件的myframe要能正常得到鍵盤事件,myframe必需要獲到焦點事件
查詢API知在frame顯示後調用requestFocus()便可獲得焦點開發
public void requestFocus()請求此 Component 獲取輸入焦點,而且此 Component 的頂層祖先成爲得到焦點的 Window。此 Component 對於所要許可的請求而言必須是不可顯示的、可聚焦的和可見的而且其全部祖先(除了頂層 Window 之外)必須是可見的。此方法會盡力完成該請求;可是在某些狀況下可能沒法完成。在此 Component 接收 FOCUS_GAINED 事件前,開發人員永遠不能假定此 Component 是焦點全部者。若是因爲此 Component 的頂層 Window 沒有成爲得到焦點的窗口而拒絕了此請求,則記住此請求,並在後來用戶使窗口成爲得到焦點的窗口時許可此請求。 get
此方法不能用於爲根本不是 Component 的內容設置焦點全部者,應該使用 KeyboardFocusManager.clearGlobalFocusOwner()。 it
由於此方法的焦點行爲與平臺有關,因此強烈建議開發人員在可能時使用 requestFocusInWindow。 io
注:並非全部的焦點傳輸都將致使防止調用此方法。一樣地,組件能夠在沒有調用此方法或 Component 的其餘任何方法的狀況下接收焦點。
附參考代碼
import java.awt.*; import java.awt.event.*; import javax.swing.*; @SuppressWarnings("serial") public class Test extends JFrame implements KeyListener { JButton btn=new JButton("button"); public Test() { setLayout(new FlowLayout()); getContentPane().add(btn); addKeyListener(this); } public static void main(String[] args) { Test myframe = new Test(); myframe.setSize(400, 300); myframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); myframe.setVisible(true); myframe.requestFocus(); } @Override public void keyPressed(KeyEvent event) { // TODO 自動生成的方法存根 switch (event.getKeyCode()) { case KeyEvent.VK_UP: System.out.println("up"); break; case KeyEvent.VK_DOWN: System.out.println("down"); break; case KeyEvent.VK_LEFT: System.out.println("left"); break; case KeyEvent.VK_RIGHT: System.out.println("right"); break; } } @Override public void keyReleased(KeyEvent e) { // TODO 自動生成的方法存根 } @Override public void keyTyped(KeyEvent e) { // TODO 自動生成的方法存根 } }