我正在寻找一种有效的方法,在对关键对象进行更改后触发一组对象的更改。我想要做的是: 有一个对象,如果更改,则在其他对象中执行方法。
我试图使用PropertyChangeListener来完成此任务:
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class BoundSample {
public static void main(String args[]) {
JFrame frame = new JFrame("PropertyChangeListener Sample");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JButton button1 = new JButton("Open");
final JButton button2 = new JButton("Cancel");
final String[] languages = { "English", "Spanish" };
final JComboBox combo = new JComboBox(languages);
final JPanel panel = new JPanel();
ActionListener actionListener = new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
JComboBox comboTmp = (JComboBox) actionEvent.getSource();
if (combo.getSelectedItem().equals("English") || combo.getSelectedItem().equals("Ingles")) {
String[] langs = { "English", "Spanish" };
comboTmp.setModel(new JComboBox(langs).getModel());
}
else if (combo.getSelectedItem().equals("Spanish") || combo.getSelectedItem().equals("Espanol")) {
String[] langs = { "Ingles", "Espanol" };
comboTmp.setModel(new JComboBox(langs).getModel());
}
}
};
PropertyChangeListener propertyChangeListener = new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent propertyChangeEvent) {
String property = propertyChangeEvent.getPropertyName();
JComboBox comboTmp = (JComboBox) propertyChangeEvent.getSource();
String language = (String) comboTmp.getItemAt(0);
System.out.println(language);
if ("model".equals(property)) {
if (language.equals("English")) {
button1.setLabel("Open");
button2.setLabel("Cancel");
} else if (language.equals("Ingles")) {
button1.setLabel("Abierto");
button2.setLabel("Cancelar");
}
}
}
};
combo.addPropertyChangeListener(propertyChangeListener);
combo.addActionListener(actionListener);
Container contentPane = frame.getContentPane();
panel.add(button1, BorderLayout.CENTER);
panel.add(button2, BorderLayout.SOUTH);
contentPane.add(combo, BorderLayout.NORTH);
contentPane.add(panel, BorderLayout.SOUTH);
frame.setSize(300, 100);
frame.setVisible(true);
}
}
这种方法的问题在于,随着对象数量的增加,propertyChange()方法将耗费并且将变得难以管理。此外,为了添加新的JComponent,我还必须修改propertyChange()。
有没有办法通过使对象“查找”关键对象的更改并使其相应地执行而不是通过在关键对象的PropertyChangeListener中执行操作来对其执行操作来反过来执行此操作?或者也许是其他简洁的方法来做到这一点?
答案 0 :(得分:3)
首先,推荐 - 总是让母语人士进行翻译。它有助于避免某些类型的错误。例如,您选择作为“开放”的替代词通常用作形容词(如“开放窗口”),而不是动词,而您使用“取消”的无意义时态。你也没有重音符号,这可能会让一些读者感到困惑(有些单词只是因为它们的重音标记而有所不同......)。
接下来,你不应该硬编码语言选择或使用;它们应该从.properties
个文件或类似文件中加载。这使得维护变得微不足道,尤其是在添加其他语言时。 @ Mort关于使用观察者模式的答案是正确的 - 这就是应该如何处理更新。这是(非常粗略地)如何处理语言方面:
首先,您需要一些.properties
个文件。
spanishButtonNames.properties
==================================
openButton=Abrir
cancelButton=Cancelar
englishButtonNames.properties
==================================
opernButton=Open
cancelButton=Cancel
当要求语言(以及可能释放资源)时,你会希望将它们包含在某种PropertyManager
中,以处理在幕后加载资源文件。
接下来,在创建按钮时,请将它们命名为:
JButton openButton = new JButton();
openButton.setName("openButton");
// And add them to a list
buttonList.add(openButton);
// More buttons....
更新按钮列表中的按钮是微不足道的。您可以只拥有buttonList
监听(和传播)更新:
for(JButton button : buttonList) {
button.setText(languagePropertyManager.getProperty(button.getName()));
}
(请注意,通过一些聪明的编码,甚至可以从文本文件中加载GUI布局,但我从未尝试过。我相信有一些框架可以处理它。)
答案 1 :(得分:2)
你知道observer pattern吗?它可以满足您的需求:对象将在对象中注册,以便在发生事件时得到通知。