【问题标题】:KeyListener active only after click on canvasKeyListener 仅在单击画布后激活
【发布时间】:2014-05-08 14:11:06
【问题描述】:

我有一个实现KeyListener 的类,一切正常,但有一个小问题是我的KeyListener 只有在我点击画布后才能工作,所以如果我开始游戏,我必须点击一次然后我可以使用我的键盘,代码:

public class Game extends Canvas implements Runnable {
    ....
    initGame() {
        ...
        addKeyListener(new Keyboard());
        setFocusable(true);
    }

    private class Keyboard implements KeyListener {
        ...
    }
}

-有没有一种方法可以让我的画布在创建后“活跃”?

【问题讨论】:

  • 因为没有焦点。对于 Swing,通常在基于 AWT 的较低级别 KeyListener 上使用键绑定。有关如何使用它们的详细信息,请参阅How to Use Key Bindings。此外,Swing 中的渲染通常在 JPanel 中完成,而不是在 Canvas..
  • 通过在组件上调用setFocusable(true); 设置焦点。
  • @Braj 不,该方法只是设置一个组件可聚焦。你在描述requestFocusInWindow()
  • @Braj 从描述性问题(和示例代码)来看,组件已经可以聚焦,因为 OP 可以单击组件并激活关键侦听器...
  • 如果您按照@AndrewThompson 的建议使用键绑定,则可以绕过KeyListener 的大部分问题。本周第 100 次,here 是我在创建键绑定时给出的简短回答。

标签: java swing canvas focus keylistener


【解决方案1】:

KeyListener 只会在它注册到的组件是可聚焦且有焦点时才会响应按键事件。

虽然您可以使用requestFocusInWindow,但不能保证焦点将转移到组件,如果由于某种原因失去焦点(您单击另一个组件),那么您将返回到第一个。

更好的解决方案是使用基于JComoponet 的组件(如JPanel)并利用Key Bindings API,它允许您定义触发关键事件的焦点级别

【讨论】:

    【解决方案2】:

    如果在使JFrame 可见后添加Canvas 可能会出现问题。

    打电话

    frame.setVisible(true)
    

    最后把所有的组件都加进去就可以了。

    如果我在使JFrame 可见之后添加Canvas 并且我必须单击Canvas 来获得焦点,这就是我所发生的事情。


    -- 编辑--

    理解它的示例代码(取消注释最后一个frame.setVisible(true)后尝试)

    import java.awt.Canvas;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    
    import javax.swing.JFrame;
    
    public class CanvasDemo extends Canvas implements ActionListener, KeyListener {
    
        public CanvasDemo() {
            addKeyListener(this);
            setFocusable(true);
        }
    
        public static void main(String[] args) {
            JFrame frame = new JFrame();
            frame.setVisible(true);
    
            CanvasDemo apple = new CanvasDemo();            
            frame.add(apple);
    
            frame.setTitle("The Game");
            // frame.setVisible(true);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
        }
    
        @Override
        // animates rectangle
        public void actionPerformed(ActionEvent arg0) {
            System.out.println("action performed");
        }
    
        @Override
        public void keyPressed(KeyEvent arg0) {
            System.out.println("key pressed");
        }
    
        @Override
        public void keyReleased(KeyEvent arg0) {
            System.out.println("key released");
        }
    
        @Override
        public void keyTyped(KeyEvent arg0) {
            System.out.println("key typed");
        }
    }
    

    【讨论】:

    • 根据提供的信息,如果在框架可见后添加组件,OP 将无法单击框架并查看关键事件,为了实现这一点,画布必须可以在屏幕上显示...
    • setBackground(Color.RED); 添加到构造函数中,您会注意到Canvas 在框架进入屏幕时可见。对setResizable 的调用可能会使容器无效。哦,intial threadssetSize 将不起作用,因为框架正在使用它自己的布局管理器,因此在调用容器进行布局时设置将被丢弃。
    • 我在删除setResizable后试过了。现在框架显示没有任何高度和宽度。我展开它并按下键。但它仍然无法正常工作。一旦我点击框架。关键监听器开始工作。
    • 遵循我的第一个建议。设置Canvas 对象的背景颜色。一旦你调整了框架的大小,框架就会失效,Canvas 会变成可显示的并且会响应事件——这就是我的观点。从OP所说的来看,他们调用 setVisible 的时间与那里的问题无关。
    【解决方案3】:

    我通过以下方式解决了这个问题:我创建了 Canvas 对象,向其中添加了 KeyListener 并使该对象具有焦点。在这些操作之后,我将 Canvas 对象添加到 JFrame,一切都开始正常工作了。

    【讨论】:

      猜你喜欢
      • 2020-05-30
      • 2021-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-04
      • 1970-01-01
      • 1970-01-01
      • 2022-11-04
      相关资源
      最近更新 更多