我应该使用监听器还是观察者?
-
09-09-2019 - |
题
我的 GUI 中有一个下拉框,它显示另一个类中 ArrayList 的内容。新对象可以添加到 GUI 中其他位置的 ArrayList 中,因此我需要知道它何时更新,以便刷新下拉菜单。据我所知,我的两个选择是扩展 ArrayList 类以允许我向其中添加自己的changeListener,或者使包含相关 ArrayList 的类扩展为可观察的。
哪一个是更合适的解决方案?
解决方案
将两种溶液基本相同的根设计模式(如由四人帮定义的“观察者”模式)。在前者的情况下的实施方式中,你可以将这个ArrayList的本身“可观察”,在后者的你是使得它使用数组列表域对象“可观察。”
我的倾向是做后者:使域对象观察到。这主要是因为你最终可能有其他的事情可能会改变关于域对象(其GUI应更新)。如果它已经观察到的,你已经设置。
请注意,您不必严格延长java.util.Observable
- 你可以实现的设计模式不这样做,
其他提示
这 Observable
Java 中的实现很少使用,并且与 Swing 的互操作性不佳。使用 EventListener
反而。
特别是,是否有理由不延长 AbstractListModel
甚至使用 DefaultListModel
直接在“GUI 中的其他位置”管理列表内容时?然后你的组合框可以使用 ComboBoxModel
委托给同一个 ListModel
实例,添加自己的实现来跟踪选择状态。
我想到了这样的事情(但我还没有测试过):
final class MyComboBoxModel
extends AbstractListModel
implements ComboBoxModel
{
private final ListModel data;
private volatile Object selection;
MyComboBoxModel(ListModel data) {
/*
* Construct this object with a reference to your list,
* which contents are managed somewhere else in the UI.
*/
this.data = data;
data.addListDataListener(new ListDataListener() {
public void contentsChanged(ListDataEvent evt) {
fireContentsChanged(this, evt.getIndex0(), evt.getIndex1());
}
public void intervalAdded(ListDataEvent evt) {
fireContentsChanged(this, evt.getIndex0(), evt.getIndex1());
}
public void intervalRemoved(ListDataEvent evt) {
fireContentsChanged(this, evt.getIndex0(), evt.getIndex1());
}
});
}
public void setSelectedItem(Object selection) {
this.selection = selection;
fireContentsChanged(this, 0, data.getSize() - 1);
}
public Object getSelectedItem() { return selection; }
public int getSize() { return data.getSize(); }
public Object getElementAt(int idx) { return data.getElementAt(idx); }
}
为什么不使用绑定?
http://wiki.eclipse.org/index.php/JFace_Data_Binding
绑定您的GUI窗口小部件到您的列表。变化将透明的两个对象之间传播完成。一定要与适当的可观察到的包模型,如WritableList(如果直接使用的ArrayList)。
始终倾向于组合物在延伸部(我的参考是有效的java和我的个人体验)。扩展ArrayList的很简单,就是你不会违反任何类别不变的承诺。它也结合你要扩展的具体列表实现。
您可以切换到使用 GUI设计图案。或构造一个有限的实现。
创建具有方法DrawXArrayList(其中X是一些meaningfull名称的GUI接口形式,它具有ArrayList类型
的参数创建一个名为GUIView新类。它至少有两种方法:UpdateXArrayList,和RegisterForm
在初始化应用程序有GUI形式实现GUIView类注册。使课堂实施GUIView可见的形式。
当在你的GUI形式的任何更新的ArrayList有它称之为UpdateXArrayList因为它的最后一件事。该UpdateXArrayList方法在实施再GUIView将依次调用DrawXArrayList经过更新的ArrayList类。然后DrawXArrayList在实施GUIFormInterface形式类将采取的步骤需要更新控制显示该ArrayList。
虽然这似乎是一个很大的相比,观察者和听众设置步骤。您可以在各种用户行为如何影响UI则观察者监听模式的更多控制。此外你记载,在代码中,用户动作和更新到UI之间的相互作用。
如果您可以添加新的JAR到应用程序,请釉面列表