JavaFx and StreamHandler



如何将日志重定向到TextArea?我尝试获取这样的日志信息:

@Override
public void initialize(URL arg0, ResourceBundle arg1)
{
    _Game.setText(getGSTextLog());
}
public void setGSTextLog(String text)
{
    _gstext = text;
}
public String getGSTextLog()
{
    return _gstext;
}
public void GameSteam() throws UnsupportedEncodingException
{
    Logger logger = Logger.getLogger("test.test");
    logger.setUseParentHandlers(false);
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    StreamHandler sh = new StreamHandler(baos, new SimpleFormatter());
    sh.setLevel(Level.ALL);
    logger.addHandler(sh);
    logger.severe("Console Test");
    sh.flush();
    int b = 0;
    if (b == 'r')
    {
        return;
    }
    if (b == 'n')
    {
        final String text = baos.toString("UTF-8");
        baos.reset();
        Platform.runLater(() -> setGSTextLog(text + "n"));
        return;
    }
    baos.write(b);
}

只需直接实现Handler

import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class LogToTextArea extends Application {
    @Override
    public void start(Stage primaryStage) {
        Logger logger = Logger.getLogger("test.test");
        logger.setUseParentHandlers(false);

        TextArea log = new TextArea();
        log.setEditable(false);
        Formatter formatter = new SimpleFormatter();
        logger.addHandler(new Handler() {
            @Override
            public void publish(LogRecord record) {
                Platform.runLater(() -> log.appendText(formatter.format(record)));
            }
            @Override
            public void flush() {}
            @Override
            public void close() {}
        });
        TextField sendToLog = new TextField();
        sendToLog.setOnAction(e -> {
            logger.info(sendToLog.getText());
            sendToLog.setText("");
        });
        BorderPane root = new BorderPane(log, sendToLog, null, null, null);
        primaryStage.setScene(new Scene(root, 400, 400));
        primaryStage.show();
    }
    public static void main(String[] args) {
        launch(args);
    }
}

如果你真的想使用StreamHandler,需要注意的一个问题是StreamHandler将其OutputStream包裹在OutputStreamWriter中,这增加了缓冲。因此,您可能希望确保处理程序刷新每个日志消息上的缓冲区。像这样:

import java.io.IOException;
import java.io.OutputStream;
import java.util.logging.Formatter;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
import java.util.logging.StreamHandler;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class LogToTextArea extends Application {
    @Override
    public void start(Stage primaryStage) {
        Logger logger = Logger.getLogger("test.test");
        logger.setUseParentHandlers(false);

        TextArea log = new TextArea();
        log.setEditable(false);
        Formatter formatter = new SimpleFormatter();
        StreamHandler handler = new StreamHandler(new OutputStream() {
            @Override
            public void write(int b) throws IOException {
                String s = String.valueOf((char)b);
                log.appendText(s);
            }
        }, formatter){
            // flush on each publish:
            @Override
            public void publish(LogRecord record) {
                super.publish(record);
                flush();
            }
        };
        logger.addHandler(handler);
        TextField sendToLog = new TextField();
        sendToLog.setOnAction(e -> {
            logger.info(sendToLog.getText());
            sendToLog.setText("");
        });
        BorderPane root = new BorderPane(log, sendToLog, null, null, null);
        primaryStage.setScene(new Scene(root, 400, 400));
        primaryStage.show();
    }
    public static void main(String[] args) {
        launch(args);
    }
}

最新更新