如下面例子讲解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 自动生成的方法存根 } }