2015-11-08 3 views
1

Я пишу приложение JavaFX, которое взаимодействует с JavaScript, используя WebView и WebEngine (метод .executeScript()).webEngine.executeScript(); Throwing Exception

Вот, у меня есть часть кода из Medow.java, который загружает map.html (содержит JavaScript код), и этот код работает довольно хорошо:

add_button.setOnAction(new EventHandler<ActionEvent>() { 
     @Override 
     public void handle(ActionEvent ea5) { 


      // webEngine.executeScript("document.fun();"); // For Drawing Shapes 
      if (add == false) { 

       webEngine.executeScript("document.fun();"); // For Drawing Shapes 
       add = true; 
      } 
//   } 
      else { 
       webEngine.executeScript("document.reSet();"); // To remove Drawing Shapes 
       add = false; 
      } 

     } 
    }); 

В этом

webEngine.executeScript();

ли Вызов соответствующей функции в JavaScript

Но теперь я хочу, чтобы мой Java код, чтобы вызывать некоторые функции JS, когда программа начинается, поэтому я сразу пишу:

webEngine.executeScript("document.draw();"); 

прямо под/после кода, который загружает файл map.html.

Итак, теперь, как оба из webEngine.execute("document.fun();"); и webEngine.executeScript("document.draw();"); почти одинаковы, я не могу понять, какая разница, это делает, чтобы быть внутри <button>.setOnAction блока и быть вне его, потому что как WebEngine и Webview объявлены как глобальные переменные ,

не может вызывать функцию document.draw() с использованием опций HTML onLoad, потому что мне нужно передать некоторые значения для функции draw from java.

Исключение Вырабатываемые:

netscape.javascript.JSException: TypeError: undefined is not a function (evaluating 'document.draw()') 

, как я могу сделать эту работу? Благодарю вас

Непрерывно пытаясь выяснить, в чем причина, я обнаружил, что объект HTMLDocument, созданный с использованием webEngine.load(), по какой-то причине видится только внутри метода дескриптора, и нигде больше, даже если он был определен снаружи.

ответ

4

Что происходит, так это то, что вы хотите вызвать функцию JavaScript до полной загрузки содержимого. Поэтому функция draw не определена. Таким образом, единственный способ - дождаться загрузки страницы. Есть два способа, которые могут оказаться полезными: Добавьте в систему состояние списка изменений и выполните JavaScript после завершения загрузки: String htmlURL = ... webView.getEngine(). Load (htmlURL);

webView.getEngine().stateProperty().addListener(new ChangeListener<Worker.State>() { 
    @Override 
    public void changed(ObservableValue<? extends Worker.State> ov, Worker.State t, Worker.State t1) { 
     if (t1 == Worker.State.SUCCEEDED) { 
      // this will be run as soon as WebView is initialized. 
      webView.getEngine().executeScript("document.draw()");    
     } 
    } 
}); 

Другой способ - это скорее решение внутри JavaScript. Сначала нужно зарегистрировать мост между Java и вашей страницы HTML (должно быть сделано в изменении SUCCEEDED состояния, а также, см WebView callback from Javascript):

JSObject window = (JSObject) webEngine.executeScript("window"); 
window.setMember("app", this); 

Сейчас этот JavaObject ссылается в вашем JavaScript. Допустим, что у вас есть метод в классе, который вышеуказанного типа this:

public void executeOnPageLoaded() { 
    ... 
} 

Тогда вы можете вызвать этот метод из JavaScript.Если вы используете JQuery это может выглядеть следующим образом:

$(document).ready(function() { 
    console.log("ready!"); 
    app.executeOnPageLoaded(); 
}); 

Этот второй подход является более сложным, но в конечном счете, может дать вам больше гибкости.

Когда вы начинаете работать с JavaScript в WebView, неплохо также иметь Firebug lite, поэтому изучите, что происходит, но главным образом, чтобы иметь возможность посеять консольный вывод JavaScript. См. Java FX application onload event