I have a javaFX application and I'm having a logging problem. I can't figure out how to dynamically output logs to a TextArea in JavaFX and to a file at the same time.
For the file I have this setup:
handlers = java.util.logging.FileHandler, java.util.logging.ConsoleHandler
java.util.logging.FileHandler.level = ALL
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
java.util.logging.FileHandler.append = true
java.util.logging.FileHandler.pattern = log.txt
And in each class such static initialization:
public class BuildTest{
static {
try(FileInputStream ins = new FileInputStream("src/main/resources/log.config")) {
LogManager.getLogManager().readConfiguration(ins);
LOGGER = Logger.getLogger(BuildTest.class.getName());
initialContext = new InitialContext();
} catch (NamingException | IOException e) {
LOGGER.log(Level.WARNING,"Error ", e);
}
}
}
But I have a problem, how can I also output to the TextArea at the same time?
The TextArea itself:
<TextArea layoutX="20.0" layoutY="705.0" prefHeight="100.0" prefWidth="560.0" fx:id="LogID"/>
And the controller is attached to the fxml file:
public class ControllerFrame {
private TextArea LogID;
static {
try(FileInputStream ins = new FileInputStream("src/main/resources/log.config")){
LogManager.getLogManager().readConfiguration(ins);
LOGGER = Logger.getLogger(ControllerFrame .class.getName());
} catch (Exception e) {
LOGGER.log(Level.WARNING,"Error ", e);
}
}
}
I tried to insert this code into both the static method and the initialize method in the controller class:
TextAreaHandler handler = new TextAreaHandler(textArea);
handler.setFormatter(new SimpleFormatter());
LOGGER.addHandler(handler);
Implementing the TextAreaHandler class:
package sample;
import java.util.logging.ErrorManager;
import java.util.logging.Handler;
import java.util.logging.LogRecord;
import javafx.application.Platform;
import javafx.scene.control.TextArea;
public class TextAreaHandler extends Handler {
private final TextArea textArea;
private volatile boolean open = true;
public TextAreaHandler(TextArea textArea) {
this.textArea = textArea;
}
@Override
public void publish(LogRecord record) {
if (open && isLoggable(record)) {
String message;
try {
message = getFormatter().format(record);
} catch (Exception ex) {
reportError(null, ex, ErrorManager.FORMAT_FAILURE);
return;
}
if (Platform.isFxApplicationThread()) {
appendMessage(message);
} else {
try {
Platform.runLater(() -> appendMessage(message));
} catch (Exception ex) {
reportError(null, ex, ErrorManager.GENERIC_FAILURE);
}
}
}
}
private void appendMessage(String message) {
try {
textArea.appendText(message);
} catch (Exception ex) {
reportError(null, ex, ErrorManager.GENERIC_FAILURE);
}
}
@Override
public void flush() {
// no buffer
}
@Override
public void close() {
open = false;
}
}
But I still don't get logs in the TextArea. The very essence is that the application displays logs both in a text file and in a TextArea