在Swing中改变运行时的语言环境

时间:2022-06-01 20:06:12

I would like to be able to change the locale in my Swing application at runtime and have all the text elements on the screen update themselves with localized text from a ResourceBundle of the new locale.

我希望能够在运行时更改我的Swing应用程序中的语言环境,并让屏幕上的所有文本元素都使用新语言环境的ResourceBundle中的本地化文本进行更新。

Can this be done without customizing swing components or creating UIDelegates for all components that handle rendering localized text?

这可以在不自定义swing组件或为处理渲染本地化文本的所有组件创建UIDelegates的情况下完成吗?

If no, then what is a good solution I can consider implementing?

如果不是,那么我可以考虑实施什么是好的解决方案?

5 个解决方案

#1


13  

  1. You have a method that is used to change app locale (and probably persist the new value) and another one to get localized strings.

    您有一个方法用于更改应用程序区域设置(可能会保留新值),另一个方法用于获取本地化字符串。

  2. Create an interface:

    创建一个界面:

    interface LocaleChangeListener {
        void onLocaleChange();
    }
    

    Implement it by UI components that need to be able to change locale at runtime and set the new values in overrides onLocaleChange().

    由需要能够在运行时更改语言环境的UI组件实现它,并在覆盖onLocaleChange()时设置新值。

  3. Now, have a list of listeners that will be notified on locale change by the first method.

    现在,有一个监听器列表,将通过第一种方法通知区域设置更改。

#2


17  

use ResourceBundle.getBundle(BUNDLE_NAME).getString(key); to access the Strings.

使用ResourceBundle.getBundle(BUNDLE_NAME).getString(key);访问字符串。

when updating the Default Locale e.g. via Locale.setDefault(Locale.GERMAN); clear the Resourcebundle cache: ResourceBundle.clearCache();

更新默认区域设置时,例如通过Locale.setDefault(Locale.GERMAN);清除Resourcebundle缓存:ResourceBundle.clearCache();

the next call of ResourceBundle.getBundle(BUNDLE_NAME).getString(key); should the return the localized String of the chosen Locale.

下一次调用ResourceBundle.getBundle(BUNDLE_NAME).getString(key);应该返回所选Locale的本地化String。

#3


2  

You may want to save the language preference out, and then require a restart of the app for changes to take effect.

您可能希望保存语言首选项,然后需要重新启动应用程序才能使更改生效。

Then, you should be able to use Locale.setDefault(Locale.<desired language>); on startup, prior to rendering the GUI. That should properly switch your locale, which will result in the desired .properties file(s) being loaded.

然后,您应该能够使用Locale.setDefault(Locale。 );在启动时,在渲染GUI之前。这应该正确切换您的语言环境,这将导致加载所需的.properties文件。

#4


0  

What about, on changing locale, do a firePropertyChangeEvent("locale", "..."), then add propertyChangeListener() and register them, whereever labels and the like are to be updated?

那么,在更改区域设置时,执行firePropertyChangeEvent(“locale”,“...”),然后添加propertyChangeListener()并注册它们,是否要更新标签等?

#5


-1  

There's two obvious approaches I see:

我看到了两种明显的方法:

Instead of getting a String from the ResourceBundle, get some kind of event-source String holder. Document would be the very heavy solution, but anything that can handle replacing an immutable value will do. Instead of just setting the text on a label, say, have a method that also sets up a listener. Note, this quite a "heavy" solution.

而不是从ResourceBundle获取String,获取某种事件源字符串持有者。文档将是非常繁重的解决方案,但任何可以处理替换不可变值的东西都可以。例如,有一个方法也可以设置一个监听器,而不是仅仅在标签上设置文本。请注意,这是一个非常“沉重”的解决方案。

Alternatively, have a central repository of listeners that are fired on a locale change, that each then go back and re-execute the relevant part of the set up code (don't duplicate). For common cases where you have, say, a JLabel using a resource string literally, then you can combine these all into one listener with a WeakHashMap<JLabel,String>. Sometimes it works out better to avoid lots of little listeners.

或者,拥有一个在区域设置更改时触发的侦听器的*存储库,然后每个都返回并重新执行设置代码的相关部分(不重复)。对于您使用资源字符串的JLabel的常见情况,您可以将这些全部组合到一个具有WeakHashMap 的侦听器中。有时它可以更好地避免许多小听众。 ,string>

#1


13  

  1. You have a method that is used to change app locale (and probably persist the new value) and another one to get localized strings.

    您有一个方法用于更改应用程序区域设置(可能会保留新值),另一个方法用于获取本地化字符串。

  2. Create an interface:

    创建一个界面:

    interface LocaleChangeListener {
        void onLocaleChange();
    }
    

    Implement it by UI components that need to be able to change locale at runtime and set the new values in overrides onLocaleChange().

    由需要能够在运行时更改语言环境的UI组件实现它,并在覆盖onLocaleChange()时设置新值。

  3. Now, have a list of listeners that will be notified on locale change by the first method.

    现在,有一个监听器列表,将通过第一种方法通知区域设置更改。

#2


17  

use ResourceBundle.getBundle(BUNDLE_NAME).getString(key); to access the Strings.

使用ResourceBundle.getBundle(BUNDLE_NAME).getString(key);访问字符串。

when updating the Default Locale e.g. via Locale.setDefault(Locale.GERMAN); clear the Resourcebundle cache: ResourceBundle.clearCache();

更新默认区域设置时,例如通过Locale.setDefault(Locale.GERMAN);清除Resourcebundle缓存:ResourceBundle.clearCache();

the next call of ResourceBundle.getBundle(BUNDLE_NAME).getString(key); should the return the localized String of the chosen Locale.

下一次调用ResourceBundle.getBundle(BUNDLE_NAME).getString(key);应该返回所选Locale的本地化String。

#3


2  

You may want to save the language preference out, and then require a restart of the app for changes to take effect.

您可能希望保存语言首选项,然后需要重新启动应用程序才能使更改生效。

Then, you should be able to use Locale.setDefault(Locale.<desired language>); on startup, prior to rendering the GUI. That should properly switch your locale, which will result in the desired .properties file(s) being loaded.

然后,您应该能够使用Locale.setDefault(Locale。 );在启动时,在渲染GUI之前。这应该正确切换您的语言环境,这将导致加载所需的.properties文件。

#4


0  

What about, on changing locale, do a firePropertyChangeEvent("locale", "..."), then add propertyChangeListener() and register them, whereever labels and the like are to be updated?

那么,在更改区域设置时,执行firePropertyChangeEvent(“locale”,“...”),然后添加propertyChangeListener()并注册它们,是否要更新标签等?

#5


-1  

There's two obvious approaches I see:

我看到了两种明显的方法:

Instead of getting a String from the ResourceBundle, get some kind of event-source String holder. Document would be the very heavy solution, but anything that can handle replacing an immutable value will do. Instead of just setting the text on a label, say, have a method that also sets up a listener. Note, this quite a "heavy" solution.

而不是从ResourceBundle获取String,获取某种事件源字符串持有者。文档将是非常繁重的解决方案,但任何可以处理替换不可变值的东西都可以。例如,有一个方法也可以设置一个监听器,而不是仅仅在标签上设置文本。请注意,这是一个非常“沉重”的解决方案。

Alternatively, have a central repository of listeners that are fired on a locale change, that each then go back and re-execute the relevant part of the set up code (don't duplicate). For common cases where you have, say, a JLabel using a resource string literally, then you can combine these all into one listener with a WeakHashMap<JLabel,String>. Sometimes it works out better to avoid lots of little listeners.

或者,拥有一个在区域设置更改时触发的侦听器的*存储库,然后每个都返回并重新执行设置代码的相关部分(不重复)。对于您使用资源字符串的JLabel的常见情况,您可以将这些全部组合到一个具有WeakHashMap 的侦听器中。有时它可以更好地避免许多小听众。 ,string>