架构MVC和Swing

7

我想使用MVC来构建我的Swing应用程序,但似乎存在冲突。

据我所知,MVC中,控制器应该处理输入并更新模型。模型应该通知观察者,其中视图是其中之一。

我有两个问题:

  • Swing全部都是视图的一部分。组件拥有自己的模型是实现细节。我想把swing特定的代码从控制器/模型中分离出来,对吗?
  • 我的控制器需要接收用户触发的事件,但这些事件来自于视图中的swing组件,而控制器不应该知道视图的存在。

我相信这个问题以前已经被解决了很多次,但我找不到一个真正的世界范例,它是一个基于MVC的Swing应用程序,规模还比较大。

更新-我忘记的一个问题

MVC不能直接提供各种MVC组件在应用程序层次结构中的结构。例如,主显示器可能有“销售”和“采购”选项卡,每个选项卡可能都有“新建”和“查询”面板。此外,可能会有一个“修改选定”按钮,该按钮将根据请求创建(可能是多个)窗口。

必须有一些东西在请求时为这些子组件创建模型、视图和控制器。它不能是控制器,因为控制器或模型不知道要创建哪个视图,也不应该是视图,因为它是应用程序逻辑,并且正在响应事件(这是控制器的工作)。

有答案吗?

2个回答

6

Swing组件,如JButton等,是控制器。视图类是JButtonUI等。

至于将事件处理逻辑与您的“视图”代码分离,最简单的方法是将特定的Controller类注入到所有面板中。这样,事件处理看起来就像:

doStuffButton.addActionListener( new ActionListener() {
    public void actionPerformed(ActionEvent e) {
       controller.doStuff(); // logic in controller
    }
});

您的面板类可以向控制器提供模型,例如:

您的面板类可以向控制器提供Model,例如:

public void doStuff() {
    MyData data = ...
    dataModel.setData(data)
}

这样,控制器就知道了模型,视图也知道了控制器,但控制器不知道视图(实现)


a) 就Swing而言,我只考虑到组件级别。我在谈论为我的应用程序使用MVC架构。 b) 实际上,Swing并不严格遵循MVC模式 - 组件既是控制器又是视图,并且它使用UIDelegate。 - Draemon
我只是想说JButton类中并没有所有的绘制逻辑(我认为这是视图)。 - oxbow_lakes
你的更新没问题,但这意味着要添加很多controller.doStuff()方法。我记得尝试过这样做并遇到了问题,但现在想不起来了。我会再试一次看看。 - Draemon
我指的是在组件级别使用MVC作为设计模式(Swing大致如此)和在应用程序级别使用MVC作为架构模式之间的区别。我认为Swing的MVC全部都属于应用程序的V。 - Draemon
这不是真的,控制器与视图在同一个对象上,即“UI delegate object” JButtonUI。JButton对象在Swing的修改MVC架构中被称为通用组件类,并且通常不会出现在大多数MVC架构中。请参阅http://java.sun.com/products/jfc/tsc/articles/architecture/#modified_mvc。 - Laurens Holst
显示剩余4条评论

0
在Java Swing中,控制器不需要了解UI组件。您可以将控制器代码实现为ActionListener。 然后将ActionListener绑定到JButton等元素上。 当单击JButton时,它会调用ActionListenerActionListener仅依赖于其他模型。 它使用某些模型作为输入,将其他模型用作其结果或输出。 这就像方法参数和返回值。 当模型得到更新时,它们通知UI。 因此,控制器逻辑无需知道UI组件。即使模型对象不知道UI,通知也是通过观察者模式完成的。 因此,模型对象只知道有人想要在模型更改时获得通知。
请看下面这个例子,取自https://www.link-intersystems.com/bin/view/Blog/The+MVC+pattern+implemented+with+java+swing 这是我如何在Java Swing中解释MVC模式的。
  • 红色 = 模型
  • 绿色 = 视图
  • 蓝色 = 控制器

enter image description here

在Java Swing中,有一些组件同时实现了模型和控制器。例如javax.swing.Action。它实现了UI模型(属性:启用、小图标、名称等),并且是一个控制器,因为它扩展了ActionListener

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接