必要: Java アプリケーションのログを JTextArea などの GUI コンポーネントに出力します。
懸念事項:静的な方法で、任意のクラスからログを記録する必要があります。ただし、GUI ロガー コンポーネントは、親コンポーネントのメンバーであるため、(明らかに) 静的であってはなりません。
私は何をすべきか?
シングルトン ログ プロバイダーを作成し、"textfield" をリスナーとして追加します。
ロガー シングルトンの例:
interface Listener {
void log(String log);
}
enum Logger {
instance;
private List<Listener> listeners = new LinkedList<Listener>();
public void addListener(Listener l) {
synchronized(listeners) {
listeners.add(l);
}
}
public void log(String log) {
synchronized(listeners) {
for(Listener l : listeners)
l.log(log);
}
}
}
次のようにリスナー (自分で実装する必要があります) を追加します。
Logger.instance.addListener(myTextField);
そして、次のように(任意のクラスから)使用します。
Logger.instance.log("Hello World!");
または、 log4jのようなパッケージを使用できます。
ファイルにログを記録し、コンポーネントがファイルの末尾に続くようにします。出力をグリッドに入れたい場合は、おそらく log4j の XML ロギングを使用することをお勧めします。
更新:代わりに、メモリ内循環ロガーを実装することもできます。
データバインディングが頭に浮かびます。ログを表すモデルが必要で、このモデルは GUI コンポーネントにバインドされています。SWT の一般的なデータバインディング フレームワークは JFace Databinding です。SWING にも同様のものが存在すると確信しています。
どのように機能しますか - ロガーはメッセージをモデルに追加します。おそらく文字列 (logentries) の配列リストです。データバインディング クラスはモデルをリッスンし、モデルが変更されるたびに GUI を更新します。逆の方法でも機能します (GUI での編集をモデルに送信できます) が、必要なのは 1 つの方向だけです。
クラスとパッケージ間の循環依存関係に注意してください。スパゲッティ コードは必要ありません。
私の Swing アプリケーションは、9 つのモジュール (コントローラー、アプリケーション、プラットフォーム、ユーティリティ、モデル、永続性、サービス、ロガー、ビュー) から構成されています。
依存関係は次のとおりです。
view -> logger, controller, utils, model
controller -> logger, application, model, utils
application -> service, model, utils, platform
service -> persistence, model, utils
platform -> model
utils -> no dependencies
model -> no dependencies
logger -> model, utils
望ましい依存関係は、ビューからコントローラーへの依存関係ですが、コントローラーからビューへの依存関係ではありません。
したがって、モジュール ロガーを追加し、オブザーバー (JFrame、JFace = オブザーバーなどのビュー) に通知するハンドラー (オブザーバブル) を作成するのが最善です。
ビューとサービス (オブザーバーをトリガーする場所) モジュールは互いに依存していませんが、ロガー モジュールを介して依存しています。
しかし、データバインダーもそのように機能すると思います。あなたがフレームワークに依存していることを除いて、私は推測します。私の解決策はそうではありません。Swing から swt に切り替えたい場合でも、心配する必要はありません。swt 用に実装するだけで、ビジネス ロジックはそのまま残ります。
皆さんは、もっとデザインを賢く考えるべきです。(そしてMavenを使用してください。)