【问题标题】:keyEvents freezes keys while other methods can call the same method properly in JavakeyEvents 冻结键,而其他方法可以在 Java 中正确调用相同的方法
【发布时间】: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


【解决方案1】:

我已通过将 private static Main2 main = new Main2(); 更改为 private static Main2 main; 解决了我的问题

然后我在 main 方法中添加了main= new Main2();。这解决了问题。为什么以及如何?我一点头绪都没有。

【讨论】:

  • 我会接受任何可以解释为什么这可以解决我的问题的答案。
  • 另见Initial Threads
猜你喜欢
  • 2011-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-27
相关资源
最近更新 更多