当从SWT 3切换到SWT 4时,JAVA SWT KeyDown事件触发3次而不是1次
以下问题让我感到困惑:我有一个SWT Java应用程序,在以下情况下,从SWT 3切换到SWT 4会导致KeyDown事件的奇怪行为: 我有一个包含浏览器小部件的shell。我通过Display对象上的一个过滤器在Java级别监听KeyDown事件,如下所示。当检测到这样的事件时,我会调用浏览器小部件的execute()函数来执行一些javascript。我选择在全局java级别检测KeyDown事件,而不是直接在javascript中检测,因为此时浏览器可能不一定有焦点 预期行为:应检测一次按键事件 实际行为:检测到三次按键事件 到目前为止我所尝试和学到的: 1) 该问题仅在使用浏览器小部件时发生。 2) 问题不仅发生在执行某些javascript时,如果我简单地设置浏览器的内容(br.setText(“…”),也会发生,因此浏览器上的任何操作似乎都会触发问题。 3) SWT3.836没有出现这个问题。它发生在SWT4.924上 恢复到SWT3并不是一个理想的选择,因为它由于libwebkitgtk而导致了很多崩溃,并且我摆脱了那些使用SWT4的人 配置:Ubuntu 18.04,Java openjdk 11 adm64,SWT 4.924(从Eclipse下载页面下载最新稳定版本4.14M1) 代码如下:当从SWT 3切换到SWT 4时,JAVA SWT KeyDown事件触发3次而不是1次,java,browser,swt,listener,keydown,Java,Browser,Swt,Listener,Keydown,以下问题让我感到困惑:我有一个SWT Java应用程序,在以下情况下,从SWT 3切换到SWT 4会导致KeyDown事件的奇怪行为: 我有一个包含浏览器小部件的shell。我通过Display对象上的一个过滤器在Java级别监听KeyDown事件,如下所示。当检测到这样的事件时,我会调用浏览器小部件的execute()函数来执行一些javascript。我选择在全局java级别检测KeyDown事件,而不是直接在javascript中检测,因为此时浏览器可能不一定有焦点 预期行为:应检测一次按
public static void main(String[] args) {
System.out.println("Launching test application");
Display display = new Display();
Shell shell = new Shell(display);
Browser br = new Browser(shell,SWT.NONE);
br.setSize(500,500);
display.addFilter(SWT.KeyDown, new Listener() {
@Override
public void handleEvent(Event event) {
System.out.println(event.keyCode);
//Try either of the following two lines to reproduce the problem. If you comment both lines, the problem disappears
br.execute("javascript:alert('hello')");
//br.setText("<html><head></head><body>TEST</body></html>");
}
});
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
{
display.sleep();
}
}
}
publicstaticvoidmain(字符串[]args){
System.out.println(“启动测试应用程序”);
显示=新显示();
外壳=新外壳(显示);
浏览器br=新浏览器(shell,SWT.NONE);
br.设置大小(500500);
display.addFilter(SWT.KeyDown,newlistener()){
@凌驾
公共无效handleEvent(事件){
System.out.println(event.keyCode);
//尝试以下两行中的任何一行来重现问题。如果您对这两行都进行了注释,问题就会消失
br.execute(“javascript:alert('hello')”);
//br.setText(“测试”);
}
});
shell.open();
而(!shell.isDisposed()){
如果(!display.readAndDispatch())
{
display.sleep();
}
}
}
有什么提示吗?提前谢谢 我已经在Windows 10和SWT 4.924上测试了您的代码,我收到了两次事件 我猜
浏览器
也在与过滤器交互,导致多个事件(请参阅此旧注释,不确定是否相关:)
此外,似乎只有当浏览器
具有焦点时,问题才会发生,并且当其他控件具有焦点时,问题才能正常工作
因此,作为一种解决方法,当浏览器没有焦点时,您可以使用过滤器,否则,当浏览器有焦点时,您可以在浏览器上使用标准键侦听器
例如:
br.addKeyListener(keyPressedAdapter(event -> {
handleBrowserKeyEvent(br, event.keyCode);
}));
display.addFilter(SWT.KeyDown, new Listener() {
@Override
public void handleEvent(Event event) {
// when the browser has focus, use his key listener instead of this filter
if (br.isFocusControl()) {
return;
}
handleBrowserKeyEvent(br, event.keyCode);
}
});
在handleBrowserKeyEvent
中放置处理逻辑
注意,在我的例子中,我还必须放置一个shell.forceFocus()代码>紧跟在shell.open()之后代码>,否则浏览器键侦听器将无法立即工作(我不知道为什么)。处理此问题的一种快速而肮脏的方法是计数事件的数量,并在每3个事件中输入2个,如下所示:
display.addFilter(SWT.KeyDown, new Listener() {
int i = 0;
@Override
public void handleEvent(Event event) {
if (i<2) {
i++;
}else {
System.out.println(event.keyCode);
i=0;
}
}
});
display.addFilter(SWT.KeyDown,newlistener()){
int i=0;
@凌驾
公共无效handleEvent(事件){
如果(iOn macOS),除非我使用某些内容初始化浏览器,否则此代码根本不会生成任何按键关闭事件,那么它只会给出1个事件加上“按键未被接受”的蜂鸣音。感谢您的回复。实际上,在我的Linux配置中,KeyListener直接连接到浏览器(br.addKeyListener)同时触发事件3次。有趣的是,可以看到一些swt元素在不同平台上的行为是如何不同的,而它应该是跨平台的。