【问题标题】:KeyEvent not getting generated due to BufferStrategy由于 BufferStrategy 未生成 KeyEvent
【发布时间】:2018-06-23 07:27:57
【问题描述】:

所以我正在制作一个游戏,我的主游戏应用程序运行良好。问题是,当我尝试通过菜单(例如使用按钮 ActionEvent)启动我的游戏时,我的游戏似乎无法检测到给它的 KeyEvents。 所以我决定在问题所在的地方制作一个简单的代码版本:

class Response
{
    static JFrame frame;
    static BufferStrategy strategy;
    public Response()
    {
        frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
        frame.setUndecorated(true);
        frame.setIgnoreRepaint(true);
        frame.addKeyListener(new KeyAdapter() {
        public void keyTyped(KeyEvent e)
        {
            System.exit(0);
        }
        });
        frame.setVisible(true);
        frame.createBufferStrategy(2);
        strategy = frame.getBufferStrategy();

        frame.requestFocus();
    }
    public static void mainLoop()
    {
        while(true)
        strategy.show();
    }
}

class Button implements ActionListener
{
    JFrame f;
    JButton b;
    public Button()
    {
        f = new JFrame();
        f.setExtendedState(JFrame.MAXIMIZED_BOTH);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        b = new JButton("Click lol");
        b.setFocusable(false);
        b.addActionListener(this);
        f.add(b);
        f.setVisible(true);
        f.setFocusable(false);
    }

    public void actionPerformed(ActionEvent e)
    {
        f.dispose();
        new Response();
        Response.mainLoop();
    }

    public static void main(String args[])
    {
        new Button();
    }
}

单击此处的按钮后,我得到一个空白屏幕,正如预期的那样,但它没有检测到 KeyTyped 事件,并且经过检查,Response.frame 似乎没有焦点。

但是,如果我将 main() 的内容更改为 new Response(); Response.mainLoop();, 检测到 KeyEvent。

调用setFocusable() 方法是希望Button 中的组件将焦点传递给Response 框架。 (在尝试找到解决方案几个小时后,我得出结论,使用 BufferStrategyJFrames 不能被关注(虽然我没有看到它在任何地方明确写过,所以请随时纠正我)。

知道发生了什么吗?

提前致谢。

【问题讨论】:

  • "I have concluded that JFrames which use a BufferStrategy cannot be focused on..." -- 是的,这完全没有意义。你为什么不使用Key Bindings 这个网站上的任何类似问题(希望你搜索过),会告诉你。
  • 您的一个问题是使用了一个占用所有 CPU 的紧密循环,以一种不必要且不受控制的方式。
  • @HovercraftFullOfEels,我没有使用键绑定,因为我正在使用不支持它们的旧版本的 Java。不,我无法改变它,因为它在我的大学里。我知道 Key Bindings 在检测游戏输入等方面效率更高,而且我以前使用过它们,遗憾的是在这种情况下我无法使用它们。
  • @HovercraftFullOfEels,在实际游戏中循环条件是一个布尔值。我刚刚创建了这段代码,以便以简单的方式模拟游戏代码。如果您仍然认为它可以做得更好,请随时提供建议。 (我对 Java 和 Swing 有点陌生)

标签: java swing keyevent bufferstrategy


【解决方案1】:

一般来说,在 java/swing 中,焦点似乎是一件相当棘手的事情。我经历过,即使在调用应该将焦点放在这些组件上的特定方法之后,组件也没有焦点。在调用setFocusable() 并且如果在任何swing 组件上存在setEnabled() 之后,您应该能够通过在应用程序运行后单击该组件来将焦点设置在该组件上,并且据我所知,这是可以实现的最佳效果,并且这是保证工作。但是,永远不要依赖组件以您希望的方式传递焦点。这不太可能发生。

【讨论】:

  • 感谢您的回答!在获得Response() 中的BufferStrategy 后,我尝试调用setFocusable(),然后立即调用setEnabled(),但它仍然无法正常工作,即使我点击了它。
  • OK,找到错误了!您的问题是,您的 mainLoop()一直在运行。这意味着,该过程没有时间对您的键盘输入做出反应。您需要做两件事:首先在strategy.show() 之后添加一个Thread.sleep(longValueInMilliSecs),并在两个调用周围加上大括号,这样while-loop 就不会耗尽您所有的CPU 能力。然后,最重要的是,在带有new Thread(() -> {Response.mainLoop();}).start(); 的新线程中启动mainLoop(),以便主线程可以对按键输入做出反应。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-14
  • 1970-01-01
  • 2011-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多