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

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

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

也许有一些更好的做法来进行分享?

谢谢。

有帮助吗?

解决方案

全局ResourceBundle对象不能是最终的,而是应该缓存在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 组件引入一些侦听器接口(属性改变监听器, 属性更改支持)而不是直接更改区域设置。

其他提示

您可以实现一个高速缓存工厂,基于输入区域设置参数的值,其返回的ResourceBundle。当第一呼叫的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 ());
}

因此可以设置为每个线程的区域设置和不是全局。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top