使按钮操作在 Java 中的多个 类 中起作用
Making a button action work across multiple classes in Java
我正在 Java 中制作一个计算器,但我似乎无法获得按钮的 actionListener 来改变其他 4 个 类 中的内容。我想要的是按钮将程序中的文本从英语更改为西班牙语。我的程序由 5 个 类 组成,我希望每个 JLabel、按钮和菜单中的语言都发生变化。
这是我的按钮监听器代码:
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 支持 build in。你需要自己处理标签重命名等。
通常swing支持的是Java资源包的概念,就是选择UI之前的所有文字的资源是build。
在您的代码中,您将不再收到短信,但您将从您的包中获取字符串。
这里有 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
在您的代码中,您在 build ui 之前加载资源包(例如在名为 App
的 class 中):
public static ResourceBundle R;
public static void main(String[] args) {
Locale l = new Locale(args[0], args[1]); // should have a check here :-)
R = ResourceBundle.getBundle("l10n/lang.properties", l);
}
当您初始化 UI 时,您将调用 use:
JButton btn = new JButton();
btn.setText(App.R.getString("button.addition.text"));
这允许在运行时不切换。不过,您可以使用 Java8 lambda 并为 L10nService
上的翻译文本注册所有带有 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 中,您将创建 uild UI,并为每个要翻译的元素注册 LabelSetter:
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);
}
注意:这有缺点。虽然您可以在运行时非常轻松地切换语言,但即使您销毁了它们曾经居住的容器,您也会将 UI 元素保留在内存中。这是因为它们在闭包 LabelSetter
中,你已经注册了。只要这个闭包存在,你的 UI 对象就不会消失。因此,在销毁 UI 元素时,您需要确保将它们也从 L10nService
中移除。此外,如果所有标签都发生变化,swing 可能需要ui重新绘制和重新布局。
这里的好处是,您实际上可以让 swing 库通过 ResourceBundles
了解 l10n 更改,并且语言切换会自行传播。
或者,您可以实现一个 L10nTextSource
,它发出 LocaleChangedEvents
。您的 UI classes 会监听这些事件并自行重写。这里的缺点是,您需要扩展每个要添加功能的 UI 元素,或者至少要将功能添加到您的组件。
我正在 Java 中制作一个计算器,但我似乎无法获得按钮的 actionListener 来改变其他 4 个 类 中的内容。我想要的是按钮将程序中的文本从英语更改为西班牙语。我的程序由 5 个 类 组成,我希望每个 JLabel、按钮和菜单中的语言都发生变化。
这是我的按钮监听器代码:
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 支持 build in。你需要自己处理标签重命名等。
通常swing支持的是Java资源包的概念,就是选择UI之前的所有文字的资源是build。
在您的代码中,您将不再收到短信,但您将从您的包中获取字符串。
这里有 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
在您的代码中,您在 build ui 之前加载资源包(例如在名为 App
的 class 中):
public static ResourceBundle R;
public static void main(String[] args) {
Locale l = new Locale(args[0], args[1]); // should have a check here :-)
R = ResourceBundle.getBundle("l10n/lang.properties", l);
}
当您初始化 UI 时,您将调用 use:
JButton btn = new JButton();
btn.setText(App.R.getString("button.addition.text"));
这允许在运行时不切换。不过,您可以使用 Java8 lambda 并为 L10nService
上的翻译文本注册所有带有 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 中,您将创建 uild UI,并为每个要翻译的元素注册 LabelSetter:
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);
}
注意:这有缺点。虽然您可以在运行时非常轻松地切换语言,但即使您销毁了它们曾经居住的容器,您也会将 UI 元素保留在内存中。这是因为它们在闭包 LabelSetter
中,你已经注册了。只要这个闭包存在,你的 UI 对象就不会消失。因此,在销毁 UI 元素时,您需要确保将它们也从 L10nService
中移除。此外,如果所有标签都发生变化,swing 可能需要ui重新绘制和重新布局。
这里的好处是,您实际上可以让 swing 库通过 ResourceBundles
了解 l10n 更改,并且语言切换会自行传播。
或者,您可以实现一个 L10nTextSource
,它发出 LocaleChangedEvents
。您的 UI classes 会监听这些事件并自行重写。这里的缺点是,您需要扩展每个要添加功能的 UI 元素,或者至少要将功能添加到您的组件。