我的GUI中有一个下拉框,显示另一个类中ArrayList的内容。 可以将新对象添加到GUI中其他位置的ArrayList,因此我需要知道它何时更新,因此我可以刷新下拉菜单。从我可以收集的内容来看,我的两个选项是扩展ArrayList类以允许我将自己的changeListener添加到它,或者使包含有问题的ArrayList的类扩展为可观察的。
哪种解决方案更合适?
答案 0 :(得分:11)
这两个解决方案基本上是相同根设计模式的实现(四人帮定义的“观察者”模式。)在前一种情况下,你使ArrayList本身“可观察”,在后者你是使用数组列表的域对象“observable。”
我倾向于做后者:使域对象可观察。这主要是因为您最终可能会有其他可能更改域对象的事情(应该更新GUI。)如果已经可以观察到,那么您已经设置好了。
请注意,您不必严格延伸java.util.Observable
- 您可以在不执行此操作的情况下实现设计模式。
答案 1 :(得分:9)
Java中的Observable
实现很少使用,并且不能与Swing良好地交互。请改用EventListener
。
特别是,在“GUI中的其他地方”管理列表内容时,是否有理由不直接扩展AbstractListModel
或甚至直接使用DefaultListModel
?然后,您的组合框可以使用委托给同一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); }
}
答案 2 :(得分:2)
为什么不使用绑定?
http://wiki.eclipse.org/index.php/JFace_Data_Binding
将GUI小部件绑定到列表。变化将透明地传播两个对象。确保使用适当的observable包装模型,例如WritableList(如果直接使用ArrayList)。
答案 3 :(得分:1)
总是喜欢构图而不是扩展(我的参考是有效的java和我的个人经验)。扩展ArrayList只是一个承诺,你不会违反任何类不变量。它还会将您绑定到您正在扩展的特定列表实现。
答案 4 :(得分:0)
您可以切换为使用GUI design pattern。或者构建一个有限的实现。
创建一个GUI表单接口,该接口具有DrawXArrayList方法(X是一个有意义的名称。它的参数类型为ArrayList
创建一个名为GUIView的新类。它至少有两个方法:UpdateXArrayList和RegisterForm
初始化应用程序时,GUI表单会自动注册实现GUIView的类。使实现GUIView的类对表单可见。
当GUI表单中的任何内容更新时,arraylist会将它调用UpdateXArrayList作为它的最后一件事。实现GUIView的类中的UpdateXArrayList方法将依次调用DrawXArrayList传递更新的arraylist。实现GUIFormInterface的表单类中的DrawXArrayList将采取更新显示ArrayList的控件的步骤。
虽然与观察者和听众设置相比,这似乎有很多步骤。您可以更好地控制各种用户操作如何影响UI,然后是观察者 - 侦听器模式。此外,您还在代码中记录了用户操作与UI更新之间的交互。
答案 5 :(得分:0)
如果您可以向应用程序添加新jar,请查看glazed Lists