Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.
 
Inhaltsverzeichnis
Vorwort
1 Neues in Java 8 und Java 7
2 Fortgeschrittene String-Verarbeitung
3 Threads und nebenläufige Programmierung
4 Datenstrukturen und Algorithmen
5 Raum und Zeit
6 Dateien, Verzeichnisse und Dateizugriffe
7 Datenströme
8 Die eXtensible Markup Language (XML)
9 Dateiformate
10 Grafische Oberflächen mit Swing
11 Grafikprogrammierung
12 JavaFX
13 Netzwerkprogrammierung
14 Verteilte Programmierung mit RMI
15 RESTful und SOAP-Web-Services
16 Technologien für die Infrastruktur
17 Typen, Reflection und Annotationen
18 Dynamische Übersetzung und Skriptsprachen
19 Logging und Monitoring
20 Sicherheitskonzepte
21 Datenbankmanagement mit JDBC
22 Java Native Interface (JNI)
23 Dienstprogramme für die Java-Umgebung
Stichwortverzeichnis

Jetzt Buch bestellen
Ihre Meinung?

Spacer
<< zurück
Java SE 8 Standard-Bibliothek von Christian Ullenboom
Das Handbuch für Java-Entwickler
Buch: Java SE 8 Standard-Bibliothek

Java SE 8 Standard-Bibliothek
Pfeil 5 Raum und Zeit
Pfeil 5.1 Weltzeit *
Pfeil 5.2 Wichtige Datum-Klassen im Überblick
Pfeil 5.2.1 Der 1.1.1970
Pfeil 5.2.2 System.currentTimeMillis()
Pfeil 5.2.3 Einfache Zeitumrechnungen durch TimeUnit
Pfeil 5.3 Sprachen der Länder
Pfeil 5.3.1 Sprachen und Regionen über Locale-Objekte
Pfeil 5.4 Internationalisierung und Lokalisierung
Pfeil 5.4.1 ResourceBundle-Objekte und Ressource-Dateien
Pfeil 5.4.2 Ressource-Dateien zur Lokalisierung
Pfeil 5.4.3 Die Klasse ResourceBundle
Pfeil 5.4.4 Ladestrategie für ResourceBundle-Objekte
Pfeil 5.4.5 Ladeprozess und Format anpassen *
Pfeil 5.5 Die Klasse Date
Pfeil 5.5.1 Objekte erzeugen und Methoden nutzen
Pfeil 5.5.2 Date-Objekte sind nicht immutable
Pfeil 5.6 Calendar und GregorianCalendar
Pfeil 5.6.1 Die abstrakte Klasse Calendar
Pfeil 5.6.2 Calendar nach Date und Millisekunden fragen
Pfeil 5.6.3 Abfragen und Setzen von Datumselementen über Feldbezeichner
Pfeil 5.6.4 Kalender-Typen *
Pfeil 5.6.5 Kalender-Exemplare bauen über den Calendar.Builder
Pfeil 5.6.6 Wie viele Tage hat der Monat, oder wie viele Monate hat ein Jahr? *
Pfeil 5.6.7 Wann beginnt die Woche und wann die erste Woche im Jahr? *
Pfeil 5.6.8 Der gregorianische Kalender
Pfeil 5.7 Zeitzonen in Java *
Pfeil 5.7.1 Zeitzonen durch die Klasse TimeZone repräsentieren
Pfeil 5.7.2 SimpleTimeZone
Pfeil 5.7.3 Methoden von TimeZone
Pfeil 5.9 Formatieren und Parsen von Datumsangaben
Pfeil 5.9.1 Ausgaben mit printf(…)
Pfeil 5.9.2 Ausgaben mit Calendar-Methoden getDisplayName(…) *
Pfeil 5.9.3 Mit DateFormat und SimpleDateFormat formatieren
Pfeil 5.9.4 Parsen von Datumswerten
Pfeil 5.10 Date-Time-API in Java 8
Pfeil 5.10.1 Datumsklasse LocalDate
Pfeil 5.10.2 Ostertage *
Pfeil 5.10.3 Die Klasse YearMonth
Pfeil 5.10.4 Die Klasse MonthDay
Pfeil 5.10.5 Aufzählung DayOfWeek und Month
Pfeil 5.10.6 Klasse LocalTime
Pfeil 5.10.7 Klasse LocalDateTime
Pfeil 5.10.8 Klasse Year
Pfeil 5.10.9 Zeitzonen-Klassen ZoneId und ZoneOffset
Pfeil 5.10.10 Temporale Klassen mit Zeitzoneninformationen
Pfeil 5.10.11 Klassen Period und Duration
Pfeil 5.10.12 Klasse Instant
Pfeil 5.10.13 Parsen und Formatieren von Datumszeitwerten
Pfeil 5.10.14 Das Paket java.time.temporal *
Pfeil 5.10.15 Konvertierungen zwischen der klassischen API und Date-Time-API
Pfeil 5.11 Die Default-Falle
Pfeil 5.12 Zum Weiterlesen
 
Zum Seitenanfang

5.4Internationalisierung und Lokalisierung Zur vorigen ÜberschriftZur nächsten Überschrift

Soll ein Programm in jeder Kultur und jedem Sprachraum optimal laufen, ist auf eine ganze Reihe von Dingen zu achten:

  • Texte der Beschriftungen

  • Konventionen in Bezug auf Datum, Dezimalzahlen, Währungen, Telefonnummern

  • Ausrichtungen und Schreibrichtung

  • Grafiken, Farben

  • Töne, Musiken

In der Softwareentwicklung gibt es zwei Begriffe, die sich um sprachabhängige Programme drehen, Internationalisierung und Lokalisierung:

  • Internationalisierung: Die Internationalisierung eines Programms bedeutet, dass es so entwickelt und vorbereitet wurde, dass es unter beliebig vielen Sprachen arbeitet.

  • Lokalisierung: Die Lokalisierung ist der Prozess des Anpassens an eine bestimmte neue Sprache.

Eine Software, die gleich internationalisiert entworfen wird, kann leicht um andere Sprachen erweitert werden, und Unternehmen können somit schnell in neue Märkte eintreten. Java unterstützt das mit diversen Möglichkeiten:

  • Format-Klassen erleichtern die Formatierung von Datum und Zahlen.

  • ResourceBundle-Objekte ermöglichen unterschiedliche Sprachen durch Übersetzungsdateien bzw. eigene Abbildungen zwischen einem Schlüssel und einer Übersetzung.

  • Collator-Klassen aus dem java.text-Paket können sprachabhängig sortieren.

  • Swing kann Text und Komponenten mühelos von rechts nach links laufen lassen.

Die Vorbereitung kostet natürlich Zeit und gestalterische Klarheit. Ein Zuviel an Grafiken kann dabei der Lokalisierung im Weg stehen, etwa bei Handgesten, Bildern von Tieren oder Gesichtern.

 
Zum Seitenanfang

5.4.1ResourceBundle-Objekte und Ressource-Dateien Zur vorigen ÜberschriftZur nächsten Überschrift

Sollen Java-Programme sprachunabhängig gestaltet werden, müssen in der ersten Phase der Internationalisierung alle Zeichenketten einer Landessprache durch symbolische Namen ersetzt werden. Die Verbindung zwischen den symbolischen Namen und den landessprachlichen Texten übernimmt ein ResourceBundle-Objekt, hinter dem eine Lokalisierungsdatei steht. Wenn das Programm später eine Zeichenkette nutzen will, greift es auf den symbolischen Namen zurück, den dann das ResourceBundle-Objekt auf die entsprechende Übersetzung überträgt. ResourceBundle-Objekte sind spezielle Assoziativspeicher, die alle programmrelevanten Texte und Informationen für ein spezielles Land repräsentieren. Ein wesentliches Merkmal von Java besteht in der Fähigkeit dieser Datenspeicher, sich die passenden Lokalisierungsdateien selbst herauszusuchen.

 
Zum Seitenanfang

5.4.2Ressource-Dateien zur Lokalisierung Zur vorigen ÜberschriftZur nächsten Überschrift

Die Übersetzungen können aus Dateien oder einfachen Listen stammen; wir nehmen im Folgenden Dateien an. Da wir die Sprachen Englisch und Deutsch unterstützen wollen, legen wir im (frei wählbaren) Verzeichnis resources zwei Dateien an, eine für die englische und eine für deutsche Version:

Listing 5.2resources/HelloWorld_en.properties

# HelloWorld_en.properties
Hello=Hello World.
Bye=Bye.

Listing 5.3resources/HelloWorld_de.properties

# HelloWorld_de.properties
Hello=Hallo Welt.
Bye=Tschüss.

Die Datei enthält Schlüssel-Wert-Paare sowie Kommentare, die mit einer Raute beginnen. Mit einem Identifizierer – wie »Hello« – sind die landes-/sprachabhängigen Zeichenketten als Werte verbunden.

[»]Hinweis

Intern greift ResourceBundle zum Laden der Ressourcen-Dateien auf die Java-Klasse Properties zurück. Die Zeichenkodierung ist standardmäßig ISO 8859-1, was eher ungewöhnlich ist, da in der Java-Welt sonst UTF-8 Standard ist. Sind die Properties-Dateien nicht im ISO-8859-1-Format, gibt es schnell Datenmüll, insbesondere, wenn Zeichen in der Datei sind, die nicht Teil von ISO 8859-1 sind. Denn Nicht-ISO-8859-1-Zeichen müssen umkodiert werden in der Form \uXXXX, wobei X für ein Hexadezimalzeichen steht. Das ist aufwändig, und das JDK-Tool native2ansi kann UTF-8-Dateien in ISO-8859-1-Dateien konvertieren. Das sieht etwa so aus:

$ native2ascii -encoding utf8 utf8-resources.properties resources.properties

Richtig schön ist das aber nicht, doch zum Glück kann ResourceBundle über ResourceBundle.Control-Objekte das Laden selbst in die Hand nehmen.

Hinweise zum Einsatz gibt etwa http://stackoverflow.com/questions/4659929/how-to-use-utf-8-in-resource-properties-with-resourcebundle.

Die Dateinamen für die Ressourcen-Dateien haben dabei einen speziellen Aufbau. Sie setzen sich aus dem so genannten Basisnamen (hier HelloWorld), einem Unterstrich (»_«), einer Landeskennung und dem Datei-Suffix properties zusammen. Damit ergeben sich für die Sprachen Englisch und Deutsch die Dateinamen HelloWorld_en.properties und HelloWorld_de.properties.

Eclipse kann die Zeichenketten eines Programms automatisch in eine Datei auslagern. Dazu ist im Menü Source der Eintrag Externalize Strings… aufzurufen.

 
Zum Seitenanfang

5.4.3Die Klasse ResourceBundle Zur vorigen ÜberschriftZur nächsten Überschrift

Um auf die Übersetzungsdateien zurückgreifen zu können, benötigen wir ein Objekt der Klasse ResourceBundle. Die statische Fabrikmethode ResourceBundle.getBundle(String) liefert den Assoziativspeicher, wobei das Argument der Basisname wie »HelloWorld« ist. Über den Schlüssel sucht die Methode getString(String key) die landesspezifische Meldung heraus:

Listing 5.4com/tutego/insel/bundle/InternationalHelloWorld.java

package com.tutego.insel.bundle;

import java.util.*;

//$java -Duser.language=en com.tutego.insel.bundle.InternationalHelloWorld
public class InternationalHelloWorld {

public static void main( String[] args ) {
String baseName = "resources.HelloWorld";

try {
ResourceBundle bundle = ResourceBundle.getBundle( baseName );
System.out.println( bundle.getString("Hello") );
}
catch ( MissingResourceException e ) {
System.err.println( e );
}
}
}
 
Zum Seitenanfang

5.4.4Ladestrategie für ResourceBundle-Objekte Zur vorigen ÜberschriftZur nächsten Überschrift

Die Methode getBundle(…) sucht automatisch anhand der eingestellten Landessprache die passende Datei aus dem Klassenpfad (aus diesem Grund heißt unser Basisname »resources.HelloWorld« und nicht nur einfach »HelloWorld«). Die Dateinamen für die jeweiligen ResourceBundle-Objekte können sehr variabel zusammengesetzt werden, wobei getBundle(…) die nachfolgenden Bildungsgesetze verwendet und bei der Dateisuche mit der speziellsten Beschreibung beginnt:

  • bundleName_localeLanguage_localeCountry_localeVariant

  • bundleName_localeLanguage_localeCountry

  • bundleName_localeLanguage

  • bundleName_defaultLanguage_defaultCountry_defaultVariant

  • bundleName_defaultLanguage_defaultCountry

  • bundleName_defaultLanguage

  • bundleName

Sind mehrere Ressourcen-Dateien im Klassenpfad, so integriert sie getBundle(…). Eine Datei wie HelloWorld_de.properties erweitert (und überschreibt unter Umständen) die Inhalte von HelloWorld.properties. Eine localeCountry ist zum Beispiel »CH« (das ist keine Variante), was zu einem Dateinamen HelloWorld_de_CH.properties führt.

Listing 5.5resources/HelloWorld_de_CH.properties

Hello=Grüezi.

Die Anfrage bundle.getString("Hello") liefert »Grüezi«, und bundle.getString("Bye") retourniert »Tschüss« aus der übergeordneten Datei. Die Datei HelloWorld_de_CH.properties überschreibt die hochdeutschen Wörter aus HelloWorld_de.properties mit Wörtern auf Schwyzerdütsch, was wiederum Wörter aus HelloWorld.properties überschreiben würde. Um das Programm zu testen, ändert folgende Zeile vor getBundle(…) die Sprache:

Locale.setDefault( new Locale("de", "CH") );

Gibt es dann eine Datei wie HelloWorld_de_CH.properties, aber HelloWorld_de.properties fehlt und die eingestellte Sprache ist nur Deutsch und nicht ausschließlich Schweizerdeutsch, beachtet getBundle(…) die Datei HelloWorld_de_CH.properties nicht, sondern nur eventuell vorgelagerte Dateien wie HelloWorld.properties.

abstract class java.util.ResourceBundle
  • static ResourceBundle getBundle(String baseName)
    Liefert das ResourceBundle für einen Basisnamen. Eine MissingResourceException folgt, wenn kein Resource-Bundle mit diesem Basisnamen gefunden werden konnte.

  • String getString(String key)
    Gibt den mit key assoziierten Wert von diesem Resource-Bundle oder von den Vätern zurück.

  • boolean containsKey(String key)
    Erfragt, ob es im Resource-Bundle für den Schlüssel eine Übersetzung gibt.

  • Set<String> keySet()
    Liefert alle Übersetzungen dieses Resource-Bundles.

  • String getBaseBundleName()
    Liefert den Namen des Resource-Bundles oder null, falls dieser nicht gegeben ist. Neu in Java 8.

Die einfache statische Fabrikmethode getBundle(…) bezieht zum Ansprechen der Dateien die Standardsprache aus Locale.getDefault().

 
Zum Seitenanfang

5.4.5Ladeprozess und Format anpassen * Zur vorigen ÜberschriftZur nächsten Überschrift

Die Lademethode getBundle(…) ist stark mit Logik verbunden, doch bietet die Java-API drei Varianten zur Anpassung:

  • Von ResourceBundle gibt es zwei Unterklassen, ListResourceBundle und PropertyResourceBundle. Während ListResourceBundle im Grunde ein zweidimensionales Feld mit den Übersetzungen aufbaut, lädt PropertyResourceBundle aus Property-Dateien, wobei hier auch beliebige Kodierungen wie UTF-8 erlaubt sind. Beispiele liefert die API-Dokumenation.

  • Die zweite Anpassung ist mit ResourceBundle.Control-Objekten möglich, die etwa bei getBundle(String baseName, ResourceBundle.Control control) übergeben werden. Diese Objekte werden »zurückgerufen« und können Einfluss auf das Laden und die Auswahl von Sprachen nehmen.

  • Die dritte Variante ist ResourceBundleControlProvider und neu in Java 8. Implementierungen dieser Schnittstelle lassen sich über den Service-Loader einbinden. Die Oracle-Seite http://docs.oracle.com/javase/tutorial/i18n/serviceproviders/resourcebundlecontrolprovider.html gibt ein paar Details.

Beispiel ListResourceBundle

Ein Resource-Bundle ohne Dateien, realisiert als ListResourceBundle, kann so aussehen:

Listing 5.6com/tutego/insel/bundle/MonthResourceBundle_de_DE.java,  MonthResourceBundle_de_DE

public class MonthResourceBundle_de_DE extends ListResourceBundle {

private static final String[] MONTHS = {
"Jan", "Feb", "Mrz", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"
};

private static final Object[][] contents = {
{ "jan", MONTHS[0] },
{ "month", MONTHS }
};

@Override
protected Object[][] getContents() {
return contents;
}
}

Die Nutzung der Klasse ist wie folgt:

Listing 5.7com/tutego/insel/bundle/MonthResourceBundleDemo.java, main()

ResourceBundle bundle = ResourceBundle.getBundle(
"com.tutego.insel.bundle.MonthResourceBundle" );
System.out.println( bundle.getString( "jan" ) ); // Jan
System.out.println( Arrays.toString( bundle.getStringArray( "month" ) ) );
// [Jan, Feb, …
System.out.println( Collections.list( bundle.getKeys() ) ); // [month, jan]

In diesem Fall lädt ResourceBundle.getBundle(…) keine Property-Datei, sondern eine Klasse im Klassenpfad. Die API von ResourceBundle bietet auch eine Methode getStringArray(), die ein Feld zurückgibt, jedoch ist das bei Ressourcen-Dateien nicht nötig, nur bei Ressourcen, die »von Hand« programmiert wurden, wie in unserem Beispiel.

 


Ihre Meinung

Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.

<< zurück
 Zum Rheinwerk-Shop
Zum Rheinwerk-Shop: Java SE 8 Standard-Bibliothek Java SE 8 Standard-Bibliothek
Jetzt Buch bestellen

 Buchempfehlungen
Zum Rheinwerk-Shop: Java ist auch eine Insel
Java ist auch eine Insel


Zum Rheinwerk-Shop: Professionell entwickeln mit Java EE 8
Professionell entwickeln mit Java EE 8


Zum Rheinwerk-Shop: Besser coden
Besser coden


Zum Rheinwerk-Shop: Entwurfsmuster
Entwurfsmuster


Zum Rheinwerk-Shop: IT-Projektmanagement
IT-Projektmanagement


 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und der Schweiz
InfoInfo

 
 


Copyright © Rheinwerk Verlag GmbH 2018
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

Cookie-Einstellungen ändern