Java 教程是为 JDK 8 编写的。本页中描述的示例和实践不利用后续版本引入的改进,并可能使用不再可用的技术。
请参阅 Java 语言更改,了解 Java SE 9 及后续版本中更新的语言功能的摘要。
请参阅 JDK 发行说明,了解所有 JDK 发行版的新功能、增强功能和已删除或弃用选项的信息。
大多数 Swing 组件都有模型。例如,按钮(JButton
)有一个模型(一个 ButtonModel
对象),它存储按钮的状态 - 键盘助记符是什么,它是否启用、选中或按下等等。有些组件有多个模型。例如,列表(JList
)使用一个 ListModel
来保存列表的内容,并使用一个 ListSelectionModel
来跟踪列表的当前选择。
通常情况下,您不需要知道组件使用的模型。例如,使用按钮的程序通常直接处理 JButton
对象,而不涉及 ButtonModel
对象。
那么为什么模型还存在呢?最大的原因是它们在确定数据的存储和检索方式方面给您带来了灵活性。例如,如果您正在设计一个以稀疏填充表格方式显示数据的电子表格应用程序,可以创建自己的表格模型,以针对这种用途进行优化。
模型还有其他好处。它们意味着数据不会在程序的数据结构和 Swing 组件之间复制。此外,模型会自动将更改传播给所有感兴趣的监听器,使得 GUI 能够轻松与数据保持同步。例如,要向列表添加项目,可以在列表模型上调用方法。当模型的数据发生变化时,模型向 JList
和任何其他已注册的监听器触发事件,GUI 相应地更新。
尽管 Swing 的模型架构有时被称为模型-视图-控制器(MVC)设计,但它实际上并不是。Swing 组件通常被实现为视图和控制器不可分割的单个 UI 对象,由外观提供。 Swing 模型架构更准确地描述为一个可分离的模型架构。如果您有兴趣了解有关 Swing 模型架构的更多信息,请参阅《Swing 架构概述》的文章,该文章是在《The Swing Connection》中发表的。
本节介绍一个名为转换器(Converter)的示例,它是一个不断在公制和美制单位之间转换距离测量的应用程序。您可以 运行 Converter (需要 下载 JDK 7 或更高版本)。或者,要自己编译和运行示例,请查看 示例索引。
如下图片所示,Converter 包含两个滑块,每个滑块都与一个文本字段关联。所有滑块和文本字段都显示相同的数据 - 距离 - 但使用两种不同的测量单位。
对于此程序而言,重要的是确保只有一个模型控制数据的值。有多种方法可以实现这一点;我们通过委托给顶部滑块的模型来实现。底部滑块的模型(一个名为 FollowerRangeModel
的自定义类的实例)将所有数据查询转发给顶部滑块的模型(一个名为 ConverterRangeModel
的自定义类的实例)。通过监听值的变化,每个文本字段与其滑块保持同步,并反之亦然。确保顶部滑块的模型对所显示的距离拥有最终决定权。
当我们开始实现自定义滑块模型时,我们首先查看了 如何使用滑块 的 API 部分。它告诉我们,所有滑块数据模型都必须实现 BoundedRangeModel
接口。 BoundedRangeModel
API 文档 告诉我们,该接口有一个名为 DefaultBoundedRangeModel
的实现类。 DefaultBoundedRangeModel
的 API 文档 显示它是 BoundedRangeModel
的通用实现。
我们没有直接使用 DefaultBoundedRangeModel
,因为它将数据存储为整数,而 Converter 使用浮点数据。因此,我们将 ConverterRangeModel
实现为 Object
的子类。然后,我们将 FollowerRangeModel
实现为 ConverterRangeModel
的子类。
要了解各个组件的模型,请参阅各个组件的 "如何" 页面和 API 文档。以下是一些直接使用模型的示例:
CrayonPanel
类直接使用颜色选择模型来设置当前颜色。DefaultTreeModel
的实例),直接与其进行交互,并监听其变化。DefaultListModel
的实例),并直接与其交互。SharedDataModel
类,它扩展了 DefaultListModel
并实现了 TableModel
。一个 JList
和 JTable
共享 SharedDataModel
的一个实例,为模型的数据提供不同的视图。DefaultListModel
。