我的 KeyListener 无法读取按键输入
Posted
技术标签:
【中文标题】我的 KeyListener 无法读取按键输入【英文标题】:My KeyListener can't read key inputs 【发布时间】:2018-12-29 20:41:29 【问题描述】:现在,我有一个扩展 JPanel
并实现 KeyListener
的类。我已经将这个类实例化为另一个在我的循环中运行它的类。 KeyListener 类看起来像
public class Keyboard extends JPanel implements KeyListener
public Keyboard()
this.addKeyListener(this);
public void update()
@Override
public void keyPressed(KeyEvent e)
if(keyCode == KeyEvent.VK_S)
System.out.println("Made it");
@Override
public void keyReleased(KeyEvent e)
@Override
public void keyTyped(KeyEvent e)
我在另一个使用MouseListener
的类中实现了这一点,在Game
类中就可以了。但由于某种原因,它不会听键盘。
public class Main
public static final int WIDTH = 640;
public static final int HEIGHT = 640;
public static final String NAME = "Game";
private static BufferedImage image;
private static Graphics2D g;
private static boolean forceQuit;
private static Game game;
private static Keyboard keyboard;
public Main()
private static void init()
image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
g = (Graphics2D) image.getGraphics();
g.setBackground(Color.BLACK);
game = new Game();
keyboard = new Keyboard();
private static void start()
run();
public static void stop()
forceQuit = true;
public static void run()
@SuppressWarnings("unused")
int frames = 0;
double unprocessedSeconds = 0;
long lastTime = System.nanoTime();
double secondsPerTick = 1.0 / 60.0;
int tickCount = 0;
while (!forceQuit)
if(keyboard.isSwampland())
game.setSwampland(true);
long now = System.nanoTime();
long passedTime = now - lastTime;
lastTime = now;
if (passedTime < 0)
passedTime = 0;
if (passedTime > 100000000)
passedTime = 100000000;
unprocessedSeconds += passedTime / 1000000000.0;
boolean ticked = false;
while (unprocessedSeconds > secondsPerTick)
game.update();
keyboard.update();
unprocessedSeconds -= secondsPerTick;
ticked = true;
tickCount++;
if (tickCount % 60 == 0)
// System.out.println("FPS:" + frames);
lastTime += 1000;
frames = 0;
if (ticked)
game.render(g);
Graphics gg = game.getGraphics();
gg.drawImage(image, 0, 0, null);
gg.dispose();
frames++;
else
try
Thread.sleep(1);
catch (InterruptedException e)
e.printStackTrace();
public static void main(String[] args)
Main.init();
JFrame frame = new JFrame(NAME);
frame.setDefaultCloseOperation(3);
frame.setContentPane(game);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
Main.start();
【问题讨论】:
【参考方案1】:好的,有很多问题...
简短的回答...
使用Key Bindings API,它克服了KeyListener
API 的缺点
长答案...
KeyListener
只会在它注册到的组件是可聚焦的并且具有键盘焦点时生成 KeyEvent
s。
我在您的代码中看到的问题是......
Keyboard
实际上并没有添加到任何东西上,因此它不会显示在屏幕上,因此它永远无法获得焦点。
KeyListener
确实应该直接注册到Game
,只是需要管理的组件少了
不推荐使用Component
中的getGraphics
,这不是绘画的方式。 Swing 组件默认情况下是双缓冲的,所以通常最好利用它的内置绘画过程,如果你真的想控制绘画过程,你应该使用Canvas
和BufferStrategy
,否则运行在您的绘制代码和现有绘制过程的 API 之间产生竞争条件的风险
【讨论】:
【参考方案2】:我这样做
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class DrawPoints
Frame f;
KeyBoard key;
Mouse mouse;
Paint c;
public void GUI()
f = new Frame("DrawPoints");
f.setSize(300, 300);
mouse = new Mouse();
c = new Paint(mouse);
c.setSize(300, 300);
c.setBackground(Color.WHITE);
c.addMouseListener(mouse);
c.addMouseMotionListener(mouse);
key = new KeyBoard();
c.addKeyListener(key);
f.add(c);
f.pack();
f.setVisible(true);
f.addWindowListener(new WindowAdapter()
@Override
public void windowClosing(WindowEvent e)
System.exit(0);
);
class KeyBoard implements KeyListener
@Override
public void keyPressed(KeyEvent e)
int key = e.getKeyCode();
if(key == KeyEvent.VK_SPACE)
System.out.println("SPACE");
@Override
public void keyTyped(KeyEvent e)
System.out.println("Typed");
@Override
public void keyReleased(KeyEvent e)
System.out.println("Released");
class Main
public static void main(String[] args)
DrawPoints app = new DrawPoints();
app.GUI();
class Paint extends Canvas
Mouse mouse;
public Paint(Mouse mouse)
this.mouse = mouse;
@Override
public void paint(Graphics g)
g.drawRect(mouse.getX(), mouse.getY(), 30, 30);
repaint();
class Mouse implements MouseListener, MouseMotionListener
private int x;
private int y;
public int getX()
return this.x;
public int getY()
return this.y;
// MouseMotionListener
@Override
public void mouseMoved(MouseEvent e)
x = e.getX();
y = e.getY();
//System.out.println(e.getX() + " " + e.getY());
@Override
public void mouseDragged(MouseEvent e)
System.out.println("mouseDragged");
// MouseListener
@Override
public void mouseEntered(MouseEvent e)
System.out.println("MOUSE Entered");
@Override
public void mousePressed(MouseEvent e)
System.out.println("MOUSE Pressed");
@Override
public void mouseReleased(MouseEvent e)
System.out.println("MOUSE Released");
@Override
public void mouseClicked(MouseEvent e)
System.out.println("MOUSE Clicked");
@Override
public void mouseExited(MouseEvent e)
System.out.println("MOUSE Exited");
【讨论】:
以上是关于我的 KeyListener 无法读取按键输入的主要内容,如果未能解决你的问题,请参考以下文章
Java KeyListener:KeyTyped Backspace,Esc 作为输入