log4j в JTextPane - PullRequest
       5

log4j в JTextPane

2 голосов
/ 17 декабря 2011

Я сейчас пытаюсь заставить 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).

Ответы [ 2 ]

2 голосов
/ 17 декабря 2011

Текстовая панель является приватной для аппендера, и у вас нет для нее получателя.Поэтому я бы предположил, что в графическом интерфейсе есть текстовая панель, а в логгере есть еще одна текстовая панель, к которой он добавляется.

То есть, или вы получаете текстовую панель из экземпляра Log, который отличается от экземпляра Log, который создает экземпляр Log4j.

Кроме того, appender может использоваться несколькими потокамино компоненты Swing могут быть доступны только из потока диспетчеризации событий.Каждое добавление к текстовой панели должно выполняться внутри SwingUtilities.invokeLater() вызова.

1 голос
/ 18 декабря 2011

Проверьте, не вызываете ли вы setText () или setContentType (), и может быть еще несколько методов, которые воссоздают Document.Вместо сохранения ссылки на документ получите его из панели.Не

doc.insertString(doc.getLength(), "Hello World!", null);

, а

log.getStyledDocument().insertString(doc.getLength(), "Hello World!", null);
...