如何使用模型
原文: https://docs.oracle.com/javase/tutorial/uiswing/components/model.html
大多数 Swing 组件都有模型。例如,按钮(JButton
)有一个模型(ButtonModel
对象),用于存储按钮的状态 - 键盘助记符是什么,是否启用,选择或按下,等等。一些组件具有多个模型。例如,列表(JList
)使用ListModel
来保存列表的内容,使用ListSelectionModel
来跟踪列表的当前选择。
您通常不需要了解组件使用的模型。例如,使用按钮的程序通常直接处理JButton
对象,而不处理ButtonModel
对象。
为什么模型存在?最大的原因是它们可以灵活地确定数据的存储和检索方式。例如,如果您正在设计一个在稀疏填充表中显示数据的电子表格应用程序,则可以创建自己的表模型,该表模型已针对此类用途进行了优化。
模型也有其他好处。它们意味着不会在程序的数据结构和 Swing 组件的数据结构之间复制数据。此外,模型会自动将更改传播到所有感兴趣的监听器,从而使 GUI 可以轻松地与数据保持同步。例如,要将项添加到列表,您可以调用列表模型上的方法。当模型的数据发生变化时,模型会将事件激发到JList
和任何其他已注册的监听器,并相应地更新 GUI。
虽然 Swing 的模型架构有时被称为模型 - 视图 - 控制器(MVC)设计,但实际上并非如此。通常实现 Swing 组件,使得视图和控制器是不可分割的,由外观提供的单个 UI 对象实现。 Swing 模型架构更准确地描述为可分离模型架构。如果您有兴趣了解有关 Swing 模型架构的更多信息,请参阅 Swing 架构概述, The Swing Connection 中的文章。
本节介绍一个名为 Converter 的示例,该应用程序可连续转换公制和美制单位之间的距离测量值。你可以运行转换器(下载 JDK 7 或更高版本)。或者,要自己编译并运行示例,请参考示例索引。
如下图所示,Converter 具有两个滑块,每个滑块都绑定到文本字段。滑块和文本字段都显示相同的数据 - 距离 - 但使用两种不同的度量单位。
这个程序的重点是确保只有一个模型控制数据的价值。有多种方法可以实现这一目标;我们通过推迟到顶部滑块的模型来做到这一点。底部滑块的模型(称为FollowerRangeModel
的自定义类的实例)将所有数据查询转发到顶部滑块的模型(称为ConverterRangeModel
的自定义类的实例)。每个文本字段与其滑块保持同步,反之亦然,由侦听值变化的事件处理器保持同步。注意确保顶部滑块的模型具有关于显示距离的最终说法。
当我们开始实现自定义滑块模型时,我们首先查看如何使用滑块的 API 部分。它通知我们所有滑块数据模型必须实现BoundedRangeModel
接口。 BoundedRangeModel
API 文档告诉我们该接口有一个名为DefaultBoundedRangeModel
的实现类。 DefaultBoundedRangeModel
的 API 文档显示它是BoundedRangeModel
的通用实现。
我们没有直接使用DefaultBoundedRangeModel
,因为它将数据存储为整数,而 Converter 使用浮点数据。因此,我们将ConverterRangeModel
实现为Object
的子类。然后我们将FollowerRangeModel
实现为ConverterRangeModel
的子类。
了解更多信息
要了解各个组件的模型,请参见“如何”页面和各个组件的 API 文档。以下是我们直接使用模型的一些示例:
- 除了最简单的表示例之外,所有这些都实现了自定义表数据模型。
- 颜色选择器演示在颜色选择器的选择模型上更改了监听器,以便在用户选择新颜色时通知他们。在 ColorChooserDemo2 中,
CrayonPanel
类直接使用颜色选择模型来设置当前颜色。 - DynamicTreeDemo 示例设置树模型(到
DefaultTreeModel
的实例),直接与它进行交互,并侦听对它的更改。 - ListDemo 设置列表数据模型(到
DefaultListModel
的实例)并直接与它进行交互。 - SharedModelDemo 定义
SharedDataModel
类,扩展DefaultListModel
并实现TableModel
。JList
和JTable
共享SharedDataModel
的实例,提供模型数据的不同视图。 - 在事件监听器示例中, ListDataEventDemo 直接创建并使用
DefaultListModel
。 - 我们的微调器示例创建微调器模型。
- 正如您所见, Converter 示例定义了两个自定义滑块模型。