四、 与所有者窗口一同工作
如前面所提及的,当一个窗口或一个对话框是另一个窗口的父亲时,就称为该父组件"拥有"它的孩子。在此,当在新的模态模式下与所有者窗口一同工作时,你应该注意几件事情:
·创建一个没有所有者的文档-模式对话框。在这种情况中,因为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; //……省略,详见所附源码文件 |
Java6中新型模态对话框API(2) src="https://www.ltesting.net/attachments/2007/07/1_200707142112241.jpg" border=1> 图2: 被阻断的和未被阻断的对话框 |
一个使用DOCUMENT_MODAL的对话框会阻止相同文档中的所有顶层窗口的输入,除了它自己的子窗口层次之外。一个文档是一种没有所有者的顶层窗口。它可以被当作单个文档的子窗口和顶层窗口。因为每一个顶层窗口必须属于某文档,所以它的根可以在没有所有者的最顶层窗口中找到。
d22.setBounds(sw - 500 + 32, 232, 300, 200); d22.addWindowListener(closeWindow); d22.setLayout(new BorderLayout()); l = new Label("DOCUMENT_MODAL"); l.setBackground(Color.BLUE); l.setAlignment(Label.CENTER); l.setFont(labelFont); d22.add(l, BorderLayout.CENTER); //第三个文档 f3 = new Frame("Excluded Frame"); f3.setModalExclusionType( Dialog.ModalExclusionType.APPLICATION_EXCLUDE); |
一个被设置为APPLICATION_MODAL的对话框将会阻断在同一Java程序中的所有的顶层窗口,除了它自己的孩子窗口层次之外。如果若干applet在一浏览器中被调用,那么可以把它们当作或者是独立的应用程序或者是单个的程序。这种行为的实现要依赖具体的环境而定。
注意,下面的f3不会被APPLICATION_MODAL和DOCUMENT_MODAL对话框所阻断。
f3.setBounds(32, sh - 200 + 32, 300, 200); f3.addWindowListener(closeWindow); f3.setLayout(new BorderLayout()); l = new Label("EXCLUDED FRAME"); l.setBackground(Color.GREEN); l.setAlignment(Label.CENTER); l.setFont(labelFont); f3.add(l, BorderLayout.CENTER); b = new Button("I'm alive!"); f3.add(b, BorderLayout.SOUTH); f3.setVisible(true); // 第四个文档 f4 = new Frame("Parent Frame"); f4.setBounds(sw - 300 + 32, sh - 200 + 32, 300, 200); f4.addWindowListener(closeWindow); f4.setLayout(new BorderLayout()); l = new Label("FRAME"); l.setBackground(Color.GRAY); l.setAlignment(Label.CENTER); l.setFont(labelFont); b = new Button("Show file dialog"); b.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { fd4.setVisible(true); } }); f4.add(b, BorderLayout.SOUTH); f4.setVisible(true); fd4 = new FileDialog(f4, "File Dialog", FileDialog.LOAD); 为了向后兼容性起见,File对话框缺省是APPLICATION_MODA。 fd4.setBounds(sw - 400 + 32, sh - 300 + 32, 300, 200); } } |
五、 有关AWT特性
下面是其它一些在使用新的模态模态时要了解的AWT特性。
(一) 总在最上面
当一个并不总是位于顶层的模式对话框阻断一个总是位于顶层的窗口时,它们的相对Z-序未特别指出并且是平台依赖的。下列实例表明这个问题:
JFrame f = new JFrame(...); f.setAlwaysOnTop(true); f.setVisible(true); JDialog d = new JDialog(frame, "Dialog", true); d.setVisible(true); |
这段代码制造了一种矛盾:一方面,d必须位于f之上(因为它是一个模式对话框并且应该阻断f)。而另一方面,f必须必须位于d之上,因为f被设置为总是位于顶层,而d不是。如此情形是未特别指出的。然而,总是有解决办法:如果d也被设置为总是位于顶层(d.setAlwaysOnTop(true)),那么该对话框将在任何时候位于框架窗口之上。
(二) toFront()和toBack()方法
一个模式对话框应该总是位于所有的被其阻断的窗口之上。这样,如果一被阻断的窗口被送到前面,那么它的阻断对话框,如果有的话,也被送到前面并且位于被阻断的窗口之上。同样,如果一模式对话框被送到后面,那么所有它的被阻断的窗口被送到后面以使其位于阻断对话框下面。
(三) 最小化,最大化和关闭被阻断的窗口
当一个模式对话框阻断一个窗口时,用户可能无法最小化或最大化被阻断的窗口。然而,实际行为并未特别指出并且是平台依赖的。在任何情况下,用户都不能交互式地关闭被阻断的窗口。但是它能被通过编程方式关闭-通过在被阻断的窗口上调用setVisible(false)或dispose()方法。
(四) 激活被阻断的窗口
当用户选择一个被阻断的窗口时,它有可能连同阻断模式对话框一起被送到前端,然后它成为当前活动窗口。然而,实际行为并未特别指出并且是平台依赖的。
(五) 隐藏模式对话框
当具有当前焦点的模式对话框被隐藏时,它的所有者未被阻断而有可能成为活动窗口。然而,实际行为并未特别指出并且是平台依赖的。如果要被隐藏的模式对话框不具有焦点,那么活动窗口保持不变。
(六) 安全性
为了显示工具箱-模式对话框,需要一种特殊的AWTPermission,toolkitModality。例如,这将防止从applet中显示的模式对话框被浏览器或JWS(Java Web Start)的软件所阻断。
相同的权限需要用于从工具箱模态中排除一个窗口。例如,这将防止一个从applet中显示的对话框被浏览器或JWS的模式对话框所阻断。
(七) 平台支持
有两个java.awt.Toolkit方法允许你检查是否当前平台支持特定的模态特征:
·isModalityTypeSupported(modalityType),返回是否给定的模态类型为当前平台所支持。如果不支持模式M并且一个对话框被设置为M-modal,那么其行为就象一个无模态对话框。
·isModalExclusionTypeSupported(modalExclusionType),返回是否给定的模态exclusion类型为当前平台所支持。如果不支持exclusion类型E并且一个窗口被标记为E-excluded,那么这没有任何影响。
六、兼容性
默认的模态类型是应用程序模式,它被如Dialog.setModal(true),Dialog(owner,true)等API所用调用。在JDK 6以前,默认类型是工具箱-模式,但是在应用程序模态和工具箱模态之间的唯一区别在于从JWS软件中激活applet和应用程序方面。
注意:任何Java SE平台API的增加或对其说明的改进必须经JSR 270专家组的过目和同意。
延伸阅读
文章来源于领测软件测试网 https://www.ltesting.net/