使用Java中的多个类进行按钮操作

时间:2016-02-09 22:08:33

标签: java jbutton

我用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是否自动将程序中的文本更改为系统语言。

提前致谢!

1 个答案:

答案 0 :(得分:0)

不幸的是,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的类中):

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 lambdas并使用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中,您将构建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中删除。此外,如果所有标签都发生变化,摆动可能需要大量重新涂漆和继电器。 这里的好处是,您可以使用ResourceBundles实际让swing库知道l10n更改,并且语言开关自行传播。

或者,您可以实施L10nTextSource,即LocaleChangedEvents。您的UI类将侦听这些事件并重写自己。这里的缺点是,您需要扩展要添加功能的每个UI元素,或者至少向组件添加功能。