java的jpanel一闪一闪的_关于JPanel上的java:KeyListener随机无响应

我在项目中使用默认的Java KeyListener遇到麻烦。

我注意到有时启动时,KeyListener似乎并没有转发KeyEvent。

问题症状:

启动应用程序时,未处理按键输入。这仅在有时发生。有时,我必须关闭并启动应用程序7至8次,直到显示出来。有时这是第一次尝试。发生这种情况后,直到我再次重新启动应用程序,它才起作用。

我正在使用什么:

Window 7 x64以及最新的Eclipse和JDK版本。

我已经发现了什么:

我已将一个断点置于调试模式,并检查了JPanel实例。似乎总是成功将KeyListener添加到它。

而且,MouseListener和MouseMotionListener一直都可以正常工作。

最小代码:

public class Player implements KeyListener

{

public void keyTyped(KeyEvent e){}

public void keyReleased(KeyEvent e){ }

public void keyPressed(KeyEvent e){

System.out.println("Key Pressed!");

}

}

public class Game {

public static void main(String[] args) {

new Game();

}

public Game(){

JFrame window = new JFrame();

window.setVisible(true);

//Now set the window size correctly

window.setSize(800, 600);

//Set-up the rest of the window

window.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );

window.setResizable(true);

//Create our panel

JPanel canvas = new JPanel();

canvas.setFocusable(true);

window.add( canvas ); //Add it to our window

Player k = new Player();

canvas.addKeyListener(k);

}

}

感谢您的时间!

PS:

好吧,回答我自己的问题:

似乎我必须在设置窗口的大小后调用setVisible(true):

JFrame window = new JFrame();

Now set the window size correctly

window.setSize(800, 600);

window.setVisible(true);

像这样切换setSize()和setVisible()似乎可以使其工作。尝试了十几遍,没有问题。

我想如果setVisible的大小为0x0,可能不喜欢将Focus赋予窗口。

问题是:为什么这只会在某些情况下导致问题?

不要使用KeyListener,而要使用键绑定。 那么,专注并不是一件大事。

间歇性问题总是让我想起初始线程。

尝试将JButton添加到"画布" JPanel中,然后按按钮并查看KeyListener发生了什么-失败是因为JPanel失去了焦点。 为了防止这种情况的发生,请改用"键绑定"(请参阅上面我的评论中的链接以获取本教程)。 例如

import java.awt.event.*;

import java.awt.*;

import javax.swing.*;

@SuppressWarnings("serial")

public class Game2 {

private static final String UP ="up";

public static void main(String[] args) {

new Game2();

}

public Game2() {

JFrame window = new JFrame("Press up-arrow key");

window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

JPanel canvas = new JPanel();

canvas.setPreferredSize(new Dimension(400, 300));

window.add(canvas);

canvas.add(new JButton(new AbstractAction("Press space-bar") {

public void actionPerformed(ActionEvent e) {

System.out.println("Button or space-bar pressed");

}

}));

ActionMap actionMap = canvas.getActionMap();

int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;

InputMap inputMap = canvas.getInputMap(condition);

inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), UP);

actionMap.put(UP, new UpAction());

window.pack();

window.setLocationRelativeTo(null);

window.setVisible(true);

}

}

@SuppressWarnings("serial")

class UpAction extends AbstractAction {

@Override

public void actionPerformed(ActionEvent arg0) {

System.out.println("Up Arrow pressed!");

}

}

感谢您的示例代码。 我已经阅读了您的链接。 剩下的问题是为什么错误如此随机地发生。

不知道这是否与您的问题有关,但是由于它的间歇性,可能是...您应该在最后一个线程中执行setVisible()。 如果需要,可以在setVisible之后调用setSize,但是用户可能会看到闪烁,并且同样应该在swing线程中完成。 做这最后一步:

SwingUtilities.invokeLater( new Runnable() {

public void run() {

window.setVisible( true );

}

} );

为此,您还需要使窗口声明为final:

...

final JFrame window = new JFrame();

...

由于在第一个setSize()之后调用setVisible()解决了该问题,因此也应该可以。 我之所以没有将它称为最后一个是因为我想获取Frames Insets以获取标题栏/边框的大小。 这仅在您事先调用setVisible()时有效。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值