2017-10-14 69 views
3

我正在制作一个基于Web的应用程序,它支持一些特定的Java请求(例如,每次打印时不需要选择打印机),并且有些东西会让我疯狂JavaFX JSObject在几分钟后停止工作?

我使用JavaFX的为实例化浏览器对象,一切工作正常,但当然我需要从JavaScript到Java回调,这里是代码:

... 
... 
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"); 
      } 
     } 
    }); 
    ... 
    ... 

这工作,但经过几次minutesthe桥完全工作,JavaScript无法再回调,如果我尝试对“应用程序”对象做出警告(),它返回我未定义。 我正在使用JDK9

+1

JSObject只包含传递给它的成员的弱引用并不是太牵强。你可以尝试持有对'Bridge'实例的引用吗? (看起来好像你的意思是,但是你为'JSObject'创建一个全新的...) – Itai

+0

@sillyfly实际上,你是对的。令人费解的是,我传递了一个新的Bridge实例,我不明白为什么,javafx似乎对这样的本地分配有点不能容忍。非常感谢。 –

回答

1

为了使解决方案更加明显:@sillyfly建议的方法有效。

而不是每创建一个新的Bridge(或在我的情况下为Console实例)实例为每个每个状态更改,请创建一个实例并重新分配它每次。沿着以下几行。

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); 
     } 
    } 
} 
相关问题