如何在Java / Swing应用程序中实现多语言?

时间:2009-05-23 17:46:58

标签: java swing internationalization multilingual

在Swing应用程序中实现多语言支持的不同方法有哪些?

您是否正在将ResourceBundle与属性文件一起使用并在每个帧中实现它?它对你有用吗?如果你使用某种GUI编辑器怎么办?还有其他方法吗?

在工作中我们正在使用Matisse4MyEclipse并且每次保存屏幕时都会重新生成代码,因此只使用Externalize Strings在这里不起作用。一种方法是将其定义为每个组件的自定义属性,这非常烦人。另一种方法是在matisse生成的代码之后再次检查多语言组件及其属性,这也是一种痛苦。

4 个答案:

答案 0 :(得分:7)

好吧,你必须使用ResourceBundle。但是,如果您要设置componet text属性而不是人类可读文本RB.getString()的文本。然后,如果马蒂斯重新生成形式,捆绑密钥将保留,本地化将起作用。例如:

我将使用Matisse页面上的这张图片:
Illustration
(来源:myeclipseide.com

您可以看到属性文字。有价值“我的新标签”。您可以使用rb.getString("myNewLabel.my.message") rb ResourceBundle来代替此{{1}}。唯一的问题应该是太聪明的属性编辑器反对你。我从不使用任何所见即所得的编辑器(个人喜好,我总是手工制作UI设计)。

答案 1 :(得分:3)

这就是我实施国际化的方式:

  • 为每个具有国际化文本的组件命名
  • 在运行时,获取容器(框架,对话框,小程序),迭代所有组件,并使用其名称和所有父名称为每个组件构建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);
    }
}

答案 2 :(得分:0)

除了ResourceBundle,我不知道任何方式。

为什么要继续重新生成代码?我想,一旦你开始页面就没问题,但在那之后它基本上没必要了。听起来像代码生成是你真正的问题。它没有为你节省任何东西。

您是否尝试使用多个组件撰写网页?我可以想象一个不需要一直改变的常见页眉,页脚和菜单。这可能是一个设计问题。

Spring对I18N的支持非常好。也许它可以帮助你。

答案 3 :(得分:0)

使用ResourceBundle并将语言设置为local:

以下是java中的代码

私有静态Map 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);
}