运行时Swing元素的java刷新语言
我的Java 8/Swing应用程序使用一个ResourceBundle
和两个.properties
文件来更改语言,当用户从JComboBox
中选择一个时:
public static ResourceBundle resourceBundle;
private JComboBox<Locale> comboBox;
private JLabel myLabel;
public Main() {
//More GUI setup here
resourceBundle = ResourceBundle.getBundle("Bundle", Locale.ENGLISH); //Set first/default language
comboBox = new JComboBox<Locale>();
comboBox.addItem(Locale.ENGLISH);
comboBox.addItem(Locale.GERMAN);
comboBox.addItem(Locale.FRENCH);
myLabel = new JLabel(resourceBundle.getString("myLabelText"));
myLabel.setFont(new Font("Tahoma", Font.PLAIN, 14));
}
JComboBox
上的ActionListener
调用此函数,这会立即更改所有GUI元素的语言:
private void changeLanguage() {
Locale locale = comboBox.getItemAt(comboBox.getSelectedIndex());
resourceBundle = ResourceBundle.getBundle("Bundle", locale);
myLabel.setText(resourceBundle.getString("myLabelText"));
}
在我的应用程序中,有更多的标签和按钮通过changeLanguage
设置语言(但并非所有标签和按钮都使用本地化,例如带有房屋图标的“主页”按钮),我打算添加更多。随着GUI项目数量的增加,忘记在函数中添加一项也变得越来越容易,这就是为什么我的问题是:
有没有办法“注册”一个JLabel
,。。。它对某个类的键(直接在创建之后)以及随后更改语言(通过加载另一个Locale
)也会自动更改JLabel
的文本,。。。?是否有一种常用的方法与我的做法不同
# 1 楼答案
我的结局是:
要使用此方法,请创建一个
ArrayList
,并在创建后直接向其中添加每个应更改其语言的组件:通过迭代列表更改语言:
我知道这会为每个组件创建一个额外的对象。:/不幸的是,这是我发现的唯一可以让我只改变
JLabel
的语言,JButton
的语言,。。。这需要改变他们的语言,而不需要在一个方法中手动列出所有这些语言(可能忘记一个)# 2 楼答案
我最近遇到了这个问题,所以我将分享我的尝试和它对我的作用。请注意,我还需要在运行时实现更改字体操作
在Swing应用程序中,我们通常为核心容器扩展容器类。假设我们想为桌面创建Facebook。有人可以创建3个核心类(扩展JPanel或JScrollPane)。让我们说:
LeftPanel extends JPanel
,MiddlePanel extends JPanel
和RightPanel extends JPanel
。左面板代表左菜单,中面板代表主滚动视图,最后右面板代表广告区域。当然,这些面板中的每一个都将继承JPanel
(其中一些面板可能也会有一个新类,例如PostPanel
、CommentSectionPanel
等等)现在,假设您已经阅读了The Use of Multiple JFrames: Good or Bad Practice?,您的应用程序只使用一个
JFrame
,并且它承载其中的每个组件。甚至模态JDialog
也基于它(将它作为其父级)。所以,你可以把它放在像Singleton
一样的地方为了更改组件文本,我们必须为每个组件调用
setText
。调用JFrame
的getComponents
将为我们提供它的所有组件。如果其中一个是container,我们将不得不为它调用getComponents
,因为它可能也包含组件。解决方案是一个递归,以找到所有这些问题:使用参数
java.awt.Component.class
和myJFrame
调用此方法将为您提供JFrame
拥有的所有组件现在,我们必须区分哪些可以“刷新”(更改语言),哪些不能。让我们为此创建一个
Interface
:现在,我们不给他们每个人这个能力,而是给大容器(facebook的例子):
LeftPanel extends JPanel implements LocaleChangeable
,RightPanel extends JPanel implements LocaleChangeable
,因为它们有具有text属性的组件这些类现在负责更改其组件的文本。pseduo的一个例子是:
(当然,
ResourceBundle
逻辑将发生,而不是一堆if-else
条件)所以。。。让我们为所有类容器调用此方法:
就这样!一个完整的例子是: