Google Maps & JavaFX: Zeigen Sie die Markierung auf der Karte an, nachdem Sie auf die JavaFX-Schaltfläche geklickt haben

Lesezeit: 9 Minuten

Benutzer-Avatar
Chandler Bing

Ich habe versucht, eine Markierung auf der Karte anzuzeigen, wenn ich auf eine Schaltfläche meiner JavaFX-Anwendung klicke. Wenn ich also auf diese Schaltfläche klicke, schreibe ich die Position in eine JSON-Datei, diese Datei wird in die HTML-Datei geladen, die die Karte enthält. Das Problem ist, dass es perfekt funktioniert, wenn ich die HTML-Seite im Browser öffne, aber in der Webansicht von JavaFX passiert nichts, und ich weiß nicht warum!

Dies ist die HTML-Datei:

<!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>

Wenn ich auf die Schaltfläche klicke, fülle ich die JSON-Datei (die perfekt funktioniert) und führe dies dann aus, um die Webansicht zu aktualisieren:

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

Wie ich bereits sagte, wenn ich die Datei im Browser öffne, sehe ich das erwartete Ergebnis, aber ich weiß nicht, was das Problem mit JavaFX ist. Wenn es einen besseren Weg gibt, dies zu tun, sagen Sie es mir bitte.

BEARBEITEN:

Ich habe eine Lösung für das Problem gefunden, indem ich die Daten (die GPS-Koordinaten) von JavaFX mit der Methode executeScript() direkt an Javascript gesendet habe, sodass ich keine JSON-Datei als Brücke zwischen den beiden Plattformen benötige. Das ist also ein Beispiel dafür, wie der Code aussieht:

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

Und hier ist das 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);
  }

Vielen Dank für Ihre Kommentare und Antworten und ein besonderes Shootout für reddit.

  • Als Referenz: reddit.com/r/ProgrammerHumor/comments/6e6wu6/…

    – Mateen Ulhaq

    30. Mai 2017 um 19:38 Uhr

  • Obwohl das Drehbuch nicht optimal geschrieben ist, scheint nichts daran auszusetzen. Es gibt einige Möglichkeiten, die dazu führen können, dass es nicht funktioniert. Stellen Sie sicher, dass die neue Markierung oben in der JSON-Datei hinzugefügt wird. Passieren cache: false zum Ajax-Aufruf, falls er zwischengespeichert ist, und stellen Sie sicher, dass Sie auf die richtige Datei abzielen. Auch einige Protokolle hier und da würden helfen, das Problem zu identifizieren.

    – Gökhan Kurt

    31. Mai 2017 um 6:36 Uhr

  • Könnte es sein, dass das JavaFX-Ding Probleme hat, Ajax zu verwenden, um Anrufe/Daten von nicht über HTTP bedienten Endpunkten wie Ihrer test.json zu empfangen?

    – Sebastian

    31. Mai 2017 um 10:02 Uhr

  • @Sebastian Was mich verrückt macht, ist, dass beim Öffnen der App die JSON-Datei korrekt geladen wird und ich das erwartete Ergebnis sehe. Das Problem ist, wenn ich die JSON-Datei mit einem anderen Wert aktualisiere (während die App geöffnet ist), möchte sie einfach nicht aktualisieren, um die neue Markierung anzuzeigen! Es gibt also kein Problem mit den Ajax-Aufrufen. Aber kann es die Callback-Sache sein? weil die initMap() aufgerufen wird, während die Seite geladen wird

    – Chandler Bing

    31. Mai 2017 um 10:10 Uhr

  • @GökhanKurt würdest du die Antwort oben lesen

    – Chandler Bing

    31. Mai 2017 um 10:14 Uhr

Benutzer-Avatar
David G

Wenn ich raten müsste – eines von zwei Dingen passiert:

Entweder A) Ihr JavaFX unterstützt keine Cross-Site-Ajax-Aufrufe oder B) es wartet nicht auf die asynchrone Ajax-Antwort/etwas anderes läuft schief.

Also lass uns zusammen ein paar Tests machen. Können wir das zunächst bereinigen, um die Ajax-Aufrufe zu verschachteln? Können Sie dann einige console.log-Anweisungen hinzufügen, um herauszufinden, was jeder zurücksendet? Wenn Sie eine Ausgabe verpassen, wissen wir, wo es schief geht, und das hilft uns, die Dinge zu beheben.

Beachten Sie, dass ich success in die ‘done’-Ergänzungen geändert habe, weil success etwas veraltet ist und alles verschachtelt ist, um die Frage zu beseitigen, ob Leerzeichen an die nächsten Aufrufe gesendet werden (Synchronizitätsprobleme):

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

Hier ist ein Link zum Abrufen der Ausgabe von console.log in System.out in Java, falls dies ein Problem darstellt: JavaFX 8 WebEngine: How to get console.log() from javascript to System.out in java?

…Auch hallo von reddit.

  • Hallo, Sie denken also, dass das Problem bei Ajax-Aufrufen liegt. Ok, ich werde versuchen, einen anderen Weg zu finden, um die GPS-Positionen an Javascript zu senden (mit Executescript).

    – Chandler Bing

    31. Mai 2017 um 8:33 Uhr

  • Nein, es sind nicht die Ajax-Anrufe. Das Problem ist, dass ich die Webansicht nicht aktualisieren kann, um die neue Markierung anzuzeigen. Wenn ich die App öffne, wird die Karte angezeigt, was bedeutet, dass die Ajax-Aufrufe einwandfrei funktionieren.

    – Chandler Bing

    31. Mai 2017 um 10:15 Uhr

Benutzer-Avatar
Matt

In der Schlange:

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

Ich würde versuchen, den Pfad zur Datei noch einmal zu überprüfen. Wenn Sie andere Antworten auf StackOverflow lesen, sieht es so aus, als ob dies relativ zum Paketstamm und entweder mit oder ohne dem führenden “https://stackoverflow.com/” sein soll. dh getResource("data/index.html"). Aber andererseits würden Sie vielleicht bereits Fehler im Zusammenhang mit sehen getResource()

Mein nächster Schritt zu Debugging-Zwecken wäre, den Teil, in dem Sie das JSON schreiben, auszukommentieren und einfach ein gutes JSON manuell zu schreiben und einfach zu versuchen, es in der WebView anzuzeigen. Je weniger bewegliche Teile, desto besser. Wenn Sie es mit Ihrem vorgefertigten JSON zum Laufen bringen können, können Sie davon ausgehen, dass es sich um ein Problem mit dem JSON handelt, das Sie mit Java schreiben und dann in den HTML-Code laden.

Bearbeiten: Ich habe etwas tiefer gegraben. Dies könnte wieder völlig falsch sein, aber vielleicht können Sie versuchen, die manuell aufzurufen initMap() Funktion von Java, die Ihr Webbrowser normalerweise zum Laden aufruft. Wie rufe ich eine JavaScript-Funktion von einem JavaFX-WebView auf einen Button-Klick auf? hat noch ein paar Details. Versuchen this.webView.getEngine().executeScript("initMap()"); nachdem Sie den JSON mit Ihrer Schaltfläche bearbeitet haben.

Bearbeiten 2 Nebenbei kann es auch sinnvoll sein, sich aufzuteilen initMap In ein initMap und updateMap Funktion, um zunächst die Karte zu erstellen und dann die Markierungen auf der Karte zu setzen. Obwohl das kaum etwas kaputt macht.

  • Nein, das ist nicht das Problem, ich zeige die Karte an, wenn ich die App über diese Zeile öffne. Aber wenn ich auf eine Schaltfläche klicke, möchte ich eine Markierung auf der Karte setzen. Aber ich kann die Karte nicht aktualisieren, um die Markierung darauf anzuzeigen.

    – Chandler Bing

    30. Mai 2017 um 22:18 Uhr

  • Ah, erwischt. Ich habe es falsch verstanden. Wollen Sie damit sagen, dass die Basisseite geladen wird, aber keine Markierungen geladen werden? Wird die Karte zumindest in Ihrem WebView angezeigt? Ich denke, Sie sind vielleicht auf etwas gestoßen, wie Sie oben initMap erwähnt haben. Wenn diese Funktion nur beim Laden der Seite aufgerufen wird, werden wahrscheinlich keine Änderungen am JSON vorgenommen. Sie müssten die Seite innerhalb der Webansicht aktualisieren oder der Seite sagen, dass sie initMap irgendwie erneut aufrufen soll – vielleicht über Ajax? Es sei denn, JavaFX kann das WebView dazu bringen, Javascript-Funktionen aufzurufen

    – Matt

    1. Juni 2017 um 6:22 Uhr


  • Beim Öffnen der App wird alles geladen, was in der json-Datei vorhanden ist. Aber wenn ich einen Wert ändere, während die App geöffnet ist, möchte ich die Webansicht aktualisieren, um die Änderung zu sehen. Aber es geht einfach nicht! Das ist das Problem.

    – Chandler Bing

    1. Juni 2017 um 6:38 Uhr

  • Siehe meine Bearbeitung – hilft das Hinzufügen eines manuellen Aufrufs von Java zur initMap-Funktion?

    – Matt

    1. Juni 2017 um 6:42 Uhr

Benutzer-Avatar
Fraser

Wenn Ihr Mausrad zum Verkleinern oder Vergrößern der Karte verwendet wird und die Markierung angezeigt wird, haben Sie das gleiche Problem wie ich.

Versuchen Sie, die Kartenansicht manuell zu zoomen, um die Markierungen wiederherzustellen. Ich musste diese Technik auch anwenden, wenn ich eine Route vom Wegbeschreibungsdienst anzeigen wollte, da sonst die Wegpunktmarkierungen nicht korrekt angezeigt wurden.

Dies ist der Code in meiner Javafx-Controller-Klasse, um dies zu tun:

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

Dazu wurde GMapsFX verwendet, das nur ein dünner Java-Wrapper um JavaScript-Engine-Aufrufe in einem JavaFX-WebView ist. Hoffentlich hilft es.

1316240cookie-checkGoogle Maps & JavaFX: Zeigen Sie die Markierung auf der Karte an, nachdem Sie auf die JavaFX-Schaltfläche geklickt haben

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy