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不过,这两种方法都需要测试。