Search code examples
javalocalizationsharingresourcebundle

Java: Best practice for sharing localization object across many GUI objects?


What would be the best practice for sharing localization object (in this case ResourceBundle, where I do save all translations) across many GUI objects in app? I have few ideas, but both have drawbacks:

1) passing ResourceBundle via each GUI class constructor, but then I need to save it inside every class (for later use) - means having the same code in each class over and over again

2) declare ResourceBundle as public static (but not final, because I may need to change it - e.g. language changed) in main GUI class (e.g. "public static ResourceBundle msg") , then later access it always via it (e.g. calling MainGuiClass.msg.getString("something")), but then it can also be modified/destroyed by any other GUI class in the same package...

Maybe there is some better practice to do the sharing?

Thanks.


Solution

  • The global ResourceBundle Object can not be final but instead should be cached in a Map. Changing the language doesn't require to change this reference:

    import java.util.HashMap;
    import java.util.Locale;
    import java.util.Map;
    import java.util.ResourceBundle;
    
    public class UIBundle {
        private static final Map<Locale, ResourceBundle> allUIResources = new HashMap<Locale, ResourceBundle>();
    
        public static String getString(final String key) {
            return getString(key, Locale.getDefault());
        }
    
        public static String getString(final String key, final Locale locale) {
            ResourceBundle rb = allUIResources.get(locale);
            if (rb == null) {
                rb = ResourceBundle.getBundle("my-ui-resource", locale);
                allUIResources.put(locale, rb);
            }
            return rb.getString(key);
        }
    
    }
    

    With this code you can either access texts in specific languages/locales or just use the default locale. If you want to switch your locale, just set the default locale. Your UI needs to know about locale changes, so you may have to introduce some listener interface for all your UI components (PropertyChangeListener, PropertyChangeSupport) and not change the locale directly.