我目前正在测试KeyEventDispatcher
。
因此我写了一个JFrame
来实现KeyEventDispatcher
和我自己的keyPressed
keyReleased
和public 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}}
答案 0 :(得分:0)
要解决此问题,请在boolean
为keys
时保留pressed
个true
变量的引用,并将它们设为false
,然后创建这些变量key
当他们各自released
为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
的差异会让您知道"点击次数"任何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}}