Java Swing与MVC之间的比较:这种模式真的可行吗?

10

我刚接触swing,但已经成功创建了一个降序gui。
我的问题是我无法应用参考/教程中建议的模式,主要是MVC模式。

是我错了吗?在JTree和使用SwingWorker时,不可能有清晰的控制器/视图/模型分离吗?
例如,我使用Swingworker,但是我无法在设计中“适合”一个控制器。

也就是说,控件的操作本质上在doBackground方法中,该方法位于例如按钮的action perform内部。
因此没有控制器类。

Swing工作程序的结果是更新Jtree,因此我将结果传递给一个名为model的类,但是这个类必须可以访问JFrame内的Jtree的treeModel,即视图,因此没有明确的视图和模型分离。

我看了很多教程,但所有呈现MVC的教程都有一个平凡的例子,在大多数情况下,视图(只是一些标签!)会更新所有内容。 我完全困惑了吗,还是在使用SwingWorkers和jtrees的swing应用程序中集成MVC模式不可能或至少不容易?

我在谈论实际领域数据而不是实现在swing组件中的MVC。

有人能帮助我(并使我免受这种可怕的头痛之苦),要么提供如何处理此设计的概述,要么至少提供有用的,具有非平凡示例的教程吗?

谢谢

4个回答

7

当我建立更大型的应用程序(数年的开发),我们经常将MVC架构抽象到单个组件之上,形成一个顶级控制器/模型和视图,并接受单个组件将成为它们自己的个性化MVC。 GeoffreyZheng在他的评估中是绝对正确的,这是我喜欢使用Swing环境进行开发的原因之一。 话虽如此,如果您想要真正的MVC,您可能需要从单个组件中抽象出来,并以更抽象的术语谈论视图。


我明白你的意思。但是如果我创建一个控制器、模型,在JTree的情况下,我必须保留有关操作结果在树中应放置在哪里的信息。控制器可以将操作的结果传递给我的自定义模型,模型可以向视图发出更新可用的事件。但是树如何知道在哪里放置新节点(或更新现有节点)?我不想重新绘制整个JTree,只想更改需要更改的部分。但这意味着模型必须了解JTree的结构。所以这不是一个清晰的分离。对吗? - Cratylus
1
当我使用JTree来表示某些东西时,通常也会将信息存储在后端作为树形结构。这意味着我可以传递一些信息 - 位置、深度等。或者,我可以在后端中使用TreeModel作为模型的一部分,并让它自己触发事件。只要视图没有直接修改模型,我认为那里并没有什么大问题。希望这有助于澄清。 - aperkins
@perkins:抱歉,我在最后一部分失去了你。您将JTree的DefaultMutableTreeModel等存储在模型中,并使用其方法(add、insertNodeInto等)进行更新?在第一部分中,您使用什么结构将信息作为树形结构存储在后端? - Cratylus
抱歉如果我表达不清楚 - 我的意思是你可以将一棵树放入JTree作为一个TreeModel(不可变),但在模型本身中它是可变的(同一数据结构)。当应用程序模型中的树模型自身发生更改时,您可以让它发送通知给其任何TreeModelListeners,以便它们更新其视图。这样,视图就不会直接修改模型中的值,但仍然以相当干净的方式得到通知。 - aperkins
@aperkins:当你说“你可以将一棵树放入JTree作为TreeModel”时,你的意思是实现TreeModel的扩展并使用它来代替默认的树模型吗?我相信你很清楚。我对swing不够熟悉,无法理解你的回答。如果你不介意的话,能否请你用更“分析性”或简单的方式解释一下,以便我完全理解你的回答? - Cratylus
1
很高兴进一步解释 - 你可以使用默认的树模型,或者自定义实现 - 这对于讨论来说并不是那么重要。我试图表达的是(有点不成功),JTree本身不应该改变树模型中的数据,而是应该触发事件,将其推送到你的应用程序(或领域)模型中。然后这些事件会被处理,最终导致树模型(默认或其他方式)发生变化,并通过其标准的监听机制(TreeListener)通知JTree发生了变化。 - aperkins

5
Swing并不是严格的MVC模式,正如曾经被称为Sun公司的公开承认的那样:
传统的MVC分离在实际应用中并不奏效,因为组件的视图和控制器部分需要紧密耦合(例如,编写一个不知道视图具体信息的通用控制器非常困难)。因此,我们将这两个实体合并成一个单一的UI(用户界面)对象。
对于JTree,您可以使用TreeModel作为模型。一些简单的组件,比如JLabel甚至没有模型。
正如链接进一步解释的那样,使用LAF提供的UI类可以获得一定程度的分离。然而,Swing组件本身必须维护和控制许多与UI相关的属性。

4
在许多情况下,这是可取且可能的:当然,控制器需要知道负责操作的组件,但视图不需要任何特定的操作实现。您只需不在视图类中实现动作,而是使用控制器(它知道视图和模型)。因此,在那里添加操作侦听器,例如更新一些模型详细信息,甚至在SwingWorker中进行。
在我看到的几乎每个示例中,都是这样实现的,我不明白这与任何其他组件(如jtree)有何不同。
也许通过查看MVC和MVP之间的差异(我更喜欢MVP),更容易理解:MVC或MVP

1

3
不,我认为SAF不能帮助解决这个特定的问题;它不会强制你采用任何GUI模式,比如MVC、MVP...在一些情况下,甚至会鼓励“意大利面条式编程”...此外,SAF已经死了几年了... - jfpoilpret

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