【发布时间】:2014-11-22 08:51:10
【问题描述】:
我遇到了一个奇怪的问题。经过数小时的反复试验,我找到了问题的根源,但对我来说没有任何意义。
我有一个主类,它具有以下方法:
public static void test(){
System.out.println("test Method is called");
}
我有一个 Keys 类。 Keys 的一个对象被添加到 Main 的一个对象中。
这是最小的完整可验证示例: Main2 类
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main2 extends JPanel {
private static Main2 main = new Main2();;
public static final Main2 main() {
return main;
}
public static void test() {
System.out.println("test Method is called");
}
public final JFrame frame = new JFrame();
public final Keys2 keys = new Keys2();
// ==============================================================
public static void main(String[] args) {}
private Main2() {
System.out.println("START");
Main2.main = this;
frameInit();
init();
gameLoop();
}
private void init() {
keys.start();
//keys.left(); Removing // from this line partially solves the problem.
}
private void frameInit() {
frame.add(main);
frame.setSize(100, 100);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
private void gameLoop() {
while (true) {// Removing while loop solves the problem
//Code here is omitted due to being irrelevant
}
}// loop end
}
键类:
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class Keys2 implements KeyListener {
// Default keys will be able to be changed
private int leftKey = 37; // left b.
public void start() {
Main2.main().addKeyListener(this);
Main2.main().setFocusable(true);
}
public boolean isPressed(int keyCode) {
return false; // pressedKeys.contains(keyCode);
}
@Override
public void keyPressed(KeyEvent e) {
// non-critical keys:
System.out.println(e.getKeyCode());
if (e.getKeyCode() == leftKey)
left();
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void keyTyped(KeyEvent e) {}
// ========================================================
// KEY METHODS
public void left() {
// default left
System.out.println("left");
Main2.test();
System.out.println("end");
}
}// END OF THE KEYS CLASS
按下键打印值。所以键正在工作。请注意,我已将 left() 方法更改为调用 Main 类中的静态 test() 方法。现在只要我不按左键就没有问题,但是当我按左键时,我只会在控制台中得到以下结果:
left
“结束”和“调用测试方法”均未打印。没有错误信息。同样在按下左键后,所有关键方法都停止工作(游戏循环仍然有效,因此程序不会冻结)。鼠标监听器也停止工作。我什至无法通过单击 X 按钮来关闭 JFrame 窗口。
但是,如果我从 Main 的对象或另一个对象,甚至从 start() 方法调用 left() 方法,它可以正常工作,并且控制台会收到以下消息:
left
test Method is called
end
之后,我可以毫无错误地按下左键并收到相同的消息。
这是什么原因?我该如何解决这个问题?
编辑:我已经用 MCVE 替换了我的代码
【问题讨论】:
-
1) 为了尽快获得更好的帮助,请发布MCVE(最小完整可验证示例)或SSCCE(简短、自包含、正确示例)。 2) 对于 Swing,我们通常使用key bindings 而不是较低级别的
KeyListener。 -
@AndrewThompson 我希望有一些我不知道的显而易见的事情。我会尝试制作一个。
-
什么是
Main.main()?如果要获取Main类型的对象,Main mainObj = new Main();有什么问题。而且,如果你想让它成为静态的,这种方法的首选命名约定是getInstance()。您的代码不完整。 -
@hfontanez 只有一个 Main 对象。 main() 是一个 getter(我从 getMain() 中缩短了它。我经常调用它,所以我希望它很短。它返回主对象。我认为问题是由事件处理程序引起的,但似乎是错误在代码的其余部分。我正在处理 MCVE。我很有可能会在生成 MCVE 的那一刻发现错误。
标签: java swing keylistener key-events