在Java中使按钮操作跨多个类工作
我正在用Java制作一个计算器,但我似乎无法让按钮的actionListener在其他4个类中进行更改。我想要的是按钮将程序中的文本从英语更改为西班牙语。我的程序由5个类组成,我希望在每个类中更改所有JLabel、按钮和菜单中的语言 这是我的按钮侦听器代码:在Java中使按钮操作跨多个类工作,java,jbutton,Java,Jbutton,我正在用Java制作一个计算器,但我似乎无法让按钮的actionListener在其他4个类中进行更改。我想要的是按钮将程序中的文本从英语更改为西班牙语。我的程序由5个类组成,我希望在每个类中更改所有JLabel、按钮和菜单中的语言 这是我的按钮侦听器代码: btnLanguage = new JButton("Language"); btnLanguage.addActionListener(new ActionListener() { public void acti
btnLanguage = new JButton("Language");
btnLanguage.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
btnAddition.setText("Añadir");
btnDivide.setText("Dividir");
btnMultiply.setText("Se multiplican");
btnSubtract.setText("Reste");
btnLanguage.setText("Idioma");
}
});
我还想知道Windows是否会自动将程序中的文本更改为系统语言
提前谢谢 不幸的是,Swing没有良好的l10n内置支持。你需要自己处理标签重命名等 通常,swing支持的是Java资源包概念,在构建UI之前,您可以选择包含所有文本的资源 在您的代码中,您将不再有文本消息,但您将从包中获得字符串 这里有4个捆绑文件,名称中至少包含您想要的语言
# Bundle file lang.properties
button.addition.text=Add
# Bundle file lang_de.properties
button.addition.text=Addieren
# Bundle file lang_en.properties
button.addition.text=Add
# Bundle file lang_fr.properties
button.addition.text=Addition
在代码中,在构建ui之前加载资源包(例如在名为App
的类中):
初始化UI时,您将调用use:
JButton btn = new JButton();
btn.setText(App.R.getString("button.addition.text"));
这允许不在运行时切换。然而,您可以使用Java8 lambda并在l10n服务
上为翻译文本的setter注册所有标签载体
public class L10nService {
ResourceBundle R = .... // initialize or change at runtime
private List<LabelSetter> setters = new ArrayList<LabelSetter>();
public void addSetter(LabelSetter setter) {
setters.add(setter);
}
public void changeLanguage(Locale l) {
R = ResourceBundle.getBundle("l10n/lang", l);
for(LabelSetter s : setters) {
s.set(R);
}
}
}
注意:这有缺点。虽然您可以在运行时非常轻松地切换语言,但即使您销毁了UI元素曾经所在的容器,您也可以将它们保留在内存中。这是因为它们位于您已注册的closure标签盒中。只要这个闭包存在,您的UI对象就不会消失。因此,在销毁UI元素时,您需要确保也将它们从l10n服务中删除。此外,如果所有标签都更改,swing可能需要大量重新绘制和重新规划。
这里的好处是,您可以通过ResourceBundles
使swing库真正了解l10n更改,并且语言开关可以自我传播
或者,您可以实现一个L10nTextSource
,它发出LocaleChangedEvents
。您的UI类将侦听这些事件并重写它们自己。这里的缺点是,您需要扩展每个要向组件添加功能或至少向组件添加功能的UI元素 您确实应该有某种模型,第一个类将更改它(某些属性),该模型将生成一个通知,其他三个可以侦听该通知并采取适当的操作
public class L10nService {
ResourceBundle R = .... // initialize or change at runtime
private List<LabelSetter> setters = new ArrayList<LabelSetter>();
public void addSetter(LabelSetter setter) {
setters.add(setter);
}
public void changeLanguage(Locale l) {
R = ResourceBundle.getBundle("l10n/lang", l);
for(LabelSetter s : setters) {
s.set(R);
}
}
}
void buildUi(L10nService fac, Locale l) {
JButton btn = new JButton();
LabelSetter s = R -> btn.setText(R.getText("button.addition.text"));
fac.addSetter(s);
// ... continue adding ui elements
// when you are ready to build:
fac.changeLanguage(l);
}