0

我目前正在测试KeyEventDispatcher.

因此我写了一些JFrame实现KeyEventDispatcher和我自己的 keyPressed方法keyReleased

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

如果您单独单击按键,一切正常。但是,如果您单击右、上、左(不释放其中任何一个),将无法识别左键。

控制台输出:

右键单击
4
向上单击
6

预期输出:

右击
4
上击
6
左击
7

我的代码如下:

主类:

public class Main {

    public static void main(String[] args) {
        UI m = new UI();
        KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(m);

    }
}

界面类:

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);
        }


    }


}
4

1 回答 1

0

要解决此问题,boolean请在特定keys时保留变量的引用pressed,并制作它们,并在它们各自为时制作true这些变量。falsekeyreleased

这是一个例子:

这里的keyPressed()方法:

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。要记录“点击”计数,您可以使用 count 变量来保存任何键发生的点击量的状态。

您可以这样做:

int leftKeyClickCount = 0; // Initially ZERO

然后在setter变量isLeftKeyPressed中,您可以执行以下操作:

public void setLeftKeyPressed(boolean value)
{
  if(isLeftKeyPressed != value)
  {
    isLeftKeyPressed = value;
    ++leftKeyClickCount;
  }
}

同样可以编写其他setter...

然后,您可以通过打印适当的xyzKeyClickCount变量值来打印每个键的点击次数,例如:

System.out.println("Left key clicked: " + leftKeyClickCount + " time(s).");
于 2014-03-12T15:47:52.510 回答