如何组织具有多个屏幕/面板的基于MVC的程序的控制器?

[英]How to organize the controller of a MVC-based program with multiple screens/panels?


I'm currently working on a hobby project, written in Java, containing about two different JFrames with about 3-4 JPanels each. The problem I'm facing is that I'm not so sure how to handle the interaction with my controller and different view classes.

我目前正在开发一个用Java编写的业余爱好项目,它包含大约两个不同的JFrame,每个JFrame大约有3-4个JPanel。我面临的问题是我不太确定如何处理与我的控制器和不同视图类的交互。

For instance, I've an article by Sun on Java App. design with MVC, where they list the option to let all the communications between model and view go through the controller as the most modern one, a tactic I've been taught as well and should do just fine. However, it doesn't quite go as deep as to explain how to handle all the ActionListeners involved for all the elements and different panels.

例如,我在Sun App on Java App上发表了一篇文章。设计与MVC,他们列出了让模型和视图之间的所有通信作为最现代的控制器通过控制器的选项,我已经教过的策略,应该做得很好。但是,它并不能解释如何处理所有元素和不同面板所涉及的所有ActionListener。

The 'way to go' I've been taught so far is to either use one controller and set the ActionListener to the various objects through getters and keep track of the active panel. The alternative my awesome Java book gives is to just stick to inner classes for each view class. Either method seems to result in pretty nasty code, while I'd prefer one or several controllers with as little bloat as possible.

到目前为止,我已经教过的“走的路”是使用一个控制器并通过getter将ActionListener设置为各种对象,并跟踪活动面板。我可怕的Java书的另一个选择就是坚持每个视图类的内部类。这两种方法似乎都会产生非常讨厌的代码,而我更喜欢一个或几个控制器尽可能少的膨胀。

My question of course is; how would you assign the ActionListeners as neatly and efficiently as possible while keeping the controller(s) usable?

我的问题当然是;在保持控制器可用的同时,如何尽可能整齐有效地分配ActionListeners?

2 个解决方案

#1


The controller can implement ActionListener and contains a List of ActionListeners.

控制器可以实现ActionListener并包含一个ActionListeners列表。

The controller you have to add to the The 3-4 top panels action listener. Now you can add any ActionListener you want to the controller action listener list.

您必须添加到3-4顶部面板动作侦听器的控制器。现在,您可以将所需的任何ActionListener添加到控制器动作侦听器列表中。

public void addListener(ActionListener listener)
{
   mActionListeners.add(listener);
}

public void removeListener(ActionListener listener)
{
   mActionListeners.remove(listener);
}

When the controller Action listener is called you have to call all action listener which are inside the controll list.

当调用控制器Action侦听器时,您必须调用控制列表中的所有动作侦听器。

public void actionPerformed(ActionEvent e) {
   List listeners = mActionListeners; // Edit 20090903
   for (Iterator iterator = listeners .iterator(); iterator.hasNext();) {
    ActionListener actionListener = (ActionListener)iterator.next();
    actionListener.actionPerformed(e);
   }
}

#2


Even though Markus' solution remains the neatest I've seen so far, I've made some slight changes, which are hopefully improvements in the eyes of the original author as well ;).

虽然马库斯的解决方案仍然是我迄今为止看到的最好的解决方案,但我做了一些细微的改动,希望在原作者的眼中也能有所改善;)。

In case you add/remove an item of the list in response to an event, there is a chance of ending up with concurrent changes to the list; the event is handled, but the loop will continue in case there are more items after the one catching the event.

如果您添加/删除列表中的项目以响应事件,则有可能最终对列表进行并发更改;事件被处理,但是如果在捕获事件之后有更多项目,则循环将继续。

Therefore it's required to use a slightly different approach. I've decided to use the ListIterator.add() method, as this one supports modifications to the list while walking through its items. Possibly there are more elegant solutions available, but this one does the job pretty decent.

因此,需要使用稍微不同的方法。我决定使用ListIterator.add()方法,因为这个方法支持在遍历其项目时对列表进行修改。可能有更优雅的解决方案,但这个工作相当不错。

In case it will be of help to others; the modified code would similar be the following:

如果它对别人有帮助;修改后的代码类似如下:

ListIterator<ActionListener> iterator = mActionListeners.listIterator();

public void actionPerformed(ActionEvent e)
{
    iterator = mActionListeners.listIterator();
    while (iterator.hasNext()) 
    {
        ActionListener actionListener = (ActionListener)iterator.next();
        actionListener.actionPerformed(e);
    }
}

public void addListener(ActionListener listener)
{
    iterator.add(listener);
}

public void removeListener(ActionListener listener)
{
    iterator.remove(listener);
}

In case there are better solutions or improvements I'll be glad to hear those as well.

如果有更好的解决方案或改进,我也很高兴听到这些。


注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:http://www.silva-art.net/blog/2009/01/06/535a5d1a42c826d34cc6ccd07340c76e.html



 
© 2014-2019 ITdaan.com 粤ICP备14056181号