我正在开发一个正在工作的项目,我的任务是实现一个自定义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选项。我们试图让开发人员像Java Swing库一样使用我们的自定义Swing库。我实施的更改对开发人员来说是透明的。
非常感谢任何帮助。
答案 0 :(得分:1)
首先在你的类路径中放入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>
答案 1 :(得分:1)
如何遍历组件树并将侦听器添加到每个组件(JButton等 - 可以与用户交互并且您需要它)?
然后开发人员可以使用简单的JButton(而不是MyButton)。 但是当您使用此方法时 - 您应该在创建所有组件后调用遍历组件方法。如果要添加其他组件,您还可以添加侦听Component#add方法并更新侦听器的ComponentListener。
答案 2 :(得分:0)
如果您可以强制他们在doCustomMethod()实现中调用方法,那么您可以从堆栈跟踪信息中访问行号。否则,您可以使用this.getClass()查找其实现的类名称,并使用ASM ClassReader查找行号/源文件。