KeyListener在Java swing中没有响应

我正在制作游戏,我有一个完美的主菜单。 当我选择其中一个选项时,它会在新窗口中显示另一个菜单。 但是在这个新窗口中,KeyListener没有响应。 如果我单击返回主菜单窗口,KeyListener仍然在那里工作。 这是代码:

主菜单:

import java.awt.*; import java.awt.event.*; import java.awt.image.*; import javax.swing.*; import java.io.*; import javax.imageio.*; public class DisplayMainMenu extends JFrame implements KeyListener{ static int width = 799, height = 463; int arrowPos = 310; boolean clear = true; BufferedImage menu = null; BufferedImage arrow = null; LevelSkip test = new LevelSkip(); boolean done = false; static DisplayMainMenu main; public static void main(String[] args){ main = new DisplayMainMenu(); main.setResizable(false); main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); main.setVisible(true); main.init(); } public void init() { try{ menu = ImageIO.read(new File("Main Menu.png")); arrow = ImageIO.read(new File("arrow.png")); }catch(IOException ie) { System.out.println(ie.getMessage()); } this.setSize(width, height); this.addKeyListener(this); clear = true; paint(getGraphics()); } public void paint (Graphics g){ if(clear==true){ g.drawImage(menu,0,0,null); clear = false; } g.drawImage(arrow,275,arrowPos,null); } public void keyPressed(KeyEvent e){ String key = e.getKeyText(e.getKeyCode()); if(key == "Up"){ clear = true; if (arrowPos > 310) arrowPos -= 30; else arrowPos = 370; paint(getGraphics()); } if(key == "Down"){ clear = true; if (arrowPos < 370) arrowPos += 30; else arrowPos = 310; paint(getGraphics()); } if(key == "Space"){ done = true; switch(arrowPos){ case 310: System.out.println("RUN NEW GAME"); test.init(); break; case 340: System.out.println("RUN HIGH SCORES"); break; case 370: System.exit(0); } } } public void keyReleased(KeyEvent e) {} public void keyTyped(KeyEvent e) {} } 

LevelSkip:

 import java.awt.*; import java.awt.*; import java.awt.event.*; import java.awt.image.*; import javax.swing.*; import java.io.*; import javax.imageio.*; public class LevelSkip extends JFrame implements KeyListener { static int width = 799, height = 463; int arrowPos = 109; boolean clear = true; BufferedImage menu = null; BufferedImage arrow = null; public void init() { LevelSkip main = new LevelSkip(); main.setSize(width, height); main.requestFocusInWindow(); main.addKeyListener(main); main.setResizable(false); main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); main.setVisible(true); try{ menu = ImageIO.read(new File("level skip.png")); arrow = ImageIO.read(new File("arrow2.png")); }catch(IOException ie) { System.out.println(ie.getMessage()); } clear = true; paint(main.getGraphics()); } public void paint (Graphics g){ if(clear==true){ g.drawImage(menu,0,0,null); clear = false; } g.drawImage(arrow,arrowPos,355,null); } public void keyPressed(KeyEvent e){ String key = e.getKeyText(e.getKeyCode()); if(key == "Left"){ clear = true; if (arrowPos > 109) arrowPos -= 260; else arrowPos = 629; paint(getGraphics()); } if(key == "Right"){ clear = true; if (arrowPos < 629) arrowPos += 260; else arrowPos = 109; paint(getGraphics()); } if(key == "Space"){ switch(arrowPos){ case 109: System.out.println("ADD 1 TO LEVEL AND RUN BATTLE"); break; case 369: System.out.println("ADD 5 TO LEVEL AND RUN BATTLE"); break; case 629: System.out.println("ADD 10 TO LEVEL AND RUN BATTLE"); } } } public void keyReleased(KeyEvent e) {} public void keyTyped(KeyEvent e) {} } 

我不确定问题是什么,Level Skip窗口显示正常,它只是没有注册任何按键。

如果你完全搜索过这个问题,你会发现它几乎总是意味着被收听的组件没有焦点。 90%的解决方案是使用密钥绑定 。

你的另一个问题是你在比较Strings == 。 你不想这样做。 请改用equals或equalsIgnoreCase(…)方法。 理解==检查两个对象是否相同而不是你感兴趣的。另一方面,这些方法检查两个字符串是否具有相同顺序的相同字符,这就是重要的。 而不是

 if (fu == "bar") { // do something } 

做,

 if (fu.equals("bar")) { // do something } 

要么,

 if (fu.equalsIgnoreCase("bar")) { // do something } 

你也是

  • 直接调用paint(...) ,你几乎不应该做的事情。
  • 绘制顶层窗口的paint(...)方法,您也应该避免使用JPAnel(或其他JComponent) paintComponent(...)方法绘制。
  • 不在方法开头调用paint或paintComponent的super方法
  • 将程序逻辑放在paint或paintComponent方法中。
  • 等等…

在进一步向专业人士学习之前,您将需要阅读Swing教程。