JavaFX webview:如何将System.out和System.err转发到Firebug Lite控制台?

时间:2015-06-15 21:42:41

标签: javafx-webengine firebug-lite dukescript

我找到了几个关于如何从System.out和System.err管道和重定向消息的示例。 决定使用JavaFX Webview和Dukescript开发应用程序后,我发现有一个地方可以显示所有消息,即Firebug Lite控制台。

见下文。

PS这与this

正好相反

1 个答案:

答案 0 :(得分:0)

首先定义一个抽象类

public abstract class FirebugConsole extends OutputStream {

  abstract void log( String msg );

  StringBuilder sb = new StringBuilder();

  @Override
  public void write(int i) {
    sb.append((char)i);
  }

  @Override
  public void flush() {
    if( sb.length() >0 && !sb.toString().equals("\r\n"))
      log(sb.toString());
    sb = new StringBuilder();
  }  
}

然后使用实现本机调用的方法将其扩展为JavaScript。这是例如如何编写日志消息

public class FirebugConsoleInfo extends FirebugConsole{
  @net.java.html.js.JavaScriptBody(args = { "msg" }, body = ""
      + "Firebug.Console.log(msg);")
  public native void log( String msg );
}

最后,将System.out和System.err传递给那些对象

  public static void onPageLoad() throws Exception {
  ...
      System.setOut(new PrintStream(new FirebugConsoleInfo(), true));
      System.setErr(new PrintStream(new FirebugConsoleError(), true));
  ...
  }

注意:由于某些原因,通常的console.log()对我不起作用,我知道如果控制台对象已经存在,Firebug不会绑定控制台,所以我怀疑WebFX webview必须自己管道控制台。首先将消息记录到System.out。

<强>更新

当消息由浏览器以外的线程生成时,上述解决方案不起作用。这是基于BrwsrCtx.execute()

的更新解决方案
  public abstract static class FirebugConsole extends OutputStream {
    protected final BrwsrCtx ctx;

    public FirebugConsole( BrwsrCtx ctx ){
      this.ctx = ctx;
    }
    abstract void logNative( String msg );

    void log(String msg) {
      ctx.execute(new Runnable(){
        @Override
        public void run() {
          logNative(msg);
        }
      });
    }

    StringBuilder sb = new StringBuilder();

    @Override
    public void write(int i) {
      sb.append((char)i);
    }

    @Override
    public void flush() {
      if( sb.length() >0 && !sb.toString().equals("\r\n"))
        log(sb.toString());
      sb = new StringBuilder();
    }  
  }

  public static class FirebugConsoleInfo extends FirebugConsole{
    public FirebugConsoleInfo(BrwsrCtx ctx) {
      super(ctx);
    }

    @net.java.html.js.JavaScriptBody(args = { "msg" }, body = ""
        + "Firebug.Console.log(msg);")
    public native void logNative( String msg );

  }

  public static class FirebugConsoleError extends FirebugConsole{
    public FirebugConsoleError(BrwsrCtx ctx) {
      super(ctx);
    }

    @net.java.html.js.JavaScriptBody(args = { "msg" }, body = ""
        + "Firebug.Console.error(msg);")
    public native void logNative( String msg );
    }
 }

  public static void onPageLoad() throws Exception {
      BrwsrCtx ctx = BrwsrCtx.findDefault(GoGPS_Fx.class);
      System.setOut(new PrintStream(new FirebugConsoleInfo(ctx), true));
      System.setErr(new PrintStream(new FirebugConsoleError(ctx), true));
  }

注意:对于大型日志来说速度相当慢,可能会有更快的替代方案(StringWriter是一个)。但我怀疑瓶颈是从Java到JavaScript的来回传递消息。