2010-06-02 7 views
5

Erforderlich: Geben Sie das Protokoll einer Java-Anwendung in einer GUI-Komponente wie JTextArea aus.Java-Protokoll ==> JTextArea

Betrifft: Müssen Dinge von jeder Klasse in einer statischen Weise protokollieren. Die GUI-Logger-Komponente darf jedoch nicht statisch sein (offensichtlich), da sie das Mitglied einer übergeordneten Komponente ist.

Was soll ich tun?

Antwort

2

Erstellen Sie einen Singleton-Protokollanbieter, und fügen Sie ihm das "Textfeld" als Listener hinzu.

Beispiel des Loggers Singelton:

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); 
     } 
    } 
} 

Beitrag Zuhörer (die Sie benötigen, um sich selbst zu implementieren) wie folgt aus:

Logger.instance.addListener(myTextField); 

und verwenden Sie es (aus jeder Klasse) wie folgt aus:

Logger.instance.log("Hello World!"); 

Oder Sie können ein Paket wie log4j verwenden.

+3

Schreiben Sie nicht noch ein anderes Logging-Framework, tun Sie es einfach nicht. Verwenden Sie log4j (oder slf4j, es scheint der letzte Schrei zu sein) – Justin

+2

Ich stimme nicht zu, fügen Sie keine weitere Abhängigkeit, wenn Sie etwas so einfach machen wollen .. – dacwe

1

Databinding kommt mir in den Sinn. Sie benötigen ein Modell, das Ihr Protokoll darstellt, und dieses Modell ist an eine GUI-Komponente gebunden. Ein gemeinsames Datenbindungs-Framework für SWT ist JFace Databinding, ich bin mir sicher, dass etwas ähnliches für SWING existiert.

Wie würde es funktionieren - der Logger fügt Nachrichten zum Modell hinzu, vielleicht nur ein Arraylist von Strings (Logentries). Die Datenbindungsklassen hören auf das Modell und aktualisieren die GUI jedes Mal, wenn sich das Modell geändert hat. Es würde auch umgekehrt funktionieren (Änderungen an der GUI könnten an das Modell gesendet werden), aber Sie brauchen nur eine Richtung.

2

In eine Datei protokollieren, die Komponente dem Ende der Datei folgen lassen. Wahrscheinlich möchten Sie log4js XML-Protokollierung verwenden, wenn Sie die Ausgabe in ein Raster einfügen möchten.

Aktualisierung: Sie könnten alternativ einen In-Memory-Rundschreiber implementieren.

+0

guten Anruf - das entkoppelt die Timing/Priorität Anforderungen. Die Protokollierung sollte eine hohe Priorität haben und das Protokoll sollte nicht angezeigt werden. –

1

Achten Sie auf zirkuläre Abhängigkeiten zwischen Ihren Klassen und Paketen, Sie wollen nicht Spaghetti-Code.

My Swing-Anwendung besteht aus 9 Modulen (Controller, Anwendung, Plattform, utils, Modell, Persistenz, Service, Logger und view)

Hier sind Abhängigkeiten:

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 

Eine gewünschte Abhängigkeits ist von Ansicht zu Controller aber nicht von Controller zu sehen.

Das Beste ist, einen Modullogger hinzuzufügen und einen Handler zu erstellen (der eine Observable ist), der Beobachter benachrichtigt (Ansicht wie JFrame, JFace = Beobachter).

Ansicht und Service (Ort, an dem Sie den Beobachter auslösen möchten) sind nicht voneinander abhängig, sondern durch das Logger-Modul.

Aber ich denke, der Databinder funktioniert auch so. Ich nehme an, außer Sie sind Framework-abhängig.Meine Lösung ist nicht, also wenn ich von Swing zu swt wechseln will, keine Sorge, ich implementiere es einfach für swt, und meine Geschäftslogik bleibt intakt.

Sie sollten alle mehr über Design denken. (Und maven verwenden.)