JavaFX 17 之后 Leaflet 在 WebEngine 中不起作用
我有一个使用 JavaFX 16 制作的应用程序,其中包含一个 WebView,用于使用 Leaflet JS 库显示交互式地图.
I have an application made with JavaFX 16 which contains a WebView used to show an interactive map using the Leaflet JS library.
当我尝试转换到 JavaFX 17 时遇到问题,交互式地图不再起作用(它无法移动或单击,但可以滚动).我在使用 Leaflet 的 OpenStreetMap 网站的一个最小示例中重现了该错误:
I have a problem when I try to transition to JavaFX 17, the interactive map does not work anymore (it cannot be moved nor clicked, but it can be scrolled). I reproduced the bug on a minimal example with the OpenStreetMap website that uses Leaflet :
package test;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
public class App extends Application {
@Override
public void start(Stage stage) {
WebView webView = new WebView();
webView.getEngine().load("https://www.openstreetmap.org/");
Scene scene = new Scene(new StackPane(webView), 640, 480);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
OpenStreetMap 网站上的交互式地图渲染正确,可以放大但不能移动.
The interactive map on the OpenStreetMap website is rendered correctly and can be zoomed in but it cannot be moved.
我正在使用 Gradle 下载 JavaFX,这是我的 build.gradle :
I am using Gradle to download JavaFX, this is my build.gradle :
plugins {
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.10'
}
repositories {
mavenCentral()
}
javafx {
version = "17"
modules = [ 'javafx.controls', 'javafx.web']
}
application {
mainClass = 'test.App'
}
我用版本重现了这个错误:
I reproduced the bug with versions :
- 18-ea+5
- 17.0.1
- 17
- 17-ea+2
但地图适用于版本:
- 16
- 15
看来是版本 17 带来了问题.
So it seems that version 17 brings the issue.
我还在 macOS 12(M1 使用 x86 JavaFX 和 Rosetta)和 Ubuntu 20 上重现了该错误.因此,macOS 上的 JavaFX 似乎不是问题.
Also I reproduced the bug on macOS 12 (M1 using x86 JavaFX with Rosetta) and on Ubuntu 20. So it does not seem to be an issue with JavaFX on macOS.
其他交互式地图,如谷歌地图、苹果地图和必应地图,使用与上述相同的代码,并且 MapBoxGL 不工作,因为不支持 WebGL.所以看来这个问题与Leaflet有关.
Other interactive maps such as Google map, Apple map and Bing map, worked with the same code as above, and MapBoxGL does not work because WebGL is not supported. So it seems that the issue is related to Leaflet.
所以我想知道这是否是一个已知问题,是否其他人也有同样的问题,还是我这边的问题?
So I wonder if it is a known issue, if anyone else has the same issue, or if it is an issue on my side ?
推荐答案
很高兴看到我们有更多人在研究这个问题.
It's nice to see that there are more of us looking into this.
我做了一些更深入的调查,并能够查明问题,从而导致我找到一种解决方法/hack,这使得拖动 Leaflet 地图在 WebKit (Java FX 17) 中正常工作.
I did some deeper investigation and was able to pinpoint the problem which consequently lead me to a workaround/hack which makes dragging of Leaflet map to work fine in WebKit (Java FX 17).
调查结果:
这绝对是回归,因为在 17 之前的 JavaFX 版本中拖动 Leaflet 地图可以正常工作.所以正如 @José 指出的那样,这很可能与 WebKit 610.2 升级有关(JDK-8259635).
好像和PointerEvent 在 Java FX 17 的情况下似乎无法正确生成.以下示例在使用鼠标按钮向下拖动时输出 1.但是对于 Java FX 17 中的 WebView/WebKit,它输出 0.请注意,在 Java 之前的 JavaFX WebView/WebKit 版本中,e.buttons
值正确设置为 1外汇 17.
It seems to be related to PointerEvent which seems to not be properly generated in the case of Java FX 17. Following example outputs 1 when dragging with the mouse button down. But it outputs 0 in the case of WebView/WebKit inside Java FX 17. Note that e.buttons
value is properly set to 1 in JavaFX WebView/WebKit versions prior to Java FX 17.
<!doctype html>
<body style="height: 200px">
<p>Click and drag & observe the console output</p>
<script>
var onMove = function (e) {
console.log("e.buttons: " + e.buttons);
}
var body = document.getElementsByTagName('body')[0];
document.addEventListener("pointermove", onMove, false);
</script>
</body>
根据调查结果没有.2 我能够识别阻止传单地图移动(在被拖动时)的 JS 代码.在传单 1.7.1 中.实际上是这个
if
表达式导致地图 not 被移动(因为PointerEvent.buttons
被 Java FX 17 错误地设置为 0):https://github.com/Leaflet/Leaflet/blob/bd88f73e8ddb90eb945a28bc1de9eb07f7386118/src/dom/DomEvent.Pointer.js#L104
Based on the finding no. 2 I was able to identify the JS code which prevent the Leaflet map from moving (while being dragged). In Leaflet 1.7.1. it's actually this
if
expression which consequently causes map to not be moved (becausePointerEvent.buttons
is wrongfully set to 0 by Java FX 17): https://github.com/Leaflet/Leaflet/blob/bd88f73e8ddb90eb945a28bc1de9eb07f7386118/src/dom/DomEvent.Pointer.js#L104
我已经通过 Oracle 错误报告系统(JDK-8278150).这个问题是错误的".已关闭 - 我已经向他们提供了此答案中解释的信息,因此他们有望重新打开它或在 JDK-8276859.
I've already reported this through the Oracle bug report system (JDK-8278150). The issue was "mistakenly" closed - I've already provided them with the info explained in this answer so they will hopefully re-open it or tackle it under JDK-8276859.
解决方法(传单 1.7.1):
解决方法/破解使 Leaflet 地图再次工作:
Workaround/hack to make Leaflet map work again:
注释掉 if
表达式:https://github.com/Leaflet/Leaflet/blob/bd88f73e8ddb90eb945a28bc1de9eb07f7386118/src/dom/DomEvent.Pointer.js#L104
这使得 Leaftlet 地图在被拖入 Java FX 17 WebView 时可以正确移动 - 但请认为这更像是一个 hack 以使其再次工作,因为这没有经过彻底测试...
This makes the Leaftlet map to move properly while being dragged in the Java FX 17 WebView - but please consider this more like a hack to make it work again as this was not tested out thoroughly...
更新
这个问题似乎随着最新的 尽管 JavaFX WebView/WebKit 中存在回归,但 Leaflet 的主分支仍然存在(任何人都可以确认这一点吗?).
This issue seems to be gone with the latest master branch of Leaflet despite regression in JavaFX WebView/WebKit remains (can anyone please confirm this?).
相关文章