2010-02-28 68 views
1

跨应用中的许多GUI对象共享本地化对象(在这种情况下ResourceBundle,我保存所有翻译)的最佳做法是什么?我有一些想法,但都有缺点:Java:跨多个GUI对象共享本地化对象的最佳实践?

1)通过每个GUI类构造函数传递ResourceBundle,但然后我需要将它保存在每个类(供以后使用) - 意味着在每个类中具有相同的代码和再次在主GUI类(例如“public static ResourceBundle msg”)中声明ResourceBundle为公共静态(但不是最终的,因为我可能需要改变它 - 例如语言改变),然后稍后访问它总是通过它(例如调用MainGuiClass.msg.getString(“something”)),但它也可以被同一包中的任何其他GUI类修改/销毁...

也许有一些更好的做法来做莎尔ING?

谢谢。

回答

3

全局的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); 
    } 

} 

有了这个代码,你可以在特定的语言/区域设置或任访问文本只使用默认的语言环境。如果您想切换语言环境,只需设置默认语言环境。您的用户界面需要了解区域设置更改,因此您可能必须为您的所有用户界面组件(PropertyChangeListener,PropertyChangeSupport)引入一些监听器界面,而不是直接更改区域设置。

0

您可以实现缓存工厂,该缓存工厂基于输入语言环境参数的值返回ResourceBundle。在第一次调用时,ResourceBundle将被构造,然后被缓存在一个静态引用中,随后可以在稍后调用工厂时返回并重用它。

0

如果您担心其他类正在执行您不想要的对象,请将其设置为具有您要在其上执行方法的类的受保护/专用字段。

Globals是邪恶的,但有时他们的便利性比他们的邪恶更大。

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

所以您可以为每个线程设置一个语言环境,而不是全局。