web-dev-qa-db-ja.com

JavaFX 8 WebEngine:console.log()をjavascriptからjava。のSystem.outに取得する方法

JavaFX WebEngine内のJavaFXとJavaScriptエンジンの両方を使用して、アプリケーションを開発しています。デバッグの目的でJavaScriptからフィードバックを得たいのですが。 WebEngine内のコンソール出力はどうなりますか?アクセスしたり、JavaでSystem.outにリダイレクトしたりする方法はありますか?

17
user4159962

次のコードは、console.log()JavaBridge.log()にリダイレクトします。

import netscape.javascript.JSObject;

[...]

public class JavaBridge
{
    public void log(String text)
    {
        System.out.println(text);
    }
}

// Maintain a strong reference to prevent garbage collection:
// https://bugs.openjdk.Java.net/browse/JDK-8154127
private final JavaBridge bridge = new JavaBridge();

[...]

webEngine.getLoadWorker().stateProperty().addListener((observable, oldValue, newValue) ->
{
    JSObject window = (JSObject) webEngine.executeScript("window");
    window.setMember("Java", bridge);
    webEngine.executeScript("console.log = function(message)\n" +
        "{\n" +
        "    Java.log(message);\n" +
        "};");
});
24
Gili

メッセージリスナーを追加するだけで、出力で何が起こっているかを確認できます。ロードされたすべてのページに対してconsole.logのような関数の再定義を使用してjsブリッジを注入する必要はありません

WebConsoleListener.setDefaultListener((webView, message, lineNumber, sourceId) -> {
    System.out.println(message + "[at " + lineNumber + "]");
});
10
dzikoysk

私は別の方向に行くのが好きです。ここではlog4jを使用しているため、次のようなJavaScriptラッパーを作成しました。

module.exports = {

    levels:[ "ALL", "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "OFF"],

    level:"INFO",

    error:function(msg){
      if(this.isErrorEnabled()){
        console.error(msg)
      }
    },
    warn:function(msg){
      if(this.isWarnEnabled()){
        console.warn(msg)
      }
    },
    info:function(msg){
      if(this.isInfoEnabled()){
        console.log("INFO: "+msg)
      }
    },
    debug:function(msg){
      if(this.isDebugEnabled()){
        console.log("DEBUG: "+msg)
      }
    },
    trace:function(msg){
      if(this.isTraceEnabled()){
        console.log("TRACE: "+msg)
      }
    },

    isErrorEnabled:function(){
      return this.isEnabled("ERROR");
    },
    isWarnEnabled:function(){
      return this.isEnabled("WARN");
    },
    isInfoEnabled:function(){
      return this.isEnabled("INFO");
    },
    isDebugEnabled:function(){
      return this.isEnabled("DEBUG");
    },
    isTraceEnabled:function(){
      return this.isEnabled("TRACE");
    },
    isEnabled:function(statementLevel){
      return this.levels.indexOf(this.level)<=this.levels.indexOf(statementLevel);
    }
  }

次に、JavaScriptの最初に、ログが存在するかどうかを確認して設定します。

if(window.log == undefined){
  window.log = require("./utils/log4j-wrapper")
  window.log.level = "INFO"
}

そして、次のようにURLをロードする前に、Log4jロガーをエンジンに直接設定すると、

WebEngine webEngine = webView.getEngine()
JSObject win = (JSObject) webEngine.executeScript("window")
win.setMember("log", log)  //log being the Java log4j logger

このようにして、ブラウザーで直接開いている場合、またはJavaFXプログラムのWebViewから実行されている場合にログインできます。また、WebViewコントローラーのパッケージに一致するレベルをJavaScriptのJavaScriptに設定できるという利点もあります。より大きなJavaScriptビューの代替手段です。

6
Tim Overly