20

我同时使用 JavaFX 和 JavaFX WebEngine 中的 javascript 引擎来开发应用程序。我想从 javascript 获得反馈以进行调试。WebEngine 中的控制台输出会发生什么?有什么方法可以访问它,或者在 java 中重定向到 System.out?

4

3 回答 3

27

以下代码重定向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" +
        "};");
});
于 2015-03-22T06:06:12.580 回答
12

您只需添加消息侦听器即可查看输出中发生的情况。您不必console.log为每个加载的页面注入重新定义功能的 js 桥接器

WebConsoleListener.setDefaultListener((webView, message, lineNumber, sourceId) -> {
    System.out.println(message + "[at " + lineNumber + "]");
});
于 2018-03-02T21:07:39.673 回答
7

我喜欢去另一个方向。我们使用 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 视图的替代方案。

于 2015-12-07T17:56:21.700 回答