带KeyEventDispatcher的JFrame无法单击3个箭头键

时间:2014-03-12 15:17:45

标签: java swing flags keyevent enum-flags

我目前正在测试KeyEventDispatcher

因此我写了一个JFrame来实现KeyEventDispatcher和我自己的keyPressed keyReleasedpublic class Main { public static void main(String[] args) { UI m = new UI(); KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(m); } } 方法。

在这些方法中,我使用基于标志的系统来仅检测每个箭头键的第一个按键。

如果单独单击按键,一切正常。但是如果你点击右,上,左(不释放任何一个),左键就不会被识别。

控制台输出:

  

右键单击
  4
  点击了   6

预期产出:

  

右键单击
  4
  点击了   6
  左键单击
  7

我的代码如下:

主要课程:

public class UI extends JFrame implements KeyEventDispatcher{

    short lurd = 0;

    enum KEYSTATES{
        LEFT(1),
        UP(2),
        RIGHT(4),
        DOWN(8);

        private int m_val;
        KEYSTATES(int val){
            m_val = val;
        }

        public int getm_val(){
            return m_val;
        }

    }

    public UI(){

        setSize(800,600);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        setVisible(true);

    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent e) {


        switch(e.getID())
        {
        case KeyEvent.KEY_PRESSED:
            keyPressed(e);
            return true;

        case KeyEvent.KEY_RELEASED:
            keyReleased(e);
            return true;

        }
        return false;
    }

    private void keyPressed(KeyEvent e){
        if(e.getKeyCode() == KeyEvent.VK_LEFT && ((lurd & KEYSTATES.LEFT.getm_val()) != KEYSTATES.LEFT.getm_val())){
            lurd |= KEYSTATES.LEFT.getm_val();
            System.out.println("Left clicked");
            System.out.println(lurd);
        }
        else if(e.getKeyCode() == KeyEvent.VK_UP && ((lurd & KEYSTATES.UP.getm_val()) != KEYSTATES.UP.getm_val()))
        {
            lurd |= KEYSTATES.UP.getm_val();
            System.out.println("Up clicked");
            System.out.println(lurd);
        }
        else if(e.getKeyCode() == KeyEvent.VK_RIGHT && ((lurd & KEYSTATES.RIGHT.getm_val()) != KEYSTATES.RIGHT.getm_val()))
        {
            lurd |= KEYSTATES.RIGHT.getm_val();
            System.out.println("Right clicked");
            System.out.println(lurd);
        }
        else if(e.getKeyCode() == KeyEvent.VK_DOWN && ((lurd & KEYSTATES.DOWN.getm_val()) != KEYSTATES.DOWN.getm_val()))
        {
            lurd |= KEYSTATES.DOWN.getm_val();
            System.out.println("Down clicked");
            System.out.println(lurd);
        }


    }

    private void keyReleased(KeyEvent e){
        if(e.getKeyCode() == KeyEvent.VK_LEFT && ((lurd & KEYSTATES.LEFT.getm_val()) == KEYSTATES.LEFT.getm_val())){
            lurd &= ~KEYSTATES.LEFT.getm_val();
            System.out.println("Left released");
            System.out.println(lurd);
        }
        else if(e.getKeyCode() == KeyEvent.VK_UP && ((lurd & KEYSTATES.UP.getm_val()) == KEYSTATES.UP.getm_val()))
        {
            lurd &= ~KEYSTATES.UP.getm_val();
            System.out.println("Up released");
            System.out.println(lurd);
        }
        else if(e.getKeyCode() == KeyEvent.VK_RIGHT && ((lurd & KEYSTATES.RIGHT.getm_val()) == KEYSTATES.RIGHT.getm_val()))
        {
            int x = ~KEYSTATES.RIGHT.getm_val();
            lurd &= x;
            System.out.println("Right released");
            System.out.println(lurd);
        }
        else if(e.getKeyCode() == KeyEvent.VK_DOWN && ((lurd & KEYSTATES.DOWN.getm_val()) == KEYSTATES.DOWN.getm_val()))
        {
            lurd &= ~KEYSTATES.DOWN.getm_val();
            System.out.println("Down released");
            System.out.println(lurd);
        }


    }


}

UI类:

{{1}}

1 个答案:

答案 0 :(得分:0)

要解决此问题,请在booleankeys时保留pressedtrue变量的引用,并将它们设为false,然后创建这些变量key当他们各自releasedkeyPressed()时。

以下是一个例子:

此处public void keyPressed(KeyEvent e) { switch(e.getKeyCode()) { case VK_LEFT: setLeftKeyPressed(true); break; case VK_RIGHT: setRightKeyPressed(true); break; case VK_UP: setUpKeyPressed(true); break; case VK_DOWN: setDownKeyPressed(true); break; //... } printKeyStates(); } 方法:

keyReleased()

以及public void keyReleased(KeyEvent e) { switch(e.getKeyCode()) { case VK_LEFT: setLeftKeyPressed(false); break; case VK_RIGHT: setRightKeyPressed(false); break; case VK_UP: setUpKeyPressed(false); break; case VK_DOWN: setDownKeyPressed(false); break; //... } printKeyStates(); } 方法:

printKeyStates()

以下是public void printKeyStates() { print("Left", isLeftKeyPressed()); print("Right", isRightKeyPressed()); print("Up", isUpKeyPressed()); print("Down", isDownKeyPressed()); } private void print(String key, boolean isPressed) { System.out.println(key + " key is " + (isPressed ? "" : "NOT ") + "pressed."); } 方法的样子:

boolean

private boolean isLeftKeyPressed; private boolean isRightKeyPressed; private boolean isUpKeyPressed; private boolean isDownKeyPressed; 变量如下所示:

setters

他们的public void setLeftKeyPressed(boolean value) { isLeftKeyPressed = value; } 喜欢:

getters

与其他选手一样......

public boolean isLeftKeyPressed() { return isLeftKeyPressed; } 喜欢:

flips

和其他吸气者一样......

通常,在游戏中,以及在预期会出现此类行为的网络远程控制中,通过此技术可以解决此问题。

boolean变量key的差异会让您知道"点击次数"任何int leftKeyClickCount = 0; // Initially ZERO 发生的事情。记录下来"点击" count,您可以使用计数变量来保存任何键发生的点击量状态。

以下是如何做到的:

setter

然后在isLeftKeyPressed public void setLeftKeyPressed(boolean value) { if(isLeftKeyPressed != value) { isLeftKeyPressed = value; ++leftKeyClickCount; } } 变量中,您可以执行以下操作:

xyzKeyClickCount

同样可以写其他二传手......

然后,您可以通过打印相应的System.out.println("Left key clicked: " + leftKeyClickCount + " time(s)."); 变量值来打印每个键的点击次数,如:

{{1}}