如何在运行时将swing组件文本更新到不同的语言环境

时间:2014-09-09 00:06:30

标签: java swing localization resourcebundle

我想让我的程序在ResourceBundle类中使用多种语言。这是我的代码:

Main.java

import java.awt.FlowLayout;
import java.util.Locale;

import javax.swing.JFrame;
import javax.swing.JLabel;

public class Main {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        JLabel label0 = new JLabel(Language.getString("Main.label0"));
        JLabel label1 = new JLabel(Language.getString("Main.label1"));
        //...
        frame.setLayout(new FlowLayout());
        frame.add(label0);
        frame.add(label1);
        //...
        frame.pack();
        frame.setVisible(true);
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Language.setLocale(new Locale("de_DE"));
        label0.setText(Language.getString("Main.label0"));
        label1.setText(Language.getString("Main.label1"));
        //...
        frame.pack();
    }
}

Language.java

import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

public class Language {
    private static final String BUNDLE_NAME = "Language";
    private static Locale locale = new Locale("en_US");
    private static ResourceBundle RESOURCE_BUNDLE = ResourceBundle
            .getBundle(BUNDLE_NAME, locale);

    private Language() {
    }

    public static String getString(String key) {
        try {
            return RESOURCE_BUNDLE.getString(key);
        } catch (MissingResourceException e) {
            return '!' + key + '!';
        }
    }

    public static void setLocale(Locale locale) {
        Language.locale = locale;
        Language.RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME, locale);
    }
}

Language_en_US.properties

#Language English
Main.label0=This is some text
Main.label1=This is some more text

Language_de_DE.properties

#Language German
Main.label0=Dies ist ein Text
Main.label1=Dies ist etwas mehr Text

如您所见,在Main.java中,我必须再次手动设置标签的所有文本。这对于5个或10个很容易,但是如果我使用其中的50个以及工具提示,选项卡名称,组合框和菜单都需要更改其中的区域设置,那么对所有这些进行此操作变得非常不切实际。有什么想法吗?

1 个答案:

答案 0 :(得分:2)

资源包背后的想法是实际“外化”应用程序中的所有字符串,以便您可以使用不同的字符串编写不同的文件(现在只讨论字符串),而不需要触及源代码。

例如,假设你有:

System.out.println("Sorry, an error has occurred");

你可以像这样使用PropertyResourceBundle:

System.out.println(bundle.getString("error_occurred"));

然后创建如下文件:

error_occurred=Sorry, an error has occurred

或者

error_occurred=Purtroppo si è verificato un errore

然后,根据用户选择的语言或平台的区域设置将正确的属性加载到资源包中:

public void initBundle(String language) throws IOException {
  InputStream is = Class.getResourceAsStream("/bundles/messages_" + language + ".properties);
  try {
    return new PropertyResourceBundle(is);
  } finally {
    fis.close();
  }      
}