繁体   English   中英

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

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

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

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

2)在主GUI类(例如“ public static ResourceBundle msg”)中将ResourceBundle声明为公共静态(但不是最终的,因为我可能需要更改它-例如更改语言),然后以后始终通过它访问它(例如调用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组件( PropertyChangeListenerPropertyChangeSupport )引入一些侦听器界面,而不是直接更改区域设置。

您可以实现一个缓存工厂,该工厂将根据输入语言环境参数的值返回ResourceBundle。 首次调用时,将构造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 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM