JavaFX 没有 TouchEvents

2023-12-23

在我的 (Windows) Surface Go 2 平板电脑上,我无法检索任何(多点触控)触摸事件。我尝试了几个 Java/FX 版本。即使使用 JavaFX 17(及更早版本),也不会生成 TouchEvents 事件,仅生成鼠标事件。是否需要某种配置参数?

package fx;

import javafx.application.Application;
import javafx.collections.ListChangeListener;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.TouchEvent;
import javafx.scene.layout.Pane;
import javafx.stage.PopupWindow;
import javafx.stage.Stage;
import javafx.stage.Window;

public class test {

    public static void main(String[] args) {
        System.setProperty("com.sun.javafx.touch", "true");
        System.setProperty("com.sun.javafx.isEmbedded", "true");   
        Application.launch(JFXApp.class, args);
    }

    public static class JFXApp extends Application implements ListChangeListener<Window> {

        @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()));
            final ComboBox<String> comboBox = new ComboBox<>();
            comboBox.getItems().addAll("Test1", "Test2", "Test3");
            Scene scene = new Scene(new Pane(comboBox));
            scene.addEventFilter(TouchEvent.ANY, e -> System.out.println("scene touch event: " + e.getEventType()));
            scene.addEventFilter(MouseEvent.ANY, e -> System.out.println("scene mouse event: " + e.getEventType()));
            primaryStage.setScene(scene);
            primaryStage.setWidth(800);
            primaryStage.setHeight(800);
            primaryStage.show();
            Window.getWindows().addListener(this);
        }

        @Override
        public void onChanged(Change<? extends Window> c) {
            if (!c.next()) return;
            for (Window w : c.getAddedSubList()) {
                if (w instanceof PopupWindow) {
                    w.addEventFilter(TouchEvent.ANY,
                            e -> System.out.println("touch event (PopupWindow): " + e.getEventType()));
                    w.addEventFilter(MouseEvent.ANY,
                            e -> System.out.println("mouse event (PopupWindow): " + e.getEventType()));
                    Window.getWindows().removeListener(this);
                }
            }
        }
    }
}

我使用运行 Windows 的 Microsoft Surface Book 2 笔记本电脑在 Java/JavaFX 16 上获取触摸事件。

样本来源

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

public class TouchTest extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage stage) {
        System.out.println("java.version: " + System.getProperty("java.version"));
        System.out.println("javafx.runtime.version: " + System.getProperties().get("javafx.runtime.version"));

        Scene scene = new Scene(new Pane(), 800, 800);
        scene.addEventFilter(TouchEvent.ANY, System.out::println);

        stage.setScene(scene);
        stage.show();
    }
}

执行指令

使用 Java 16 和 JavaFX 16,运行示例程序并触摸显示的空窗格(通过用手指触摸触摸屏,而不是使用触控板并按下它)。

程序输出

C:\Users\send2\.jdks\temurin-16.0.2\bin\java.exe "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2019.3.2\lib\idea_rt.jar=56576:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2019.3.2\bin" -Dfile.encoding=UTF-8 -classpath C:\Users\send2\.m2\repository\org\openjfx\javafx-controls\16\javafx-controls-16.jar;C:\Users\send2\.m2\repository\org\openjfx\javafx-graphics\16\javafx-graphics-16.jar;C:\Users\send2\.m2\repository\org\openjfx\javafx-base\16\javafx-base-16.jar;C:\Users\send2\.m2\repository\org\openjfx\javafx-fxml\16\javafx-fxml-16.jar -p C:\Users\send2\.m2\repository\org\openjfx\javafx-base\16\javafx-base-16-win.jar;C:\Users\send2\.m2\repository\org\openjfx\javafx-graphics\16\javafx-graphics-16-win.jar;C:\dev\fxdemo\target\classes;C:\Users\send2\.m2\repository\org\openjfx\javafx-controls\16\javafx-controls-16-win.jar;C:\Users\send2\.m2\repository\org\openjfx\javafx-fxml\16\javafx-fxml-16-win.jar -m org.jewelsea.fxdemo/org.jewelsea.fxdemo.TouchTest
java.version: 16.0.2
javafx.runtime.version: 16+8
TouchEvent [source = javafx.scene.Scene@3968dc9e, target = Pane@295c8184[styleClass=root], eventType = TOUCH_PRESSED, consumed = false, touchCount = 1, eventSetId = 1, touchPoint = TouchPoint [state = PRESSED, id = 1, target = Pane@295c8184[styleClass=root], x = 394.5, y = 330.5, z = 0.0, pickResult = PickResult [node = Pane@295c8184[styleClass=root], point = Point3D [x = 394.5, y = 330.5, z = 0.0], distance = 1492.820323027551]]
TouchEvent [source = javafx.scene.Scene@3968dc9e, target = Pane@295c8184[styleClass=root], eventType = TOUCH_MOVED, consumed = false, touchCount = 1, eventSetId = 2, touchPoint = TouchPoint [state = MOVED, id = 1, target = Pane@295c8184[styleClass=root], x = 394.0, y = 331.0, z = 0.0, pickResult = PickResult [node = Pane@295c8184[styleClass=root], point = Point3D [x = 394.0, y = 331.0, z = 0.0], distance = 1492.820323027551]]
TouchEvent [source = javafx.scene.Scene@3968dc9e, target = Pane@295c8184[styleClass=root], eventType = TOUCH_STATIONARY, consumed = false, touchCount = 1, eventSetId = 3, touchPoint = TouchPoint [state = STATIONARY, id = 1, target = Pane@295c8184[styleClass=root], x = 394.0, y = 331.0, z = 0.0, pickResult = PickResult [node = Pane@295c8184[styleClass=root], point = Point3D [x = 394.0, y = 331.0, z = 0.0], distance = 1492.820323027551]]
TouchEvent [source = javafx.scene.Scene@3968dc9e, target = Pane@295c8184[styleClass=root], eventType = TOUCH_STATIONARY, consumed = false, touchCount = 1, eventSetId = 4, touchPoint = TouchPoint [state = STATIONARY, id = 1, target = Pane@295c8184[styleClass=root], x = 394.0, y = 331.0, z = 0.0, pickResult = PickResult [node = Pane@295c8184[styleClass=root], point = Point3D [x = 394.0, y = 331.0, z = 0.0], distance = 1492.820323027551]]
TouchEvent [source = javafx.scene.Scene@3968dc9e, target = Pane@295c8184[styleClass=root], eventType = TOUCH_RELEASED, consumed = false, touchCount = 1, eventSetId = 5, touchPoint = TouchPoint [state = RELEASED, id = 1, target = Pane@295c8184[styleClass=root], x = 394.0, y = 331.0, z = 0.0, pickResult = PickResult [node = Pane@295c8184[styleClass=root], point = Point3D [x = 394.0, y = 331.0, z = 0.0], distance = 1492.820323027551]]

执行行仅供参考,当我使用其内部运行函数启动应用程序时,它是由我的 IDE (Intellij Idea) 自动生成的。我确信它可以在 IDE 之外使用不同的执行命令正常工作,但使用相同的 JRE/JavaFX 版本。

示例适用于 JavaFX 16,不适用于 17.0.0.1

如果您使用当前版本的 JavaFX 17,则在我设置的运行 Windows 的 Surface Book 2 上,上述示例将不会接收触摸事件(它们映射到鼠标事件)。何塞对此问题的评论对此进行了解释:

JavaFX 16 发布后,此问题JDK-8249737 https://bugs.openjdk.java.net/browse/JDK-8249737已修复。它改变了 Windows 上处理触摸事件的方式:并非所有事件都是直接事件。在此修复之前,触摸事件会报告给场景,但现在间接事件会退出:link https://github.com/openjdk/jfx/blob/master/modules/javafx.graphics/src/main/java/javafx/scene/Scene.java#L2799,并视为鼠标事件。

这也(大部分)适用于此处找到的旧 Oracle TouchEvent 教程示例代码:

  • https://docs.oracle.com/javase/8/javafx/events-tutorial/touch_events.htm#CHDHBGJA https://docs.oracle.com/javase/8/javafx/events-tutorial/touch_events.htm#CHDHBGJA

该代码的多点触控文件夹拖动部分适用于我的 Java 16 设置。

该代码中将球拖到盒子部分对我来说在 Java 16 上不起作用。它似乎记录了初始触摸,但我无法计算出将球带到另一个盒子的触摸或触摸和拖动序列,因此它看起来已损坏。

对于 Java 17,触摸事件示例中没有任何内容响应触摸事件(或鼠标事件)。

FAQ

对于 MacOS,如果触控板事件也生成触摸事件就好了。

使用 Mac 触控板不会生成触摸事件(在 JavaFX 17 上测试)。与 Windows 触摸处理不同,我认为此 Mac 代码没有针对 JavaFX 17 进行更新,因此可能一直都是这样。我没有触摸屏来尝试。

对于 iOS 实现,通过检查代码可以看出,当您触摸 iOS 设备的屏幕时,它会生成触摸事件(但我还没有运行 JavaFX iOS 的设置来测试它)。

看来有多个问题。

是的我同意。

我还认为,有些问题是特定于平台和设备的,最终可能会有点微妙,而且并不完全简单。

我提供的信息几乎是我对这个主题的知识的限制,因此不幸的是,我无法提供更多帮助。

当我使用bell-sw或Azul Full-JDK 16测试它时,它不起作用

有点奇怪的是,它适用于 gluon JavaFX 16 发行版,但不适用于 azul 或 bell-sw 捆绑发行版,因为人们会认为它们具有相同的功能,但也只能说这么多了。

我想可以联系这些捆绑的 JDK/JavaFX 发行版的制造商,或者为此针对他们提交问题报告。但是,随着 Java 17 的功能发生变化,我不确定它会带来很大的变化,至少目前是这样。

当我使用 Oracle Java 17 并使用从 gluonhq.com/products/javafx 下载的 JavaFX 16 时,它确实有效!但 JavaFX 17 无论如何都不起作用。

是的,这与我使用来自 Maven 中心的模块化 JavaFX 版本得到的结果相同。

或者必须以不同的方式检索触摸事件?

我认为除了破解 JavaFX 核心之外,没有其他方法可以检索它们。该实现位于 JavaFX 库代码中,无法通过公共 API 进行配置。

对于某些平台(例如 iOS),触摸事件似乎是通过标准事件过滤器生成和路由的。

但对于其他平台,其中有特定的代码可以在某些情况下忽略 TouchEvents。至少对于 17.0.0.1 版本,在 JavaFX 框架中检测到 TouchEvent 时会被故意忽略。当您的手指触摸 Windows 操作系统设备上的触摸屏时,它们不会路由到用户 JavaFX 应用程序代码。请注意,在这种情况下,触摸将被视为 MouseEvents 并相应地执行操作 (AFAICT)。

因此,您需要自定义和更改核心 JavaFX 代码,以获取 Windows 操作系统平台上的触摸事件,方法是自行破解 JavaFX 库代码,或者将更改集成到未来 JavaFX 版本的库中。

关于 JavaFX TouchEvent 实现(及其更改)的思考

也许这个问题已经得到了彻底的考虑,并且 JavaFX 17.0.0.1 中的平台代码正在按设计运行。也许人们的想法是,当前的行为虽然不理想,但却是合理的妥协。也许结果可能是文档更新以更好地描述 TouchEvent 行为,而不是功能更新来更改它。

但在我看来,从目前的行为来看,当 JavaFX 在某些平台(例如 Windows 操作系统)上运行时,JavaFX 中的 TouchEvent 处理功能的设计和实现似乎存在问题。我不知道如何准确分类或解决这些问题。

如果您希望与 JavaFX 开发人员合作,我建议您加入openjfx-dev https://mail.openjdk.java.net/mailman/listinfo/openjfx-dev邮件列表并描述那里的问题(链接回这个问题)并开始讨论可以采取什么措施。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JavaFX 没有 TouchEvents 的相关文章

  • 如何将变量的全部内容发送/导出到文本文件/xml 文件/剪贴板?

    我想将实例的内容 最好以树形形式 发送给某人 打印屏幕是不行的 因为类太复杂了 您需要将输出转回实例吗 在这种情况下 其他答案都是正确的 如果您只想手动检查实例的内容 理想情况下您的类都将实现toString 你可以将其重定向到一个文件 如
  • 将一种类型的对象声明为另一种类型的实例有什么好处? [复制]

    这个问题在这里已经有答案了 可能的重复 Base b2 new Child 是什么意思 表示 https stackoverflow com questions 4447924 what does base b2 new child sig
  • 单元测试组合服务方法

    我正在为一个类编写 junit 单元测试 该类使用以下方法实现公开的接口 public Set
  • 如何提取文件 jre-9/lib/modules?

    In JRE 9 lib目录 至少在 Windows 上 有一个名为modules其大小约为107 MB 是否可以提取该文件或在其中列出 java 模块 我可以看到一个名为jmod可以在jdk 9 bin jmod exe 但那是为了阅读
  • 在命令行java中突出显示文本[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我有一项任务是重新创建 unix cal 程序 除了一部分之外 相当简单 今天 它突出显示了该数字 我不知道该怎么做 关于如何在 Ja
  • 项目缺少所需的注释处理库

    我的 Eclipse IDE 突然在问题视图中显示 xxxx 项目缺少所需的注释处理库 xxxx M2 REPO 中的一些旧 jar 我用谷歌搜索 没有找到任何答案 为什么我的项目使用旧的 jar 以及错误来自哪里 To remove th
  • 尝试获取屏幕上绘制的每个随机圆圈的 x、y 坐标

    您好 我正在制作一款游戏 该游戏将在屏幕上创建随机圆圈 随机创建的圆圈的值为红色或绿色 我的问题是 我希望不仅能够确定用户何时单击其中一个圆圈 而且还能够确定他们最终单击的圆圈 红色或绿色 下面是我的代码 我的主要问题是试图找到将要绘制的圆
  • 检查 IPv4 地址是否在私有范围内

    在 Python 中 使用 IPy 模块您可以执行以下操作 gt gt gt ip iptype PRIVATE 有没有一个库或简单的方法可以在 Java 中执行相同的操作 似乎不完全是但是InetAddress有一些 isXX 方法 例如
  • JTextField 和 JTextArea

    JTextField 和 JTextArea 有什么不同 是否可以在一个班级中使用这两个班级 总之 JTextField 是单行文本字段 而 JTextArea 可以跨越多行 文档中清楚地解释了这些差异 文本区 http docs orac
  • 在 Junit 测试中使用 ReflectionTestUtils.setField()

    我是 JUnittesting 的新手 所以我有一个问题 谁能告诉我为什么我们使用ReflectionTestUtils setField 在我们的 Junit 测试示例中 正如评论中提到的 java 文档很好地解释了用法 但我还想给你们举
  • Java 中的 ExecuteUpdate sql 语句不起作用

    我正在学习如何将 SQL 与 Java 结合使用 我已成功安装 JDBC 驱动程序 并且能够从数据库读取记录并将其打印在屏幕上 我的问题发生在尝试执行更新或插入语句时 没有任何反应 这是我的代码 问题所在的方法 public static
  • 将现有 eclipse 项目导出到 war 文件时出现“模块名称无效”

    我正在尝试将现有 Eclipse 项目导出到 war 文件 但无论我在 WAR Export 对话框页面中输入什么 系统总是返回 模块名称无效 我不知道如何解决这个问题 谢谢您的帮助 我有同样的问题 我修复了它 请按照以下步骤操作 您可以创
  • 更改 JComboBox 中滚动条的大小

    有谁知道如何手动更改 jComboBox 中的滚动条大小 我已经尝试了一大堆东西 但没有任何效果 好吧 我明白了 您可以实现 PopUpMenuListener 并使用它 public void popupMenuWillBecomeVis
  • Jetty Plugin 9启动不喜欢icu4j-2.6.1.jar

    我对 mortbay 的 Maven jetty 插件 6 有相同的配置
  • java swing:向 JTree 项目添加自定义图形按钮

    我想在 JTree 中的项目右侧添加一个带有小图标的附加按钮 这可以做到吗 如果是这样 怎么办 thanks Clamp 你在这方面成功了吗 我想做同样的事情 但很难让 JButton 响应用户 设置渲染器以显示按钮的过程很顺利 但所有鼠标
  • 在循环中按名称访问变量

    我正在开发一个 Android 项目 并且有很多可绘制对象 这些绘图的名称都类似于icon 0 png icon 1 png icon 100 png 我想将这些可绘制对象的所有资源 ID 添加到整数 ArrayList 中 对于那些不了解
  • Android项目中使用java获取电脑的IP地址

    我在用ksoap2 android http code google com p ksoap2 android 我需要使用java获取IP地址 这样我就不必每次都手动输入它 我所说的 IP 地址是指 例如 如果我这样做ipconfig使用命
  • CXF:通过 SOAP 发送对象时如何排除某些属性?

    我使用 Apache CXF 2 4 2 当我将数据库中的某个对象返回给用户时 我想排除一些属性 例如密码 我怎样才能做到这一点无需创建临时的班级 有这方面的注释吗 根据 tomasz nurkiewicz 评论我应该使用 XmlTrans
  • Android Google 地图无法在当前主题中找到样式“mapViewStyle”

    添加谷歌地图视图时 我扩展了MapView 使用xml编辑器将其添加到活动中 并将我的谷歌地图api密钥手动添加到布局xml文件中 我的权限在清单文件中允许互联网 我想知道的是 在 xml 编辑器中 我收到错误 无法在当前主题中找到样式 m
  • 将数组值导出到 csv 文件 java

    我只需要帮助将数组元素导出到 csv 文件 我不知道我的代码有什么问题 任何帮助将不胜感激 谢谢 for int index 0 index lt cols length index FileWriter fw new FileWriter

随机推荐

  • 野牛转移而不是减少。减少/减少错误

    用我的语言我可以写 a 1 b 2 if true else if true Here is the problem else 我的语法不支持语句之间的换行符 else 只能与 if 一起使用 当我在规则中添加可选NL时 IfExpr IF
  • WPF 将文本从一个窗口传递到另一个窗口

    我有一个主窗口 它有一个按钮 当我按下主窗口按钮时 它将打开子窗口 在子窗口中 我有一个文本框 当我输入文本并单击子窗口中的添加按钮时 文本应显示在主窗口上 我该如何实现这一目标 提前致谢 您可以创建 MainWindow 类的参数化构造函
  • 调试 TestNG 配置失败

    我正在从 Ant 运行 TestNG 我正在使用我自己的测试监听器 我正在重构代码 有一段时间我得到了 testng Total tests run 7 Failures 0 Skips 7 testng Configuration Fai
  • 对重载函数的不明确调用

    我有两个功能 void DoSomething const tchar apsValue void DoSomething size t aiValue 现在我想将 0 作为 size t 传递 DoSomething 0 编译器抛出错误
  • Meteor:“=> 退出,代码:8”错误

    刚刚开始使用 Meteor 按照中提供的教程进行操作发现流星 https www discovermeteor com 实现第 3 章的代码后 我不断收到以下错误 W20150714 18 47 36 539 7 STDERR W20150
  • 优化多个OR查询

    我有一个数据库表 我需要验证用户是否输入了相同或部分相同的信息 这就是我的想法 数据库布局 rec id pk user id name phone address 1 address 2 zip company co phone co a
  • iPhone崩溃日志中的内存地址代表什么意思?

    我今天一直在查看 iPhone 应用程序生成的崩溃日志 Thread 0 Crashed 0 libobjc A dylib 0x3002d7da 0x3002b000 10202 1 UIKit 0x31ec4abc 0x31e4d000
  • 为服务/数据/缓存部署多个实例的好处

    尽管我有很多编写代码的经验 我真的没有太多部署经验 我正在编写一个项目 使用 mongodb 进行持久化 使用 redis 进行元缓存 并使用 play 来提供页面服务 我正在决定是否购买专用服务器 还是从 amazon linode 购买
  • 在 WebViewClient 中启用通用 JavaScript

    在谷歌搜索答案时 似乎我并不是唯一一个遇到似乎无法解决的问题的人 我成功地使用自定义 WebViewClient 创建了一个 WebView 这使得我可以拥有一个进程对话框 并在无法加载 URL 时显示错误消息 但这会给 JavaScrip
  • 出现错误 #1221 - UNION 和 LIMIT 的使用不正确

    我正在尝试使用这两个查询进行联合查询union在查询之间但出现错误 121 UNION 和 LIMIT 的使用不正确 请帮助我进行联合查询以获得这两个查询的结果 query1 SELECT t1 TraineeID t2 attnDate
  • 无需事务即可获取数据

    下面是 spring transaction 的示例代码片段 我的问题 相同的会话将用于获取第 1 行和第 2 行的实体吗 我的理解 我相信是的 这将由春季交易来保证 Transactional public void method1 fe
  • 如何为 f.select 表单字段设置空白值

    我使用以下内容允许我的用户在他们的个人资料中选择他们的性别 如果没有任何内容传递到 user sex 列 我将如何创建列表默认的空白值 我只是将男性或女性作为字符串传递 目的是我想要一个空白值 以便验证可以确保他们知道必须选择它 有两种可能
  • MySQL 获取两个用户之间的对话

    我有一个名为 private messages 的 SQL 表 其中包含字段 id from to message stamp 标记字段对应于消息的日期 那么我需要什么查询 1 获取两个用户之间的对话 按日期排序 我已经尝试过查询 SELE
  • Hive 中的 Presto UNNEST 函数相当于什么

    急板有一个UNNEST函数分解由数组组成的列 Hive 有类似的吗 请参阅文档UNNEST急速功能here https prestodb io docs current sql select html Use lateral view ou
  • 使用 DTO 时,Automapper 和 Nhibernate 反映正在更新的域对象中 DTO 子集合的更改

    我对这个设计不是很熟悉 但我希望得到一些指导 我有一个后端服务 它将 DTO 发送到 WPF 智能客户端 在 WPF 智能客户端上 用户将更改 删除和修改项目 然后将更改发送回 客户端 gt 服务器 举个例子 目前我正在处理客户详细信息表单
  • 无法让 dokka 在 gradle/android 项目上生成 kotlin 文档

    我正在关注 gradle 插件部分https github com Kotlin dokka https github com Kotlin dokka 我还尝试了 dokka gradle example 中的示例https github
  • Spring结果集提取器

    如何使用ResultSetExtractor从数据库检索数据 这里我使用oracle 10g作为后端 如果从员工表中搜索员工详细信息 哪个更好ResultSetExtractor or RowMapper 从 java 8 开始 还可以使用
  • 无继承的 OOP 重用:这在“现实世界”中有多实用?

    本文描述了一种我觉得很有趣的 OOP 方法 如果对象存在为 封装和通信 通过消息 如果代码重用了怎么办 与继承无关 但是 使用组合 委托 甚至 老式的辅助对象或任何 程序员认为合适的技术 本体并没有消失 但它 与实现分离 最令我震惊的是无需
  • 如何使用 Spring 的 JDBCTemplate 有效执行 IN() SQL 查询?

    我想知道是否有一种更优雅的方法来使用 Spring 的 JDBCTemplate 进行 IN 查询 目前我正在做类似的事情 StringBuilder jobTypeInClauseBuilder new StringBuilder for
  • JavaFX 没有 TouchEvents

    在我的 Windows Surface Go 2 平板电脑上 我无法检索任何 多点触控 触摸事件 我尝试了几个 Java FX 版本 即使使用 JavaFX 17 及更早版本 也不会生成 TouchEvents 事件 仅生成鼠标事件 是否需