Java: Лучшая практика для разделения объекта локализации между многими объектами GUI - PullRequest
1 голос
/ 28 февраля 2010

Что было бы лучшим методом для совместного использования объекта локализации (в данном случае ResourceBundle, где я сохраняю все переводы) между многими объектами GUI в приложении? У меня мало идей, но у обоих есть недостатки:

1) передача ResourceBundle через каждый конструктор класса GUI, но затем мне нужно сохранить его внутри каждого класса (для последующего использования) - значит, иметь один и тот же код в каждом классе снова и снова

2) объявить ResourceBundle как общедоступную статическую (но не окончательную, потому что мне может потребоваться изменить ее - например, язык изменился) в основном классе GUI (например, «общедоступная статическая ResourceBundle msg»), а затем позднее обращаться к нему всегда через него (например вызывая MainGuiClass.msg.getString («что-то»)), но затем он также может быть изменен / уничтожен любым другим классом GUI в том же пакете ...

Может быть, есть лучшая практика для совместного использования?

Спасибо.

Ответы [ 4 ]

3 голосов
/ 28 февраля 2010

Глобальный объект ResourceBundle не может быть окончательным, но вместо этого должен кэшироваться на карте. Изменение языка не требует изменения этой ссылки:

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 голосов
/ 19 января 2016

Класс 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 ());
}

Таким образом, вы можете установить локаль для каждого потока, а не глобально.

0 голосов
/ 28 февраля 2010

Если вы обеспокоены тем, что другие классы делают вещи, которые вы не хотите, с объектом, сделайте его защищенным / закрытым полем класса, в котором есть методы, которые вы хотите выполнить для него.

Глобалы злые, но иногда их удобство больше, чем их зло.

0 голосов
/ 28 февраля 2010

Можно реализовать фабрику кэширования, которая возвращает ResourceBundle на основе значения параметра входного языкового стандарта. При первом вызове ResourceBundle будет создан и затем кэширован в статической ссылке, которая впоследствии может быть возвращена и повторно использована в последующих вызовах к фабрике.

...