Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中使按钮操作跨多个类工作_Java_Jbutton - Fatal编程技术网

在Java中使按钮操作跨多个类工作

在Java中使按钮操作跨多个类工作,java,jbutton,Java,Jbutton,我正在用Java制作一个计算器,但我似乎无法让按钮的actionListener在其他4个类中进行更改。我想要的是按钮将程序中的文本从英语更改为西班牙语。我的程序由5个类组成,我希望在每个类中更改所有JLabel、按钮和菜单中的语言 这是我的按钮侦听器代码: btnLanguage = new JButton("Language"); btnLanguage.addActionListener(new ActionListener() { public void acti

我正在用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内置支持。你需要自己处理标签重命名等

通常,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);
}