Веб-обзор 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.