7

可能重复:
如何在 ResourceBundle 的资源属性中使用 UTF-8

我想允许我的 Java Swing 应用程序国际化。我使用捆绑文件将所有标签保存在其中。

作为测试,我尝试将瑞典语标题设置为JButton. 所以在捆绑文件中我写道:

nextStepButton=nästa

在我写的Java代码中:

nextStepButton.setText(bundle.getString("nextStepButton"));

但是按钮的标题字符在运行时出现错误:
替代文字

我正在使用支持 Unicode 的 Tahoma 字体。当我通过代码手动设置按钮标题时,它看起来很好:

nextStepButton.setText("nästa");

知道为什么它在捆绑文件中失败吗?

-------------------------------------------------------->编辑:编码标题:
我尝试使用以下代码对来自捆绑文件的文本进行编码:

nextStepButton.setText(new String(bundle.getString("nextStepButton").getBytes("UTF-8")));

结果仍然是:
替代文字

4

3 回答 3

9

根据javadoc,使用 ISO-8859-1 读取属性文件。

.. 输入/输出流采用 ISO 8859-1 字符编码进行编码。不能用这种编码直接表示的字符可以使用 Unicode 转义来编写;转义序列中只允许使用单个 'u' 字符。native2ascii 工具可用于将属性文件与其他字符编码进行转换。

除了使用 native2ascii 工具将 UTF-8 属性文件转换为 ISO-8859-1 属性文件之外,您还可以使用自定义ResourceBundle.Control,以便您可以控制属性文件的加载并在那里使用 UTF-8。这是一个启动示例:

public class UTF8Control extends Control {
    public ResourceBundle newBundle
        (String baseName, Locale locale, String format, ClassLoader loader, boolean reload)
            throws IllegalAccessException, InstantiationException, IOException
    {
        // The below is a copy of the default implementation.
        String bundleName = toBundleName(baseName, locale);
        String resourceName = toResourceName(bundleName, "properties");
        ResourceBundle bundle = null;
        InputStream stream = null;
        if (reload) {
            URL url = loader.getResource(resourceName);
            if (url != null) {
                URLConnection connection = url.openConnection();
                if (connection != null) {
                    connection.setUseCaches(false);
                    stream = connection.getInputStream();
                }
            }
        } else {
            stream = loader.getResourceAsStream(resourceName);
        }
        if (stream != null) {
            try {
                // Only this line is changed to make it to read properties files as UTF-8.
                bundle = new PropertyResourceBundle(new InputStreamReader(stream, "UTF-8"));
            } finally {
                stream.close();
            }
        }
        return bundle;
    }
}

按如下方式使用它:

ResourceBundle bundle = ResourceBundle.getBundle("com.example.i18n.text", new UTF8Control());

这样你就不需要使用 native2ascii 工具了,你最终会得到更好的可维护的属性文件。

也可以看看:

于 2010-12-13T13:29:04.947 回答
6

查看Java 国际化常见问题解答。如果您在.properties文件中放入了非 ASCII 字符,则必须使用native2ascii工具对其进行转换。然后一切都应该工作。

于 2010-12-13T12:44:06.673 回答
3

问题是资源包属性文件以 UTF-8 编码,但您的应用程序使用 Latin-1 加载它。

如果您采用“LATIN SMALL A WITH DIAERESIS”(Latin-1 中的 E4 或 0000E4 作为 Unicode 代码点)并将其表示为 UTF-8,您将得到 C3 A4。如果您随后将它们视为 Latin-1 字节,您将得到“LATIN CAPITAL LETTER A WITH TILDE”和方形“CURRENCY SIGN”字符......这就是字符在按钮屏幕截图中的显示方式!

(顺便说一句,这是一个新词,用于表示由于使用错误的字符编码而导致的混乱…… mojibake。通过在对话中使用它来迷惑你的朋友。)

于 2010-12-13T12:59:33.197 回答