Веб-обзор JavaFX: как перенаправить System.out и System.err на консоль Firebug Lite?

Я нашел несколько примеров того, как передавать и перенаправлять сообщения из System.out и System.err. Решив разработать приложение с использованием JavaFX Webview и Dukescript, я нашел полезным иметь одно место для отображения всех сообщений, а именно консоль Firebug Lite.

Увидеть ниже.

PS Это как раз наоборот

1 ответ

Сначала определите абстрактный класс

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 само должно передавать сообщения console.log в 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.

Другие вопросы по тегам