为什么资源包中的瑞典语文本显示为乱码?

时间:2010-12-13 12:13:10

标签: java swing internationalization resourcebundle mojibake

  

可能重复:
  How to use UTF-8 in resource properties with ResourceBundle

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

作为测试,我尝试将瑞典语标题设置为JButton。所以在我写的包文件中:

nextStepButton=nästa

在我写的Java代码中:

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

但是按钮的标题字符在运行时出现错误:
alt text

我正在使用支持Unicode的Tahoma字体。 当我通过代码手动设置按钮标题时,它显示正常:

nextStepButton.setText("nästa");

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

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

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

结果仍然是:
alt text

3 个答案:

答案 0 :(得分: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工具,最终可以获得更好的可维护属性文件。

另见:

答案 1 :(得分:6)

看看Java Internationalization FAQ。如果您在.properties文件中添加了非ASCII字符,则必须使用native2ascii工具进行转换。一切都应该有效。

答案 2 :(得分:3)

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

如果您将“LATIN SMALL A WITH DIAERESIS”(拉丁语-1中的E4或0000E4中的Unicode作为Unicode代码点)并将其表示为UTF-8,则会获得C3 A4。如果你把它们视为拉丁文1字节,你会得到“带有TILDE的LATIN CAPITAL LETTER A”和正方形的“CURRENCY SIGN”字符......这就是字符在按钮截图中的显示方式!!

(顺便说一下,这是因使用错误的字符编码而导致的错误修正的新词...... mojibake。在对话中使用它来阻止你的朋友。)