Dynamisches I18n

X

xoom4

Hi

Ich habe ein JMenü mit meheren Sprachen zur Auswahl und möchte gerne das die gesamte Swing GUI bei Auswahl einer Sprache automatisch ändert ohne das die Applikation neu gestartet werden muss. Das geht mit der konventionellen bzw. statischen Methode ResourceBundle nicht, soweit mir bekannt. Doch habe ich bereits andere Java Programme gesehen die so etwas können. Jetzt fehlt mir nur noch ein Licht wie so etwas auch in meiner GUI Anwendung implementiert werden kann.

Hat jemand so etwas bereits realisiert oder entsprechende Links mit weiteren Infos? :)
 
Zuletzt bearbeitet von einem Moderator:
Ich würde so vergehen :
alle Components dir geändert werden können als Referenzen halten. Die Component die die Sprache wechselt erhält einen ActionListener. In diesem ActionListener gehst du nun alle Referenzen ab und rufst setText(String) auf. Zur Not leite dir eine eigene Klasse von der ab die du haben möchtest und implementiere die Methode entsprechend. Eine andere möglichkeit wäre sonst noch über updateUI() über den UI-Manager ... aber wie das funktioniert weis ich nicht.
 
Vielen Dank, den Hinweis mit dem Listener hat mir sehr geholfen :D

Ich hab das nun wie folgt realisiert (Bemerkung: Code ist in Scala). Zuerst wurde ein globaler i18n Manager erstellt:
Code:
object LocaleManager {
  var listeners = Buffer[LocaleListener]()
 
  def locale = localeInstance
 
  def locale_= (locale: Locale) {
    localeInstance = locale
    listeners.foreach(listener => listener.localeChanged)
  }
 
  def text(key: String) = ResourceBundle.getBundle("MessagesBundle", locale).getString(key)
 
  private var localeInstance = new Locale("en", "US")
}
Anschliessend wurden wie du beschrieben hast ein Listener erstellt:
Code:
trait LocaleListener { def localeChanged }
Zum Schluss wurden diejenigen Swing Komponenten die i18n benötigen um diesen LocaleListener erweitert und die localeChange Funktion definiert, Beispiel anhand der scala.swing.Menu Klasse:
Code:
class LMenu(title0: String) extends Menu(title0) with LocaleListener {
  val textKey = title0

  //Setze Text mit der jeweiligen Sprache.
  localeChanged

  // Füge mich selbst als Listener dem LocaleManager hinzu.
  LocaleManager.listeners += this

  // Werde vom LocaleManager aufgerufen wenn sich die Sprache ändert.
  def localeChanged { 
    if(textKey != null)
      if(!textKey.isEmpty)
        super.text = LocaleManager.text(textKey)
  }

  def text_= (s: String) {
    textKey = s
    localeChanged
  }

}
So, dass ist mal das Grundgerüst. Jetzt müssen die Klassen nur noch eingesetzt werden:
Code:
// Menu mit i18n unterstützung, standardmässig englischer Text.
new LMenu("menu.file")
// Schalte jetzt auf Deutschsprachigen Text um.
LocaleManager.locale = new Locale("de", "CH")
Zum Schluss brauchen wir nur noch zwei Sprachdateien, zum einen die Englischsprachige MessagesBundle_en_US.properties:
Code:
menu.file = File
und eine Deutschsprachige:
MessagesBundle_de_CH.properties:
Code:
menu.file = Datei
Wer es gern in Java möchte dem werden die unteren Links jeweils weiter Helfen.

http://geosoft.no/software/locale/docs/no/geosoft/cc/locale/package-summary.html
Bei diesem Link handelt es sich um exakt das was ich oben implementierte habe. Nur fiel mir auf das die GeoSoft Locale API probleme mit dem finden der Sprachdatei hat (speziell die Methode getText in LocaleManager scheint mir dubios :confused:). Das war auch der eigentliche Grund warum ich eine neu implementierung vor nahm.

http://www.java-forum.org/415098-post14.html
Ist eine alternative Implementierung, hab sie nicht getestet.

Zum schluss hab ich noch eine GNU Gettext API für Java gefunden: http://code.google.com/p/gettext-commons/wiki/Tutorial. Für Scala funktioniert es leider nicht, dass xgettext meckert dauernd das die Syntax nicht unterstützt wird.
 
Zuletzt bearbeitet von einem Moderator:
Da währe noch was, wie mach ich das der LocaleManager die Resourcen aus dem Listener Array/Buffer automatisch entfernt wenn Bsp. ein zweites Fenster das ein Menü hat geschlossen wird?
 
In dem du dir ne ganze Menge Schreibaufwand machst und es hardcodest ...
 

Neue Beiträge

Zurück