java swing vs mvc:这种模式真的可能吗?

Posted

技术标签:

【中文标题】java swing vs mvc:这种模式真的可能吗?【英文标题】:java swing vs mvc: is this pattern indeed possible? 【发布时间】:2011-04-11 19:29:12 【问题描述】:

我是摇摆新手,但设法创建了一个下降 gui。 但我的问题是我无法应用参考/教程中建议的模式,主要是 MVC 模式。

是我,还是在 JTree 中使用 SwingWorker,无法明确分离控制器/视图/模型? 例如,我使用 Swingworker,但我无法在设计中“安装”控制器。

即控件的动作本质上是在 doBackground 方法中,例如按钮的动作执行。 所以没有控制器类。

swing worker 中的操作结果是更新 Jtree,所以我将结果传递给我命名为 model 的类,但该类必须有权访问 JFrame 内的 Jtree 的 treeModel,即视图,因此视图和模型没有明确的分离。

我查看了很多教程,但所有介绍 MVC 的教程都有一个简单的示例,并且在大多数情况下,视图(只是一些标签!)更新了所有内容。我是不是完全糊涂了,或者在使用 swingworkers 和 jtrees 的 Swing 应用程序中集成 MVC 模式是不可能的或至少不容易?

我说的是实际的域数据,而不是在 swing 组件中实现的 MVC。

有人可以帮助我(让我摆脱这种可怕的头痛),或者概述如何处理这种设计,或者至少提供一个有用的教程,并提供一个不平凡的例子吗?

谢谢

【问题讨论】:

【参考方案1】:

当我构建更大的应用程序(人年开发)时,我们经常将单个组件之上的 MVC 架构抽象为***控制器/模型和视图,并接受各个组件将是它们自己的个性化 MVC。 GeoffreyZheng 的评估是绝对正确的,这是我真正喜欢在 Swing 环境中开发的地方。话虽如此,如果您想要真正的 MVC,您可能需要从单个组件中抽象出来,并用更抽象的术语来讨论视图。

【讨论】:

我明白你在说什么。但是,如果我创建一个控制器、模型,在 JTree 的情况下,我必须保留有关操作产生的结果应该放置在树中的什么位置的信息。控制器可以将操作的结果传递给我的自定义模型,并且模型可以向视图触发一个事件,表明更新可用。但是树怎么知道在哪里放置新节点(或更新现有节点)?我不想重新绘制整个 JTree。只有必须更改的部分。但这意味着模型必须了解 JTree 结构。所以这不是一个干净的分离。对吗? 当我使用 JTree 来表示某些东西时,我通常将后端的信息也存储为树。这意味着我可以传递一些信息——位置、深度等。或者,我可以使用后端的 TreeModel 作为模型的一部分并让它自己触发事件。只要视图不直接修改模型,我看不出有什么大问题。希望这有助于澄清。 @perkins:对不起,我在最后一部分失去了你。您将例如存储在模型中JTree 的 DefaultMutableTreeModel,并使用模型中的方法(add、insertNodeInto 等)对其进行更新?在第一部分中,您使用什么结构将信息作为树存储在后端? 对不起,如果我不清楚 - 我的意思是您可以将一棵树作为 TreeModel(不可变)放入 JTree,但在模型本身中它是可变的(相同的数据结构) .当应用程序模型中的树模型本身发生变化时,您可以让它向它拥有的任何 TreeModelListener 发送通知,以便他们更新他们的视图。这样,视图不会直接修改模型中的值,但仍会以一种相当干净的方式得到通知。 很高兴进一步解释-您可以使用默认树模型或自定义实现-这对于讨论而言并不重要。我想说的(有点不成功)是 JTree 本身不应该更改树模型中的数据,而是应该触发推送到您的应用程序(或域)模型中的事件。然后处理这些事件,最终导致树模型(默认或其他)发生变化,通过它的标准侦听机制 (TreeListener) 通知 JTree。【参考方案2】:

Swing 并不是严格意义上的 MVC,因为该公司以前称为 Sun openly admits it:

(传统的 MVC 分离)没有 在实际中工作得很好,因为 a 的视图和控制器部分 组件需要紧密耦合 (例如,很难 编写一个没有的通用控制器 了解有关视图的详细信息)。所以我们 将这两个实体折叠成一个 单个 UI(用户界面)对象。

对于 JTree,您可以使用 TreeModel 作为模型。一些像 JLabel 这样简单的组件甚至没有模型。

正如链接进一步解释的那样,您确实可以与 LAF 提供的 UI 类进行一定程度的分离。然而 Swing 组件本身必须维护和控制许多与 UI 相关的属性。

【讨论】:

【参考方案3】:

在许多情况下它仍然是可取的并且可能的:当然控制器需要知道负责动作的组件,但视图仍然不需要任何特定的动作实现。您只是不在视图类中实现该操作,而是使用控制器(它知道视图和模型)。因此,在此处添加动作侦听器,更新一些模型细节,例如,即使在 SwingWorker 中也是如此。

在我看到的几乎每个示例中,直到知道它是这样实现的,我看不出这与任何其他组件有什么不同,比如 jtree。

也许看看 MVC 和 MVP(我更喜欢)之间的区别更容易理解:MVC or MVP

【讨论】:

【参考方案4】:

不确定这是否有帮助,但请尝试 Swing 应用程序框架 (SAF) (JSR 296)。就我阅读或尝试这一点而言,它有助于将视图与事件处理分开。但是对于更复杂的示例(例如 JTree),我并没有那么详细

http://java.sun.com/developer/technicalArticles/javase/swingappfr/

https://appframework.dev.java.net/

祝你好运!

【讨论】:

不,我认为 SAF 不会对这个特定主题有所帮助;它不会强迫您进入任何 GUI 模式,例如 MVC、MVP……在某些情况下,它甚至鼓励意大利面条式编程……此外,SAF 已经死了几年了……

以上是关于java swing vs mvc:这种模式真的可能吗?的主要内容,如果未能解决你的问题,请参考以下文章

java swing计算器布局

Java 和 GUI - 根据 MVC 模式,ActionListener 属于哪里?

2018-03-19面试之下面关于Java Swing的描述,说法错误的是?

Swing编程

Swing编程

Java Swing 简单介绍