我应该使用监听器还是观察者?

发布于 2024-07-16 20:18:19 字数 211 浏览 7 评论 0原文

我的 GUI 中有一个下拉框,它显示另一个类中 ArrayList 的内容。 新对象可以添加到 GUI 中其他位置的 ArrayList 中,因此我需要知道它何时更新,以便刷新下拉菜单。 据我所知,我的两个选择是扩展 ArrayList 类以允许我向其中添加自己的changeListener,或者使包含相关 ArrayList 的类扩展为可观察的。

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

I have a dropdown box in my GUI which shows the contents of an ArrayList in another class.
New objects can be added to the ArrayList elsewhere in the GUI, so I need to know when it is updated, so I can refresh the dropdown menu. From what I can gather, my two options are to extend the ArrayList class to allow me to add my own changeListener to it, or to make the class which contains the ArrayList in question extend observable.

Which would be a more appropriate solution?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

假装不在乎 2024-07-23 20:18:20

总是更喜欢组合而不是扩展(我的参考是有效的java和我的个人经验)。 扩展 ArrayList 只是一个承诺,即您不会违反任何类不变量。 它还将您绑定到您正在扩展的特定列表实现。

Always prefer composition over extension (my reference is effective java and my personal experience). extending ArrayList is simply a promise that you will not violate any of the classes invariants. It also binds you to the specific list implementation you are extending.

起风了 2024-07-23 20:18:20

您可以改用 GUI 设计模式。 或者构建一个有限的实现。

创建一个 GUI 表单接口,它有一个方法 DrawXArrayList(X 是一些有意义的名称。它有一个 ArrayList 类型的参数。

创建一个名为 GUIView 的新类。它至少有两个方法:UpdateXArrayList 和 RegisterForm

当您初始化应用程序时,有GUI Form 向实现 GUIView 的类注册自身。

当 GUI Form 中的任何内容更新 arraylist 时,它会调用 UpdateXArrayList 作为实现 GUIView 的类中的 UpdateXArrayList 方法。反过来,在实现 GUIFormInterface 的表单类中调用 DrawXArrayList 传递更新的数组列表,然后将采取更新显示 ArrayList 的控件所需的步骤,

但与观察者和侦听器设置相比,您有更多步骤。控制各种用户操作如何影响 UI,然后是观察者-侦听器模式。此外,您还用代码记录了用户操作和 UI 更新之间的交互。

You could switch to using a GUI design pattern. Or construct a limited implementation.

Create a GUI Form Interface that has a method DrawXArrayList (with X being some meaningfull name. It has a parameters of type ArrayList

Create a new class called GUIView. It has at least two methods: UpdateXArrayList, and RegisterForm

When you initialize your application have the GUI Form register itself with the class implementing GUIView. Make the class implementing GUIView visible to the form.

When anything in your GUI Form updates the arraylist have it call UpdateXArrayList as the last thing it does. The UpdateXArrayList method in the class implementing GUIView will then in turn call DrawXArrayList passing the updated arraylist. DrawXArrayList in the form class implementing the GUIFormInterface will then take the steps need to update the control displaying the ArrayList.

While this seems like a lot of steps compared to a observer and listener setup. You have more control over how the various user actions effect the UI then the observer-listener pattern. In addition you documented, in code, the interaction between the user action and the updates to the UI.

淡笑忘祈一世凡恋 2024-07-23 20:18:20

如果您可以向应用程序添加新的 jar,请查看 glazed Lists

If you can add a new jar to the application, check out glazed Lists

夏末 2024-07-23 20:18:19

这两种解决方案本质上是相同根设计模式(四人帮定义的“观察者”模式)的实现。在前一种情况下,您使 ArrayList 本身“可观察”,在后一种情况下,您使域使用数组列表“observable”的对象。

我的倾向是做后者:使领域对象可观察。 这主要是因为您最终可能会对域对象进行其他更改(应更新 GUI)。如果它已经是可观察的,则您已经设置好了。

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

The two solutions are essentially implementations of the same root design pattern (the "Observer" pattern as defined by the Gang of Four.) In the former case, you are making the ArrayList itself "observable", in the latter you are making the domain object which uses the array list "observable."

My tendency would be to do the latter: make the domain object observable. This is primarily because you may eventually have other things that could change about the domain object (for which the GUI should be updated.) If it is already observable, you're already set.

Note that you don't strictly have to extend java.util.Observable - you can implement the design pattern without doing that.

幽蝶幻影 2024-07-23 20:18:19

Java 中的 Observable 实现很少使用,并且与 Swing 的互操作性不佳。 请改用 EventListener

特别是,是否有理由不扩展 < code>AbstractListModel 甚至使用 DefaultListModel 直接在“GUI 中的其他位置”管理列表内容时? 然后,您的组合框可以使用委托给同一 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); }

}

The Observable implementation in Java is rarely used, and doesn't inter-operate well with Swing. Use an EventListener instead.

In particular, is there a reason not to extend AbstractListModel or even use DefaultListModel directly when managing the contents of the list "elsewhere in the GUI"? Then your combo box could use a ComboBoxModel that delegates to the same ListModel instance, adding its own implementation to track the selection state.

I have in mind something like this (but I haven't test it):

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

}
绳情 2024-07-23 20:18:19

为什么不使用绑定?

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

绑定您的 GUI小部件到您的列表。 更改将在两个对象之间透明地传播。 请务必使用适当的可观察对象包装您的模型,例如 WritableList(如果直接使用 ArrayList)。

Why not use bindings?

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

Bind your GUI widget to your List. Changes will propogate between the two objects transparently. Be sure to wrap your model with an appropriate observable, such as WritableList (if using the ArrayList directly).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文