Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/378.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 带有KeyEventDispatcher的JFrame可以';t单击3个箭头键_Java_Swing_Flags_Keyevent_Enum Flags - Fatal编程技术网

Java 带有KeyEventDispatcher的JFrame可以';t单击3个箭头键

Java 带有KeyEventDispatcher的JFrame可以';t单击3个箭头键,java,swing,flags,keyevent,enum-flags,Java,Swing,Flags,Keyevent,Enum Flags,我目前正在测试KeyEventDispatcher 因此,我编写了一个小的JFrame,它实现了KeyEventDispatcher和我自己的 按键按下和按键释放方法 在这些方法中,我使用基于标志的系统仅检测每个箭头键的第一次按键 如果单独单击这些键,一切都可以正常工作。但是,如果单击Right、Up、Left(不释放其中任何一个),将无法识别Left键 控制台输出: 右键单击 4 向上单击 六, 预期产出: 右键单击 4 向上单击 6 左键单击 七, 我的代码如下: public void s

我目前正在测试
KeyEventDispatcher

因此,我编写了一个小的
JFrame
,它实现了
KeyEventDispatcher
和我自己的
按键按下
按键释放
方法

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

如果单独单击这些键,一切都可以正常工作。但是,如果单击Right、Up、Left(不释放其中任何一个),将无法识别Left键

控制台输出:

右键单击
4
向上单击
六,

预期产出:

右键单击
4
向上单击
6
左键单击
七,

我的代码如下:

public void setLeftKeyPressed(boolean value)
{
  if(isLeftKeyPressed != value)
  {
    isLeftKeyPressed = value;
    ++leftKeyClickCount;
  }
}
主要类别:

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


    }


}

要解决此问题,请在按下
键时,为特定的
键按住
布尔
变量的引用,并使其
为true
,在释放相应的
键时,使这些变量
为false

下面是一个例子:

以下是
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();
}
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();
}
下面是
keyreased()
方法:

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();
}
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.");
}
private boolean isLeftKeyPressed;
private boolean isRightKeyPressed;
private boolean isUpKeyPressed;
private boolean isDownKeyPressed;
boolean
变量如下所示:

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.");
}
private boolean isLeftKeyPressed;
private boolean isRightKeyPressed;
private boolean isUpKeyPressed;
private boolean isDownKeyPressed;
他们的
设定者像:

public void setLeftKeyPressed(boolean value)
{
  isLeftKeyPressed = value;
}
public boolean isLeftKeyPressed()
{
  return isLeftKeyPressed;
}
同样的,其他二传手

getter
类似于:

public void setLeftKeyPressed(boolean value)
{
  isLeftKeyPressed = value;
}
public boolean isLeftKeyPressed()
{
  return isLeftKeyPressed;
}
同样的,其他的获得者

通常,在游戏和网络远程控制中,这种行为是可以预期的,通过这种技术可以解决

布尔
变量的
翻转
的差异将让您知道任何
发生的“点击”次数。要记录“单击”计数,可以使用计数变量,该变量将保存任何键发生的单击量的状态

以下是如何做到这一点:

int leftKeyClickCount = 0; // Initially ZERO
然后在
isLeftKeyPressed
变量的
setter
中,您可以执行以下操作:

public void setLeftKeyPressed(boolean value)
{
  if(isLeftKeyPressed != value)
  {
    isLeftKeyPressed = value;
    ++leftKeyClickCount;
  }
}
同样地,也可以编写其他setter

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

System.out.println("Left key clicked: " + leftKeyClickCount + " time(s).");

当你说点击键时,你的意思是按物理键盘上的键吗?您可能有一个质量较低的键盘,无法识别发生在一起的多个按键。是的。我的意思是按物理键盘上的键。也许我的键盘质量较低:)如果你复制我的代码并测试它,它与你一起工作,我知道这不是代码问题。我有一个很好的机械键盘,但我没有时间测试它。同时,您可以通过打开文本编辑器并尝试同时按下一组键来测试键盘,例如,查看是否可以在不松开键的情况下按住qwerf并打印每个字母。我的机械装置做得很好,但我的笔记本电脑做不到。我的键盘似乎不是问题,因为一些键的顺序不起作用,而另一些键的顺序不起作用(左键、下键、右键(任意顺序),但左键、上键、右键不起作用,右键、下键、上键不起作用,但右键、上键、左键(反之亦然?:D)我想我在if语句中遇到了一个问题您的代码工作正常。如果您只是在方法keyPressed的开头打印出KeyCode,您会意识到当您已经上下按下时,LEFT永远不会被识别。非常确定这就像NessPowerGlove说的,与键盘有关。我没有机械k不过,这两种方法都需要测试。