1

アプリ内の多くの GUI オブジェクトでローカリゼーション オブジェクト (この場合はすべての翻訳を保存する ResourceBundle) を共有するためのベスト プラクティスは何でしょうか? アイデアはほとんどありませんが、どちらにも欠点があります。

1)各GUIクラスコンストラクターを介してResourceBundleを渡しますが、(後で使用するために)すべてのクラス内に保存する必要があります-各クラスに同じコードが何度も何度もあることを意味します

2) ResourceBundle を public static として宣言します (ただし、変更する必要がある可能性があるため、最終的なものではありません。言語の変更など)。その後、常にそれを介してアクセスします (MainGuiClass. msg.getString("something")) ですが、同じパッケージ内の他の GUI クラスによって変更/破棄される可能性もあります...

共有を行うためのより良い方法があるでしょうか?

ありがとう。

4

4 に答える 4

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 コンポーネント ( PropertyChangeListenerPropertyChangeSupport ) に何らかのリスナー インターフェイスを導入し、ロケールを直接変更しないようにする必要がある場合があります。

于 2010-02-28T13:52:38.057 に答える
0

入力ロケール パラメータの値に基づいて ResourceBundle を返すキャッシング ファクトリを実装できます。最初の呼び出しで、ResourceBundle が構築され、静的参照にキャッシュされます。これは、後で返されて、ファクトリへの後の呼び出しで再利用できます。

于 2010-02-28T12:40:18.173 に答える
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 ());
}

したがって、グローバルではなく、スレッドごとにロケールを設定できます。

于 2016-01-19T17:41:52.047 に答える