2010-02-28 64 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()); 
} 

所以您可以爲每個線程設置一個語言環境,而不是全局。