Как реализовать мультиязычность в приложениях Java / Swing? - PullRequest
5 голосов
/ 23 мая 2009

Каковы различные способы реализации многоязычной поддержки в приложениях Swing?

Используете ли вы ResourceBundle с файлом свойств и реализуете его в каждом кадре? Это работает хорошо для вас? Что делать, если вы используете какой-то графический редактор? Есть ли другой путь?

На работе мы используем Matisse4MyEclipse, и код обновляется каждый раз, когда мы сохраняем экран, поэтому простое использование Externalize Strings здесь не работает Один из способов - определить его как пользовательское свойство для каждого компонента, что очень раздражает. Другой способ - снова просмотреть мультиязычные компоненты и их свойства после сгенерированного кода Матисса, что тоже является проблемой.

Ответы [ 4 ]

7 голосов
/ 24 мая 2009

Ну, вы должны были использовать ResourceBundle с. Но если вы устанавливаете свойство текста компонента, вместо текста, удобного для чтения, используйте текст для RB.getString(). Тогда, если Matisse восстановится из формы, ключ пакета останется, и локализация будет работать. Пример:

Я буду использовать это изображение со страниц Матисса:
Illustration
(источник: myeclipseide.com ) .

там вы можете увидеть свойство текст . Есть значение «Моя новая метка». Вместо этого вы можете использовать rb.getString("myNewLabel.my.message"), где rb равно ResourceBundle. Единственной проблемой должен быть слишком интеллектуальный редактор свойств, идущий против вас. Я никогда не работаю с любым редактором wysiwyg (личные предпочтения, я всегда делаю дизайн интерфейса вручную).

3 голосов
/ 24 мая 2009

Вот как я реализовал интернационализацию:

  • дать имя каждому компоненту, который имеет интернационализированный текст
  • во время выполнения, возьмите контейнер (фрейм, диалог, апплет), выполните итерации всех компонентов и создайте ключ i18n для каждого компонента, используя его имя и все родительские имена.
  • для каждого типа компонента (JTextField, JLable и т. Д.) Определите некоторые ключи для каждого поля интернационализации (текст, метка, подсказка и т. Д.).
  • возьмите этот ключ i18n и запросите свой ResourceBundle, возьмите результаты и заполните поля компонента.

Работает с сгенерированным кодом или с созданным вручную кодом.

Редактировать: Вот оно:

public void buildIds() {
    buildId(true);
    int count = getComponentCount();
    if (count == 0) {
        return;
    }
    for (int i = 0; i < count; i++) {
        Component component = getComponent(i);
        if (component instanceof AbstractComponent) {
            ((AbstractComponent) component).buildIds();
        }
    }
}

protected void buildId(boolean fireChange) {
    String prevId = this.id;
    String computedId;
    if (getName() == null) {
        computedId = ClassUtilities.shortClassName(getClass()).toLowerCase() + "_" + Long.toHexString(ID_GENERATOR.getAndIncrement());
    } else {
        java.util.List<Component> parents = null;
        Component parent = getParent();
        if (parent != null) {
            StringBuilder buider = new StringBuilder(80);
            parents = new ArrayList<Component>();
            while (parent != null) {
                if (parent.getName() != null) {
                    parents.add(parent);
                }
                parent = parent.getParent();
            }
            Collections.reverse(parents);
            if (parents.size() > 0) {
                for (Component component : parents) {
                    if (buider.length() > 0) {
                        buider.append('.');
                    }
                    buider.append(component.getName());
                }
                buider.append('.');
            }
            buider.append(name);
            computedId = buider.toString().toLowerCase();
        } else {
            computedId = name;
        }
    }
    this.id = computedId;
    if (fireChange && prevId != null && !prevId.equals(computedId)) {
        componentIdChanged(this, prevId);
    }
}
0 голосов
/ 17 февраля 2016

Используйте ResourceBundle и установите язык на локальный:

Ниже приведен код в Java

приватная статическая карта resourceBundles;

private static ResourceBundle loadBundle(String language) {
    if (resourceBundles == null) {
        resourceBundles = new HashMap<String, ResourceBundle>();
    }

    ResourceBundle currentBundle = resourceBundles.get(language);

    if (currentBundle == null) {

        Locale locale = new Locale(language);
        currentBundle = ResourceBundle.getBundle("i18n.Messages", locale);
        resourceBundles.put(language, currentBundle);
    }

    return currentBundle;
}

public static String messageForKey(String key, String language) {
    ResourceBundle currentBundle = loadBundle(language);
    return currentBundle.getString(key);
}
0 голосов
/ 23 мая 2009

Я не знаю другого пути, кроме ResourceBundle.

Почему вы продолжаете регенерировать код? Я полагаю, что было бы хорошо, если бы вы запустили страницу, но после этого это было бы в основном ненужным. Похоже, генерация кода - это ваша настоящая проблема. Это ничего не спасет.

Вы пытаетесь составить страницы из нескольких компонентов? Я могу представить общий заголовок, нижний колонтитул и меню, которые не должны были бы меняться все время. Это может быть проблема дизайна.

Spring имеет очень хорошую поддержку I18N. Может быть, это может помочь вам здесь.

...