为什么这个keyListener不起作用?
问题描述:
public class game extends Applet implements KeyListener {
int movex = 10;
int movey = 10;
int x = 50, y = 50;
JTextArea typingArea;
Random rand = new Random();
public void paint(Graphics page){
typingArea = new JTextArea();
typingArea.addKeyListener(this);
//Drawing borders w/ Random colors
page.setColor(new Color(rand.nextFloat(), rand.nextFloat(), rand.nextFloat()));
page.drawRect(0,0,200,200);
//delay
try {
Thread.sleep(1);
} catch (InterruptedException e) {
}
//Draws square
page.drawRect(x, y, 10, 10);
x+=movex;
y+=movey;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
Dimension d = getSize();
page.setColor(Color.WHITE);
page.fillRect(0, 0, d.width, d.height);
paint(page);
}
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
System.out.println("Key is pressed");
switch(keyCode) {
case KeyEvent.VK_UP:
movex = 0;
movey = 10;
break;
case KeyEvent.VK_DOWN:
movex = 0;
movey = -10;
break;
case KeyEvent.VK_LEFT:
movex = -10;
movey = 0;
break;
case KeyEvent.VK_RIGHT :
movex = 10;
movey = 0;
break;
}
}
@Override
public void keyReleased(KeyEvent arg0) {
}
@Override
public void keyTyped(KeyEvent e) {
}}
目前我正在做一个快速的贪吃蛇游戏,因为我对Java相对陌生,但对编程不熟悉。使用Applet我绘制了一个正方形,并通过递增x,y坐标来移动它,然后递归地调用paint方法。我使用了错误的对象(JTextArea)还是使用了我的方法?请快速回答,谢谢。为什么这个keyListener不起作用?
答
让我们看看我们是否能够打破这一点...
在你paint
方法,为您打造JTextArea
一个新的实例,并添加您自己作为KeyListener
。
public void paint(Graphics page) {
typingArea = new JTextArea();
typingArea.addKeyListener(this);
三个问题在这里...
- 你真的不应该被一个
paint
方法中创建新的组件。当组件需要重新绘制(并且可能经常快速连续调用)时,paint
方法将被调用,并且paint
应该只绘制组件的当前状态,从不改变它 - 您真的不应该使用
KeyListener
与文本组件 - 你从来没有真正加入
JTextArea
到显示的组件,这意味着它永远无法获得键盘焦点,因此从来没有触发KeyEvent
小号
然后调用...
//delay
try {
Thread.sleep(1);
} catch (InterruptedException e) {
}
//...
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
您的paint
方法。这是一个非常糟糕的主意,万一发生绘画尽可能快,因为直到paint
方法存在,Graphics
上下文的内容可能不会被画到屏幕
最后,你呼唤我
paint(page);
}
这是一个坏主意,因为一旦它被调用,您将永远不会真的退出paint
方法(请参阅上一条评论),最终将以*Exception
结尾。
AWT会在您要重新绘制组件时调用您的paint
方法。您可以通过调用repaint
来请求更新,但是您应该知道,绘画将在重绘管理器决定需要更新的内容时发生,因此可能不会立即发生。
- 我首先看看Painting in AWT and Swing和Performing Custom Painting以了解绘画是如何工作的。
- 然后我放下applet/AWT API并使用Swing或JavaFX,你会得到更好的一般支持。
- 如果你想使用Swing,我想看看How to use Swing Timers约如果你要使用Swing你怎么可能产生一个游戏循环
- 一些想法,我建议你在看看How to Use Key Bindings并忘记
KeyListener
- 你可以看看这example一些想法。
“KeyListener”不起作用的“主要”原因是它从未实际注册过屏幕上显示的任何内容,因此永远无法获得键盘焦点。你不应该使用带有文本组件的'KeyListener',它完全不合适。 – MadProgrammer
我首先看看[在AWT和Swing中绘画](http://www.oracle.com/technetwork/java/painting-140037.html)和[Performing Custom Painting](http:// docs .oracle.com/javase/tutorial/uiswing/painting /)了解绘画的工作原理。然后,我将删除applet/AWT API并使用[Swing](http://docs.oracle.com/javase/tutorial/uiswing/)或JavaFX,您将获得更好的一般支持。我还会看看[如何使用Swing Timers](http://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html)了解如何生成游戏循环的一些想法 – MadProgrammer
你可以看看这个[例子](http://*.com/questions/31508913/snakegame-how-to-make-the-tail-follow-the-head/31509204#31509204) 。如果你打算使用Swing,我建议看看[如何使用关键绑定](http://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html),并忘记'KeyListener' – MadProgrammer