| ![]() |
|
||||||
|
![]() | Package de.qfs.lib.log | ![]() |
![]() |
Auch wenn die API Referenz zum
Beginnen wir mit einigen Grundlagen: Jeder Logmeldung ist ein Level zugeordnet, der ein Maß für ihre Wichtigkeit darstellt. Es gibt fünf Stufen mit jeweils einer Unterstufe für Details, für die folgende Konstanten in der Log Klasse definiert sind:
Neben dem Level und der eigentlichen Mitteilung enthält eine Logmeldung ausserdem einen Zeitstempel, den laufenden Thread sowie die absendende Klasse und Methode. Die Ausgabe einer Logmeldung hat folgendes Format: Level (Uhrzeit) Thread Klasse.Methode: Mitteilung Uhrzeit, Thread und Klasse werden automatisch generiert. Leider gibt es in Java keine Möglichkeit die umgebende Methode zu ermitteln, so dass diese immer von Hand angegeben werden muß. Erzeugen von Logmeldungen
Kommen wir zum eigentlichen Erzeugen einer Meldung. Dies sollte
immer mit Hilfe eines
Der Selbstbezug auf die Klasse beim Erstellen des
Beispiel 1 zeigt drei typische Aufrufe
der
Dieser Aufruf ist durch die Abfrage von
Im Prinzip ist die Ausgabe des Methodenaufrufs (Zeilen 12-16)
völlig identisch. Sie enthält jedoch einen zusätzlichen Kniff: Der
Wert des Parameters
Konfiguration des Logging Systems
Betrachten wir als nächstes die Konfiguration des Logging
Systems. Was passiert eigentlich mit den generierten Meldungen? Es
würde an dieser Stelle zu weit führen, die mehrstufigen Filter im
einzelnen zu erläutern. Details hierzu finden Sie in der
API Referenz zur
Mit der Version 0.98 der qflib wurde im
Die folgenden Beispiele illustrieren die typischen Anwendungsfälle
und erläutern die Grundlagen, auf denen
Am einfachsten ist die Ausgabe auf
Das Erstellen einer Logdatei geschieht am einfachsten mittels der
Methode
Zeile 22 zeigt, wie die Verbindung mit dem Logserver qflog hergestellt werden
kann. Hierzu finden Sie die Details in der API Referenz zu
Vor dem Beenden des Programms ist es sinnvoll, das Logging sauber
zu beenden (Zeilen 30-32). Zunächst wird mit Hilfe von
Einstellen der
|
|
Beispiel 3: Einstellen der level für die
Logger |
Beispiel 3 erläutert zwei der
Möglichkeiten, die Generierung der Meldungen zu konfigurieren:
Durch direkte Angabe der Level im Quellcode und über die
Kommandozeile. In Zeile 12 wird zunächst der Level für alle
Klassen auf Log.MSGDETAIL
angehoben. Zeile 13
beschränkt die Meldungen aus der qflib auf
Fehlermeldungen. Zeilen 14 und 15 erlauben den Klassen aus
mypackage
Meldungen bis zum Level
Log.MTD
, für die Klasse
mypackage.NewClass
sogar bis
Log.DBGDETAIL
. Wichtig ist der Punkt ('.') am Ende
der Packageangabe in Zeilen 13 und 14. Die Reihenfolge dieser
Aufrufe ist übrigens völlig unerheblich.
Diese Methode ist wenig elegant, da Änderungen an den
Einstellungen nur über eine Anpassung des Programmcodes und
Neucompilierung erfolgen können. Besser ist es, die Einstellungen
in eine Property
Datei zu stellen, diese beim
Programmstart zu laden und die Properties
direkt an
Logger.setLogLevels zu übergeben.
Des weiteren kann der ArgsParser aus dem de.qfs.lib.util
Package der qflib
verwendet werden, um die Einstellungen beim Aufruf des Programms
über die Kommandozeile vorzunehmen. Zeilen 17-23 demonstrieren den
Einsatz des ArgsParsers
. Den zu Zeilen 12-15
identischen Effekt erzielt man dann mit einem Aufruf von
|
Am komfortabelsten ist der Einsatz des Logservers qflog, mit dessen Hilfe die Einstellungen über eine grafische Oberfläche selbst noch zur Laufzeit des Programms vorgenommen werden können. Was von Ihrer Seite für seinen Einsatz zu tun ist, wurde bereits im Beispiel 2 gezeigt. Genaueres zu Installation und Bedienung von qflog finden Sie im qflog Handbuch.
Das Logfenster von qflog läßt sich auch direkt in Ihr Programm integrieren, und zwar sehr einfach, wie das folgende Beispiel zeigt:
|
Beispiel 4: Einbinden der LogView
Komponente |
In Zeile 12 wird die LogView
Komponente initialisiert
und damit ist auch schon alles getan. Das Öffnen des Logfensters
wie in Zeile 13 werden Sie in einer echten Anwendung vermutlich
nicht generell beim Programmstart durchführen wollen, sondern
z.B. von einem Menü aus aufrufen.
![]() | Logging und Applets | ![]() |
![]() |
Ein Applet zu schreiben, das in allen gängigen Browsern läuft ist ungefähr so schwierig, wie eine interessante Webseite zu designen, die überall gleich aussieht. Es gibt einige versteckte Inkompatibilitäten zwischen den VM Implementationen im Netscape Navigator, Microsofts Internet Explorer und dem Java Plugin von SUN, das zudem noch in Versionen von 1.1 bis 1.3 verfügbar ist. Ein weiteres Problem ist die Sandbox, die die Möglichkeiten eines Applets aus Sicherheitsgründen einschränkt. Ein signiertes Applet kann zwar aus der Sandbox ausbrechen, aber das Signieren ist nicht gerade einfach und natürlich ist das Vorgehen für jede VM anders. Ein Wiedersehen mit dem "Hello world" AppletAll das macht das Schreiben und Debuggen von Applets nicht einfacher, so dass Logging eine große Hilfe wäre. Leider litt auch die qflib unter diesen Problemen (und leidet z.T. immer noch), aber wir haben mit Version 0.97.0 versucht, Lösungen zu finden.
Das größte Problem bestand darin, dass Microsoft ihren Internet
Explorer bis vor kurzem ohne RMI Unterstützung ausgeliefert
haben. Da es eine indirekte RMI-Abhängigkeit in der
Trotzdem sind die RMI Klassen nötig um Verbindung zu qflog aufnehmen zu können. Zum Glück stellen Microsoft wenigstens ein Paket zum Herunterladen auf ihrer Java Resources Seite zur Verfügung, mit dessen Hilfe sich die RMI Funktionalität im Internet Explorer nachrüsten läßt. Es reicht aus, dieses Paket auf dem Entwicklungsrechner zu installieren, für den späteren Einsatz eines Applets ist es nicht erforderlich.
Das nächste Problem unter dem qflib leidet ist die Einschränkung
der Kommunikation über das Netzwerk durch die Sandbox. Ein
unsigniertes Applet darf lediglich Verbindungen zu dem Rechner
aufnehmen, von dem es heruntergeladen wurde und es darf nicht
selbst auf Verbindungen von aussen warten. Dadurch muss qflog
auf dem Rechner gestartet werden, auf dem der Webserver für die
Applets liegt und RMI Callbacks, die für die Kontrolle der Level
der Es folgt ein Beispiel Applet, das alles Nötige beinhaltet, um Logging wenigstens so weit wie möglich zu nutzen:
Wie Sie in Zeile 9 sehen, dürfen Sie keine RMI-abhängigen
Klassen direkt importieren, da sonst die Initailisierung des
Applets mit einer
Der Rest des Applets ist ziemlich offensichtlich und enthält keine
neuen Konzepte. Ein Blick auf die Zeilen 32-36 und die
|
![]() | Package de.qfs.lib.util | ![]() |
![]() |
Im Folgenden wollen wir den Einsatz einiger wichtiger Klassen aus
dem Kommandozeilenoptionen auswerten mit dem
|
|
erwartet, d.h. mit den Optionen version
,
dir
und option
, wobei dir
und option
Parameter erwarten und option
mehrfach auftreten darf. Darüber hinaus soll die Konfiguration des
Logging Systems über Optionen, die mit log-
beginnen
möglich sein (siehe auch Beispiel 3 des
de.qfs.lib.log
Packages). Nach den Optionen wird die Angabe eines
Dateinamens erwartet.
|
Beispiel 1: Kommandozeile mit Hilfe eines
ArgsParsers auswerten |
Der Aufruf
|
führt im Beispiel 1 dazu, dass
filename
den Wert "myfile"
annimmt und
die Hashtable
options
wie folgt
aufgebaut ist:
Key | Value |
---|---|
"dir" |
"/home" |
"option" |
["opt1", "opt2"] |
Aufbauend auf dem ArgsParser
wurde mit Version 0.98
die neue Klasse LogSetup
eingeführt, die diverse
Argumente auswertet und das Logging entsprechend konfiguriert. So
ist es z.B. möglich, diverse Parameter der Log
Klasse
anzugeben (Ausgabelevel etc.), ebenso wie die Level der
Logger
. Ausgaben lassen sich in ein oder mehrere
Dateien umleiten, die Verbindung mit dem Logserver qflog läßt
sich herstellen und sogar die LogView
Komponente des
Logservers direkt in die Applikation einbinden.
Die genauen Angaben über die Optionen und deren Bedeutung
entnehmen Sie bitte der API
Referenz zu LogSetup
. Das folgende
Beispiel zeigt, wie einfach es ist, LogSetup
in Ihre
Applikation einzubinden:
|
Beispiel 2: Einbinden der LogSetup Klasse
|
MapResourceBundle
Java bietet mit dem ResourceBundle
Mechanismus
eine weitreichende Unterstützung von länderspezifischer
Lokalisierung. Das MapResourceBundle
erweitert diesen
um einige nützliche Funktionen:
jar
ArchivenExceptions
beim Abfragen von
ResourcenIcons
|
Beispiel 3: Lokalisierung mit dem
MapResourceBundle |
In Zeile 12 wird das MapResourceBundle
zunächst mit
den Properties der qflib bestückt. Anschliessend (Zeile 13)
werden eigene Properties aus mypackage
hinzugefügt,
die durchaus Werte aus der qflib überschreiben können, um diese
an das eigene Programm anzupassen. Die übergebenen Klassen dienen
zum Auffinden der Property Dateien in jar
Archiven. Sie müssen so gewählt sein, dass sie im selben Archiv
liegen wie die Property Datei.
Das so inititalisierte MapResourceBundle
kann nun zum
Beispiel an die Message
Klasse aus
dem de.qfs.lib.gui
Package zur Ausgabe
von lokalisierten Fehlerdialogen weitergereicht werden.
Zeile 17 demonstriert die Abfrage eines Wertes aus den Properties,
bei der der Defaultwert angegeben wird, für den Fall, dass
der Schlüssel des Wertes nicht vorhanden ist. Das vereinfacht die
Handhabung im Vergleich zu Exceptions
erheblich.
Damit die Abfrage des Icons
(Zeile 18) funktioniert,
muß in mypackage/resources/myproperties
dem Schlüssel
"myicons.arrow"
der Pfad der Grafikdatei mit dem
entsprechenden Icon zugeordnet sein, zum Beispiel
"/mypackage/myicons/arrow.gif".
![]() | Package de.qfs.lib.gui | ![]() |
![]() |
Eine Tabelle mit automatischer Sortierung
Das
Beispiel 1 zeigt, wie Sie eine Tabelle mit
der Standardfunktionalität zur Sortierung erzeugen. Diese hat
keinen Filter, sortiert wird in Abhängigkeit der Klasse von
Objektern einer Spalte, wie sie von
Ein komplexeres Demo, das auch einen Filter implementiert, ist als
Die Spalte für die Sortierung wird durch einfachen Click in den Spaltenkopf bestimmt. Ein weiterer Click in den selben Kopf kehrt die Sortierrichtung um. Ein kleiner Pfeil im Spaltenkopf zeigt die aktuelle Sortierung an. Des weiteren können Sie mit einem Doppelklick in den Spaltenkopf die Spalte auf die Breite anpassen, die zur Anzeige für die aktuell sichtbaren Zellen dieser Spalte benötigt wird.
Eine sortierte Tabelle behält beim Umsortieren die Selektion ihrer
Zeilen bei, wie Sie leicht nachvollziehen können indem Sie ein
paar Zeilen selektieren und dann die Sortierung ändern. Sollten
Sie das Mit Hilfe der ComboBox oben im Fenster können Sie zwischen verschiedenen Filtereinstellungen wählen.
Es gibt einen wichtigen Punkt bei der Implementierung einer
sortierten Tabelle dessen Sie sich bewusst sein sollten: Das
|