public class TextAreaAppender extends WriterAppender {
private static volatile TextArea textArea = null;
private static final Logger log = LoggerFactory.getLogger(TextAreaAppender.class);
/**
* Set the target TextArea for the logging information to appear.
*
* @param textArea
*/
public static void setTextArea(final TextArea textArea) {
TextAreaAppender.textArea = textArea;
}
/**
* Format and then append the loggingEvent to the stored TextArea.
*
* @param loggingEvent
*/
@Override
public void append(final LoggingEvent loggingEvent) {
final String message = this.layout.format(loggingEvent);
// Append formatted message to text area using the Thread.
Task<Void> task = new Task<Void>() {
@Override
protected Void call() throws Exception {
try {
if (textArea != null) {
if (textArea.getText().length() == 0) {
Platform.runLater( () -> {
textArea.setText(message);
});
} else {
textArea.selectEnd();
Platform.runLater( () -> {
textArea.insertText(textArea.getText().length(), message);
});
}
}
} catch (final Throwable t) {
log.error("Unable to append log to text area: " + t.getMessage());
}
return null;
}
};
new Thread(task).start();
}
那是我的班级。 从http://www.rshingleton.com/javafx-log4j-textarea-log-appender/得到它 它将在控制台上显示的日志写入textarea。 问题是日志的显示顺序与控制台中的顺序不同。 为什么? 提前谢谢
答案 0 :(得分:2)
您在另一个Task
上开始Thread
,使用Runnable
发布Platform.runLater
。 Runnable
按照发布顺序执行,但是通过从新Thread
发布它们,您可以放松对它们提交顺序的控制。
我不确定为什么你在这里使用不同的线程。只需直接从当前线程发布它。代码可能很昂贵&#34;无论如何都跑到那里:
@Override
public void append(final LoggingEvent loggingEvent) {
// create a copy to make sure it's not overwritten somewhere
final TextArea target = textArea;
if (target != null) {
final String message = this.layout.format(loggingEvent);
Platform.runLater(() -> {
target.selectEnd();
target.appendText(message);
});
}
}