Я сейчас пытаюсь заставить Log4J войти в систему JTextPane
.Я хочу использовать TextPane, потому что мне нужна базовая подсветка (например, ошибки красные, а информация зеленая).
У меня настроено два регистратора, один (root-logger) записывает все в файл, а другой(guiLogger
) регистрирует только некоторые ошибки и информацию в графическом интерфейсе в JTextPane
.
Проблема, с которой я сейчас сталкиваюсь, заключается в том, что я не могу заставить приложение TextPane работать.То, что у меня сейчас есть, выглядит примерно так:
public class Log extends AppenderSkeleton{
private final JTextPane log;
private final StyledDocument doc;
public Log(){
super();
log = new JTextPane();
doc = log.getStyledDocument();
}
@Override
protected void append(LoggingEvent loggingEvent) {
try {
doc.insertString(doc.getLength(), "Hello World!", null);
} catch (BadLocationException e) {
e.printStackTrace();
}
}
public JTextPane getView(){
return log;
}
}
Файл конфигурации Log4J выглядит так:
# The root-logger should log everything.
log4j.rootLogger = DEBUG, file
# Append the logs to a file.
log4j.appender.file = org.apache.log4j.RollingFileAppender
# [...]
# The logger which logs on the GUI (just some user-information).
log4j.logger.guiLogger = INFO, gui
# Append the logs to the GUI
log4j.appender.gui = mypackage.Log
# Formatting of the output:
log4j.appender.gui.layout = org.apache.log4j.PatternLayout
log4j.appender.gui.layout.ConversionPattern = %m%n
Вызывается метод append()
, и insertString()
-method выполняет очистку (он не входит в catch
-блок), но я не вижу никакого содержимого в TextPane в графическом интерфейсе.
Что я пытался исправить это:
- Выполнить
insertString()
-метод, используя SwingUtilities.invokeLater()
- Выполнить
insertString()
-метод из SwingWorker
- Методы, такие как
validate()
, revalidate()
иrepaint()
в JTextPane
- Не использовать глобальный
StyledDocument
-объект, но напрямую получить его из log
-экземпляра: log.getStyledDocument().insertString(0, "Hello World!", info_log);
setText()
-методиз JTextPane
(работает только в конструкторе).
Поскольку JTextPane
не имеет fireContentChanged()
-метода (или аналогичного), я как бы здесь потерялся.
Я немного поиграл и нашел еще кое-что:
- Обновляется
StyledDocument
(вызов getText()
показывает, что текст вставлен). - Когда я звоню
append()
или insertString()
-метод напрямую из компилятора (после инициализации StyledDocument
и JTextPane
) все работает нормально.
Кроме того, я проверил, какой поток вызвал метод, добавив его вappend()
тело метода:
System.out.println("Thread: "+Thread.currentThread().getName());
Это показывает следующее, если я просто делаю два оператора журнала где-то в коде:
Thread: AWT-EventQueue-0
Thread: AWT-EventQueue-0
и когда я вызываю append()
-метод непосредственно из конструктора Log
-класса (плюс два оператора регистрации выше) показывает следующее:
Thread: AWT-EventQueue-0
Thread: AWT-EventQueue-0
Thread: AWT-EventQueue-0
Первый вызов добавляет текст, вероятно.Но остальные два не работают,
Мой графический интерфейс собран из AWT-EventQueue
с использованием SwingUtilities.invokeLater()
.Два вызова регистрации выполняются в одном и том же контексте (и поэтому также поступают из EventQueue).