5

我在设计我正在尝试开发的应用程序的架构时遇到了一些麻烦。我正在研究 JAVA,我开始研究这个应用程序是因为我想加深我对 JAVA、体系结构和模式的整体了解。我想按照指南制作一个可重用、低耦合的应用程序,就像它应该的那样。应用程序只有一个 JFrame,但在其中有几个 JPanel,每个 JPanel 代表应用程序的一个模块。

问题是:在JAVA Swing中,如何实现一个合适的MVC模式?我挣扎于如何理解它应该做的方式。

我应该有一个主控制器类,它包含对所有其他控制器的引用吗?(我有一张图片来证明这一点:https ://docs.google.com/file/d/0B7tBdn5slIFeY2FoSmxESTREQ1k/edit?usp=sharing )

在这种情况下,是否所有需要更改正在呈现的模块的事件都重定向到主控制器?

还是我应该将 JFrame 与应用程序的控制器耦合,并直接与它们通信?

基本上,我想知道我是否需要一个“管理”所有其他人的课程。我已经阅读了一些解释和不同的意见,但我相信这更具体一点。

希望我已经把自己说清楚了(也希望我的解释比我的画更好:))。

编辑: 应用程序使用示例:

  • 一个(唯一一个)JFrame,贯穿应用程序的整个生命周期;
  • 菜单将在左侧,如 BorderLayout.WEST;
  • 应用程序的当前模块将位于中心,如 BorderLayout.CENTER;
  • 当用户按下菜单的一个按钮时,相应的模块被加载到BorderLayout.CENTER中;

菜单(视图)是否应该有它自己的控制器,并且这个控制器与 JFrame 通信?JFrame 将新模块加载到它的布局中吗?或者 JFrame 应该有自己的控制器(或模型,如 Gilbert Le Blanc 所说)?

我知道这可能看起来很具体,或者很容易理解,但是每次我想到桌面应用程序时,我都很难理解这一点。

4

2 回答 2

4

当您有一个带有 GUI 的应用程序时,GUI 模型就变成了应用程序视图。应用程序通过 GUI 模型与 GUI 交互。

还是我应该将 JFrame 与应用程序的控制器耦合,并直接与它们通信?

这就是我所做的。我已经将控制器类打包在一起,但我从未创建过一个主控制器类。

我将 GUI 控制器类与任何其他应用程序控制器类(如数据访问对象)放在一个单独的包中。

我通常将每个 JPanel 放在它自己的类中,但我不会称之为要求。JFrame 有自己的类,尽管 JFrame 的实例和 GUI 模型的实例被传递给几乎所有的 GUI 组件。这使得菜单操作成为可能。

这篇交通信号 GUI文章介绍了如何编写一个非常简单的 GUI 的基础知识。

编辑以回应问题的变化。

GUI 控制器与 GUI 模型是分开的。GUI 模型包含构成 GUI 的所有数据元素。JTextFields 的字符串,JTables 的 DefaultTableModels。

根据您的应用程序设计,我建议您为要置于应用程序中心的每个 JPanel 创建一个 Java 类。您的 JFrame 将根据菜单控制显示哪个 JPanel。我还建议您查看JTabbedPane,它使用不同的用户界面来完成选择使用哪个面板的任务。

假设您使用左侧的菜单,每个菜单选项(切换 JButton?)将有它自己的控制器方法或类。这些控制器必须具有 JFrame 的实例,以便控制器可以调用 JFrame 类中的方法,将适当的面板置于显示的中心。控制器决定调用哪个方法,但方法本身是 JFrame 类的一部分。

我一直在谈论 JFrame 和 JPanel 类。使用组合而不是继承来构建这些类很重要。JFrame 类包含一个 JFrame。它不扩展 JFrame。唯一一次扩展 Swing 组件是在您想要覆盖组件方法时。

于 2013-03-28T22:45:50.320 回答
2

正如这里所讨论的,Swing 组件使用可分离的模型架构,模型和视图使用观察者模式松散耦合。并非每个 GUI 控件都必须是应用程序控制器的一部分。使用ActionListener,例如Action,对于封装应用程序功能特别方便。

附录:我会使用CardLayout,此处说明来切换面板。请注意Action处理程序如何与按钮、菜单、组合、工具栏等一起使用。每张卡片的内容都可以有自己的 MVC 模式实现,与其他卡片分开。使用 a PropertyChangeEvent,在这里看到,用于组件之间的通信。

通常,Swing 组件(例如按钮和表格)已经监听了它们各自的模型,让您专注于应用程序的数据模型及其监听视图。方便地,一个 Swing 模型,例如ComboBoxModelTableModel`,可以有多个听众。

于 2013-03-29T02:48:38.950 回答