2017-10-14 4 views
3

Ich mache eine Web-basierte App mit Java-Unterstützung für bestimmte Anforderungen (z. B. drucken, ohne den Drucker jedes Mal zu wählen) und es gibt etwas, das mich treibt verrückt.JavaFX JSObject funktioniert nach ein paar Minuten nicht mehr?

ich JavaFX für instantiate der Browser-Objekt und alles funktioniert gut, aber natürlich muss ich Rückrufe von JavaScript zu Java machen, hier ist der Code:

... 
... 
we.getLoadWorker().stateProperty().addListener(new ChangeListener<Worker.State>() 
    { 
     @Override 
     public void changed(ObservableValue<? extends State> observable, State oldValue, State newValue) 
     { 
      if (newValue == Worker.State.SUCCEEDED) 
      { 
       bridge = new Bridge(); 
       JSObject jsobj = (JSObject) we.executeScript("window"); 
       jsobj.setMember("app", new Bridge()); 
      } 

      if (newValue == Worker.State.CANCELLED) 
      { 
       System.out.println(newValue); 
       System.out.println("An error accourred"); 
      } 
     } 
    }); 
    ... 
    ... 

Das funktioniert aber nach ein paar minutesthe Brücke stoo funktioniert total, javascript kann keine callbacks mehr machen und wenn ich versuche eine alarm() auf das "app" objekt zu setzen gibt es mich undefined zurück. Ich benutze JDK9

+1

Es ist nicht zu weit hergeholt, dass das 'JSObject' nur schwache Referenzen auf die Member enthält, die an es übergeben werden. Könnten Sie versuchen, einen Verweis auf die 'Bridge'-Instanz zu halten? (Es sieht so aus, als ob Sie das wollten, aber dann erstellen Sie ein ganz neues für das 'JSObject' ...) – Itai

+0

@sillyfly tatsächlich, Sie haben Recht. Unerklärlicherweise habe ich eine neue Instanz von Bridge übergeben und ich weiß nicht wieso, javafx scheint auf lokale Art so wenig intolerant zu sein. Danke vielmals. –

Antwort

1

Um die Lösung deutlicher zu machen: der Ansatz von @sillyfly funktioniert.

Anstatt eine neue Instanz Bridge (oder in meinem Fall Console) für jede Statusänderung zu erstellen, erstellen Sie eine einzelne Instanz und weisen Sie sie jedes Mal neu zu. Etwas in den folgenden Zeilen.

public class AppController { 
    public WebView webview; 

    @FXML 
    public void initialize() { 
     final Console console = new Console(); 
     final WebEngine engine = webview.getEngine(); 
     engine.setJavaScriptEnabled(true); 
     engine.getLoadWorker().stateProperty().addListener(new ChangeListener<Worker.State>() { 
      @Override 
      public void changed(ObservableValue<? extends Worker.State> observable, Worker.State oldValue, Worker.State newValue) { 
       final JSObject window = (JSObject) engine.executeScript("window"); 
       window.setMember("console", console); 
      } 
     }); 
    } 

    public class Console { 
     public void log(String text) { 
      System.out.println("[WebView console] " + text); 
     } 
    } 
} 
Verwandte Themen