Карти Google і JavaFX: Показуйте маркер на карті після натискання кнопки JavaFX


359

Я намагаюся відобразити маркер на карті, коли натискаю кнопку кнопки програми JavaFX. Отже, що відбувається, коли я натискаю на цю кнопку, я записую позицію у файлі JSON, цей файл буде завантажений у файл html, який містить карту. Проблема полягає в тому, що вона прекрасно працює, коли я відкриваю сторінку html у браузері, але в веб-перегляді JavaFX нічого не відбувається, і я не знаю чому!

Це файл 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 (який прекрасно працює), а потім виконую це, щоб оновити веб-перегляд:

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

Як я вже говорив раніше, коли я відкриваю файл у браузері, я бачу очікуваний результат, але не знаю, у чому проблема з JavaFX. Якщо є кращий спосіб зробити це, будь ласка, скажіть мені.

Редагувати:

Я знайшов рішення проблеми, переправивши безпосередньо дані (GPS координати) з JavaFX в Javascript методом ExecuteScript (), тому мені не потрібен файл 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);
  }

Дякуємо за ваші коментарі та відповіді та спеціальну перестрілку для редагування.



1
Хоча сценарій написаний не найкращим чином, з цим не здається нічого поганого. Є кілька можливостей, які можуть змусити його не працювати. Переконайтеся, що новий маркер доданий у верхній частині файлу json. Перейдіть cache: falseдо виклику Ajax, якщо він є кешованим, і переконайтеся, що ви орієнтуєтесь на потрібний файл. Також деякі журнали тут і там допоможуть визначити проблему.
Gökhan Kurt

1
Можливо, у JavaFX виникають проблеми з використанням ajax для отримання дзвінків / даних з кінцевих точок, які не обслуговуються HTTP, як-от ваш test.json?
Себастьян

@Sebastian Що мене зводить з розуму, це те, що коли я відкриваю додаток, файл json завантажується правильно, і я бачу очікуваний результат. Проблема полягає в тому, що коли я оновлюю файл json з іншим значенням (поки програма відкрита), він просто не хоче оновитись, щоб відобразити новий маркер! Так що проблем з дзвінками Ajax немає. Але це може бути справою зворотного дзвінка? тому що initMap () викликається під час завантаження сторінки
Чандлер Бінг

@ GökhanKurt Ви прочитали б відповідь вище
Чандлер Бінг

Відповіді:


70

Якби мені довелося здогадатися - відбувається одна з двох речей:

Або A) ваш javaFX не підтримує виклики Ajax між веб-сайтами, або B) він не чекає асинхронної відповіді на ajax / щось інше йде не так.

Тож давайте разом зробимо тестування. По-перше, чи можемо ми це почистити, щоб вбудувати дзвінки в Аякс? Потім ви можете додати деякі консолі.log заяви, щоб дізнатися, що кожен надсилає назад? Якщо ви пропустите якийсь результат, ми знаємо, куди йде не так, і це допоможе нам виправити речі.

Зауважте, що я змінив успіх на доповнення "зроблено", оскільки успіх трохи застарів, і все вкладено, щоб усунути питання про те, чи надсилаються будь-які заготовки на наступні дзвінки (проблеми синхронічності):

$.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.out на Java, якщо це проблема: JavaFX 8 WebEngine: Як отримати console.log () з javascript до System.out у Java?

... Також привіт від reddit.


Привіт там, тож ви вважаєте, що проблема в Ajax-дзвінках. Гаразд, я спробую знайти інший спосіб надсилання GPS-позицій на javascript (за допомогою Executescript).
Чендлер Бінг

Ні його не Ajax дзвінки. Проблема полягає в тому, що я не можу оновити веб-перегляд, щоб показати новий маркер. Коли я відкриваю програму, відображається карта, що означає, що дзвінки ajax справно працюють.
Чендлер Бінг

18

У рядку:

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

Я б спробував двічі перевірити правильність шляху до файлу. Читаючи інші відповіді на StackOverflow, схоже, що це повинно бути відносно кореня пакета і з або без провідного '/'. тобто getResource("data/index.html"). Але знову ж таки, можливо, ви вже бачили б помилки, пов'язані з getResource()...

Наступним моїм переходом до налагодження буде прокоментувати частину, де ви пишете JSON і просто вручну написати хороший JSON і просто спробувати його відобразити у веб-перегляді. Чим менше рухомих деталей, тим краще. Якщо ви можете змусити його працювати з попередньо написаним JSON, ви можете припустити, що це певна проблема з JSON, який ви пишете з Java, а потім він завантажується в HTML.

Редагувати: я копав трохи глибше. Знову це може бути абсолютно помилково, але, можливо, ви можете спробувати зателефонувати вручну з initMap()функції Java, яку ваш веб-браузер зазвичай викликає при завантаженні. Як викликати функцію JavaScript з натискання кнопки JavaFX WebView? має ще кілька деталей. Спробуйте this.webView.getEngine().executeScript("initMap()");після редагування JSON кнопкою.

Edit 2 Як і в сторону, теж, можливо , має сенс для розколу initMapв initMapі updateMapфункції для складання карти , щоб почати з , а потім встановити маркери на карті. Хоча це навряд чи щось порушує.


Ні в чому не проблема, я показую карту, коли я відкриваю програму, призначена для цього рядка. Але коли натискаю кнопку, я хочу поставити маркер на карті. Але я не можу оновити карту, щоб показати маркер на ній.
Чендлер Бінг

1
Ах, готча. Я неправильно зрозумів. Ви кажете, що основна сторінка завантажується, але маркери не завантажуються? Чи принаймні карта відображається у вашому веб-перегляді? Я думаю, ви можете бути на чомусь, як ви згадали в initMap вище. Якщо він викликає цю функцію лише під час завантаження сторінки, вона, ймовірно, не отримує правки до json. Вам доведеться оновити сторінку у веб-перегляді або сказати сторінці якось знову зателефонувати в initMap - можливо через ajax? Якщо JavaFX не зможе змусити webView викликати функції JavaScript
Метт

Коли програма відкриється, завантажується все, що існує у файлі json. Але коли я змінюю значення, поки програма відкрита, я хочу оновити веб-перегляд, щоб побачити зміни. Але це просто не працює! У цьому проблема.
Чендлер Бінг

1
Дивіться мою редагування - чи допомагає додавання вручну дзвінка з Java до функції initMap?
Метт

4

Якщо колесо миші використовується для збільшення або зменшення масштабу карти, і маркер з’являється, то у вас виникає та сама проблема, що і я.

Спробуйте вручну збільшити масштаб карти перегляду, щоб відновити маркери. Мені також довелося застосовувати цю техніку під час відображення маршруту від служби маршрутів, інакше маркери маршрутної точки відображаються неправильно.

Це код у моєму класі контролера 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, який є просто тонкою обгорткою Java навколо дзвінка двигуна javascript на JavaFX WebView. Сподіваємось, це допомагає.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.