【问题标题】:KeyListener Works at Random in JFrameKeyListener 在 JFrame 中随机工作
【发布时间】:2019-03-13 08:36:11
【问题描述】:

每次我运行我的应用程序时,KeyListener 是否能正常工作都是一个问题。如果它可以运行,那么之后的任何时候都不会出现任何问题,但如果它在应用程序启动时无法运行,则它永远不会运行,直到程序关闭并重新启动。

public ThreeDimChessRunner() {
    record = new ArrayList<Integer>();
    winner = Player.NONE;
    game = new ThreeDimBoard(0);
    addMouseListener(this);
    addKeyListener(this);
    setFocusable(true);

    tm.start();
    screenWidth = screenSize.width;
    screenHeight = screenSize.height;
}

public static void main(String[] args){
    screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    ThreeDimChessRunner p = new ThreeDimChessRunner();
    JFrame frame = new JFrame("3D Chess");  
    frame.setExtendedState(Frame.MAXIMIZED_BOTH);
    frame.setUndecorated(true);

    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.add(p);
}

ThreeDimChessRunner 类扩展 JPanel 并实现 KeyListenerActionListenerMouseInputListener

tm 是一个Timer 对象

screenSize 是一个Dimension 对象

【问题讨论】:

  • JFrame 是否无响应?可能是主线程工作量太大

标签: java swing jframe jpanel keylistener


【解决方案1】:

组件应该在框架变得可行之前添加到框架中。

如果组件尚未添加到框架中,则无法将焦点赋予组件,并且 KeyListener 仅适用于具有焦点的组件。

通常会出现随机结果,因为您没有在 Event Dispatch Thread (EDT) 上创建 GUI。所有 Swing 组件和对 Swing 组件的更新都应在 EDT 上完成。阅读Concurrency 部分,了解更多信息和创建 GUI 的正确方法示例。

另外,您不应该使用 KeyListener 来监听事件。正如您所注意到的,它们是不可靠的,因为它们依赖于具有焦点的组件。相反,您应该使用Key Bindings。即使组件没有焦点,它们也可以配置为工作。

【讨论】:

  • 好的,所以在框架可行之前添加组件可以解决问题。一般来说,我对编程非常陌生,并且有点将我的程序与各种知识花絮拼凑在一起。我不知道...主要方法与事件调度线程相同吗?另外,为什么我需要使用键绑定?我的程序在没有焦点时不需要运行,它只运行单个帧,除了改变帧的方法之外,在帧之外没有任何其他内容。所以 Keylistener 应该没问题,对吧?
  • is the main method the same as the EDT? - 没有。阅读我提供的教程链接。它显示了如何将代码添加到 EDT。 why do I need to use Key bindings? - 这是更新更好的方法。再次阅读教程。您的简单示例现在有效。但是,当您在框架上拥有多个组件时,未来的应用程序会怎样呢?一旦面板失去焦点,KeyListener 就会停止工作。学习正确的解决方案,它将适用于所有情况。见Motion Using the Keyboard
猜你喜欢
  • 2017-03-15
  • 1970-01-01
  • 2014-06-04
  • 2017-07-24
  • 2012-11-01
  • 1970-01-01
相关资源
最近更新 更多