Ответ от Rupe sh правильный и должен быть принят. Его комментарий вызвал этот ответ.
Enum
Относительно того, как отслеживать локали, поддерживаемые в настоящее время вашим приложением, определите перечисление. Перечисление - это хороший способ обработки списка элементов , известных во время компиляции и , неизменяемых во время выполнения . См. tutorial от Oracle.
public enum L10n
{
fr_CA , es_ES ; // Names of reference variables automatically set to point to objects automatically instantiated when this class loads.
}
Используйте конструктор для передачи объекта Locale
, представленного каждым элементом перечисления. Мы используем L10n
в качестве имени класса для нашего перечисления, где «L10N» является общим сокращением слова «локализация».
public enum L10n
{
// Enum elements.
fr_CA( Locale.CANADA_FRENCH ) ,
es_ES( new Locale("es", "ES") ) ;
final private Locale locale ;
// Constructor
L10n( Locale localeArg )
{
this.locale = Objects.requireNonNull( localeArg ) ;
}
}
Элементы перечисления являются константами. Таким образом, в Java соглашениях об именах каждое имя элемента должно быть в верхнем регистре, например FR_CA
& ES_ES
. Я считаю, что наш случай здесь является исключением из этого соглашения, так как для программиста важно знать верхний / нижний регистр значения каждого имени (коды языка и культуры).
Вы можете использовать Locale
объекты, содержащиеся в этом перечислении, для доступа к вашему пакету ресурсов. Мы добавляем getResourceBundle
метод для предоставления этой возможности.
public enum L10n
{
// Enum elements.
fr_CA( Locale.CANADA_FRENCH ) ,
es_ES( new Locale("es", "ES") ) ;
final private Locale locale ; // Remember the `Locale` object behind each element in this enum.
// Constructor
L10n( Locale localeArg )
{
this.locale = Objects.requireNonNull( localeArg ) ;
}
// Access the ResourceBundle for a particular locale.
public ResourceBundle getResourceBundle()
{
…
}
}
Внимание: подумайте о thread-safety . В вашем приложении есть только один экземпляр для каждого объекта enum. Так что метод getResourceBundle
должен быть потокобезопасным, если вы можете вызывать его через потоки. Если вызывается только из одного потока, связанного с пользовательским интерфейсом, безопасность потока не является проблемой. Но не забудьте рассмотреть наборы тестов, ведение журнала или другие места, которые могут вызываться из потоков, отличных от основного потока пользовательского интерфейса.
Пример использования этого метода getResourceBundle
.
L10n preferredLocalization = L10n.es_ES ; // Perhaps taken from a dialog interaction with user.
ResourceBundle resourceBundle = preferredLocalization.getResourceBundle() ;
Это перечисление сейчас действует как фасад перед обработкой вашего пакета ресурсов. Вы можете изменить этот код обработки, не затрагивая места в вашем приложении, где вы звоните L10n::getResourceBundle
.
Чтобы представить список локализаций, поддерживаемых вашим приложением, добавьте метод для получения отображаемого имени. Этот метод делегирует содержавшемуся Locale
объекту Locale::getDisplayName
метод. Возможно, вы захотите локализовать это отображаемое имя в соответствии с языковыми и культурными нормами каждой локали.
public enum L10n
{
// Enum elements.
fr_CA( Locale.CANADA_FRENCH ) ,
es_ES( new Locale("es", "ES") ) ;
final private Locale locale ; // Remember the `Locale` object behind each element in this enum.
// Constructor
L10n( Locale localeArg )
{
this.locale = Objects.requireNonNull( localeArg ) ;
}
// Access the ResourceBundle for a particular locale.
public ResourceBundle getResourceBundle()
{
…
}
// For presentation to the user.
public String getDisplayName()
{
String name = this.locale.getDisplayName( this.locale ) ; // Pass a `Locale` to `Locale::getDisplayName` to have that locale's name automatically localized.
return name ;
}
}
Получите список отображаемых имен.
Вы можете получить коллекцию элементов enum. Метод Enum.values
- это специальный «неявный» метод, определенный в Java specs , возвращающий массив всех объектов, определенных как элементы этого перечисления. К сожалению, этот метод почти исключен из Enum
Javado c, а упоминание похоронено в описании метода valueOf
.
for ( L10n localization : L10n.values() )
{
System.out.println( localization.getDisplayName() );
}
français (Канада)
español (España)
С этим можно еще больше полюбить, добавив еще одно поле члена в класс перечисления для значка флага страны, представляющего это язык и культура. Затем флаг может появиться в пользовательском интерфейсе, чтобы идентифицировать текущую локализацию. Передайте изображение значка для каждого элемента перечисления в качестве второго аргумента в конструкторе. Или напишите код в классе enum для поиска изображения значка. И, конечно, добавьте метод getFlag
в наш класс enum для возврата указанного изображения флага.