Java - Язык:Лучшая практика для совместного использования объекта локализации во многих объектах графического интерфейса?

StackOverflow https://stackoverflow.com/questions/2350735

Вопрос

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

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

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

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

Спасибо.

Это было полезно?

Решение

Глобальный объект 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);
    }

}

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

Другие советы

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

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

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

Класс ResourceBundle уже реализует кэш, поэтому нет необходимости реализовывать кэширование самостоятельно.Ваш класс access может быть реализован как singleton .Чтобы переключить язык, я использую ThreadLocal для локали:

public final class ThreadLocale extends ThreadLocal<Locale>
{
    public static final ThreadLocale theInstance = new ThreadLocale ();

    private ThreadLocale () 
    {
        super ();
    }

    protected Locale initialValue()
    {
        return Locale.getDefault ();
    }
}

В методе класса access, который получает текст из пакета ресурсов, я использую текущую локаль потока:

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 с атрибуция
Не связан с StackOverflow
scroll top