我有一个带JavaFX
TextArea
的GUI窗口,我希望实时输出所有记录器输出(信息,调试,错误等)(类似于控制台的输出)运行项目时的IDE。)
我已经查看了this answer并且我已经尝试调整代码但它不起作用,我感觉有些东西没有被初始化或调用,或者logback.xml
不是指向正确的班级。
在这里包含所有代码太难了所以我在GitHub上有一个演示项目,请克隆并告诉我你的想法?
记录器:logback
,slf4j
,log4j
使用的IDE:IntelliJ 2018.1
package Demo_Logger;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.OutputStream;
import static Demo_Logger.controller.ControllerMain.CONTROLLER_MAIN;
public class Main extends Application {
private static final Logger logger = LoggerFactory.getLogger(Main.class);
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
Parent parent = FXMLLoader.load(getClass().getResource("/view/main.fxml"));
primaryStage.setTitle("Demo logger");
primaryStage.setWidth(400);
primaryStage.setHeight(400);
primaryStage.setScene(new Scene(parent));
primaryStage.show();
Platform.runLater(this::setTextArea);
Platform.runLater(this::logToTexArea);
System.out.println("Main -> init"); //OK called
}
private void setTextArea() {
OutputStream outputStream = new TextAreaOutputStream(CONTROLLER_MAIN.textArea);
MyStaticOutputStreamAppender.setStaticOutputStream(outputStream);
}
private void logToTexArea() {
logger.debug("Debug example");
logger.error("Error example");
CONTROLLER_MAIN.textArea.setText("ADD LOGGER OUTPUT HERE");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<BorderPane xmlns="http://javafx.com/javafx/8.0.121" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="Demo_Logger.controller.ControllerMain">
<center>
<HBox alignment="CENTER">
<VBox alignment="CENTER" minWidth="100.0" spacing="10.0">
<Button fx:id="btnLogInfo" mnemonicParsing="false" onAction="#btnLogInfo" text="Log Info" />
<Button fx:id="btnLogError" mnemonicParsing="false" onAction="#btnLogError" text="Log Error" />
</VBox>
<TextArea fx:id="textArea" promptText="logger has to output here" />
</HBox>
</center>
</BorderPane>
package Demo_Logger.controller;
import Demo_Logger.Main;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ControllerMain {
public static ControllerMain CONTROLLER_MAIN;
private static final Logger logger = LoggerFactory.getLogger(Main.class);
@FXML
public TextArea textArea;
@FXML
public Button btnLogInfo, btnLogError;
public ControllerMain() {
CONTROLLER_MAIN = this;
}
@FXML
public void btnLogInfo() {
logger.info("Button info click");
}
@FXML
public void btnLogError() {
logger.error("Button error click");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>
<!-- THE PATTERN IS NOT WORKING - INVESTIGATE -->
%-50(%d{HH:mm:ss} [%level{}] %class{0}.%method{0}\(\)) - %message{}%n{}
</Pattern>
</layout>
</appender>
<!--<appender name="MyCustomAppender" class=".src.main.java.Demo_Logger.MyStaticOutputStreamAppender">-->
<!--<appender name="MyCustomAppender" class="src.main.java.Demo_Logger.MyStaticOutputStreamAppender">-->
<!--<appender name="MyCustomAppender" class=".main.java.Demo_Logger.MyStaticOutputStreamAppender">-->
<!--<appender name="MyCustomAppender" class="main.java.Demo_Logger.MyStaticOutputStreamAppender">-->
<!--<appender name="MyCustomAppender" class=".java.Demo_Logger.MyStaticOutputStreamAppender">-->
<!--<appender name="MyCustomAppender" class="java.Demo_Logger.MyStaticOutputStreamAppender">-->
<!--<appender name="MyCustomAppender" class=".Demo_Logger.MyStaticOutputStreamAppender">-->
<!--<appender name="MyCustomAppender" class="Demo_Logger.MyStaticOutputStreamAppender">-->
<!--<appender name="MyCustomAppender" class=".MyStaticOutputStreamAppender">-->
<!--<appender name="MyCustomAppender" class="MyStaticOutputStreamAppender">-->
<appender name="MyCustomAppender" class="Demo_Logger.MyStaticOutputStreamAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ALL</level>
</filter>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{5} - %msg%n</pattern>
</encoder>
</appender>
<root>
<appender-ref ref="STDOUT" />
<appender-ref ref="MyCustomAppender" />
</root>
</configuration>
package Demo_Logger;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class DelegatingOutputStream extends FilterOutputStream {
/**
* Creates a delegating outputstream with a NO-OP delegate
*/
public DelegatingOutputStream(OutputStream out) {
super(new OutputStream() {
@Override
public void write(int b) throws IOException {
}
});
System.out.println("DelegatingOutputStream -> init"); //OK called
}
void setOutputStream(OutputStream outputStream) {
this.out = outputStream;
System.out.println("DelegatingOutputStream -> setOutputStream"); //OK called
}
}
package Demo_Logger;
import javafx.scene.control.TextArea;
import java.io.IOException;
import java.io.OutputStream;
public class TextAreaOutputStream extends OutputStream {
private TextArea textArea;
public TextAreaOutputStream(TextArea textArea) {
this.textArea = textArea;
System.out.println("TextAreaOutputStream -> init"); //OK called
}
@Override
public void write(int b) throws IOException {
textArea.appendText(String.valueOf((char) b));
System.out.println("TextAreaOutputStream -> write");
}
}
package Demo_Logger;
import ch.qos.logback.core.OutputStreamAppender;
import java.io.OutputStream;
public class MyStaticOutputStreamAppender<E> extends OutputStreamAppender<E> {
private static final DelegatingOutputStream DELEGATING_OUTPUT_STREAM = new DelegatingOutputStream(null);
@Override
public void start() {
setOutputStream(DELEGATING_OUTPUT_STREAM);
System.out.println("MyStaticOutputStreamAppender -> start");
super.start();
}
static void setStaticOutputStream(OutputStream outputStream) {
DELEGATING_OUTPUT_STREAM.setOutputStream(outputStream);
System.out.println("MyStaticOutputStreamAppender -> setStaticOutputStream"); //OK called
}
}