Best Practice Localization über ResourceBundle

Ernesto95

Bekanntes Mitglied
Moin zusammen !

Ich habe hier ein kleines Problem wo ich mal eure Hilfe bräuchte bzgl. möglichem Umsetzungsvarianten und Best Practice.

Ein Programm soll mehrsprachig programmiert werden. Diverse Standardsprachen werden werden als Resourcen innerhalb der JAR im src Ordner mit ausgeliefert.

Der Anwender soll die Möglichkeit haben weitere Sprachen / Varianten hinzuzufügen. Diese werden außerhalb der JAR in einem separaten Ordner abgelegt (in meinem Fall im Home Verzeichnis in einem versteckten Ordner).

Die Auswahl der entsprechenden Datei im Programm funktioniert auch, aber das Problem ist, da sich die Property Files in unterschiedlichen Ordner befinden funktioniert die unten aufgeführte Ladestrategie bei fehlenden Schlüsseln nicht.

  • bundleName_localeLanguage_localeCountry_localeVariant
  • bundleName_localeLanguage_localeCountry
  • bundleName_localeLanguage
  • bundleName_defaultLanguage_defaultCountry_defaultVariant
  • bundleName_defaultLanguage_defaultCountry
  • bundleName_defaultLanguage
  • bundleName

Ich hoffe das Problem ist verständlich.

Was wäre jetzt hier die BestPractice das so umzusetzen das die Ladestrategie wieder funktioniert ?

1.
In der API habe ich nirgends eine Möglichkeit gefunden 2 unterschiedliche Ordner als Quelle für das RessourceBundle anzugeben. Falls es doch eine Möglichkeit gibt dann gebt mir bitte einen Hinweis, das wäre dann wahrscheinlich die beste Lösung

2.
Alternativ könnte ich zur Laufzeit sämtliche Property Files in EINEN externen, temporären Ordner kopieren, nur auf diesen Ordner zugreifen und diesen bei Programmende wieder löschen.

3.
Eine weitere Möglichkeit wäre statt über ResourceBundle die Properties-Klasse zu nutzen. Hier könnte ich für jede Locale ein Properties Objekt erstellen und diese dann entsprechend der gewünschten Ladestrategie miteinander verketten.

Vielen Dank für eure Hilfe !
 

Ernesto95

Bekanntes Mitglied
Hallo Max40,

danke für deinen Beitrag. Du hast aber glaube ich mein Problem nicht verstanden, oder ich verstehe deine Antwort nicht.

Folgendes:

Ich liefere mit der JAR im src Ordner die Dateien text.properties (Englisch als default) und text_de.properties aus. Der Anwender fügt nachträglich außerhalb des Klassenpfades in dem dafür definierten Ordner z.B. die Datei text_de_CH.properties hinzu.

Im Programm selbst wählt er unter Settings als Sprache Schweizerdeutsch. Ich übergebe demnach dem ResourceBundle Object den Pfad auf den externen Ordner in dem sich die Datei text_de_CH.properties befindet.

Jetzt sind aber in der Datei text_de_CH.properties nicht alle Schlüssel hinterlegt, sondern nur die von der Datei text_de.properties abweichenden. Da die Datei text_de.properties aber nicht im externen Ordner liegt sondern im src Ordner der JAR, kann das Resource Bundle nicht darauf zugreifen, da als Quelle nur der externe Ordner bekannt ist.

Frage nun: Wie bekomme ich es Best Practice hin alle vorhandenen properties Dateien aus 2 Ordnern in einem ResourceBundle zu vereinen ?

Nachtrag:
Beim Schreiben jetzt wurde mir gerade klar was du vielleicht meinst. Soll ich 2 ResourceBundle Objekte erstellen, dann erst beim ResourceBundle des externen Ordners anfragen und sollte es hier keinen Treffer geben dann die Anfrage an das ResourceBundle des internen Ordners weiterleiten ?

Grüße
 

Joose

Top Contributor
Lade default deine "text_de.properties" (bzw. die Datei in der alles enthalten ist). Wenn der User nun die Sprache des Programms ändern willst ladest du die gewünschte Sprache "einfach darüber" sprich alle unterschiede werden übernommen.
 

Ernesto95

Bekanntes Mitglied
Hallo Joose,

danke für deine Nachricht ! Habe einmal versucht das von dir erwähnte so wie ich es verstehe umzusetzen, allerdings mit wenig Erfolg.

Um es einfach zu halten habe ich auf den externen Ordner verzichtet und nur 2 unterschiedliche Resourcen Ordner im Project angelegt.

Folgende Struktur:
-src
--resourcebundletest
---ResourceBundleTest.java
---resourcebundletest.res1
----text.properties
----text_de.properties
---resourcebundletest.res2
----text_de_CH.properties
----text_de_CH_var.properties

text.properties
1=1_default
2=2_default
3=3_default
4=4_default

text_de.properties
1=1_de
2=2_de
3=3_de

text_de_CH.properties
1=1_de_CH
2=2_de_CH

text_de_CH_var.properties
1=1_de_CH_var

Java:
package resourcebundletest;

import java.util.Locale;
import java.util.ResourceBundle;

public class ResourceBundleTest {

    public static void main(String[] args) {
        ResourceBundle bundle = ResourceBundle.getBundle("resourcebundletest.res1.text");
        System.out.println("key 1 = "+bundle.getString("1"));
        System.out.println("key 2 = "+bundle.getString("2"));
        System.out.println("key 3 = "+bundle.getString("3"));
        System.out.println("key 4 = "+bundle.getString("4"));
        System.out.println("**********************************************");
        Locale loc = new Locale ("de", "CH", "var");
        bundle = ResourceBundle.getBundle("resourcebundletest.res2.text", loc);
        System.out.println("key 1 = "+bundle.getString("1"));
        System.out.println("key 2 = "+bundle.getString("2"));
        System.out.println("key 3 = "+bundle.getString("3"));
        System.out.println("key 4 = "+bundle.getString("4"));
        System.exit(0);
    }
}

Das Ergebnis auf der Console lautet wie folgt:

Code:
key 1 = 1_de
key 2 = 2_de
key 3 = 3_de
key 4 = 4_default
**********************************************
key 1 = 1_de_CH_var
key 2 = 2_de_CH
Exception in thread "main" java.util.MissingResourceException: Can't find resource for bundle java.util.PropertyResourceBundle, key 3
    at java.util.ResourceBundle.getObject(ResourceBundle.java:450)
    at java.util.ResourceBundle.getObject(ResourceBundle.java:444)
    at java.util.ResourceBundle.getString(ResourceBundle.java:407)
    at resourcebundletest.ResourceBundleTest.main(ResourceBundleTest.java:19)
/home/javosoft/.cache/netbeans/8.2/executor-snippets/run.xml:53: Java returned: 1
BUILD FAILED (total time: 0 seconds)

Die default Locale auf meinem System ist de, demnach sind die ersten 4 Zeilen korrekt. Erst zieht er sich die 3 Schlüssel für de, danach den fehlenden Schlüssel aus der default.

Dann simuliere ich im Code das der User die Sprache auf de_CH_var umstellt und lade das entsprechende bundle nach (in finalen Programm läge dies dann in einem externen Ordner).

Schlüssel 1 zieht er sich aus dem _de_CH_var File, Schlüssel 2 entsprechend der Ladestrategie aus dem _de_CH File. Schlüssel 3 müsste er sich eigentlich aus dem _de File und Schlüssel 4 aus dem default File ziehen, da diese aber in einem anderen Ordner liegen gibt es eine MissingResourceException.

Du schreibst oben ich könnte die gewünschte Sprache einfach drüberladen und die Unterschiede werden übernommen, aber hier löscht er vor dem 2. einlesen alle vorher eingelesenen keys.

Danke für deine Hilfe !

Grüße
 

Joose

Top Contributor
Dann simuliere ich im Code das der User die Sprache auf de_CH_var umstellt und lade das entsprechende bundle nach (in finalen Programm läge dies dann in einem externen Ordner).
Du ladest das Bundle und ersetzt das bereits vorhandene! Leider kenne ich mich mit diesen Klassen nicht so gut aus um dir zu sagen ob du einfach ein anderes Bundle nachladen kannst.
Du könntest aber eine eigene Klasse schreiben welche eben die Default Sprache ladet und die spezielle vom User. Wenn dann nach etwas gefragt wird schaust du zuerst in der Speziellen Sprache nach dann in der Default.

Du schreibst oben ich könnte die gewünschte Sprache einfach drüberladen und die Unterschiede werden übernommen
Ja das habe ich geschrieben, aber nicht in dem Sinn das dies mit Bundle so funktionieren muss.
 

Ernesto95

Bekanntes Mitglied
Hallo Joose,

danke für deine Antwort !

Du könntest aber eine eigene Klasse schreiben welche eben die Default Sprache ladet und die spezielle vom User. Wenn dann nach etwas gefragt wird schaust du zuerst in der Speziellen Sprache nach dann in der Default.
Damit wären wir ja dann im Grunde bei der schon von Max40 angedeuteten Lösung. Die sähe dann so aus ...

Java:
package resourcebundletest;

import java.util.Locale;

public class ResourceBundleTest {

    public static void main(String[] args) {
        Bundle bundle = new Bundle();
        System.out.println("key 1 = "+bundle.getString("1"));
        System.out.println("key 2 = "+bundle.getString("2"));
        System.out.println("key 3 = "+bundle.getString("3"));
        System.out.println("key 4 = "+bundle.getString("4"));
        System.out.println("**********************************************");
        Locale loc = new Locale ("de", "CH", "var");
        bundle.setUserBundle(loc);
        System.out.println("key 1 = "+bundle.getString("1"));
        System.out.println("key 2 = "+bundle.getString("2"));
        System.out.println("key 3 = "+bundle.getString("3"));
        System.out.println("key 4 = "+bundle.getString("4"));
        System.exit(0);
    }
}

Java:
package resourcebundletest;

import java.util.Locale;
import java.util.ResourceBundle;

public class Bundle {

    private ResourceBundle userBundle;
    private ResourceBundle defaultBundle;
   
    public Bundle(){
        defaultBundle = ResourceBundle.getBundle("resourcebundletest.res1.text");
    }
   
    public void setUserBundle (Locale loc){
        userBundle = ResourceBundle.getBundle("resourcebundletest.res2.text", loc);
    }
   
    public String getString(String key){
        if(userBundle!=null){
            if(userBundle.containsKey(key)) return userBundle.getString(key);
            else return defaultBundle.getString(key);
        }
        else return defaultBundle.getString(key);
    }      
}

Die Ausgabe erfolgt dann korrekt wie folgt:
Code:
key 1 = 1_de
key 2 = 2_de
key 3 = 3_de
key 4 = 4_default
**********************************************
key 1 = 1_de_CH_var
key 2 = 2_de_CH
key 3 = 3_de
key 4 = 4_default

Frage ist nur, ist das BestPractice ? Wundert mich gerade das es für dieses triviale Problem keine vorgefertigte Lösung gibt. Eigentlich ist das doch ein Problem was bei jedem Project auftaucht wo der Programmierer das Erstellen zusätzlicher Sprachpakete an die Community "outsourced" , oder nicht ? Oder wie wird sonst das nachträgliche zufügen von Sprachpaketen umgesetzt ?

Grüße
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
F Test für Localization Allgemeine Java-Themen 6
G Sprachauswahl-Dialog (Localization-Frage) Allgemeine Java-Themen 2
kodela Datenübergabe über Buttons Allgemeine Java-Themen 8
W Jar-File Start nur über Terminal Allgemeine Java-Themen 13
A ByteArray über Socket Allgemeine Java-Themen 3
berserkerdq2 Text über einen Shape anzeigen (Scenebuilder) Allgemeine Java-Themen 1
I 2D-Grafik Vektor-Grafik über die Zwischenablage nach Adobe Illustrator transferieren Allgemeine Java-Themen 8
TheSkyRider Methode über DataInputStream "auslösen" Allgemeine Java-Themen 6
I OpenPDF erzeugt riesige PDFs, wenn Grafiken über PdfGraphics2D#drawImage gezeichnet werden Allgemeine Java-Themen 1
T Etikettendrucker über TCP-IP Allgemeine Java-Themen 1
Encera Gleichzeitiges Ausführen und verbinden von 2 Java-Klassen über die Eingabeaufforderung und Eclipse Allgemeine Java-Themen 21
B HTTP Allgemeine Fragen über Suchmaschine nutzen mit Java Allgemeine Java-Themen 20
torresbig Klasse mit extends Calendar über Methoden ändern (Hirnblockade) Allgemeine Java-Themen 7
B Liste ändern während Iteration über Diese? Allgemeine Java-Themen 16
Master3000 Java Konsole über Buffered Reader Zeilenweise auslesen ? Allgemeine Java-Themen 26
J Daten über serielle Schnittstelle empfangen Allgemeine Java-Themen 4
L Aufwandsabschätzung: Android-App Aufnahmefunktion (foto) und zweiter Ebene über dem Foto (teiltransparent) Allgemeine Java-Themen 6
M Registry Autostart Eintrag mit Java erstellen (über Windows cmd) Allgemeine Java-Themen 7
OSchriever Programm über Linux-Kommandozeile ausführen Allgemeine Java-Themen 20
J Namen von Methoden über Reguläre Ausdrücke bearbeiten Allgemeine Java-Themen 6
M Schnelleres Speichern von XML-Daten über URLConnection Allgemeine Java-Themen 4
M Keine weitere Eingabe in der Main möglich. Eventueller Ansatz über while. Allgemeine Java-Themen 8
Drachenbauer Wie kann eine vorgegebene Farbe über einen String erkannt werden? Allgemeine Java-Themen 11
W Variablenübergabe über mehrere Klassen Allgemeine Java-Themen 4
N Über einen Button in JavaFX ein Event über eine Pipeline schicken(Netty) Allgemeine Java-Themen 1
M Threads über Kommandozeile Allgemeine Java-Themen 5
david19 Software AE über Domain laufen lassen Allgemeine Java-Themen 0
Q Selbständig ActionEvent auslösen zum Daten senden über serielle Schnittstelle Allgemeine Java-Themen 7
T Problem mit externen Datenbankzugriff über SSH Tunnel Allgemeine Java-Themen 4
K Auf Dateiverzeichnis extern zugreifen (evtl über XML??) Allgemeine Java-Themen 22
C VisualVM oder Jconsole über Jolokia-Proxy Allgemeine Java-Themen 0
G USB-Pins über Java ansteuern Allgemeine Java-Themen 8
C Classpath Neue Klasse über einen Button ausführen Allgemeine Java-Themen 3
C Auslesen auslösen über Button-Click Allgemeine Java-Themen 8
M Fragen beantworten über Textfeldeingabe Allgemeine Java-Themen 5
AssELAss Best Practice Checksumme über jede Spalte zweier Tabellen und vergleichen Allgemeine Java-Themen 3
T Strings über Bluetooth zwischen PC,µc oder Samrtphone senden und empfangen Allgemeine Java-Themen 0
F Try/catch über ganze Klasse Allgemeine Java-Themen 9
kodela Eigenartige Datumsberechnung über GregorianCalendar Allgemeine Java-Themen 15
HarleyDavidson Best Practice Integer-Zahlenfolge über mehrere Programmstarts Allgemeine Java-Themen 7
T .jar über cmd ausführen (später dann batch) Allgemeine Java-Themen 6
F In OSX: Java-Programm über URI-Scheme aufrufen mit Parameter? Allgemeine Java-Themen 0
C Input/Output Zip Files über Socket senden und empfangen Allgemeine Java-Themen 6
M WebService - Zugriff auf Webservice Methode über Browser Allgemeine Java-Themen 1
C .jar File lässt sich nur über Konsole öffnen Allgemeine Java-Themen 1
L Videodateien über Java öffnen unabhängig vom Format Allgemeine Java-Themen 4
Thallius Hash über serialisiertes Objekt? Allgemeine Java-Themen 3
A Threads Lock über mehrere Abschnitte in verschiedenen Methoden Allgemeine Java-Themen 5
T Daten über port abfangen mit proxy server Allgemeine Java-Themen 12
M Eingabe von Arrays geht über gewünschte Anzahl hinaus Allgemeine Java-Themen 2
L Prüfen, ob Programm über 32bit oder 64bit Java ausgeführt wird Allgemeine Java-Themen 4
F Content-Disposition ermitteln über URL Allgemeine Java-Themen 2
ARadauer Checksumme über BigDecimal Werte Allgemeine Java-Themen 11
A Class Datei aus Verzeichnis über URLClassLoader laden Allgemeine Java-Themen 2
G Darstellung von Ergebnissen einer Dokumentensuche über eine JTable Allgemeine Java-Themen 19
S VLC + Lied über Java starten Allgemeine Java-Themen 17
M HTML-Code von Webseite über Browser oder Console auslesen?? Allgemeine Java-Themen 5
A Sinuston ausgeben und über Mikro Amplitude messen – machbar? Allgemeine Java-Themen 6
R Java-Progamm über Icon starten unter Windows Allgemeine Java-Themen 9
C Daten über URL an PHP verschicken Allgemeine Java-Themen 4
O Fragen über Fragen - Bei Änderung XML-Datei -> Anpassung GUI Allgemeine Java-Themen 7
aze Jar ausführen über Runtime.execute funktioniert nicht Allgemeine Java-Themen 4
S NoSuchMethodError beim Ausführen einer C Methode über JNI Allgemeine Java-Themen 5
H OOP Daten über TCP Allgemeine Java-Themen 5
Pastafari Iterator über nested HashMaps Allgemeine Java-Themen 7
R ListIterator über mehrere Arrays Allgemeine Java-Themen 13
G Interface Laden der Konfiguration über Interfaces sinnvoll? Allgemeine Java-Themen 28
D Player Objekt - Frame über Server anzeigen lassen. Allgemeine Java-Themen 3
B VoIP-Gespräche über Computer führen Allgemeine Java-Themen 3
S Jar-File startet nicht über doppelklick Allgemeine Java-Themen 2
C Java Programm über SSH starten Allgemeine Java-Themen 16
K Internetverbindung über PuTTy herstellen?! Allgemeine Java-Themen 9
C Kapselung Warum graift man auf Variablen nur über Methoden und nich direkt zu? Allgemeine Java-Themen 10
G Auf Kommandozeile über Processobjekt mit Outputstream Allgemeine Java-Themen 3
S Input/Output Binärdatei über Bytestreams Allgemeine Java-Themen 4
S Kommunikation von Core und GUI über Schnittstellen Allgemeine Java-Themen 2
J Explorer über Code starten Allgemeine Java-Themen 15
kodela Problem mit Kopieren über FileChannel Allgemeine Java-Themen 4
L Java und Javascript um Distanz über Google Maps zu berchnen Allgemeine Java-Themen 10
B UNIX Shell befehl über JavaCode ausführen Allgemeine Java-Themen 19
D Java Excel API - Schreiben in Excel lässt sich nicht über Makro starten Allgemeine Java-Themen 18
M Ampelsteuerung über Timer in Java realisieren Allgemeine Java-Themen 3
L CMD über Java öffnen Allgemeine Java-Themen 8
U Mailclient über getDesktop.mail vorbereiten, Problem beim Anhang: Allgemeine Java-Themen 3
R Klasse über Button Event in anderer Klasse informieren Allgemeine Java-Themen 11
R Frequenzausgabe (2 Kanal) über Lautsprecherausgang Allgemeine Java-Themen 22
J Java-Klasse über Konsole starten Allgemeine Java-Themen 6
E FF Einstellungen über Programm ändern? Allgemeine Java-Themen 7
D JVM kann nicht über die jvm.dll gestartet werden? Allgemeine Java-Themen 1
S File im windowexploer öffnen über java Allgemeine Java-Themen 6
J Receive eines Hex-Bytes über COM-Port Allgemeine Java-Themen 4
Nicer Prozess über Prozessnamen beenden Allgemeine Java-Themen 15
reibi File über FileChannel locken Allgemeine Java-Themen 5
B Serialisierung mit Unterobjekten über Netzwerk Allgemeine Java-Themen 3
K Objekt-Austausch zwischen zwei Programmen über System-Clipboard Allgemeine Java-Themen 5
B parallele / Multithreaded Iteration über Map Allgemeine Java-Themen 12
D Unix/Linux Benutzer-Authentifikation über Java Allgemeine Java-Themen 3
M Tastatur eingabe über Buttons Allgemeine Java-Themen 15
S GPS-Maus über USB ansprechen Allgemeine Java-Themen 8
reibi Files über Classpath laden Allgemeine Java-Themen 22

Ähnliche Java Themen


Oben