Java SWT KeyEvent错误或设计完全错过了发布事件

Java SWT KeyEvent错误或设计完全错过了发布事件,java,events,swt,Java,Events,Swt,在IDE中复制下面的代码。我用Windows10和Java8测试了这段代码 按2个键A(第一个)和B(第二个),然后释放第一个按下的键,然后快速释放第二个按下的键。按下第二个键的释放事件丢失 如果您按住第二个键,它将再次开始生成重复键,然后捕捉到按键释放 此事件实际上会使代码出错,因为它无法解释错过的发布事件,并且状态已出错。这个虫子真丢脸!!比AWT Linux密钥事件bug更糟糕,我找到了一个不错的修复方案 你看到解决办法了吗?您可以禁用SWT中的按键重复(可能) import org.ec

在IDE中复制下面的代码。我用Windows10和Java8测试了这段代码

按2个键A(第一个)和B(第二个),然后释放第一个按下的键,然后快速释放第二个按下的键。按下第二个键的释放事件丢失

如果您按住第二个键,它将再次开始生成重复键,然后捕捉到按键释放

此事件实际上会使代码出错,因为它无法解释错过的发布事件,并且状态已出错。这个虫子真丢脸!!比AWT Linux密钥事件bug更糟糕,我找到了一个不错的修复方案

你看到解决办法了吗?您可以禁用SWT中的按键重复(可能)

import org.eclipse.swt.swt;
导入org.eclipse.swt.events.KeyAdapter;
导入org.eclipse.swt.events.KeyEvent;
导入org.eclipse.swt.layout.FillLayout;
导入org.eclipse.swt.widgets.Button;
导入org.eclipse.swt.widgets.Display;
导入org.eclipse.swt.widgets.Shell;
公共类SWTKeyEvent{
公共静态void main(字符串[]args){
显示=新显示();
外壳=新外壳(显示);
setText(“SWT KeyEvent示例”);
setLayout(新的FillLayout());
按钮=新按钮(外壳,SWT.中心);
setText(“键入某物”);
addKeyListener(新的KeyAdapter(){
按下公共无效键(按键事件e){
布尔值isKeyRepeat=isKeyRepeat(例如keyCode);
如果(!isKeyRepeat){
System.out.println(“\t按下键”+e.keyCode);
}否则{
System.out.println(“重复键”+e.keyCode);
}
}
公共无效密钥已释放(密钥事件e){
System.out.println(“\t\t keyreased”+e.keyCode);
按键释放重复(如按键代码);
}
});
shell.open();
而(!shell.isDisposed()){
如果(!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
受保护的静态按键计数器;
受保护的静态整数[]按按键=新整数[20];
公共静态布尔值isKeyRepeat(int-keyCode){
对于(int i=0;i0){
按键计数器--;
}
}

编辑:在Swing或JavaFX中,发布事件永远不会丢失

您首先想要实现什么?@Baz一个与SWT兼容的游戏框架。我将使用JInput来解决此错误。并使用Linux错误技术(将事件放在一起太近)绕开我的意思是:你发布了一个代码示例和指令来重现某个特定的(不需要的)行为。不过我想知道:你的应用程序应该具体做什么,你的代码与此有什么不同。我收集到的数据都与重复的按键有关。@Baz我绝对需要释放事件!!!否则游戏引擎会认为按键被按下了!!!!!就像向上和向左键一样同时按下。向上释放,然后向左…左键仍然处于按下状态。实际上,我不想重复事件。我将它们丢弃。在Swing中,它工作得很好。对不起,我不明白你在说什么。我帮不了你。还有,一个感叹号就足够了。
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public class SWTKeyEvent {
 public static void main(String[] args) {
  Display display = new Display();
  Shell shell = new Shell(display);
  shell.setText("SWT KeyEvent Example");

  shell.setLayout(new FillLayout());

  Button button = new Button(shell, SWT.CENTER);

  button.setText("Type Something");

  button.addKeyListener(new KeyAdapter() {
     public void keyPressed(KeyEvent e) {
        boolean isKeyRepeat = isKeyRepeat(e.keyCode);
        if (!isKeyRepeat) {
           System.out.println("\t keyPressed " + e.keyCode);
        } else {
           System.out.println("keyRepeated " + e.keyCode);
        }
     }

     public void keyReleased(KeyEvent e) {
        System.out.println("\t\t keyReleased " + e.keyCode);
        keyReleaseRepeat(e.keyCode);
     }

  });

  shell.open();

  while (!shell.isDisposed()) {
     if (!display.readAndDispatch())
        display.sleep();
  }
  display.dispose();
 }

protected static int   pressedKeyCounter;

protected static int[] pressedKeys = new int[20];



public static boolean isKeyRepeat(int keyCode) {
  for (int i = 0; i < pressedKeyCounter; i++) {
     if (pressedKeys[i] == keyCode) {
        return true;
     }
  }
  pressedKeys[pressedKeyCounter] = keyCode;
  pressedKeyCounter++;
  return false;
}


public static void keyReleaseRepeat(int keyCode) {
  boolean shift = false;
  for (int i = 0; i < pressedKeyCounter; i++) {
     if (pressedKeys[i] == keyCode) {
        shift = true;
     } else if (shift) {
        pressedKeys[i - 1] = pressedKeys[i];
     }
  }
  if (pressedKeyCounter > 0) {
     pressedKeyCounter--;
  }
}