2015-08-27 11 views
5

Ich habe eine JavaFX-Anwendung, die stark von einem WebView Gebrauch macht. Ich versuche, ein Objekt in das DOM einzufügen, das der JavaScript-Code verwenden kann. Diese Objekte müssen verfügbar sein, wenn neue Seiten geladen werden.Warum wird die JavaScript-Methode nicht ausgeführt, wenn sie von JavaFX in das DOM eingefügt wird?

Wenn ich jedoch das Programm ausführen, zeigt FirebugLite das Objekt im DOM, aber die Funktionen werden nicht ausgeführt.

Laut some Oracle documentation scheint dies der geeignete Weg zu sein, Up-Calls von JavaScript zu Java bereitzustellen. Ich habe auch ein paar StackOverflow posts gesehen, die dasselbe erklären.

Was fehlt mir? Ich bin mit Java 8, 51 aktualisieren, 64-Bit-Windows 7.

Java:

public class DemoApplication extends Application { 

    Debug debug; 

    @Override 
    public void start(final Stage stage) throws Exception { 
     debug = new Debug(); 

     WebView browser = new WebView(); 
     WebEngine webEngine = browser.getEngine(); 
     webEngine.getLoadWorker().stateProperty().addListener(
       new ChangeListener<Worker.State>() { 
        @Override 
        public void changed(ObservableValue<? extends Worker.State> observable, Worker.State oldValue, Worker.State newValue) { 
         if (newValue == Worker.State.SUCCEEDED) { 
          JSObject windowObject = (JSObject) webEngine.executeScript("window"); 
          windowObject.setMember("Debug", debug); 
         } 
        } 
       } 
     ); 
     webEngine.load("http://localhost:8080/page1.html"); 

     stage.setScene(new Scene(browser)); 
     stage.show(); 
    } 

} 

public class Debug { 
    public void print(final Object text) { 
     System.err.println(text); 
    } 
} 

HTML/JavaScript:

<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="UTF-8"> 
    <title></title> 
    <script type="text/javascript" src="https://getfirebug.com/firebug-lite.js"></script> 
    <script> 
    Debug.print("Hello"); 
    </script> 
</head> 
<body> 
    Page 1 
    <a href="page2.html">Page 2</a> 
</body> 
</html> 

Firebug Screenshot:

enter image description here

Antwort

3

Ich glaube, was passiert ist, dass WebEngine die Seite lädt, in der sich der ChangeListener befindet an verschiedenen Stellen (SCHEDULED, RUNNING, SUCCEEDED usw.). Sobald das Worker.State.SUCCEEDED-Ereignis eintritt, ist die Seite bereits mit dem Laden des gesamten Inhalts fertig und hat beendet, wobei dieser Inhalt ebenfalls ausgeführt wird. Meine Aufrufe von Debug.print() im JavaScript-Code geschahen daher früh und rufen ein Objekt auf, das undefined oder null war.

Das ist meine beste Schätzung sowieso, denn wenn ich eine JavaScript-Funktion, die von der Java-Teil nach Hinzufügen der Objekte ausgeführt wird, funktioniert alles wie erwartet.

Dies ist, wie ich die JavaScript-Seite geändert:

<script> 
    // callback that uses java objects 
    window.ready = function() { 
    Debug.print("Hello"); 
    } 
</script> 

Und das ist, wie ich geändert, um die Java-Seite:

webEngine.getLoadWorker().stateProperty().addListener(
    new ChangeListener<Worker.State>() { 
     @Override 
     public void changed(ObservableValue<? extends Worker.State> observable, Worker.State oldValue, Worker.State newValue) { 
      if (newValue == Worker.State.SUCCEEDED) { 
       JSObject windowObject = (JSObject) webEngine.executeScript("window"); 
       windowObject.setMember("Debug", debug); // insert object 
       windowObject.call("ready"); // execute callback 
      } 
     } 
    } 
); 

Die wichtigsten Änderungen sind hier die bereit() Funktion im JavaScript und ruft die Funktion nach auf, die Objekte auf der Java-Seite einfügt. Dies stellt sicher, dass diese Objekte verfügbar sind, bevor sie aufgerufen werden.

Ich versuchte dies auf ein paar verschiedenen Seiten und beim Gehen von Seite zu Seite, wenn die ready() - Funktion Debug.print() ordnungsgemäß ausgeführt wurde, auch wenn WebEngine.reload() oder WebHistory.go ().

Verwandte Themen