AWT 模态

本文档连同模态相关类的 API 文档(例如 java.awt.Dialog )简要描述了新的模态功能以及如何使用它们。它包含以下部分:

定义

文档 - 一个没有所有者的窗口,连同它的所有子层次结构,可以作为一个独立的文档进行操作。每个窗口都属于某个文档——它的根可以作为最近的没有所有者的祖先窗口找到。

Modal blocked window - 一个窗口,即:

  • 不接收任何用户输入事件
  • 没有收到输入焦点
  • 将其 Z 顺序保持在阻止它的模态对话框下方

警告!一些窗口管理器允许用户以任意方式更改窗口的 Z 顺序——在这种情况下,可能无法满足最后的要求。

模态对话框 - 一种在可见时会阻止某些窗口的对话框。被拦截的窗口是根据对话框的拦截范围来确定的。

模态排除窗口 - 当模态对话框可见时保持畅通的窗口。如果一个窗口是模态排除的,那么它所有的窗口和子组件也被排除在外。

阻塞范围 (SB) - 模式对话框在可见时被阻塞的一组窗口(java.awt.Window 实例和所有派生类)。


笔记:在本文档中的任何地方,“窗口”的概念都等同于 Java 编程语言中的顶级窗口——换句话说,java.awt.Window 的实例或任何后代类。

模态类型

有四种支持的模态类型:

  • 工具包
  • 应用
  • 文档
  • 无模式
默认情况下,对话框是无模式的。默认情况下,模态对话框是应用程序模态的。
  1. 无模式对话框
    无模式对话框在可见时不会阻挡任何窗口。
  2. 文档模式对话框
    文档模式对话框会阻止来自同一文档的所有窗口,但来自其子层次结构的窗口除外。文档根被确定为最近的没有所有者的祖先窗口。
  3. 应用程序模式对话框
    应用程序模式对话框会阻止来自同一应用程序的所有窗口,但来自其子层次结构的窗口除外。如果在浏览器中启动了多个小程序,则可以将它们视为单独的应用程序或单个应用程序。此行为依赖于实现。
  4. 工具包模态对话框
    工具包模式对话框会阻止在同一工具包中运行的所有窗口,但来自其子层次结构的窗口除外。如果启动了多个小程序,它们都使用相同的工具包运行,那么从一个小程序显示的工具包模式对话框可能会影响其他小程序和浏览器实例的所有窗口,浏览器实例嵌入了该工具包的 Java 运行时环境。请参阅下面的安全部分。

模态优先级按阻塞强度排列:无模态、文档模态、应用程序模态和工具包模态。如果两个对话框可见并相互阻塞,则在确定应保持畅通的对话框时使用此安排。它自然地反映了对话框阻塞范围(SB)的嵌套:无模式对话框有一个空的SB,文档模式对话框的SB在某些应用程序中是完整的,所有应用程序都在一个工具包中运行。

关于所有者的注意事项:

  • 创建没有所有者的文档模式对话框:
    由于 Dialog 是从 Window 派生的类,如果 Dialog 实例没有所有者,它会自动成为文档的根。因此,如果这样的对话框是文档模式的,那么它的阻塞范围是空的,并且它的行为方式与无模式对话框相同。
  • 与所有者创建应用程序模式或工具包模式对话框:
    与文档模式对话框相反,应用程序或工具包模式对话框的阻塞范围不取决于其所有者。因此,在这种情况下,所有者唯一影响的是 Z 顺序:对话框始终位于其所有者之上。

实现说明:更改可见对话框的模态类型可能无效,直到它被隐藏然后再次显示。

显示/隐藏阻止

显示窗口或无模式对话框:“F”
浏览所有可见的模态对话框——如果 F 来自其中一个的 SB,它就会被它屏蔽。如果有多个这样的对话框,则使用显示的第一个。如果不存在这样的对话框,则 F 保持畅通。

显示模态对话框:“M”
当显示模态对话框 M 时,所有可见窗口都属于三个不同的组之一:

  • M 的阻止者(阻止 M 的模态对话要么在 M 的子层次结构中,要么不被 M 阻止,要么具有更大的模态模式,要么阻止 M 的其他一些阻止者)
  • 被 M 阻止(来自 M 的 SB 的窗口不是阻止程序并且不在任何阻止程序的子层次结构中)
  • 所有其他窗口(M 的 SB 之外的窗口或无模式对话框和 M 的 SB 之外不阻止 M 的模式对话框)。

显示模态对话框 M 后,它会被第一组中第一个显示的对话框(如果有的话)阻止,第二组中的所有窗口都被 M 阻止,第三组中的所有窗口保持不变。

在典型情况下,当没有子对话框在其所有者之前显示时,可以简化此规则。 (以下简化案例,可能会省略一些细节)。

显示文档模式对话框:“M”
查看所有可见的应用程序和工具包模式对话框——如果 M 来自其中一个的 SB,它就会被它阻止。如果有多个这样的对话框,则使用显示的第一个。如果不存在这样的对话框,则 M 保持畅通。

显示应用程序模式对话框:“M”
查看所有可见的工具包模式对话框——如果 M 来自其中一个的 SB,它将被它阻止。如果有多个这样的对话框,则使用显示的第一个。如果不存在这样的对话框,则 M 保持畅通。

显示工具包模式对话框:“M”
M 保持畅通。

标准阻塞矩阵
当前/显示 框架和无模式 文档 应用 工具包
- - - - -
文档 封锁 - - -
应用 封锁 封锁 - -
工具包 封锁 封锁 封锁 -

模式对话框显示后,其 SB 中的所有窗口都被阻止,除了那些阻止该模式对话框的窗口。

隐藏窗口或无模式对话框:“F”
如果 F 被任何模式对话框 M 阻止,它就会解除阻止并从 M 的阻止窗口列表中删除。

隐藏模态对话框:“M”
如果 M 被任何其他模式对话框阻止,例如“N”,它就会解除阻止并从 N 的阻止窗口列表中删除。然后,所有被 M 阻止的窗口和对话框都被解除阻止,然后按照它们最初显示的顺序对它们中的每一个执行相同的检查(如显示模态对话框:“M”)。

从 JDK 6 开始引入了两种模态排除类型

  • 排除阻止工具包模式对话框
  • 排除阻止应用程序模式对话框
默认情况下,窗口的模态排除属性处于关闭状态。
  1. 应用程序模式排除
    如果一个窗口被排除在应用程序模式之外,则它不会被任何应用程序模式对话框阻止。此外,它不会被来自其子层次结构外部的文档模式对话框阻止。
  2. 工具包模态排除
    如果一个窗口被排除在工具包模态之外,则它不会被任何应用程序或工具包模态对话框阻止。此外,它不会被来自其子层次结构外部的文档模式对话框阻止。

实现说明:更改可见窗口的模态排除类型可能无效,直到它被隐藏然后再次显示。

总在最前面
当一个不总是在最上面的模式对话框阻塞一个总是在最上面的窗口时,它们的相对 Z 顺序是未指定的并且依赖于平台。

toFront()toBack() 方法
模态对话框应始终位于其所有被阻止的窗口之上。因此,如果一个被阻挡的窗口被带到前面,它的阻挡对话框(如果有的话)也被带到前面并保持在被阻挡的窗口之上。同样,如果一个模式对话框被发送到后面,它所有被阻止的窗口都会被发送到后面以保持它们在阻止对话框之下。

最小化、最大化和关闭被阻止的窗口
当模态对话框阻塞窗口时,用户可能无法最大化或最小化被阻塞的窗口——但是,实际行为是未指定的并且依赖于平台。在任何情况下,用户都无法以交互方式关闭被阻止的窗口,但可以通过调用被阻止窗口的 setVisible(false)dispose() 方法以编程方式关闭。

阻止的 Windows 激活
当用户选择一个被阻止的窗口时,它可能会被带到前面,连同将成为活动窗口的阻止模态对话框一起——但是,实际行为是未指定的并且依赖于平台。

隐藏模态对话框
当当前获得焦点的模态对话框被隐藏时,它是未指定的和平台相关的,其他窗口将成为活动窗口。以下任何一个都可能成为活动窗口:

  1. 模态对话框的所有者 - 如果所有者未被阻止。
  2. Window 在此模态对话框获得焦点之前处于活动状态 - 如果模态对话框的所有者不存在或被阻止。
如果要隐藏的模态对话框没有焦点,则活动窗口保持不变。

Security

需要特殊的 AWTPermission"toolkitModality" 来显示工具包模式对话框。例如,这将防止通过小程序显示的模态对话框阻止浏览器或 Java Web Start (JWS)。

从工具包模态中排除窗口需要相同的权限。例如,这将防止从 applet 显示的对话框不被浏览器或 JWS 的模态对话框阻止。

平台支持

两个 java.awt.Toolkit 方法允许您检查当前平台是否支持特定模态功能:

  • isModalityTypeSupported(modalityType)
    返回当前平台是否支持指定的模态类型。如果不支持模式“M”并且对话框设置为 M-modal,则它表现为无模式。
  • isModalExclusionTypeSupported(modalExclusionType)
    返回当前平台是否支持给定的模态排除类型。如果不支持排除类型“E”并且窗口被标记为 E-排除,则这没有效果。

兼容性

默认模态类型是应用程序模态。 API 调用使用它:Dialog.setModal(true)Dialog(owner, true) 等。在 JDK 6 之前,默认类型是工具包模式,但应用程序模式和工具包模式之间的唯一区别是小程序和从 Java Web Start 启动的应用程序。

示例

示例 1

  1. 显示帧 F
  2. 文档模式对话框 Di显示
  3. F被D挡住i— 在同一份文件中
  4. 文档模式对话框 Dii显示
  5. Di被D挡住了ii— 在同一份文件中

Example 1

示例 2

  1. 显示帧 F
  2. 文档模式对话框 Di显示
  3. F被D挡住i— 在同一份文件中
  4. 文档模式对话框 Dii显示
  5. Di被D挡住了ii— 在同一份文件中

Example 2

示例 3

  1. 显示帧 F
  2. 工具包模态对话框 Di已创建,但未显示
  3. 文档模式对话框 Dii显示
  4. F被D挡住ii— 在同一份文件中
  5. 应用程序模式对话框 D显示
  6. Dii被D挡住了— 在同一个应用程序中
  7. Di显示
  8. Di被D挡住了ii——它是它的主人
  9. D保持畅通——它阻塞了 Dii和Dii积木Di

Example 3

例 4

  1. 显示帧 F
  2. 工具包模态对话框 Di已创建,但未显示
  3. 文档模式对话框 Dii显示
  4. F被D挡住ii— 在同一份文件中
  5. 应用程序模式对话框 D显示
  6. Dii被D挡住了— 在同一个应用程序中
  7. Di显示
  8. D被D挡住了i— Di没有被阻止
  9. Di保持畅通

Example 4