Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.
 
Inhaltsverzeichnis
Vorwort
1 Java ist auch eine Sprache
2 Imperative Sprachkonzepte
3 Klassen und Objekte
4 Der Umgang mit Zeichenketten
5 Eigene Klassen schreiben
6 Objektorientierte Beziehungsfragen
7 Ausnahmen müssen sein
8 Äußere.innere Klassen
9 Besondere Typen der Java SE
10 Generics<T>
11 Lambda-Ausdrücke und funktionale Programmierung
12 Architektur, Design und angewandte Objektorientierung
13 Die Klassenbibliothek
14 Einführung in die nebenläufige Programmierung
15 Einführung in Datenstrukturen und Algorithmen
16 Einführung in grafische Oberflächen
17 Einführung in Dateien und Datenströme
18 Einführung ins Datenbankmanagement mit JDBC
19 Einführung in <XML>
20 Testen mit JUnit
21 Bits und Bytes und Mathematisches
22 Die Werkzeuge des JDK
A Java SE Paketübersicht
Stichwortverzeichnis

Download:
- Beispielprogramme, ca. 20,0 MB
- Übungsaufgaben, ca. 1,8 MB
- Musterlösungen, ca. 0,8 MB

Buch bestellen
Ihre Meinung?

Spacer
<< zurück
Java ist auch eine Insel von Christian Ullenbloom
Das umfassende Handbuch
Buch: Java ist auch eine Insel

Java ist auch eine Insel
Rheinwerk Computing
1306 Seiten, gebunden, 11. Auflage
49,90 Euro, ISBN 978-3-8362-2873-2
Pfeil 13 Die Klassenbibliothek
Pfeil 13.1 Die Java-Klassenphilosophie
Pfeil 13.1.1 Übersicht über die Pakete der Standardbibliothek
Pfeil 13.1.2 Compact-Profile
Pfeil 13.2 Sprachen der Länder
Pfeil 13.2.1 Sprachen und Regionen über Locale-Objekte
Pfeil 13.3 Die Klasse Date
Pfeil 13.3.1 Objekte erzeugen und Methoden nutzen
Pfeil 13.3.2 Date-Objekte sind nicht immutable
Pfeil 13.4 Calendar und GregorianCalendar
Pfeil 13.4.1 Die abstrakte Klasse Calendar
Pfeil 13.4.2 Calendar nach Date und Millisekunden fragen
Pfeil 13.4.3 Abfragen und Setzen von Datumselementen über Feldbezeichner
Pfeil 13.4.4 Kalender-Exemplare bauen über den Calendar.Builder
Pfeil 13.4.5 Der gregorianische Kalender
Pfeil 13.4.6 Date-Time-API in Java 8
Pfeil 13.5 Klassenlader (Class Loader) und Klassenpfad
Pfeil 13.5.1 Woher die kleinen Klassen kommen
Pfeil 13.5.2 Setzen des Klassenpfades
Pfeil 13.5.3 Die wichtigsten drei Typen von Klassenladern
Pfeil 13.6 Die Utility-Klasse System und Properties
Pfeil 13.6.1 Systemeigenschaften der Java-Umgebung
Pfeil 13.6.2 line.separator
Pfeil 13.6.3 Eigene Properties von der Konsole aus setzen *
Pfeil 13.6.4 Umgebungsvariablen des Betriebssystems *
Pfeil 13.6.5 Einfache Zeitmessung und Profiling *
Pfeil 13.7 Einfache Benutzereingaben
Pfeil 13.7.1 Grafischer Eingabedialog über JOptionPane
Pfeil 13.7.2 Geschützte Passwort-Eingaben mit der Klasse Console *
Pfeil 13.8 Ausführen externer Programme *
Pfeil 13.8.1 ProcessBuilder und Prozesskontrolle mit Process
Pfeil 13.8.2 Einen Browser, E-Mail-Client oder Editor aufrufen
Pfeil 13.9 Benutzereinstellungen *
Pfeil 13.9.1 Benutzereinstellungen mit der Preferences-API
Pfeil 13.9.2 Einträge einfügen, auslesen und löschen
Pfeil 13.9.3 Auslesen der Daten und Schreiben in einem anderen Format
Pfeil 13.9.4 Auf Ereignisse horchen
Pfeil 13.9.5 Zugriff auf die gesamte Windows-Registry
Pfeil 13.10 Zum Weiterlesen
 
Zum Seitenanfang

13.9Benutzereinstellungen * Zur vorigen ÜberschriftZur nächsten Überschrift

Einstellungen des Benutzers – wie die letzten vier geöffneten Dateien oder die Position eines Fensters – müssen abgespeichert und erfragt werden können. Dafür bietet Java eine Reihe von Möglichkeiten. Sie unterscheiden sich unter anderem in dem Punkt, ob die Daten lokal beim Benutzer oder zentral auf einem Server abgelegt sind.

Im lokalen Fall lassen sich die Einstellungen zum Beispiel in einer Datei speichern. Das Dateiformat kann in Textform oder binär sein. In Textform lassen sich die Informationen etwa in der Form Schlüssel=Wert oder im XML-Format ablegen. Werden Datenstrukturen mit den Benutzereinstellungen serialisiert, kommen in der Regel binäre Dateien heraus. Unter Windows gibt es eine andere Möglichkeit der Speicherung: die Registry. Auch sie ist eine lokale Datei, nur kann das Java-Programm keinen direkten Zugriff auf die Datei vornehmen, sondern muss über Betriebssystemaufrufe Werte einfügen und erfragen.

Sollen die Daten nicht auf dem Benutzerrechner abgelegt werden, sondern zentral auf einem Server, so gibt es auch verschiedene Standards. Die Daten können zum Beispiel über einen Verzeichnisdienst oder Namensdienst verwaltet werden. Bekanntere Dienste sind hier LDAP oder Active Directory. Zum Zugriff auf die Dienste lässt sich das Java Naming and Directory Interface (JNDI) einsetzen. Natürlich können die Daten auch in einer ganz normalen Datenbank stehen, auf die dann die eingebaute JDBC-API Zugriff gewährt. Bei den letzten beiden Formen können die Daten auch lokal vorliegen, denn eine Datenbank oder ein Server, der über JDNI zugänglich ist, kann auch lokal sein. Der Vorteil von nichtlokalen Servern ist einfach der, dass sich der Benutzer flexibler bewegen kann und immer Zugriff auf seine Daten hat.

Zu guter Letzt lassen sich Einstellungen auch auf der Kommandozeile übergeben. Das lässt die Option -D auf der Kommandozeile zu, wenn das Dienstprogramm java die JVM startet. Nur lassen sich dann die Daten nicht einfach vom Programm ändern, aber zumindest lassen sich so sehr einfach Daten an das Java-Programm übertragen.

 
Zum Seitenanfang

13.9.1Benutzereinstellungen mit der Preferences-API Zur vorigen ÜberschriftZur nächsten Überschrift

Mit der Klasse java.util.prefs.Preferences können Konfigurationsdateien gespeichert und abgefragt werden. Für die Benutzereinstellungen stehen zwei Gruppen zur Verfügung: die Benutzerumgebung und die Systemumgebung. Die Benutzerumgebung ist individuell für jeden Benutzer (jeder Benutzer hat andere Dateien zum letzten Mal geöffnet), aber die Systemumgebung ist global für alle Benutzer. Je nach Betriebssystem verwendet die Preferences-Implementierung unterschiedliche Speichervarianten und Orte:

  • Unter Windows wird dazu ein Teilbaum der Registry reserviert. Java-Programme bekommen einen Zweig, SOFTWARE\JavaSoft\Prefs unter HKEY_LOCAL_MACHINE bzw. HKEY_CURRENT_USER zugewiesen. Es lässt sich nicht auf die gesamte Registry zugreifen!

  • Unix und Mac OS X speichern die Einstellungen in XML-Dateien. Die Systemeigenschaften landen bei Unix unter /etc/.java/.systemPrefs und die Benutzereigenschaften lokal unter $HOME/.java/.userPrefs. Mac OS X speichert Benutzereinstellungen im Verzeichnis /Library/Preferences/.

Erfragen der Ausgangsobjekte Preferences

Preferences-Objekte lassen sich über statische Methoden auf zwei Arten erlangen:

  • Die erste Möglichkeit nutzt einen absoluten Pfad zum Registry-Knoten. Die Methoden sind am Preferences-Objekt befestigt und heißen für die Benutzerumgebung userRoot() und für die Systemumgebung systemRoot().

  • Die zweite Möglichkeit nutzt die Eigenschaft, dass automatisch jede Klasse in eine Paketstruktur eingebunden ist. userNodeForPackage(Class) oder systemNodeForPackage(Class) liefern ein Preferences-Objekt für eine Verzeichnisstruktur, in der die Klasse selbst liegt.

[zB]Beispiel

Erfrage ein Benutzer-Preferences-Objekt über einen absoluten Pfad und über die Paketstruktur der eigenen Klasse:

Preferences userPrefs = Preferences.userRoot().node( "/com/tutego/insel" );
Preferences userPrefs = Preferences.userNodeForPackage( this.getClass() );

Eine Unterteilung in eine Paketstruktur ist anzuraten, da andernfalls Java-Programme gegenseitig die Einstellung überschreiben könnten; die Registry-Informationen sind für alle sichtbar. Die Einordnung in das Paket der eigenen Klasse ist eine der Möglichkeiten.

abstract class java.util.prefs.Preferences

  • static Preferences userRoot()
    Liefert ein Preferences-Objekt für Einstellungen, die lokal für den Benutzer gelten.

  • static Preferences systemRoot()
    Liefert ein Preferences-Objekt für Einstellungen, die global für alle Benutzer gelten.

 
Zum Seitenanfang

13.9.2Einträge einfügen, auslesen und löschen Zur vorigen ÜberschriftZur nächsten Überschrift

Die Klasse Preferences hat große Ähnlichkeit mit den Klassen Properties bzw. HashMap (vergleiche Kapitel 15, »Einführung in Datenstrukturen und Algorithmen«). Schlüssel/Werte-Paare lassen sich einfügen, löschen und erfragen. Allerdings ist die Klasse Preferences kein Mitglied der Collection-API, und es existiert auch keine Implementierung von Collection-Schnittstellen.

abstract class java.util.prefs.Preferences

  • abstract void put(String key, String value)

  • abstract void putBoolean(String key, boolean value)

  • abstract void putByteArray(String key, byte[] value)

  • abstract void putDouble(String key, double value)

  • abstract void putFloat(String key, float value)

  • abstract void putInt(String key, int value)

  • abstract void putLong(String key, long value)
    Bildet eine Assoziation zwischen den Schlüsselnamen und dem Wert. Die Varianten mit den speziellen Datentypen nehmen intern eine einfache String-Umwandlung vor und sind nur kleine Hilfsmethoden; so steht in putDouble(…) nur put(key, Double.toString(value)). Die Hilfsmethode putByteArray(…) konvertiert die Daten nach der Base64-Kodierung und legt sie intern als String ab.

  • abstract String get(String key, String def)

  • abstract boolean getBoolean(String key, boolean def)

  • abstract byte[] getByteArray(String key, byte[] def)

  • abstract double getDouble(String key, double def)

  • abstract float getFloat(String key, float def)

  • abstract int getInt(String key, int def)

  • abstract long getLong(String key, long def)
    Liefert den gespeicherten Wert typgerecht aus. Fehlerhafte Konvertierungen werden etwa mit einer NumberFormatException bestraft. Der zweite Parameter erlaubt die Angabe eines Alternativwerts, falls es keinen assoziierten Wert zu dem Schlüssel gibt.

  • abstract String[] keys()
    Liefert alle Knoten unter der Wurzel, denen ein Wert zugewiesen wurde. Falls der Knoten keine Eigenschaften hat, liefert keys() ein leeres Feld.

  • abstract void flush()
    Die Änderungen werden unverzüglich in den persistenten Speicher geschrieben.

Unser folgendes Programm richtet einen neuen Knoten unter /com/tutego/insel ein. Aus den über System.getProperties() ausgelesenen Systemeigenschaften sollen alle Eigenschaften, die mit »user.« beginnen, in die Registry übernommen werden:

Listing 13.13com/tutego/insel/prefs/PropertiesInRegistry.java, Ausschnitt 1

static Preferences prefs = Preferences.userRoot().node( "/com/tutego/insel" );

static void fillRegistry() {
for ( Object o : System.getProperties().keySet() ) {
String key = o.toString();

if ( key.startsWith("user.") && ! System.getProperty(key).isEmpty() )
prefs.put( key, System.getProperty(key) );
}
}

Um die Elemente auszulesen, kann ein bestimmtes Element mit getXXX(…) erfragt werden. Die Ausgabe aller Elemente unter einem Knoten gelingt am besten mit keys(). Das Auslesen kann eine BackingStoreException auslösen, falls der Zugriff auf den Knoten nicht möglich ist.

Mit get(…) erfragen wir im folgenden Code den mit dem Schlüssel assoziierten Wert. Wir geben »---« aus, falls der Schlüssel keinen assoziierten Wert besitzt:

Listing 13.14com/tutego/insel/prefs/PropertiesInRegistry.java, Ausschnitt 2

static void display() {
try {
for ( String key : prefs.keys() )
System.out.println( key + ": " + prefs.get(key, "---") );
}
catch ( BackingStoreException e ) {
System.err.println( "Knoten können nicht ausgelesen werden: " + e );
}
}

[+]Hinweis

Die Größen der Schlüssel und Werte sind beschränkt! Der Knoten- und Schlüsselname darf maximal Preferences.MAX_NAME_LENGTH/MAX_KEY_LENGTH Zeichen umfassen, und die Werte dürfen nicht größer als MAX_VALUE_LENGTH sein. Die aktuelle Belegung der Konstanten gibt 80 Zeichen und 8 KiB (8.192 Zeichen) an.

Um Einträge wieder loszuwerden, gibt es drei Methoden: clear(…), remove(…) und removeNode(…). Die Namen sprechen für sich.

 
Zum Seitenanfang

13.9.3Auslesen der Daten und Schreiben in einem anderen Format Zur vorigen ÜberschriftZur nächsten Überschrift

Die Daten aus den Preferences lassen sich mit exportNode(OutputStream) bzw. exportSubtree(OutputStream) im UTF-8-kodierten XML-Format in einen Ausgabestrom schreiben. exportNode(OutputStream) speichert nur einen Knoten, und exportSubtree(OutputStream) speichert den Knoten inklusive seiner Kinder. Und auch der umgekehrte Weg funktioniert: importPreferences(InputStream) importiert Teile in die Registrierung. Die Schreib- und Lesemethoden lösen eine IOException bei Fehlern aus, und eine InvalidPreferencesFormatException ist beim Lesen möglich, wenn die XML-Daten ein falsches Format haben.

 
Zum Seitenanfang

13.9.4Auf Ereignisse horchen Zur vorigen ÜberschriftZur nächsten Überschrift

Änderungen an den Preferences lassen sich mit Listenern verfolgen. Zwei sind im Angebot:

  • Der NodeChangeListener reagiert auf Einfüge- und Löschoperationen von Knoten.

  • Der PreferenceChangeListener informiert bei Wertänderungen.

Es ist nicht gesagt, dass, wenn andere Applikationen die Einstellungen ändern, diese Änderungen vom Java-Programm auch erkannt werden.

Eine eigene Klasse NodePreferenceChangeListener soll die beiden Schnittstellen NodeChangeListener und PreferenceChangeListener implementieren und auf der Konsole die erkannten Änderungen ausgeben:

Listing 13.15com/tutego/insel/prefs/NodePreferenceChangeListener.java, NodePreferenceChangeListener

class NodePreferenceChangeListener implements
NodeChangeListener, PreferenceChangeListener {

@Override public void childAdded( NodeChangeEvent e ) {
Preferences parent = e.getParent(), child = e.getChild();

System.out.println( parent.name() + " hat neuen Knoten " + child.name() );
}

@Override public void childRemoved( NodeChangeEvent e ) {
Preferences parent = e.getParent(), child = e.getChild();

System.out.println( parent.name() + " verliert Knoten " + child.name() );
}

@Override public void preferenceChange( PreferenceChangeEvent e ) {
String key = e.getKey(), value = e.getNewValue();

Preferences node = e.getNode();

System.out.println( node.name() + " hat neuen Wert " + value + " für " + key );
}
}

Zum Anmelden eines Listeners bietet Preferences zwei addXXXChangeListener(…)-Methoden:

Listing 13.16com/tutego/insel/prefs/PropertiesInRegistry.java, addListener()

NodePreferenceChangeListener listener = new NodePreferenceChangeListener();
prefs.addNodeChangeListener( listener );
prefs.addPreferenceChangeListener( listener );
 
Zum Seitenanfang

13.9.5Zugriff auf die gesamte Windows-Registry Zur vorigen ÜberschriftZur nächsten Überschrift

Wird Java unter MS Windows ausgeführt, so ergibt sich hin und wieder die Aufgabe, Eigenschaften der Windows-Umgebung zu kontrollieren. Viele Eigenschaften des Windows-Betriebssystems sind in der Registry versteckt, und Java bietet als plattformunabhängige Sprache keine Möglichkeit, diese Eigenschaften in der Registry auszulesen oder zu verändern. (Die Schnittstelle java.rmi.registry.Registry ist eine Zentrale für entfernte Aufrufe und hat mit der Windows-Registry nichts zu tun. Auch das Paket java.util.prefs mit der Klasse Preferences erlaubt nur Modifikationen an einem ausgewählten Teil der Windows-Registry.)

Um von Java aus auf alle Teile der Windows-Registry zuzugreifen, gibt es mehrere Möglichkeiten, unter anderem:

  • Um auf allen Werten der Windows-Registry, die dem Benutzer zugänglich sind, operieren zu können, lässt sich mit einem Trick ab Java 1.4 eine Klasse nutzen, die Preferences unter Windows realisiert: java.util.prefs.WindowsPreferences. Damit ist keine zusätzliche native Implementierung – und damit eine Windows-DLL im Klassenpfad – nötig. Die Bibliothek http://sourceforge.net/projects/jregistrykey/ realisiert eine solche Lösung.

  • eine native Bibliothek, wie das Windows Registry API Native Interface (http://tutego.com/go/jnireg), die frei zu benutzen ist und unter keiner besonderen Lizenz steht

  • das Aufrufen des Konsolenregistrierungsprogramms reg.exe zum Setzen und Abfragen von Schlüsselwerten

Registry-Zugriff selbst gebaut

Für einfache Anfragen lässt sich der Registry-Zugriff schnell auch von Hand erledigen. Dazu bringt Windows zwei Kommandozeilenprogramme mit: regedit.exe und reg.exe. Während regedit eher ein grafisches Werkzeug ist, welches aber auch Textdateien mit Registrierungsdaten schreiben kann, ist reg etwas einfacher gestrickt. Ein guter Start ist reg /?, das alle Befehle anzeigt. Interessant sind die Befehle query (Abfrage), add (Eintrag hinzufügen) und delete (Eintrag löschen). Die Abfrage, wie der Dateiname für den Desktop-Hintergrund aussieht, sieht damit so aus:

$ reg query "HKEY_CURRENT_USER\Control Panel\Desktop" /v Wallpaper

! REG.EXE VERSION 3.0

HKEY_CURRENT_USER\Control Panel\Desktop
Wallpaper REG_SZ C:\Dokumente und Einstellungen\tutego\Anwendungsdaten\Hg.bmp

Der Aufruf reg query /? liefert weitere Erklärungen.

Wenn wir reg von Java aufrufen, haben wir den gleichen Effekt:

Listing 13.17com/tutego/insel/lang/JavaWinReg.java, main()

ProcessBuilder builder = new ProcessBuilder(
"reg", "query",
"\"HKEY_CURRENT_USER\\Control Panel\\Desktop\"", "/v", "Wallpaper" );
Process p = builder.start();
try ( Scanner scanner = new Scanner( p.getInputStream() ) ) {
scanner.nextLine(); // Springe über ! REG.EXE VERSION 3.0
scanner.nextLine(); // Springe über HKEY_CURRENT_USER\Control Panel\Desktop
scanner.useDelimiter( "\\s+\\w+\\s+\\w+\\s+" );
System.out.println( scanner.next() );
}

 


Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.

>> Zum Feedback-Formular
<< zurück
 Zum Katalog
Zum Katalog: Java ist auch eine Insel Java ist auch eine Insel
Jetzt bestellen

 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchempfehlungen
Zum Katalog: Java SE 8 Standard-Bibliothek
Java SE 8 Standard-Bibliothek


Zum Katalog: Professionell entwickeln mit Java EE 7
Professionell entwickeln mit Java EE 7


Zum Katalog: Schrödinger programmiert Java
Schrödinger programmiert Java


Zum Katalog: Einführung in Java
Einführung in Java


Zum Katalog: Programmieren lernen mit Java
Programmieren lernen mit Java


Zum Katalog: Apps entwickeln für Android 5
Apps entwickeln für Android 5


Zum Katalog: Apps entwickeln mit Android Studio
Apps entwickeln mit Android Studio


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo

 
 


Copyright © Rheinwerk Verlag GmbH 2016
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

 
Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de