Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Swing - switch locale dynamically at runtime

I understand how to internationalize a java program, but I have a problem. Language in my program can be switched anytime, but my program can exist in many states, which means that it may or may not have several JLabels, JPanels, JFrames, etc, open. Is there a class or a method which will update the current GUI to the switched language, or does it have to be done manually?

If nothing else works, I'll just require user to restart the program to switch the language, but runtime change would be nice...

like image 435
Karlovsky120 Avatar asked Nov 13 '22 00:11

Karlovsky120


1 Answers

The solution generally used is to have a hash of user-facing strings in a central manager class. You make a call into that class whenever you want to populate a field with data:

JLabel label = new JLabel();
label.setText(LocalizationManager.get("MY_LABEL_TEXT"));

Inside the LocalizationManager you will have to fetch the current language of the program, then look up the appropriate string for MY_LABEL_TEXT in the appropriate language. The manager then returns the now 'localized' string, or some default if the language or string isn't available.

Think of the manager as a slightly more complicated Map; it's mapping from a key (ie 'MY_LABEL_TEXT') to what you want to display ("Good day!" or "Bienvenido!") depending on which language you're in. There are a lot of ways to implement this, but you want the manager to be static or a singleton (loaded once) for memory/performance reasons.

For instance: (1)

public class LocalizationManager {
  private SupportedLanguage currentLanguage = SupportedLanguage.ENGLISH;//defaults to english
  private Map<SupportedLanguage, Map<String, String>> translations;

  public LocalizationManager() {
    //Initialize the strings. 
    //This is NOT a good way; don't hardcode it. But it shows how they're set up.

    Map<String, String> english = new HashMap<String, String>();
    Map<String, String> french = new HashMap<String, String>();

    english.set("MY_LABEL_TEXT", "Good day!");
    french.set("MY_LABEL_TEXT", "Beinvenido!");//is that actually french?

    translations.set(SupportedLanguage.ENGLISH, english);
    translations.set(SupportedLanguage.FRENCH, french);
  }

  public get(String key) {
    return this.translations.get(this.currentLanguage).get(key);
  }

  public setLanguage(SupportedLanguage language) {
    this.currentLanguage = language;
  }

  public enum SupportedLanguage {
    ENGLISH, CHINESE, FRENCH, KLINGON, RUSSIAN; 
  }
}

(1) I haven't tested this, nor is it a singleton, but it's an off the cuff example.

like image 159
Nathaniel Ford Avatar answered Dec 22 '22 11:12

Nathaniel Ford