передача значений в JavaFX из javascript

Так как это мой первый пост, прошу прощения за неточности. Моя проблема, я хочу передать значение из функции javascript в Javafx в методе инициализации

public void initialize(URL arg0, ResourceBundle arg1) {

    // TODO Auto-generated method stub
    final URL urlGoogleMaps = getClass().getResource("googlemaps.html");
    System.out.println("fjdsoij");
    browser.getEngine().load(urlGoogleMaps.toExternalForm());
    WebEngine webEngine = browser.getEngine(); 
    webEngine.getLoadWorker().stateProperty().addListener(
            new ChangeListener<State>(){

                @Override
                public void changed(ObservableValue<? extends State> ov, State oldState, State newState) {
                    if(newState == State.SUCCEEDED){
                        JSObject window = (JSObject)webEngine.executeScript("window");
                        window.setMember("app", new JavaApplication());

                    }
                }
            });
}

public class JavaApplication{
    public void calljavascript( int lengthInMeters){

        System.out.println(lengthInMeters);
    }
}   

}

и часть javascript выглядит так

   function initialize() {
  var mapOptions = {
    zoom: 3,
    center: new google.maps.LatLng(0, -180),
    mapTypeId: google.maps.MapTypeId.TERRAIN
  };

  var map = new google.maps.Map(document.getElementById('map-canvas'),
      mapOptions);

  var flightPlanCoordinates = [
    new google.maps.LatLng(37.772323, -122.214897),
    new google.maps.LatLng(21.291982, 157.821856)

  ];
  var flightPath = new google.maps.Polyline({
    path: flightPlanCoordinates,
     //geodesic: true,
    strokeColor: '#FF0000',
    strokeOpacity: 1.0,
    strokeWeight: 2
  });
var lengthInMeters = google.maps.geometry.spherical.computeLength(flightPath.getPath());

  flightPath.setMap(map);
   alert("polyline is "+lengthInMeters+" long");
   app.calljavascript(lengthInMeters);
}

google.maps.event.addDomListener(window, 'load', initialize);

Значение, которое я хочу передать, - это lengthInMeters в методе calljavascript любые идеи? спасибо заранее


person n00bfighter    schedule 03.11.2014    source источник


Ответы (1)


Я пробовал упрощенную версию вашего кода:

    WebEngine webEngine = browser.getEngine();

    webEngine.getLoadWorker().stateProperty().addListener((ov,oldState,newState)->{
        if(newState==State.SUCCEEDED){
            JSObject window = (JSObject) webEngine.executeScript("window");
            window.setMember("app", new JavaApplication());
        }
    });
    webView.getEngine().loadContent("<html>\n"
            + " <script>function initialize() {"
            + " var lengthInMeters = 5; " 
            + " app.calljavascript(lengthInMeters);"
            + "} </script> "
            + "    <body onLoad=\"initialize()\">Hi!\n"
            + "    </body>\n"
            + "</html>");

и это не работает.

В вашем случае и в моем подходе setMember() вызывается после загрузки сети, поэтому initialize() вызывается до методом load. Следовательно, app.calljavascript() терпит неудачу.

Решение такое:

    WebEngine webEngine = browser.getEngine();
    JSObject window = (JSObject) webEngine.executeScript("window");
    window.setMember("app", new JavaApplication());

    browser.getEngine().loadContent("<html>\n"
            + " <script>function initialize() {"
            + " var lengthInMeters = 5; " 
            + " app.calljavascript(lengthInMeters);"
            + "} </script> "
            + "    <body onLoad=\"initialize()\">Hi!\n"
            + "    </body>\n"
            + "</html>");

Обратите внимание, что мы устанавливаем элемент до загрузки веб-содержимого.

ИЗМЕНИТЬ

Я создал более подробный ответ здесь.

person José Pereda    schedule 03.11.2014
comment
трепло, это было решением именно сейчас, все работает нормально, спасибо, чувак :) - person n00bfighter; 04.11.2014
comment
это не работает при последующих вызовах нагрузки. больше невозможно установить элементы перед загрузкой. Есть ли лучшее решение? - person mohamnag; 01.03.2016
comment
Пожалуйста, разместите новый вопрос по этому решению - person José Pereda; 01.03.2016
comment
ВАЖНОЕ ПРИМЕЧАНИЕ. Начиная с Java 8u101 существует ошибка. new JavaApplication() должен быть определен в частном поле, чтобы предотвратить его удаление сборщиком мусора. Сначала может показаться, что локальная переменная работает, но случайно перестает работать. - person Eric Duminil; 08.03.2018
comment
У меня та же проблема, что и у @mohamnag, мост работает для загрузки первой страницы, но не для последующих. - person Guillaume F.; 29.12.2019