1

私は仕事中のプロジェクトに取り組んでおり、Swingコンポーネントがユーザーによって操作されるたびにイベントをファイルに記録するカスタムJavaSwingライブラリーの実装を任されています。つまり、ユーザーがGUIのボタンやチェックボックスなどを操作するたびに、イベントがファイルに記録されます。ログエントリには、イベントが発生したソースファイル名と行番号が含まれている必要があります。1つの落とし穴があります。ライブラリの外部で開発者によって実装されたメソッドのロギングメカニズムは、ライブラリ内で自動的に発生する必要があります。できますか?これが私がこれまでに持っているものです:

カスタムライブラリアクションリスナー:

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オプションを含める必要があります。開発者に、JavaSwingライブラリと同じようにカスタムSwingライブラリを使用してもらうようにしています。私が実装する変更は、開発者には透過的です。

どんな助けでも大歓迎です。

4

3 に答える 3

1

コンポーネント ツリーをトラバースし、リスナーを各コンポーネント (JButton など - ユーザーと対話でき、必要なコンポーネント) に追加するのはどうですか?

その後、開発者は単純な JButton (MyButton ではなく) を使用できます。ただし、このアプローチを使用する場合は、すべてのコンポーネントが作成された後で、トラバース コンポーネント メソッドを呼び出す必要があります。他のコンポーネントが追加される場合は、Component#add メソッドをリッスンしてリスナーを更新する ComponentListener も追加できます。

于 2012-05-16T19:52:53.783 に答える
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 に答える
0

doCustomMethod()実装でメソッドを呼び出すように強制できる場合は、スタックトレース情報から行番号にアクセスできます。それ以外の場合は、this.getClass()を使用して実装のクラス名を確認し、 ASMClassReaderを使用して行番号/ソースファイルを確認できます。

于 2012-05-16T19:58:19.207 に答える