Kategória: Java standard könyvtárak.
A Java már kezdettől fogva nagy hangsúlyt fektet arra, hogy minél szélesebb kulturális környezetben lehessen használni. (Emögött valószínűleg az a tapasztalat is benne van, hogy amikor a számítógépet megalkották, akkor először az angolon kívül semelyik más nyelvre nem gondoltak, majd csak a nyugatiakra, melyből nagyon sok probléma adódott, és adódik, mind a mai napig.) Nem sokat kellett rajta változtatni az idők folyamán. Sőt, talán picit út is estek a ló túloldalára: a Stringet pl. a kissé pazarló UTF16-ban tárolják, a telepítés során mindig feltelepül a rengeteg apró lokalizációs állomány, és számos eljárásnak opcionális paramétere a Locale, amit ha nem adunk meg, a fordító gyakran figyelmeztetést ad.
Két fogalmat kell megismernünk, ami lényegében ugyanannak a dolognak a két vetülete: a szoftver szempontjából a nemzetköziesítés, angolul internationalization, szokásos rövidítéssel I18N (az I és a N között 18 karakter szerepel), ill. hasonlóan, egy adott nyelv szempontjából a lokalizáció, angolul localization, szokásos rövidítéssel L10N (hasonló logika mentén). A lényeg: az I18N során figyelembe vesszük azt, hogy nem csak egy nyelven lesz elérhető a szoftver, a L10N során pedig egy adott nyelvre fordítjuk le a programot.
Mindez esősorban, de nem kizárólag azt jelenti, hogy a megjelenítendő szöveg nincs egy nyelven "bedrótozva", hanem a forrásban kulcsok szerepelnek, melyek értékei külön fájlokban szerepelnek, mindegyik nyelvre külön. Egészen pontosan: mindegyik kultúrára, azaz nyelv + ország párosra, tehát pl. külön lehet venni az osztrák és a németországi német nyelvet. Másrészt sok egyéb apróságot is jelent, pl. a dátumok vagy számok formázása.
Amint azt már említettem, a főszerepet a Locale osztály játssza. Lássunk egy példát!
import java.text.DateFormat; import java.util.*; public class I18NExample { static void testLocale(Locale locale) { System.out.println(locale.getDisplayCountry() + ", " + locale.getDisplayLanguage() + ", " + locale.getISO3Country()); String date = DateFormat.getDateInstance(DateFormat.DEFAULT, locale).format(new Date()); System.out.println(date); ResourceBundle messages = ResourceBundle.getBundle("MessagesBundle", locale); System.out.println(messages.getString("greetings") + " " + messages.getString("inquiry") + " " + messages.getString("farewell")); } public static void main(String[] args) { System.out.println("Default locale: " + Locale.getDefault().getDisplayName()); testLocale(new Locale("hu", "HU")); testLocale(new Locale("en", "US")); testLocale(new Locale("de", "DE")); } }
Ahhoz, hogy futtatni tudjuk, létre kell hoznunk még 3 fájlt, melyeket vagy ugyanoda kell tennünk, ahol a java és a class található, vagy (maven projekt esetén) az src/main/resources könyvtárba:
MessagesBundle_hu_HU.properties:
greetings = Szia.
farewell = Viszontlátásra.
inquiry = Hogy vagy?
MessagesBundle_en_US.properties:
greetings = Hello.
farewell = Goodbye.
inquiry = How are you?
MessagesBundle_de_DE.properties:
greetings = Hallo.
farewell = Tschüß.
inquiry = Wie geht's?
A példában a ResourceBundle használatával nemzetköziesítettük az alkalmazást, majd lokalizáltuk a magyarországi magyar, az amerikai angol és a németországi német nyelvekre. A dátumot is kiírjuk az adott nyelven.
A példát a hivatalos Oracle dokumentációban találtam, amely igen jól elmagyarázza a témát: https://docs.oracle.com/javase/tutorial/i18n/intro/index.html.