【Java精品源码栏目提醒】:文章导读:在新的一年中,各位网友都进入紧张的学习或是工作阶段。
网学会员整理了Java精品源码-Java_6中新型模态对话框API - 其它资料的相关内容供大家参考,祝大家在新的一年里工作和学习顺利!
Java 6 中新型模态对话框 API一、引言 对话框,是指一个最顶层的拥有标题和边框的弹出窗口,典型地应用于用户进行某种形式的输入操作。
在 JDK 5.0 和早期版本中,构建一个对话框时,它必须拥有一个作为它的所有者窗口的框架窗口或另一个对话框,即使窗口是不可见的。
当用户最小化一个可见对话框的所有者窗口时会自动隐藏该对话框而当用户随后恢复所有者窗口时,该对话框再次出现。
一个对话框可以是无模式的也可以是模式的。
除了该对话框的所有者的窗口之外,模式对话框将阻止在应用程序中其它顶层窗口的输入。
模式对话框捕获窗口焦点直到其被关闭为止经常响应于一次按钮点击。
另一方面,一个无模式对话框允许用户改变它的状态,而此时其它窗口仍然可拥有焦点。
后者常用于工具栏窗口中,例如你在一个图像编辑程序中所见的。
在 JDK 5.0 和早期版本中的模态模型有一些局限。
而且,这种模态模型也存在一些问题。
JavaHelp,最著名的问题涉及到 JavaHelp 工具窗口。
Java 应用程序中提供帮助信息的 API,使用独立的窗口来显示所有的必要信息。
然而,如果应用程序显示任何模式对话框,例如一标准 Save As 对话框,那么该对话框将阻止用户与 JavaHelp 工具窗口进行交互。
但是
Java 6,代码名称为 Mustang,已经通过一种新的抽象窗口工具箱AWT模态模型解决了此问题以及其它几个问题。
这种新型模型允许开发者根据其选择的模态类型指定范围或限制一个对话框的模态阻断。
如此模态类型也允许窗口和对话框成为真正的无父窗口,也即,拥有一个 null 父窗口,它可以帮助限制窗口的范围和对话框的模态。
二、模态类型
Java 6 支持四种模态类型: 无模式。
无模式对话框在自己为可见时并不阻断任何其它窗口。
文档-模式。
文档-模式对话框阻断所有的来自同一文档的窗口,除了那些来自于它的子层次上的窗口外。
在此意义中,一个文档是指一个窗口层次-框架窗口,对话框等等,它们共享一个文档根窗口。
文档根窗口是所有没有所有者的最顶级窗口。
应用程序-模式。
应用程序-模式对话框能够阻断同一应用程序中的所有窗口,除了那些来自于它的子层次上的窗口外。
如果在浏览器中激活若干 applet,那么浏览器将把它们当作独立的应用程序或者作为一个单一的应用程序。
具体情况依赖实现的具体环境。
工具箱-模式。
工具箱-模式对话框能够阻断所有的运行于同样的工具箱中的窗口,除了那些来自于它的子层次上的窗口外。
如果激活多个 applet,那么它们都运行于同样的工具箱上。
因此,从 applet 中显示的工具箱-模式对话框可能影响其它的 applet。
正如以前的 JDK 一样,一个对话框在缺省情况下是无模式的。
但是如果你在 Mustang中构造一个模式对话框的话,现在它将缺省使用应用程序-模式类型。
另外,模式和无模式对话框的行为已经在 Mustang 作了改变,它们可以一直出现在其父窗口的顶部。
模态优先权是由阻断强度决定的。
这种模态优先权帮助处理两个对话框可见并且能够彼此阻断的情形。
优先权按升序排列分别是:无模式,文档-模式,应用程序-模式和工具箱-模式。
这种优先权自然地反映了一个对话框的范围阻断的嵌套情形。
一个无模式对话框有一个空范围的阻断。
文档-模式对话框的范围阻断是在特定的应用程序中完成的,并且所有的应用程序是运行于一种工具箱中。
图 1 展示了这样的一个例子。
图 1:对话框的模态优先权 注意,这种新型的模态模型并没有实现一个系统模态,这将会阻断
Java 或其它所有被显示在桌面上的应用程序,而只有一个模式对话框处于活动状态。
三、了解新的构造器 能提供真正无父窗口而不中断向后兼容对于 AWT 开发小组来说是一个挑战。
在 JDK5.0 及以前的版本中,允许传递 null 作为 JDialog 或 Jwindow 的父窗口。
这意味着,一不可见的共享所有者的框架窗口将成为这个对话框或窗口的父窗口。
这个共享所有者的框架窗口的创建是为了创建无父窗口对话框。
这种情况直到
Java SE 6 才得以成功-
Java SE 6 引入了新型的文档-模式对话框能够阻止所有的窗口使用相同的文档。
因而,工具箱会知道这样的对话框或窗口是没有 null 父窗口的。
在 Mustang 中,仍然允许传递 null 作为一个父窗口到旧式的 JDialog 或 JWindow 构造器中。
并且这可以完成相同的事情:其成为共享的所有者框架窗口而不是成为父窗口,这也照顾了向后兼容问题。
然而,现在能把 null 传递到 Dialog 或 Window 构造器中,而且也能传递到新的 JDialog或 JWindow 构造器中,这意味着这些对话框能够真正成为无父窗口。
下面列举的是一些比较有用的构造器: JDialogDialog owner创建一个无标题并用一个指定的对话框作为其父窗口的无模式对话框JDialogDialog owner,boolean modal用指定的所有者 Dialog 和模态创建一个具有指定的模态和所有者对话框的对话框JDialogDialog owner,String title创建一个具有指定的标题和所有者对话框的无模式对话框JDialogDialog owner,String title,boolean modal创建一个具有指定的标题,模态和所有者对话框的对话框JDialogDialog owner,String title,boolean modal,GraphicsConfiguration gc创建一个具有指定的标题,模态和所有者对话框和 GraphicsConfiguration 的对话框JDialogFrame owner创建一个无标题但用指定的框架作为其所有者的无模式对话框JDialogWindow owner,String title,Dialog.ModalityType modalityType创建一个具有指定的标题,模态和所有者窗口的对话框有关这里每个构造器的更多细节请参考 Mustang 有关文档。
四、 与所有者窗口一同工作 如前面所提及的,当一个窗口或一个对话框是另一个窗口的父亲时,就称为该父组件拥有它的孩子。
在此,当在新的模态模式下与所有者窗口一同工作时,你应该注意几件事情: 创建一个没有所有者的文档-模式对话框。
在这种情况中,因为 Dialog 是 Window 的一个子类所以,如果一个 Dialog 实例没有所有者的话,它自动地成为该文档的根。
这样,如果这个对话框是文档-模式的,那么它的阻断范围是空的,并且其行为就象一个无模式对话框。
创建一个有所有者的应用程序-模式或工具箱-模式对话框。
一个应用程序-模式或文档-模式对话框的阻断范围并不依靠它的所有者。
在这种情况中,所有者所唯一影响的是 Z-顺序顶级组件的相对顺序。
如果你有两个窗口,一个遮住另一个,第一个窗口位于第二窗口上面,那么最顶端的窗口通常是一个活动的窗口。
一个相关概念是总是位于顶层,这时一个窗口总是出现在系统中所有其它窗口之上。
对话框总是会位于它的所有者的上部。
在运行时刻改变模态类型。
改变一可见的对话框的模态类型可能没有什么影响,直到该对话框被隐蔽并且被再次显示。
下列代码实例展示了新型的模态 API 的应用,其中包括现在可灵活在应用于对话框窗口的
java.awt.Dialog.ModalExclusionType 和
java.awt.Dialog.ModalityType。
图 2 显示出当你运行该代码后的最终结果。
import
java.awt. import
java.awt.event. import sun.awt. public class ModalityDemo2 // 第一个文档red:框架,无模式对话框,文档-模式对话框 private static Frame f1 private static Dialog d11 //……省略,详见所附
源码文件 图 2: 被阻断的和未被阻断的对话框 一个使用 DOCUMENT_MODAL 的对话框会阻止相同文档中的所有顶层窗口的输入,除了它自己的子窗口层次之外。
一个文档是一种没有所有者的顶层窗口。
它可以被当作单个文档的子窗口和顶层窗口。
因为每一个顶层窗口必须属于某文档,所以它的根可以在没有所有者的最顶层窗口中找到。
d22.setBoundssw - 500 32, 232, 300, 200 d22.addWindowListenercloseWindow d22.setLayoutnew BorderLayout l new LabelDOCUMENT_MODAL l.setBackgroundColor.BLUE l.setAlignmentLabel.CENTER l.setFontlabelFont d22.addl, BorderLayout.CENTER //第三个文档 f3 new FrameExcluded Frame f3.setModalExclusionType Dialog.ModalExclusionType.APPLICATION_EXCLUDE 一个被设置为 APPLICATION_MODAL 的对话框将会阻断在同一
Java 程序中的所有的顶层窗口,除了它自己的孩子窗口层次之外。
如果若干 applet 在一浏览器中被调用,那么可以把它们当作或者是独立的应用程序或者是单个的程序。
这种行为的实现要依赖具体的环境而定。
注意,下面的 f3 不会被 APPLICATION_MODAL 和 DOCUMENT_MODAL 对话框所阻断。
f3.setBounds32, sh - 200 32, 300, 200 f3.addWindowListenercloseWindow f3.setLayoutnew BorderLayout l new LabelEXCLUDED FRAMEl.setBackgroundColor.GREENl.setAlignmentLabel.CENTERl.setFontlabelFontf3.addl, BorderLayout.CENTERb new ButtonIm alivef3.addb, BorderLayout.SOUTHf3.setVisibletrue// 第四个文档f4 new FrameParent Framef4.setBoundssw - 300 32, sh - 200 32, 300, 200f4.addWindowListenercloseWindowf4.setLayoutnew BorderLayoutl new LabelFRAMEl.setBackgroundColor.GRAYl.setAlignmentLabel.CENTERl.setFontlabelFontb new ButtonShow file dialogb.addActionListenernew ActionListener public void actionPerformedActionEvent e fd4.setVisibletruef4.addb, BorderLayout.SOUTHf4.setVisibletruefd4 new FileDialogf4, File Dialog, FileDialog.LOAD为了向后兼容性起见,File 对话框缺省是 APPLICATION_MODA。
fd4.setBoundssw - 400 32, sh - 300 32, 300, 200五、 有关 AWT 特性 下面是其它一些在使用新的模态模态时要了解的 AWT 特性。
一 总在最上面 当一个并不总是位于顶层的模式对话框阻断一个总是位于顶层的窗口时,它们的相对Z-序未特别指出并且是平台依赖的。
下列实例表明这个问题: JFrame f new JFrame... f.setAlwaysOnToptrue f.setVisibletrue JDialog d new JDialogframe, Dialog, true d.setVisibletrue 这段代码制造了一种矛盾:一方面,d 必须位于 f 之上因为它是一个模式对话框并且应该阻断 f。
而另一方面,f 必须必须位于 d 之上,因为 f 被设置为总是位于顶层,而 d 不是。
如此情形是未特别指出的。
然而,总是有解决办法:如果 d 也被设置为总是位于顶层d.setAlwaysOnToptrue,那么该对话框将在任何时候位于框架窗口之上。
二 toFront和 toBack方法 一个模式对话框应该总是位于所有的被其阻断的窗口之上。
这样,如果一被阻断的窗口被送到前面,那么它的阻断对话框,如果有的话,也被送到前面并且位于被阻断的窗口之上。
同样,如果一模式对话框被送到后面,那么所有它的被阻断的窗口被送到后面以使其位于阻断对话框下面。
三 最小化,最大化和关闭被阻断的窗口 当一个模式对话框阻断一个窗口时,用户可能无法最小化或最大化被阻断的窗口。
然而,实际行为并未特别指出并且是平台依赖的。
在任何情况下,用户都不能交互式地关闭被阻断的窗口。
但是它能被通过编程方式关闭-通过在被阻断的窗口上调用 setVisiblefalse或dispose方法。
四 激活被阻断的窗口 当用户选择一个被阻断的窗口时,它有可能连同阻断模式对话框一起被送到前端,然后它成为当前活动窗口。
然而,实际行为并未特别指出并且是平台依赖的。
五 隐藏模式对话框 当具有当前焦点的模式对话框被隐藏时,它的所有者未被阻断而有可能成为活动窗口。
然而,实际行为并未特别指出并且是平台依赖的。
如果要被隐藏的模式对话框不具有焦点,那么活动窗口保持不变。
六 安全性 为了显示工具箱-模式对话框,需要一种特殊的 AWTPermission,toolkitModality。
例如,这将防止从 applet 中显示的模式对话框被浏览器或 JWSJava Web Start的软件所阻断。
相同的权限需要用于从工具箱模态中排除一个窗口。
例如,这将防止一个从 applet 中显示的对话框被浏览器或 JWS 的模式对话框所阻断。
七 平台支持 有两个
java.awt.Toolkit 方法允许你检查是否当前平台支持特定的模态特征: isModalityTypeSupportedmodalityType,返回是否给定的模态类型为当前平台所支持。
如果不支持模式 M 并且一个对话框被设置为 M-modal,那么其行为就象一个无模态对话框。
isModalExclusionTypeSupportedmodalExclusionType,返回是否给定的模态exclusion 类型为当前平台所支持。
如果不支持 exclusion 类型 E 并且一个窗口被标记为E-excluded,那么这没有任何影响。
六、兼容性 默认的模态类型是应用程序模式,它被如 Dialog.setModaltrue, true Dialogowner,等 API 所用调用。
在 JDK 6 以前,默认类型是工具箱-模式,但是在应用程序模态和工具箱模态之间的唯一区别在于从 JWS 软件中激活 applet 和应用程序方面。
注意:任何
Java SE 平台 API 的增加或对其说明的改进必须经 JSR 270 专家组的过目和同意。