Какова наилучшая практика для локалей и поддержки нескольких языков? - PullRequest
1 голос
/ 04 апреля 2020

Я хочу, чтобы в моей программе было несколько языков. Класс java Locale имеет несколько локалей, например Locale.GERMAN, Locale.ENGLISH и т. Д. Но мне нужны дополнительные локали, например, spani sh et c.

Как их хранить и правильно использовать? Какова лучшая практика?

Должен ли я создать какой-нибудь LanguageHandler, который будет хранить все необходимые локали в массиве? Любой опыт и практика в этой области c?

Редактировать: Приложение для рабочего стола и написано в Java.

Ответы [ 3 ]

2 голосов
/ 04 апреля 2020

Получить список всех поддерживаемых локалей:

Вы можете использовать Locale spanish = new Locale("es", "ES"); для испанского языка sh в Испании.

Как я могу хранить их и правильно их использовать? Какова лучшая практика?

Насколько я понимаю, вам не нужно хранить основной список поддерживаемых локалей. Вы можете использовать их как вы go. Определение локали, как указано выше, поможет вам загрузить ResourceBundles путем передачи объектов локали, но тогда вам нужно будет создать ResourceBundles для каждой локали, которую вы хотите использовать в своем приложении.

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

Дополнительная информация о том, как использовать локаль для инициализации resourceBundle.

http://tutorials.jenkov.com/java-internationalization/resourcebundle.html

https://mkyong.com/java/java-resourcebundle-example/

Как загрузить пакет ресурсов из файлового ресурса в Java?

1 голос
/ 05 апреля 2020

Ответ от 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 для возврата указанного изображения флага.

0 голосов
/ 04 апреля 2020

Вы всегда можете использовать код страны, соответствующий стандарту ISO 3166 . Для испанцев sh это будет

Locale spanish = new Locale("es", "ES");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...