Google Maps & JavaFX: afficher le marqueur sur la carte après avoir cliqué sur le bouton JavaFX

j'ai essayé d'afficher un marqueur sur la carte quand je clique sur un bouton de mon application JavaFX. Donc ce qui se passe quand je clique sur ce bouton, j'écris de la position dans un fichier JSON, ce fichier sera chargé dans le fichier html qui contient la carte. Le problème est qu'il fonctionne parfaitement quand j'ouvre la page html dans le navigateur, mais rien ne se passe dans la vue Web de JavaFX, et je ne sais pas pourquoi !

C'est le fichier 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>

quand je clique sur le bouton, je remplis le fichier JSON (qui fonctionne parfaitement) et j'exécute ceci pour rafraîchir le webview:

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

comme je l'ai déjà dit, lorsque j'ouvre le fichier sur le navigateur, je vois le résultat escompté, mais je ne sais pas quel est le problème avec JavaFX. Si il ya une meilleure façon de le faire s'il vous plaît dites-moi.

EDIT:

j'ai trouvé une solution au problème en envoyant directement les données (les coordonnées GPS) de JavaFX à Javascript en utilisant la méthode executeScript (), donc je n'ai pas besoin d'un fichier json comme pont entre les deux plateformes. Voici donc un exemple de l'apparence du code:

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

et voici le 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);
  }

je vous Remercie pour vos commentaires et vos réponses, et une fusillade à reddit.

353
demandé sur Chandler Bing 2017-05-23 12:08:11

3 réponses

si je devais deviner - une de deux choses se produit:

soit A) votre javaFX ne supporte pas les appels ajax cross site ou B) il n'attend pas la réponse ajax asynchrone/quelque chose d'autre va mal.

alors faisons quelques tests ensemble. Tout d'abord, pouvons-nous nettoyer cela pour emboîter les appels ajax? Puis vous pouvez ajouter une console.enregistrez les déclarations pour savoir ce que chacun renvoie? Si vous ratez une sortie, on sait où elle va. faux et ça nous aidera à arranger les choses.

Note j'ai changé le succès en additions "faites" parce que le succès est un peu dépassé, et tout est imbriqué pour éliminer la question de savoir si des blancs sont envoyés aux prochains appels (problèmes de synchronisation):

$.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);
});

voici un lien pour obtenir la console.la sortie du journal dans le Système.en Java si c'est un problème: JavaFX 8 WebEngine: Comment obtenir la console.journal (le) de javascript au système.dans java?

...Bonjour aussi de la part de reddit.

68
répondu David G 2017-05-30 19:57:19

dans la ligne:

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

j'essaierais de double-vérifier le chemin du fichier est correct. En lisant d'autres réponses sur StackOverflow, il semble que cela soit supposé être relatif à la racine du paquet et soit avec ou sans le '/'. c'est à dire getResource("data/index.html") . Mais, encore une fois, peut-être que vous verriez déjà des erreurs liées à getResource() ...

mon prochain aller à, à des fins de débogage, serait de commenter la partie où vous Ecrire le JSON et juste écrire manuellement un bon JSON et juste essayer de le faire apparaître dans le webView. Moins il y a de pièces mobiles, mieux c'est. Si vous pouvez le faire fonctionner avec votre JSON pré-écrit, alors vous pouvez supposer qu'il y a un problème avec le JSON que vous écrivez avec Java et qu'il est chargé dans le HTML.

Edit: j'ai creusé un peu plus profond. Cela pourrait être totalement faux à nouveau, mais peut-être Pouvez-vous essayer d'appeler manuellement la fonction initMap() à partir de Java que votre navigateur Web appelle normalement onload. comment faire pour appeler une fonction JavaScript à partir d'un JavaFX WebView sur le bouton cliquez? a plus de détails. Essayez this.webView.getEngine().executeScript("initMap()"); après avoir édité le JSON avec votre bouton.

Edit 2 de plus, il serait peut-être judicieux de diviser initMap en une fonction initMap et updateMap pour faire la carte et ensuite placer les marqueurs sur la carte. Si c'est à peine de casser quoi que ce soit.

17
répondu Matt 2017-06-01 06:40:07

si votre souris-roue est utilisé pour zoomer la carte ou dans et le marqueur apparaît, alors vous rencontrez le même problème que j'ai fait.

essayez de zoomer manuellement sur la mapview pour restaurer les marqueurs. J'ai aussi dû utiliser cette technique pour afficher un itinéraire à partir du service des Directions, sinon les marqueurs de points de cheminement ne s'affichaient pas correctement.

C'est le code dans ma classe de contrôleur Javafx pour le faire:

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);

cela utilisait GMapsFX, qui est juste un emballage Java mince autour des appels de moteur javascript sur un JavaFX WebView. Espérons que cela aide.

3
répondu Fraser 2017-06-02 09:45:34