2

我最近开始在 Java 中使用 Swing 应用程序,目前主要使用 JTables。来自 .NET WPF 背景的世界,它使用 MVVM 设计模式进行了巨大的架构,我在 Swing 方面有点挣扎。原因是,使用 JTables 似乎有很多方法可以实现模型-视图-控制器模式(至少是我在查看可用类后的感受)。因此,我想分享一些可能的通用方法,这些方法在我的脑海中以及到目前为止我所看到的,以及收集您对这个问题的评论,这些评论可能适用于其他控件/应用程序:

  1. JTable <--> TableModel:在这种方法中,我们在某种意义上只有一个视图和一个模型。TableModel 具有有用的更新方法,例如 setValueAt,您可以在其中放置任何 UI 更新的处理代码,进而可以在模型更新时引发事件。我猜这是 DefaultTableModel 的默认实现。因此模型处理直接在单元格(数据)上进行的更新。View (JTable) 将在用作 View 的类后面的代码中注册任何进一步的处理程序。代码可能如下所示:

    类视图扩展 JPanel {

    public View(TableModel model) {
        super(new BorderLayout(1, 0));
        JTable table = new JTable(model) {
    
            //override anything you need here - renderers etc.
    
        };
    
        //add any listeners here
    }
    //Listeners that would perform actions on events, and possibly call model to update
    

    我喜欢这个的是我们只有两个地方可以放代码,并且在实现中提供的 JTable 和 TableModel 之间有一个自然的联系,即 setValueAt 方法。不过,我讨厌的是,在我看来,完全无视 MVC 模式,在 MVVM 的情况下,你的代码结构非常出色

  2. JTable --> Controller <--> TableModel : 添加另一个层来执行逻辑我们现在将有一个中央控制器来实例化(或接收在构造函数中注入的)视图和模型。此外,它会在视图上注册任何侦听器,并且无论何时发生这种情况,我们都会在模型上调用一些更新方法。也许另一种方法是将事件从视图的注册处理程序转发到控制器,但这需要视图了解控制器......我猜事件的触发返回到视图当我们调用 update 方法时,它将保留在模型上,除非我们只是在表上调用 tableChanged 方法。然而,这破坏了事件机制的整体整洁性,这是在 TableModel 实现中免费提供的......这里必须考虑的进一步的事情是,我们需要在每次处理时注意从视图索引转换为模型索引视图中的事件(可能是我目前无法想到的其他考虑因素)

  3. JTable <--> TableModel --> BusinessModel:我们使用 TableModel 作为协调器,并将我们的业务知识保存在其他地方 到目前为止,我假设 TableModel 包含原始业务数据,例如以 List 的形式。现在我们可能会在 TableModel 上使用 setValueAt 方法 + 注册处理程序,这些处理程序随后会修改底层的 BusinessModel,封装 List。我唯一担心的是 TableModel真的应该是一个模型而不是控制器。

这些是我对此事的看法。我非常期待您的回复和评论。

4

2 回答 2

2

Swing MVC 模型,据我了解,它并没有严格地将视图与模型分开,即两者之间存在一些通信以避免不必要地通过控制器。当我使用它时,JTable 是视图,TableModel 是模型,而您的听众充当需要更多控制的事物的控制器,而不仅仅是“显示模型中的内容”。

于 2012-08-03T11:00:14.933 回答
2

澄清一下,Swing可分离模型架构使用观察者模式松散地耦合模型和视图,如下所示。通常在内部使用,但这里提到了其他实现。UI 委托控制用户与视图的交互。这允许组件在不同的平台上正常工作,正如用户所感知的那样。EventListenerList

那么模型是通过特定的Listener接口向视图组件注册的吗?

不,每个模型都在EventListenerList内部维护一个;addXxxListener()每个对应的视图都通过模型的方法将自己添加为侦听器。大多数组件也PropertyChangeLister用于绑定属性。

于 2012-08-03T19:55:37.480 回答