快捷搜索:

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开拓小组来说是一个寻衅。在JDK 5.0及曩昔的版本中,容许通报null作为JDialog或Jwindow的父窗口。这意味着,一弗成见的共享所有者的框架窗口将成为这个对话框或窗口的父窗口。这个共享所有者的框架窗口的创建是为了创建无父窗口对话框。这种环境直到Java SE 6才得以成功-Java SE 6引入了新型的文档-模式对话框能够阻拦所有的窗口应用相同的文档。

因而,对象箱会知道这样的对话框或窗口是没有null父窗口的。在Mustang中,仍旧容许通报null作为一个父窗口到旧式的JDialog或JWindow构造器中。并且这可以完成相同的工作:其成为共享的所有者框架窗口而不是成为父窗口,这也照应了向后兼容问题。然而,现在能把null通报到Dialog或Window构造器中,而且也能通报到新的JDialog或JWindow构造器中,这意味着这些对话框能够真正成为无父窗口。

下面枚举的是一些对照有用的构造器:

·JDialog(Dialog owner)

创建一个无标题并用一个指定的对话框作为其父窗口的无模式对话框

·JDialog(Dialog owner,boolean modal)

用指定的所有者Dialog和模态创建一个具有指定的模态和所有者对话框的对话框

·JDialog(Dialog owner,String title)

创建一个具有指定的标题和所有者对话框的无模式对话框

·JDialog(Dialog owner,String title,boolean modal)

创建一个具有指定的标题,模态和所有者对话框的对话框

·JDialog(Dialog owner,String title,boolean modal,GraphicsConfiguration gc)

创建一个具有指定的标题,模态和所有者对话框和GraphicsConfiguration的对话框

·JDialog(Frame owner)

创建一个无标题但用指定的框架作为其所有者的无模式对话框

·JDialog(Window 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.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专家组的过目和批准。

您可能还会对下面的文章感兴趣: