2015-11-08 212 views
1

我正在編寫一個JavaFX應用程序,它與JavaScript交互,使用WebView和WebEngine(.executeScript()方法)。webEngine.executeScript();拋出異常

在這裏,我有從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的聲明爲全局變量。

無法使用HTML的onLoad選項調用document.draw()函數,因爲我需要傳遞一些值來從java中繪製函數。

產生的例外是:

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

我怎樣才能使這項工作?謝謝

雖然連續試圖弄清楚原因究竟是什麼,我發現使用webEngine.load()創建的HTMLDocument對象由於某種原因只能在句柄方法內部看到,而在其他任何地方,即使它已被定義在外部。

回答

4

這裏發生的事情是,您希望在內容完全加載之前調用JavaScript函數。因此,函數draw未定義。所以唯一的方法是等待頁面加載。有兩種方式可能證明有用: 在狀態中添加changelistener並在加載成功後執行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); 

現在這個Java對象是在你的JavaScript引用。比方說,你有一個方法上是上述類型的this的類:

public void executeOnPageLoaded() { 
    ... 
} 

然後,你可以從JavaScript調用此方法。如果您在使用jQuery它看起來是這樣的:

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

第二種方法是比較複雜的,但是從長遠來看,可能會給你更多的靈活性。

當你開始在WebView中使用JavaScript時,在那裏也有Firebug lite是一個好主意,所以調查一下發生了什麼,但主要是想擁有種子JavaScript的控制檯輸出的方法。見Java FX application onload event