Java Swing Key事件随机切断

时间:2017-03-12 06:42:42

标签: java swing events keyboard macos-sierra

我用Java制作2D游戏。在播放时,控件将随机锁定,通常在30秒内,并且绑定将停止对按键的反应。控件有时会短时间返回。我使用Z,X和箭头键。单独使用箭头键似乎很好,但Z和X键似乎触发了锁定。

对于控件,我最初使用的是KeyListeners,然后是KeyEventDispatcher,然后我尝试了键绑定。它适用于所有这些,虽然KeyListeners似乎仍然触发KeyReleased事件,而不是KeyPressed。键绑定完全停止。

游戏窗口是JFrame中JPanel中的Canvas。使用面板的输入和动作映射设置绑定。

我在Mac上,最近我升级到macOS Sierra。我在升级之前就已经看到过这个问题,但升级后它变得更糟,游戏变得无法播放。我还没有在其他操作系统或其他Mac上测试过。

我发现网上有一些人似乎遇到了同样的问题,有人提交了错误报告:

https://bugs.openjdk.java.net/browse/JDK-8167263

但除此之外,我还没有找到很多解决方法。我在这一点上最好的猜测是它是一个连接到Sierra的bug,并且要么会有修复,要么我的mac上有一些需要重新配置的东西。我一直在寻找。任何建议都会很棒,因为我可能错过了重要的一步。谢谢大家!

以下是使用WASD键的可编辑示例:

import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;

public class KeyErrorTest
{
    public KeyErrorTest() {}

    public static void main(String[] args)
    {
        KeyErrorTest keyErrors = new KeyErrorTest();
        keyErrors.go();
    }

    public void go()
    {
        //create panel
        JPanel panel = new JPanel();
        panel.setFocusable(true);
        panel.requestFocusInWindow();

        //set up bindings for press and release
        InputMap inputMap = panel.getInputMap(JPanel.WHEN_IN_FOCUSED_WINDOW);
        ActionMap actionMap = panel.getActionMap();
        //W
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0, false), 1);
        actionMap.put(1, new KeyPresser(KeyEvent.VK_W));
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0, true), 2);
        actionMap.put(2, new KeyReleaser(KeyEvent.VK_W));
        //A
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0, false), 3);
        actionMap.put(3, new KeyPresser(KeyEvent.VK_A));
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0, true), 4);
        actionMap.put(4, new KeyReleaser(KeyEvent.VK_A));
        //S
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0, false), 5);
        actionMap.put(5, new KeyPresser(KeyEvent.VK_S));
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0, true), 6);
        actionMap.put(6, new KeyReleaser(KeyEvent.VK_S));
        //D
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0, false), 7);
        actionMap.put(7, new KeyPresser(KeyEvent.VK_D));
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0, true), 8);
        actionMap.put(8, new KeyReleaser(KeyEvent.VK_D));

        //create frame
        JFrame frame = new JFrame("Key Bindings Test");
        frame.getContentPane().add(panel);
        frame.pack();
        frame.setVisible(true);

        System.out.println("Press [W], [A], [S], or [D] several times");
        System.out.println("The error tends to occur within 30 seconds");
        System.out.println("The keys will randomly stop registering");
    }

    private class KeyPresser extends AbstractAction
    {
        int key;

        public KeyPresser(int key)
        {
            this.key = key;
        }

        @Override
        public void actionPerformed(ActionEvent e)
        {
            System.out.println((char)key+" down");
        }
    }

    private class KeyReleaser extends AbstractAction
    {
        int key;

        public KeyReleaser(int key)
        {
            this.key = key;
        }

        @Override
        public void actionPerformed(ActionEvent e)
        {
            System.out.println((char)key+" up");
        }
    }
}

0 个答案:

没有答案