当我单击JavaFX应用程序的按钮时,我一直试图在地图上显示一个标记。当我点击那个按钮时,我把位置写在JSON文件中,这个文件会被加载到包含地图的html文件中。问题是,当我在浏览器中打开html页面时,它工作得很好,但在JavaFX的web视图中什么都没有发生,我不知道为什么!

这是html文件:

<!DOCTYPE html>
<html>
  <head>
  <title>Simple Map</title>
  <meta name="viewport" content="initial-scale=1.0">
  <meta charset="utf-8">
  <style>
  /* Always set the map height explicitly to define the size of the div
   * element that contains the map. */
  /*#map {
    height: 100%;
  }*/
  #map{width:100%;height:100%;margin:auto;}
  /* Optional: Makes the sample page fill the window. */
  html, body {
    height: 100%;
    margin: 0;
    padding: 0;
  }
</style>
</head>
<body>
<div id="map"></div>
<script>
  var map;
  var marker;
  // Multiple Markers
  var markers = [];
  var pos = {lat: 46.662388, lng: 0.3599617};
  var itinerary_markers = [];

  function initMap() {

    var currentLat, currentLng;//Latitude et longtitude courante

    $.ajax({
      url: 'https://maps.googleapis.com/maps/api/geocode/json?address=My+ADDRESS&key=MY_KEY',
      async: false,
      dataType: 'json',
      success: function (data) {
        currentLat = data.results[0].geometry.location.lat;
        currentLng = data.results[0].geometry.location.lng;
      }
    });

    map = new google.maps.Map(document.getElementById('map'), {
      center: {lat: currentLat, lng: currentLng},
      zoom: 15,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    });


    /*MARQUEUR*/ 
    $.ajax({
        async: false,
        url: 'test.json',
        data: "",
        accepts:'application/json',
        dataType: 'json',
        success: function (data) {
            for (var i = 0; i < data.hydrants.length; i++) {
                markers.push( data.hydrants[i]);
            }
        }
    });

      var posi = new google.maps.LatLng(markers[0].Lat, markers[0].Lng);
      marker = new google.maps.Marker({
          position: posi,
          map: map,
          //title: markers[i][0]
          title: markers[0].Name
        });

  }
</script>

<script
    src="https://code.jquery.com/jquery-3.2.1.min.js"
    integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
    crossorigin="anonymous">
</script>


<script src="https://maps.googleapis.com/maps/api/js?key=MY_KEY&callback=initMap&language=fr"
async defer></script>

</body>
</html>

当我点击按钮,我填充JSON文件(这是完美的工作),然后我执行这个刷新webview:

this.webView.getEngine().load(getClass().getResource("/data/index.html").toString());

如前所述,当我在浏览器上打开文件时,我看到了预期的结果,但我不知道JavaFX有什么问题。 如果有更好的办法请告诉我。

编辑:

我通过使用executeScript()方法将数据(GPS坐标)从JavaFX直接发送到Javascript找到了解决方案,因此我不需要json文件作为两个平台之间的桥梁。 下面是代码的示例:

eng.executeScript("updateMarker(" + lat + ", " + lng + ")");//eng is a WebEngine instance

这里是Javascript:

/*The initial latitude and longtitude*/
var currentLat = the latitude;
var currentLng = the longtitude;

function initMap() {

    map = new google.maps.Map(document.getElementById('map'), {
      center: {lat: currentLat, lng: currentLng},
      zoom: 15,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    });

    var posi = new google.maps.LatLng(currentLat, currentLng);
    marker = new google.maps.Marker({
        position: posi,
        map: map,
        visible: false
    });
  }

/*The method that is I call from JavaFX*/
function updateMarker(_lat, _lng){
    marker.setPosition({lat: _lat, lng: _lng});
    map.setCenter(new google.maps.LatLng(_lat, _lng));
    marker.setVisible(true);
  }

谢谢你的评论和回答,还有reddit的特别枪战。


如果要我猜的话,有两件事正在发生:

要么是A)你的javaFX不支持跨站点ajax调用,要么是B)它没有等待异步ajax响应,要么是其他地方出了问题。

让我们一起做一些测试。首先,我们可以清理这个嵌套ajax调用?然后,您是否可以添加一些console.log语句来找出每个语句发回的内容?如果你错过了一些输出,我们知道哪里出了问题,这将帮助我们解决问题。

注意,我将success改为“done”,因为success有点过时了,并且所有内容都被嵌套以消除是否有空白被发送到下一次调用的问题(同步性问题):

$.ajax({
    url: 'https://maps.googleapis.com/maps/api/geocode/json?address=My+ADDRESS&key=MY_KEY',
    async: false,
    dataType: 'json'
}).done(function(data) {
    currentLat = data.results[0].geometry.location.lat;
    currentLng = data.results[0].geometry.location.lng;
    console.log(currentLat);
    console.log(currentLng);
    // Multiple Markers
    var markers = [];
    var pos = {lat: 46.662388, lng: 0.3599617};
    var itinerary_markers = [];
    var map = new google.maps.Map(document.getElementById('map'), {
        center: {lat: currentLat, lng: currentLng},
        zoom: 15,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    });
    console.log(map);
    /*MARQUEUR*/ 
    $.ajax({
        async: false,
        url: 'test.json',
        data: "",
        accepts:'application/json',
        dataType: 'json'
    }).done(function(data) {
        for (var i = 0; i < data.hydrants.length; i++) {
            markers.push( data.hydrants[i]);
        }
        console.log(markers);
        var posi = new google.maps.LatLng(markers[0].Lat, markers[0].Lng);
        console.log(posi);
        var marker = new google.maps.Marker({
            position: posi,
            map: map,
            //title: markers[i][0]
            title: markers[0].Name
        });
        console.log(marker);
    }).fail(function(jqXHR, testStatus){
        console.log(textStatus);
    });
}).fail(function(jqXHR, testStatus){
    console.log(textStatus);
});

下面是将console.log输出输出到System的链接。如果这是一个问题,在Java中: JavaFX 8 WebEngine:如何从javascript获取console.log()到System。在爪哇?

...reddit向你问好。


行内:

this.webView.getEngine().load(getClass().getResource("/data/index.html").toString());

我会再次检查文件的路径是否正确。阅读StackOverflow上的其他答案,看起来这应该是相对于包根,或者带或不带先导'/'。即getResource(“数据/ index . html”)。但是,也许您已经看到了与getResource()相关的错误…

出于调试目的,我接下来要注释掉写JSON的部分手动写一些好的JSON,让它显示在webView中。活动部件越少越好。如果你能让它与你预先编写的JSON一起工作,那么你可以假设它是你用Java编写的JSON的一些问题,然后它被加载到HTML。

编辑:我挖掘得更深了一点。这可能是完全错误的,但也许你可以尝试从Java手动调用initMap()函数,你的web浏览器通常调用onload。如何调用一个JavaScript函数从JavaFX WebView按钮点击?有更多细节。尝试this.webView.getEngine () .executeScript(“initMap () ");在你用按钮编辑JSON之后。

顺便说一句,将initMap分割为initMap和updateMap函数,用于开始制作地图,然后在地图上设置标记,这可能是有意义的。尽管这几乎没有破坏任何东西。


如果您使用鼠标滚轮缩小或放大地图时出现了标记,那么您将遇到与我相同的问题。

尝试手动缩放mapview来恢复标记。我还必须在从方向服务显示路线时使用这种技术,否则路标标记就不能正确显示。

这是我的Javafx控制器类中的代码:

KeyFrame kf1 = new KeyFrame(Duration.seconds(0.75), e -> map.setZoom(map.getZoom() - 1));
KeyFrame kf2 = new KeyFrame(Duration.seconds(1.5), e -> map.setZoom(map.getZoom() + 1));
Timeline timeline = new Timeline(kf1, kf2);
Platform.runLater(timeline::play);

这是使用GMapsFX,它只是一个针对JavaFX WebView上的javascript引擎调用的精简Java包装。希望能有所帮助。