如何使用模型

大多数 Swing 组件都有模型。例如,一个按钮(JButton)具有一个模型(一个ButtonModel对象),该模型存储该按钮的状态-键盘助记符是什么,是否已启用,已选择或已按下等等。一些组件具有多个模型。例如,列表(JList)使用ListModel来保存列表的内容,并使用ListSelectionModel来跟踪列表的当前选择。

您通常不需要了解组件使用的模型。例如,使用按钮的程序通常直接处理JButton对象,而根本不处理ButtonModel对象。

为什么会存在模型?最大的原因是它们使您可以灵活地确定如何存储和检索数据。例如,如果您正在设计一个电子表格应用程序,该应用程序在稀疏填充的表中显示数据,则可以创建自己的表模型,并为此进行优化。

模型也有其他好处。它们意味着数据不会在程序的数据结构和 Swing 组件的数据结构之间复制。此外,模型会自动将更改传播到所有感兴趣的侦听器,从而使 GUI 易于与数据保持同步。例如,要将项目添加到列表中,可以调用列表模型上的方法。当模型的数据更改时,模型将向JList和任何其他已注册的侦听器触发事件,并且相应地更新了 GUI。

尽管 Swing 的模型体系结构有时被称为模型视图控制器(MVC)设计,但实际上并非如此。 Swing 组件通常是由外观提供的单个 UI 对象实现的,因此视图和控制器是不可分割的。 Swing 模型架构更准确地描述为*“可分离模型架构” 。如果您想了解有关 Swing 模型体系结构的更多信息,请参阅Swing 体系结构概述,这是 The Swing Connection *中的文章。

示例:转换器

本节以称为转换器的示例为例,该应用程序可以连续转换公制单位与美国单位之间的距离测量值。您可以run Converter(下载 JDK 7 或更高版本)。或者,要自己编译并运行示例,请参考example index

如下图所示,Converter 具有两个滑块,每个滑块都与一个文本字段相关联。滑块和文本字段都显示相同的数据(距离),但是使用两个不同的度量单位。

Metal 外观中的 Converter 屏幕截图

对于此程序而言,重要的是确保只有一个模型可以控制数据的值。有多种方法可以实现此 Object。我们通过遵循顶部滑块的模型来做到这一点。底部滑块的模型(称为FollowerRangeModel的自定义类的实例)将所有数据查询转发到顶部滑块的模型(称为ConverterRangeModel的自定义类的实例)。每个文本字段都通过侦听值更改的事件处理程序与其滑块保持同步,反之亦然。注意确保顶部滑块的模型对显示的距离拥有final决定权。

当我们开始实现自定义滑块模型时,我们首先查看了如何使用滑块的 API 部分。它告知我们所有滑块数据模型都必须实现BoundedRangeModelinterface。 BoundedRangeModel API 文档告诉我们该interface有一个名为DefaultBoundedRangeModel的实现类。 DefaultBoundedRangeModel 的 API 文档表示它是BoundedRangeModel的通用实现。

我们没有直接使用DefaultBoundedRangeModel,因为它以整数形式存储数据,而 Converter 使用浮点数据。因此,我们将ConverterRangeModel实现为Object的子类。然后,我们将FollowerRangeModel实现为ConverterRangeModel的子类。

有关更多信息

要了解各个组件的模型,请参阅"How to"页和各个组件的 API 文档。以下是一些直接使用模型的示例:

  • 除了最简单的table examples之外,所有其他方法都实现了自定义表数据模型。

  • 颜色 selectors 演示在颜色 selectors 的选择模型上具有更改侦听器,因此可以在用户选择新颜色时通知它们。在 ColorChooserDemo2 中,CrayonPanel类直接使用颜色选择模型来设置当前颜色。

  • DynamicTreeDemo示例设置树模型(为DefaultTreeModel的实例),直接与之交互,并监听对其的更改。

  • ListDemo设置列表数据模型(为DefaultListModel的实例)并直接与其交互。

  • SharedModelDemo定义了SharedDataModel类,该类扩展DefaultListModel并实现TableModelJListJTable共享SharedDataModel的实例,从而提供了模型数据的不同视图。

  • 在事件侦听器示例中,ListDataEventDemo直接创建并使用DefaultListModel

  • 我们的spinner examples创建微调器模型。

  • 如您所见,Converter示例定义了两个自定义滑块模型。