触摸输入和使用JavaFX 11的OpenJDK 11存在问题

10
我正在开发JavaFX项目,并希望从Oracle JDK 1.8切换到OpenJDK 11。到目前为止,转换非常顺利,但仍存在一个与触摸/鼠标输入相关的主要问题,这导致一些麻烦。
JavaFX UI应该在触摸设备上运行,原本在Oracle JDK 1.8上可以直接使用。当我触摸屏幕时,会按预期触发以下一系列鼠标事件:
MOUSE_PRESSED
MOUSE_RELEASED
MOUSE_CLICKED
使用OpenJDK11构建相同的应用程序(使用OpenJFX 11作为外部库,因为JavaFX不再是默认JDK的一部分),我得到以下事件序列:
MOUSE_ENTERED_TARGET
MOUSE_ENTERED_TARGET
MOUSE_EXITED_TARGET
MOUSE_EXITED_TARGET
这就解释了为什么我无法单击任何按钮(或控件)。到此为止都很好。问题是,我如何恢复MOUSE_{PRESSED、RELEASED、CLICKED}事件?
SSCE:
package com.example.jfxtouchtest;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.TouchEvent;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;


public class JFXTouchTest {

    public static void main(String[] args) {
        Application.launch(JFXApp.class, args);
    }

    public static class JFXApp extends Application {
        @Override
        public void start(Stage primaryStage) {
            primaryStage.addEventFilter(TouchEvent.ANY, e -> System.out.println("touch event: " + e.getEventType()));
            primaryStage.addEventFilter(MouseEvent.ANY, e -> System.out.println("mouse event: " + e.getEventType()));
            primaryStage.setScene(new Scene(new Pane()));
            primaryStage.setWidth(800);
            primaryStage.setHeight(600);
            primaryStage.show();
        }
    }
}

值得注意的是,所有的触发事件都是MouseEvents(而不是TouchEvents),无论我是否使用触摸屏。就本身而言,在我看来这有点奇怪,但至少我在JDK 8中得到了期望的行为……

一些背景信息:

  • 操作系统:Ubuntu 18.04.01 LTS
  • 内核:4.15.0-42-generic
  • Oracle JDK 1.8.0_191
  • OpenJDK 11.0.1
  • 触摸屏(如xinput所报告):Atmel maXTouch数位板
  • 触摸屏在其他应用程序中运作正常,点击事件似乎按预期处理。
  • 与问题相关的VM参数

    -Dcom.sun.javafx.isEmbedded=true

    -Dcom.sun.javafx.touch=true

    似乎对问题没有影响

  • 根据我是使用鼠标还是触摸屏,xev输出中似乎存在细微差别:

    鼠标(state在ButtonPress时为0x0,在ButtonRelease时为0x100):

    ButtonPress event, serial 34, synthetic NO, window 0x3400001,
        root 0x193, subw 0x0, time 16982696, (93,90), root:(964,612),
        state 0x0, button 1, same_screen YES
    
    ButtonRelease event, serial 34, synthetic NO, window 0x3400001,
        root 0x193, subw 0x0, time 16983364, (93,90), root:(964,612),
        state 0x100, button 1, same_screen YES
    

    触摸屏(state 在这两种情况下均为 0x100):

    ButtonPress event, serial 34, synthetic NO, window 0x3400001,
        root 0x193, subw 0x0, time 17599475, (93,145), root:(964,667),
        state 0x100, button 1, same_screen YES
    
    ButtonRelease event, serial 34, synthetic NO, window 0x3400001,
        root 0x193, subw 0x0, time 17599537, (93,145), root:(964,667),
        state 0x100, button 1, same_screen YES
    

    我不太确定这是什么意思。

即使只是确认在另一台机器上使用另一种类型的触摸屏也可以复制该问题,任何帮助都将不胜感激!非常感谢!

更新:与此同时,我已经得到了一个不同的触摸屏,似乎它可以正常工作。有趣的是,就像普通的鼠标事件一样,xev报告ButtonPress和ButtonRelease的两种不同状态,所以可能在另一种触摸屏上两种事件类型的状态字段相同与此有关?

2个回答

1
我在使用触摸屏和JFX时遇到了同样的问题。我的代码在Open JDK 1.8及其对应的JFX上正常工作,但在OpenJDK 11及其对应的JFX上失败。使用来自Liberica的JDK和JFX可以正常工作https://bell-sw.com/pages/java-11.0.7-for-Embedded/
因此,我的解决方法是切换到Liberica JDK 11和JFX发行版。其他选择可能包括来自Azul或Corretto的JDK、JFX发行版。

好的,我会试一下。顺便说一下,问题的根本原因已经找到了。它是由于GTK后端没有正确处理所有类型的触摸输入事件。这里有一个更详细的GitHub问题:https://github.com/javafxports/openjdk-jfx/issues/329,以及一个官方的JBS错误报告:https://bugs.openjdk.java.net/browse/JDK-8217955。 - jln-ho

0

通过使用Java参数-Djdk.gtk.version=2来强制JavaFX使用gtk-2。触摸屏在该设置下工作,尽管这会导致我们的应用程序出现其他问题(可能与第三方库有关)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接