java - JTextPane 中的 log4j

标签 java swing log4j jtextpane

我目前正在尝试使 Log4J 登录到 JTextPane。我想使用 TextPane,因为我想要基本的突出显示(例如,错误为红色,信息为绿色)。

我设置了两个记录器,一个(根记录器)将所有内容记录到文件中,另一个(guiLogger)仅在 JTextPane 中记录 GUI 上的一些错误和信息.

我当前面临的问题是,我无法附加到 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() 方法执行清理(它不会进入 catch)- block ),但我在 GUI 上的 TextPane 中没有看到任何内容。

我尝试解决这个问题:

  • 使用 SwingUtilities.invokeLater() 执行 insertString() 方法
  • SwingWorker 执行 insertString() 方法
  • JTextPane 上的 validate()revalidate()repaint() 等方法
  • 不使用全局 StyledDocument 对象,而是直接从 log 实例获取它:log.getStyledDocument().insertString(0, "Hello World !", info_log);
  • JTextPanesetText() 方法(仅在构造函数中有效)。

由于JTextPane没有fireContentChanged()方法(或类似的),我有点迷失在这里。


我玩了更多,发现了一些其他东西:

  • StyledDocument 已更新(调用 getText() 显示文本已插入)。
  • 当我直接从编译器调用 append()insertString() 方法时(在初始化 StyledDocument >JTextPane),一切正常。

此外,我通过将其添加到 append() 方法主体来检查哪个线程调用了该方法:

System.out.println("Thread: "+Thread.currentThread().getName());

如果我只是从代码中的某个位置执行两个日志语句,它会显示以下内容:

Thread: AWT-EventQueue-0
Thread: AWT-EventQueue-0

当我直接从 Log 类的构造函数调用 append() 方法(加上上面的两个日志记录语句)时,它显示以下:

Thread: AWT-EventQueue-0
Thread: AWT-EventQueue-0
Thread: AWT-EventQueue-0

第一次调用可能会附加文本。但另外两个似乎不起作用。

我的 GUI 是使用 SwingUtilities.invokeLater()AWT-EventQueue 构建的。这两个日志记录调用是在同一上下文中进行的(因此也来自 EventQueue)。

最佳答案

文本 Pane 对于附加程序来说是私有(private)的,并且您没有任何 setter/getter 。所以我猜测 GUI 有一个文本 Pane ,并且记录器有另一个附加的文本 Pane 。

或者您从与 Log4j 实例化的 Log 实例不同的 Log 实例获取文本 Pane 。

此外,appender 可能由多个线程使用,但 Swing 组件只能从事件分派(dispatch)线程访问。文本 Pane 的每次追加都应在 SwingUtilities.invokeLater() 调用内完成。

关于java - JTextPane 中的 log4j,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8546995/

相关文章:

java - 更改(重命名)jung 中的顶点标签

java - 中文/日文机器支持 char* 吗?

java - SWT Composite 在 3.6.1 中需要 pack()

java - 在 Tomcat 中作为 WAR 运行的 Grails 项目中 Maven-build JAR 的 SLF4J 配置位置

java - admob interstitial 未显示在 google play 服务中?

java - Java 中的 "runtime class"是什么?

java - 如何保持 JTextArea 的大小不变?

java重置游戏方法,玩过的游戏数量不增加

java - Log4j DailyRollingFileAppender : Specifying rollover directory

java - 使用 Maven 从依赖 jar 中排除资源