Java:跨多个GUI对象共享本地化对象的最佳实践?

Java:跨多个GUI对象共享本地化对象的最佳实践?,java,localization,sharing,resourcebundle,Java,Localization,Sharing,Resourcebundle,在应用程序中的许多GUI对象之间共享本地化对象(在本例中是ResourceBundle,我保存所有翻译)的最佳实践是什么?我的想法不多,但都有缺点: 1) 通过每个GUI类构造函数传递ResourceBundle,但我需要将其保存在每个类中(供以后使用)——这意味着在每个类中反复使用相同的代码 2) 在主GUI类中将ResourceBundle声明为public static(但不是final,因为我可能需要更改它-例如语言更改)(例如“public static ResourceBundle

在应用程序中的许多GUI对象之间共享本地化对象(在本例中是ResourceBundle,我保存所有翻译)的最佳实践是什么?我的想法不多,但都有缺点:

1) 通过每个GUI类构造函数传递ResourceBundle,但我需要将其保存在每个类中(供以后使用)——这意味着在每个类中反复使用相同的代码

2) 在主GUI类中将ResourceBundle声明为public static(但不是final,因为我可能需要更改它-例如语言更改)(例如“public static ResourceBundle msg”),然后始终通过它访问它(例如调用MainGuiClass.msg.getString(“某物”),但是,它也可以被同一个包中的任何其他GUI类修改/销毁

也许有更好的方法来分享


谢谢。

您可以实现一个缓存工厂,它根据输入区域设置参数的值返回ResourceBundle。在第一次调用时,将构造ResourceBundle,然后将其缓存在静态引用中,该引用随后可以在以后对工厂的调用中返回和重用。

如果您担心其他类会执行您不想创建对象的操作,使其成为类的受保护/私有字段,该类具有要在其上执行的方法


全局对象是邪恶的,但有时它们的便利性大于它们的邪恶性。

全局ResourceBundle对象不能是最终的,而是应该缓存在映射中。更改语言不需要更改此引用:

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);
    }

}
import java.util.HashMap;
导入java.util.Locale;
导入java.util.Map;
导入java.util.ResourceBundle;
公共类UIBundle{
私有静态最终映射allUIResources=newhashmap();
公共静态字符串getString(最终字符串键){
返回getString(key,Locale.getDefault());
}
公共静态字符串getString(最终字符串键、最终区域设置){
ResourceBundle rb=allUIResources.get(语言环境);
if(rb==null){
rb=ResourceBundle.getBundle(“我的ui资源”,语言环境);
allUIResources.put(区域设置,rb);
}
返回rb.getString(键);
}
}

使用此代码,您可以访问特定语言/区域设置中的文本,也可以只使用默认区域设置。如果要切换区域设置,只需设置默认区域设置。您的UI需要了解区域设置的更改,因此您可能必须为所有UI组件(,)引入一些侦听器接口,而不是直接更改区域设置。

ResourceBundle类已经实现了缓存,因此无需自己实现缓存。您的access类可以实现为singleton。要切换语言,我对区域设置使用ThreadLocal:

public final class ThreadLocale extends ThreadLocal<Locale>
{
    public static final ThreadLocale theInstance = new ThreadLocale ();

    private ThreadLocale () 
    {
        super ();
    }

    protected Locale initialValue()
    {
        return Locale.getDefault ();
    }
}
因此,您可以为每个线程设置区域设置,而不是全局设置

public synchronized String getMessage (Object messageKey, Locale locale) throws MissingResourceException
{
    ResourceBundle resourceBundle = null;
    resourceBundle = ResourceBundle.getBundle (filename, ThreadLocale.theInstance.get ());
    return resourceBundle.getString (messageKey.toString ());
}