4

在 Swing 应用程序中实现多语言支持的不同方法是什么?

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

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

4

4 回答 4

7

好吧,你必须使用ResourceBundles。但是,如果您要设置组件文本属性,则使用RB.getString(). 然后,如果 Matisse 从捆绑密钥中重新生成,则将保留并且本地化将起作用。例子:

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

在那里你可以看到属性文本。有“我的新标签”的价值。取而代之的是,您可以使用rb.getString("myNewLabel.my.message")where rbis ResourceBundle。唯一的问题应该是过于智能的属性编辑器对你不利。我从不使用任何所见即所得的编辑器(个人喜好,我总是手工进行 UI 设计)。

于 2009-05-24T11:13:19.527 回答
2

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

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

我不知道除了 ResourceBundle 之外的任何方法。

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

您是否尝试使用多个组件组成页面?我可以想象一个不需要一直更改的通用页眉、页脚和菜单。这可能是一个设计问题。

Spring 对 I18N 有很好的支持。也许它可以在这里帮助你。

于 2009-05-23T19:19:09.457 回答
0

使用 ResourceBundle 类并将语言设置为区域设置:

以下是java中的代码

private static Map<String, ResourceBundle> 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);
}
于 2016-02-17T05:10:53.073 回答