1

我正在处理一个项目,我的任务是实现一个自定义 Java Swing 库,只要用户与 Swing 组件交互,就会将事件记录到文件中。换句话说,每当用户与 GUI 上的按钮、复选框等交互时,该事件都会记录到文件中。日志条目必须包含事件发生位置的源文件名和行号。有一个问题:对于开发人员在库外实现的方法,日志记录机制需要在中自动发生。可以做到吗?这是我到目前为止所拥有的:

自定义库动作监听器:

public abstract class MyActionListener implements ActionListener
{
    // Prevents the developer from implementing the "actionPerformed" method
    @Override
    public final void actionPerformed(ActionEvent e)
    {
        // Do nothing
    }

    // Custom method
    public void actionPerformed(MyActionEvent e)
    {
        doCustomMethod();

        // Tried obtaining the stack trace here but there's no entry
        // in the trace for "doCustomMethod()"
        StackTraceElement [] elements = Thread.currentThread().getStackTrace();
        for (StackTraceElement element : elements)
        {
            // print each element
        }
    }

    // Forces the developer to implement this method
    public abstract void doCustomMethod();
}

自定义库按钮:

public class MyButton extends JButton
{
    ...

    // Custom method
    public void addActionListener(MyActionListener l)
    {
        listenerList.add(MyActionListener.class, l);
    }
}

开发人员创建的 GUI:

public class TestGui extends JFrame
{
    TestGui()
    {
        ...

        MyButton button = new MyButton("Push");
        button.addActionListener(new MyActionListener()
        {
            public void doCustomMethod()
            {
                // Want to log this line number and file name,
                // but need the library to do it; NOT the developer.
            }
        });
    }
}

我已经准备好所有正确的逻辑,以便调用正确的addActionListener()actionPerformed()方法。我的问题是尝试记录事件。我也尝试过实现自定义 Java 注释,但没有奏效。此外,开发人员必须在构建 GUI 时包含 -processor 选项。我们试图让开发人员使用我们的自定义 Swing 库,就像 Java Swing 库一样。我实施的更改对开发人员来说是透明的。

任何帮助是极大的赞赏。

4

3 回答 3

1

也许Logback + SLF4J可以帮助你

首先将 logback-classic.jar、logback-core.jar 和 slf4j-api 放在你的类路径中

如果不存在,则有一个默认配置,但如果您想要更详细的配置,您可以添加一个 logback.xml 配置文件,如下所示:

<?xml version="1.0" encoding="UTF-8" ?>

<configuration scan="true" scanPeriod="60 seconds">

<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    <layout class="ch.qos.logback.classic.PatternLayout">
        <pattern>[%d{ISO8601}] [%-5level] \(%F:%L\) - %msg%n</pattern>
    </layout>
</appender>

<logger name="org.hibernate" level="WARN" />
<logger name="org.springframework" level="INFO" />

<root level="INFO">
    <appender-ref ref="CONSOLE" />
</root>

</configuration>
于 2012-05-16T19:49:12.997 回答
1

遍历组件树并将您的侦听器添加到每个组件(JButton 等 - 可以与用户交互并且您需要它)怎么样?

然后开发人员可以使用简单的 JButton(不是 MyButton)。但是当您使用这种方法时 - 您应该在创建所有组件后调用遍历组件方法。如果要添加其他组件,您还可以添加侦听 Component#add 方法的 ComponentListener 并更新您的侦听器。

于 2012-05-16T19:52:53.783 回答
0

如果您可以强制他们在其 doCustomMethod() 实现中调用方法,那么您可以从堆栈跟踪信息中访问行号。否则,您可以使用 this.getClass() 找出其实现的类名,并使用 ASM ClassReader找出行号/源文件。

于 2012-05-16T19:58:19.207 回答