如何将日志重定向到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);
    }
}

10-08 13:36