加载本地化资源

Dar*_*ust 4 java localization

在我正在进行的项目中,我想根据当前区域设置加载不同的资源。对于字符串,这非常简单:只需通过添加一些文件来创建资源包,Localization.properties然后Localization_de.properties通过ResourceBundle.getBundle("domain.project.Localization").

但是如何加载不是简单字符串的本地化资源呢?

具体来说,我想根据区域设置加载图像和 HTML 文件。获取该资源的正确 URL 就足够了。例如,我想要一个Welcome.htmlandWelcome_de.html文件,并在当前语言环境为德语时加载该文件。

简单地使用getClass().getResource("Welcome.html")是行不通的,它总是返回确切的文件并且不进行区域设置处理。除了根据当前区域设置手动弄乱文件名之外,我还没有找到解决此问题的便捷方法。

我提出的一种解决方案是向我的Localization.properties文件添加一个键,其中包含正确的本地化 HTML 文件的名称。但这感觉很古怪而且错误。

请注意,这不是 Android 应用程序,只是一个标准的 Java 8 桌面应用程序。

Dar*_*ust 5

事实上,获得与 相同的行为非常容易ResourceBundle.getBundle。我查看了代码,发现处理区域设置和文件名的最重要部分是ResourceBundle.Control

因此,这里有一个简单的方法,它返回本地化资源的 URL(遵循与资源包相同的文件名方案),无需缓存并仅支持当前区域设置:

/** Load localized resource for current locale.
 * 
 * @param baseName Basename of the resource. May include a path.
 * @param suffix File extension of the resource.
 * @return URL for the localized resource or null if none was found.
 */
public static URL getLocalizedResource(String baseName, String suffix) {
    Locale locale = Locale.getDefault();
    ResourceBundle.Control control = ResourceBundle.Control.getControl(ResourceBundle.Control.FORMAT_DEFAULT);
    List<Locale> candidateLocales = control.getCandidateLocales(baseName, locale);

    for (Locale specificLocale : candidateLocales) {
        String bundleName = control.toBundleName(baseName, specificLocale);
        String resourceName = control.toResourceName(bundleName, suffix);

        // Replace "Utils" with the name of your class!
        URL url = Utils.class.getResource(resourceName);
        if (url != null) {
            return url;
        }
    }

    return null;
}
Run Code Online (Sandbox Code Playgroud)

如果有人想扩展它以支持通用语言环境作为参数:实现中的重要部分ResourceBundle.getBundleImpl是:

for (Locale targetLocale = locale;
     targetLocale != null;
     targetLocale = control.getFallbackLocale(baseName, targetLocale)) {
         List<Locale> candidateLocales = control.getCandidateLocales(baseName, targetLocale);
         ...
}
Run Code Online (Sandbox Code Playgroud)

最后一个条目getCandidateLocales是空区域设置 ( Locale.ROOT)。for在测试回退语言环境之前,当在第一次迭代中找到默认资源以来的语言环境时,应该忽略它。