2009-04-13 90 views
15

我在我的GUI中有一个下拉框,它显示了另一个类中ArrayList的内容。 新的对象可以添加到GUI中其他地方的ArrayList,所以我需要知道它何时更新,因此我可以刷新下拉菜单。从我可以收集的内容来看,我的两个选择是扩展ArrayList类以允许我将自己的changeListener添加到它,或者使包含所讨论的ArrayList的类可扩展。我应该使用Listener还是Observer?

这将是一个更合适的解决方案?

+1

你指的JComboBox?如果是这样,我会看看ComboBoxModel及其实现。 – Avrom 2009-04-14 20:37:30

回答

10

这两种方案在本质上是同根生的设计模式的实现(在“观察家报”的格局被定义)在前一种情况下,您将ArrayList本身设置为“可观察”,后者是使用数组列表“可观察”的域对象。

我的倾向是做后者:使域对象可观察。这主要是因为您可能最终还会有其他可能会改变的域对象(应该更新GUI)。如果它已经被观察到,那么您已经设置好了。

请注意,您不必严格延伸java.util.Observable - 您可以在不这样做的情况下实现设计模式。

+0

这似乎是最简单的方法,但感谢所有其他答案。 – Simonw 2009-04-13 18:18:42

9

在Java中的Observable实现很少使用,并且不能与Swing良好地互操作。改为使用EventListener

尤其是有什么原因不延长AbstractListModel甚至管理列表中的“其他地方的GUI”的内容时使用DefaultListModel直接?然后您的组合框可以使用代理到相同的ListModel实例的ComboBoxModel,添加自己的实现来跟踪选择状态。

我想到的是这样的(但我没有测试它):

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); } 

} 
1

总是比延伸更喜欢构图(我的参考是有效的Java和我的个人经验)。扩展ArrayList只是一个承诺,你不会违反任何类的不变式。它还将您绑定到您正在扩展的特定列表实施。

0

您可以切换到使用GUI design pattern。或者构建一个有限的实现。

创建具有方法DrawXArrayList(其中X是一些meaningfull名称的GUI接口形式它具有ArrayList类型

创建一个名为GUIView新类的参数,具有至少两种方法:。UpdateXArrayList,和RegisterForm

当你初始化应用程序有GUI形式注册本身与类实现GUIView。让执行GUIView可见的窗体类。

当你的GUI形式的任何更新ArrayList中有它调用UpdateXArrayList作为它所做的最后一件事然后,实现GUIView的类中的UpdateXArrayList方法将调用DrawXArrayList传递更新后的数组列表。然后,实现GUIFormInterface的表单类中的DrawXArrayList将执行需要更新显示ArrayList的控件的步骤。

尽管与观察者和侦听器设置相比,这看起来像很多步骤。您可以更好地控制各种用户操作如何影响UI,然后控制观察者 - 监听器模式。此外,您在代码中记录了用户操作和UI更新之间的交互。

2

为什么不使用绑定?

http://wiki.eclipse.org/index.php/JFace_Data_Binding

绑定你的GUI窗口小部件到您的列表。变化将透明地在两个对象之间传播。一定要用适当的observable包装你的模型,比如WritableList(如果直接使用ArrayList)。

0

如果你可以添加新的JAR到应用程序,看看glazed Lists

相关问题