没有调用java keylistener

我已经使用Java中的KeyListener编写了示例代码,我创build了一个JPanel ,然后将其焦点设置为true,我创build了一个KeyListener,请求一个焦点,然后将KeyListener添加到我的面板。 但是keyListener的方法永远不会被调用。 看来,虽然我已经要求重点,但并不重点。

谁能帮忙?

 listener = new KeyLis(); this.setFocusable(true); this.requestFocus(); this.addKeyListener(listener); class KeyLis implements KeyListener{ @Override public void keyPressed(KeyEvent e) { currentver += 5; switch (e.getKeyCode()) { case KeyEvent.VK_LEFT : if(horizontalyInBounds()) currentPos-= 5; break; case KeyEvent.VK_RIGHT: if(horizontalyInBounds()) currentPos+= 5; break; } repaint(); } @Override public void keyReleased(KeyEvent e) { // TODO Auto-generated method stub } @Override public void keyTyped(KeyEvent e) { } } 

如果需要任何可运行的代码:

  import java.awt.Color; import java.awt.Graphics; import java.util.Random; import javax.swing.JFrame; import javax.swing.JLabel; public class test extends JFrame { private AreaOfGame areaOfGame; public test() { super(""); setVisible(true); this.setBackground(Color.darkGray); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.pack(); setLayout(null); setBounds(200, 10, 400, 700); areaOfGame = new AreaOfGame(); this.add(areaOfGame); startGame(); } public int generateNext() { Random r = new Random(); int n = r.nextInt(7); return n; } public void startGame() { while(!areaOfGame.GameOver()) { areaOfGame.startGame(generateNext()); } } public static void main(String[] args) { new MainFrame(); } import java.awt.Color; import java.awt.Graphics; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.util.ArrayList; import java.util.List; import java.util.Random; import javax.swing.JPanel; public class AreaOfGame extends JPanel { private static final int rightside = 370; private int bottom; private int top; private int currentPos; private int currentver; private KeyLis listener; public AreaOfGame() { super(); bottom = 650; top = 50; setLayout(null); setBounds(20, 50, 350, 600); setVisible(true); this.setBackground(Color.lightGray); listener = new KeyLis(); this.setFocusable(true); if(this.requestFocus(true)) System.out.println("true");; this.addKeyListener(listener); currentPos = 150; currentver=0; } public void startGame(int n) { while(verticallyInBound()){ System.out.println("anything"); } } public boolean verticallyInBound() { if(currentPos<= bottom -50) return true; return false; } public boolean GameOver() { if(top>= bottom){ System.out.println("game over"); return true; } else return false; } public boolean horizontalyInBounds() { if(currentPos<=rightside && currentPos>= 20) return true; else return false; } class KeyLis implements KeyListener{ @Override public void keyPressed(KeyEvent e) { System.out.println("called"); currentver += 5; switch (e.getKeyCode()) { case KeyEvent.VK_LEFT : if(horizontalyInBounds()) currentPos-= 5; break; case KeyEvent.VK_RIGHT: if(horizontalyInBounds()) currentPos+= 5; break; } repaint(); } @Override public void keyReleased(KeyEvent e) { // TODO Auto-generated method stub } @Override public void keyTyped(KeyEvent e) { System.out.println("called 3"); } } } 

我敢打赌,在JPanel被渲染之前(在顶层窗口已经调用了pack()setVisible(true)之前)你要求焦点,如果是的话,这将不起作用。 焦点请求只有组件被渲染后才可能被授予。 你有没有检查你的调用requestFocus()已经返回? 它必须为你的来电返回真正有成功的机会。 另外最好使用requestFocusInWindow()而不是requestFocus()

但更重要的是,您不应该使用KeyListeners来实现这个function,而应该使用键绑定,这是Swing本身用于响应按键的更高层次的概念。

编辑
一个SSCCE的例子:

 import java.awt.Dimension; import java.awt.event.*; import javax.swing.*; public class TestKeyListener extends JPanel { private KeyLis listener; public TestKeyListener() { add(new JButton("Foo")); // something to draw off focus listener = new KeyLis(); this.setFocusable(true); this.requestFocus(); this.addKeyListener(listener); } @Override public Dimension getPreferredSize() { return new Dimension(300, 200); } private class KeyLis extends KeyAdapter { @Override public void keyPressed(KeyEvent e) { switch (e.getKeyCode()) { case KeyEvent.VK_LEFT: System.out.println("VK_LEFT pressed"); break; case KeyEvent.VK_RIGHT: System.out.println("VK_RIGHT pressed"); break; } } } private static void createAndShowGui() { TestKeyListener mainPanel = new TestKeyListener(); JFrame frame = new JFrame("TestKeyListener"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(mainPanel); frame.pack(); frame.setLocationByPlatform(true); frame.setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGui(); } }); } } 

编辑2
和使用密钥绑定的等效SSCCE :

 import java.awt.*; import java.awt.event.*; import javax.swing.*; @SuppressWarnings("serial") public class TestKeyBindings extends JPanel { public TestKeyBindings() { add(new JButton("Foo")); // something to draw off focus setKeyBindings(); } private void setKeyBindings() { ActionMap actionMap = getActionMap(); int condition = JComponent.WHEN_IN_FOCUSED_WINDOW; InputMap inputMap = getInputMap(condition ); String vkLeft = "VK_LEFT"; String vkRight = "VK_RIGHT"; inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), vkLeft); inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), vkRight); actionMap.put(vkLeft, new KeyAction(vkLeft)); actionMap.put(vkRight, new KeyAction(vkRight)); } @Override public Dimension getPreferredSize() { return new Dimension(300, 200); } private class KeyAction extends AbstractAction { public KeyAction(String actionCommand) { putValue(ACTION_COMMAND_KEY, actionCommand); } @Override public void actionPerformed(ActionEvent actionEvt) { System.out.println(actionEvt.getActionCommand() + " pressed"); } } private static void createAndShowGui() { TestKeyBindings mainPanel = new TestKeyBindings(); JFrame frame = new JFrame("TestKeyListener"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(mainPanel); frame.pack(); frame.setLocationByPlatform(true); frame.setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGui(); } }); } } 

编辑3
关于您最近的SSCCE,您的while (true)循环阻塞了您的Swing事件线程,并可能阻止用户交互或绘画发生。 更好地使用Swing Timer而不是while (true) 。 例如:

 import java.awt.*; import java.awt.event.*; import java.util.Random; import javax.swing.*; public class BbbTest extends JFrame { private AreaOfGame areaOfGame; public BbbTest() { super(""); // setVisible(true); this.setBackground(Color.darkGray); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.pack(); setLayout(null); setBounds(200, 10, 400, 700); areaOfGame = new AreaOfGame(); this.add(areaOfGame); setVisible(true); startGame(); } public int generateNext() { Random r = new Random(); int n = r.nextInt(7); return n; } public void startGame() { // while (!areaOfGame.GameOver()) { // areaOfGame.startGame(generateNext()); // } areaOfGame.startGame(generateNext()); } public static void main(String[] args) { new BbbTest(); } class AreaOfGame extends JPanel { private static final int rightside = 370; private int bottom; private int top; private int currentPos; private int currentver; private KeyLis listener; public AreaOfGame() { super(); bottom = 650; top = 50; setLayout(null); setBounds(20, 50, 350, 600); setVisible(true); this.setBackground(Color.lightGray); listener = new KeyLis(); this.setFocusable(true); if (this.requestFocus(true)) System.out.println("true"); ; this.addKeyListener(listener); currentPos = 150; currentver = 0; } public void startGame(int n) { // while (verticallyInBound()) { // System.out.println("anything"); // } int timeDelay = 50; // msecs delay new Timer(timeDelay , new ActionListener() { public void actionPerformed(ActionEvent arg0) { System.out.println("anything"); } }).start(); } public boolean verticallyInBound() { if (currentPos <= bottom - 50) return true; return false; } public boolean GameOver() { if (top >= bottom) { System.out.println("game over"); return true; } else return false; } public boolean horizontalyInBounds() { if (currentPos <= rightside && currentPos >= 20) return true; else return false; } class KeyLis implements KeyListener { @Override public void keyPressed(KeyEvent e) { System.out.println("called"); currentver += 5; switch (e.getKeyCode()) { case KeyEvent.VK_LEFT: if (horizontalyInBounds()) currentPos -= 5; break; case KeyEvent.VK_RIGHT: if (horizontalyInBounds()) currentPos += 5; break; } repaint(); } @Override public void keyReleased(KeyEvent e) { // TODO Auto-generated method stub } @Override public void keyTyped(KeyEvent e) { System.out.println("called 3"); } } } } 

可以使用“TAB”button在button和按键监听器之间切换。 我有一个button的程序,按下后,关键听众不起作用。 我意识到,如果按下“TAB”button,程序的“注意”或“焦点”将返回到按键监听器。

也许这将有助于: http : //docstore.mik.ua/orelly/java-ent/jfc/ch03_08.htm