【问题标题】:Why is text in Swedish from a resource bundle showing up as gibberish? [duplicate]为什么资源包中的瑞典语文本显示为乱码? [复制]
【发布时间】:2011-05-24 15:25:22
【问题描述】:

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

我想允许我的 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")));

结果仍然是:

【问题讨论】:

  • 也许你的捆绑文件编码不正确?
  • 如何创建属性文件?
  • 我使用 Eclipse ...我从 Eclipse 内部创建属性文件作为普通文本文件 + 我将其编码设置为“UTF-8”。

标签: java swing internationalization resourcebundle mojibake


【解决方案1】:

根据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 工具,并且最终获得更好的可维护属性文件。

另见:

【讨论】:

  • 我花了一些时间来理解和测试这个......它真的很好......现在是I18N。
  • 不客气。究竟哪一部分难以理解?我可以编辑答案以使其更清楚。
  • 在我的情况下&根据你的回答......从 UTF8Control 初始化一个对象将是: ResourceBundle bundle = ResourceBundle.getBundle( "swedish", new UTF8Control() );
【解决方案2】:

看看Java Internationalization FAQ。如果您在 .properties 文件中放入了非 ASCII 字符,则必须使用 native2ascii 工具对其进行转换。那么一切都应该正常。

【讨论】:

    【解决方案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。在对话中使用它来迷惑你的朋友。)

    【讨论】:

      猜你喜欢
      • 2011-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-03
      • 2011-06-04
      • 2020-04-16
      相关资源
      最近更新 更多