在应用程序中的许多GUI对象之间共享本地化对象(在本例中为ResourceBundle,我保存所有翻译)的最佳实践是什么?我的想法很少,但两者都有缺点:
1)通过每个GUI类构造函数传递ResourceBundle,但是我需要将它保存在每个类中(供以后使用) - 意味着在每个类中一遍又一遍地使用相同的代码
2)将ResourceBundle声明为公共静态(但不是最终的,因为我可能需要在主GUI类中更改它 - 例如语言已更改)(例如“public static ResourceBundle msg”),然后稍后通过它来访问它(例如调用MainGuiClass.msg.getString(“something”)),但它也可以被同一个包中的任何其他GUI类修改/销毁...
也许有更好的做法来分享?
感谢。
答案 0 :(得分:3)
全局ResourceBundle对象不能是final,而应该缓存在Map中。更改语言不需要更改此引用:
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);
}
}
使用此代码,您可以访问特定语言/区域设置中的文本,也可以使用默认区域设置。如果要切换语言环境,只需设置默认语言环境即可。您的UI需要了解区域设置更改,因此您可能必须为所有UI组件(PropertyChangeListener,PropertyChangeSupport)引入一些侦听器界面,而不是直接更改区域设置。
答案 1 :(得分:0)
您可以实现一个缓存工厂,它根据输入语言环境参数的值返回ResourceBundle。在第一次调用时,将构造ResourceBundle,然后将其缓存在静态引用中,随后可以在以后的工厂调用中返回并重用它。
答案 2 :(得分:0)
如果您担心其他类不需要对象,则将其作为类的受保护/私有字段,并使用您希望在其上执行的方法。
全球是邪恶的,但有时他们的便利性大于他们的邪恶。
答案 3 :(得分:0)
ResourceBundle类已经实现了一个缓存,因此不需要自己实现缓存。您的访问类可以实现为单例。要切换语言,我使用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 ());
}
因此,您可以为每个线程设置区域设置,而不是全局。