我在项目中使用MVC模式。 btnAdd
创建新的Customer并将MyJPanel1
添加为侦听器。当客户更改其状态时,它将触发事件并调用customerChanged
。什么时候MyJPanel1
的customerChanged
称为执行某些操作,
其他一些视图将具有相同的行为。
我在
MyJPanel1
的customerChanged
方法本身中实现了这两个要求。已更新
我的问题是:
fireEvent
方法时,因此c.removeListener(this);
中的MyJPanel1
会将其自身从侦听器中删除,因此,导致fireEvent' because
侦听器中的in
for``循环发生了错误。 我会感谢您的帮助。
class Customer {
// ...
private void fireEvent(CustomerEvent event) {
for (IListener listener : listeners) {
listener.customerChanged(event);
}
}
}
class MyJPanel1 extends JPanel implements IListener {
MyJPanel2 otherPanel;
MyJPanel1(MyJPanel2 panel) {
this.otherPanel = panel;
createGui();
}
private void createGui() {
JButton btnAdd = new JButton("Add");
btnAdd.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
Customer c = new Customer();
c.addListener(this);
}
});
// ...
}
@Override
public void customerChanged(CustomerEvent event) {
if (event instanceof AddedCustomerEvent) {
Customer c = event.getCustomer();
// do something
c.removeListener(this);
c.addListener(otherPanel);
}
}
}
最佳答案
视图仅显示数据;他们永远不会自己拥有任何功能。
更改内容(例如添加/删除侦听器)是控制器的目的。它将模型连接到视图,并确保一切正常。使视图尽可能哑。
关于第二个问题:正如您所注意到的,您不能让听众自杀。有几种解决方案:
for (Iterator<IListener> iter = listeners.iterator(); iter.hasNext(); ) {
if (!listener.customerChanged(event)) {
iter.remove();
}
}
MyJPanel1
,直到完成该视图为止。从现在开始,该事件将转到其他视图。一个好的解决方案是让新的侦听器侦听两个事件:
CustomerEvent
和IAmDoneEvent
发布的MyJPanel1
。它有两个侦听器列表。在收到
IAmDoneEvent
之前,所有CustomerEvent
都进入第一个列表。此事件后,所有CustomerEvent
进入第二个列表。将MyJPanel1
添加到第一个列表,并将所有其他视图添加到第二个列表。使用您的控制器来建立此侦听器网络。