辅助功能*

Charles Ward

Charles Ward

Adobe

出版日期:
2008 年 2 月 28 日
用户级别:
中/高级
产品:
Adobe AIR

控制窗口的显示顺序

Adobe AIR 提供多种方法和属性, 用于控制应用程序窗口的显示顺序。图 1 中显示的 Z 范例应用程序演示 AIR 的以下功能:

  • 激活窗口
  • 将窗口拉至显示顺序的最前面
  • 将窗口推至显示顺序的最后面
  • 确定某个窗口相对于其它应用程序窗口的顺序
  • 使某个窗口保持在其它窗口的前面

Z 应用程序

图 1。Z 范例应用程序演示如何控制应用程序窗口的显示顺序。

可以运行 Z 范例来观察这些功能的行为方式, 也可以研究 Z 的源代码来查看如何使用这些功能。

注意: 本范例应用程序按原样提供, 用于教学目的。

要求

若要充分利用本篇文章, 您需要以下软件和文件:

Adobe AIR

Adobe Flash CS3 Professional

为 Flash CS3 Professional 提供的 Adobe AIR 更新

范例文件:

本范例应用程序包括以下文件:

  • Z.as: 应用程序主文件 (Flex 的 MXML 格式), 其中包括本文所讨论的代码
  • Z.fla: 与 Adobe Flash CS3 配合使用的 Flash 文档
  • Z-app.xml: AIR 应用程序描述符文件
  • ZWindow.as: 扩展 NativeWindow 类, 用于自定义 Z 应用程序中示例窗口的行为
  • CircularZWindow.as: 扩展 ZWindow, 用于绘制圆形窗口
  • RectangularZWindow.as: 扩展 ZWindow, 用于绘制矩形窗口
  • TriangularZWindow.as: 扩展 ZWindow, 用于绘制三角形窗口
  • AIR 图标文件范例

必备知识

应具备使用 Flash CS3 构建应用程序的一般经验。有关使用此快速入门指南的详细信息, 请参阅用 Flash 构建快速入门范例应用程序

关于窗口深度排序

通过 AIR, 可以根据 alwaysInFront 属性的值对众多窗口进行排序, 将其分为两个显示顺序组。alwaysInFront 被设置为 true 的任何窗口都显示在 alwaysInFront 被设置为 false 的任何窗口的前面。 (前一类窗口还会显示在其它应用程序的其它窗口的前面, 因此将此属性设置为 true 时应该谨慎而行。)

AIR 提供四种方法, 用于排列某个窗口相对于其它窗口的显示深度:

  • orderToFront()
  • orderToBack()
  • orderInFrontOf(NativeWindow)
  • orderInBackOf(NativeWindow)

此外, activate() 方法也能将窗口排到前面。

更改 alwaysInFront 属性的值也可以更改窗口的排序。例如, 将值从 true 改为 false 会使窗口排在任何其它“alwaysInFront”窗口的后面, 但仍在其它窗口的前面。使用 orderInFrontOf()orderInBackOf() 方法时, 窗口采用目标窗口的 alwaysInFront 设置。

窗口排序方法返回一个布尔值, 表明排序操作是否已成功。排序操作可能失败的唯一原因是被排序的窗口不可见。

Z 范例应用程序

Z 应用程序绘制三个示例窗口, 从中可以试验深度排序 API 及其如何与用户对窗口的操作进行交互。在 Windows 操作系统中将再绘制第四个窗口, 该窗口提供一个菜单栏, 其中包含针对深度排序方法和属性的菜单命令。

若要测试此应用程序, 请启动 Z 安装程序文件 (Z.air)。使用应用程序菜单或窗口菜单, 对三个几何形状窗口采用原有窗口的深度排序方法和属性。

了解代码

Z 应用程序创建三个示例窗口, 通过菜单命令可以设置这些窗口的显示顺序。定义基类 ZWindow, 用于建立窗口行为。子类 CircularZWindow、TriangularZWindow 和 RectangularZWindow 扩展此基类, 用于绘制特殊的几何形状。

调度排序命令

根据从菜单中选择的命令调用排序的方法和属性。每个示例窗口都添加其自身的菜单, 并带有事件处理函数, 以采用排序的方法和属性:

alwaysInFrontvisible 属性为布尔值, 因此对它们的当前值取反可以切换设置:

private function toggleAlwaysInFront(event:Event):void{
    alwaysInFront = !alwaysInFront;
}

private function toggleVisibility(event:Event):void{
    visible = !visible;
}

orderToFront()orderToBack() 方法将窗口移至其显示顺序组的前面或后面。使用 Z 应用程序时, 请谨记这些命令的行为如何根据窗口的 alwaysInFront 属性而改变。

private function orderToFrontCommand(event:Event):void{
    orderToFront();
}

private function orderToBackCommand(event:Event):void{
    orderToBack();
}

activate() 方法使窗口可见, 将其排至前面, 并将焦点给予窗口。

private function activateCommand(event:Event):void{
    activate();
}

orderInBackOf()orderInFrontOf() 方法需要引用另一个窗口。在 Z 中, 这些引用存储在相关菜单命令的 data 属性中, 以便可以从菜单项 select 事件对象的目标中检索引用。请注意, alwaysInFront 设置也进行更改, 以便与作为参数传递的窗口的该设置相匹配。

private function orderBehindCommand(event:Event):void{
    orderInBackOf(event.target.data as ZWindow);
}

private function orderInFrontCommand(event:Event):void{
    orderInFrontOf(event.target.data as ZWindow);
}

设置菜单

ZWindow 类的 makeZOrderMenu() 方法创建一个菜单, 其中含有控制单个窗口的命令。Z 主类对每个窗口都调用此方法, 以使应用程序对这三个示例窗口中的每个窗口都有一个菜单。

Mac OS X 与 Windows 操作系统处理菜单的方式大不相同, 因此在不同的操作系统中运行此应用程序时要调用不同的函数。在 Windows 中将调用以下函数, 为应用程序初始窗口创建菜单, 同时为每个 Z 窗口都添加一个菜单, 此外还添加一个 Source Code (源代码) 菜单:

private function createWindowMenu():NativeMenu{
    var menu:NativeMenu = new NativeMenu();
    for each(var zWindow:ZWindow in ZWindow.zWindows){
        menu.addSubmenu(zWindow.makeZOrderMenu(), zWindow.title);
    }
    menu.addSubmenu(createSourceCodeMenu(),"Source Code");
    return menu;
}

在 Mac OS X 中将调用以下函数, 用于修改标准的应用程序菜单。Z 删除现有的 File (文件) 、Edit (编辑) 和 Window (窗口) 菜单, 并为每个 Z 窗口都添加一个菜单, 此外还添加一个 Source Code 菜单。

private function modifyApplicationMenu():void{
    var menu:NativeMenu = NativeApplication.nativeApplication.menu;
    //删除不需要的标准菜单
    for each(var item:NativeMenuItem in menu.items){
        if((item.label == "File") ||
           (item.label == "Edit") ||
           (item.label == "Window")){
                menu.removeItem(item);
        }
    }
    //为每个示例窗口添加一个菜单
    for each(var zWindow:ZWindow in ZWindow.zWindows){
        menu.addSubmenu(zWindow.makeZOrderMenu(), zWindow.title);
    }
    //添加 Source Code 菜单
    menu.addSubmenu(createSourceCodeMenu(), "Source Code");
}

创建命令菜单

ZWindow 基类定义 makeZOrderMenu() 方法, 该方法返回一个 NativeMenu 对象, 其中包含窗口的菜单命令和子菜单:

public function makeZOrderMenu():NativeMenu{
    var menu:NativeMenu = new NativeMenu();
 
    var stateAlwaysInFront:NativeMenuItem =
        menu.addItem(new NativeMenuItem("Always in front"));
    stateAlwaysInFront.addEventListener(Event.SELECT, toggleAlwaysInFront);

    var stateVisible:NativeMenuItem = menu.addItem(new NativeMenuItem("Visible"));
    stateVisible.addEventListener(Event.SELECT, toggleVisibility);
    menu.addEventListener(Event.DISPLAYING, function(event:Event):void{
        stateAlwaysInFront.checked = alwaysInFront;
        stateVisible.checked = visible;
    });

    menu.addItem(new NativeMenuItem("",true));//分隔符
 
    var commandActivate:NativeMenuItem = menu.addItem(new NativeMenuItem("Activate"));
    commandActivate.addEventListener(Event.SELECT, activateCommand);
    var commandOrderToFront:NativeMenuItem =
    menu.addItem(new NativeMenuItem("Order to front"));
    commandOrderToFront.addEventListener(Event.SELECT, orderToFrontCommand);
    var commandOrderToBack:NativeMenuItem =
        menu.addItem(new NativeMenuItem("Order to back"));
    commandOrderToBack.addEventListener(Event.SELECT, orderToBackCommand);
 
    var submenuOrderInFront:NativeMenuItem =
        menu.addSubmenu(createWindowSubmenu(),"Order in front of");
    submenuOrderInFront.submenu.addEventListener(Event.SELECT, orderInFrontCommand);
    var submenuOrderBehind:NativeMenuItem =
    menu.addSubmenu(createWindowSubmenu(),"Order behind");
    submenuOrderBehind.submenu.addEventListener(Event.SELECT, orderBehindCommand);
    return menu;
}

菜单中前两项显示窗口的 alwaysInFrontvisible 设置。为了确保菜单的状态与窗口的状态相匹配, 将根据菜单的 displaying 事件更新菜单项的 checked 属性。即将使菜单可见之前将调度 displaying 事件。

menu.addEventListener(Event.DISPLAYING, function(event:Event):void{
    stateAlwaysInFront.checked = alwaysInFront;
    stateVisible.checked = visible;
});

在项目构造函数中将 isSeparator 参数设置为 true, 从而创建分隔符项。

menu.addItem(new NativeMenuItem("",true));//分隔符

添加具有适当标签的项目并附加用于执行命令的事件侦听器, 从而添加命令项。例如, 下面的语句添加 activate (激活) 命令:

var commandActivate:NativeMenuItem = menu.addItem(new NativeMenuItem("Activate"));
commandActivate.addEventListener(Event.SELECT, activateCommand);

事件处理函数仅调用窗口的 activate() 方法。

private function activateCommand(event:Event):void{
    activate();
}

创建窗口子菜单

为了使 Order in front of (排在所选窗口之前) 和 Order behind (排在所选窗口之后) 命令发挥作用, 必须标识对于命令所需的另一个窗口。对于这些命令, Z 提供了一个子菜单, 其中列出其它示例窗口。createWindowSubmenu() 方法为 Order in front ofOrder behind 菜单创建 NativeMenu 对象:

private function createWindowSubmenu():NativeMenu{
    var windowMenu:NativeMenu = new NativeMenu();
    windowMenu.addEventListener(Event.DISPLAYING, displayWindows);
    return windowMenu;
}

这些子菜单最初没有成员。而是在菜单调度 displaying 事件时, Z 为每个此类窗口添加一项。displayWindows() 方法通过遍历静态 ZWindow.zWindows 数组 (其中包含 ZWindow 的每个实例), 向子菜单添加项目:

		
private function displayWindows(event:Event):void{
    for each(var existing:NativeMenuItem in event.target.items){
        event.target.removeItem(existing);
    }
    for each(var zWindow:ZWindow in ZWindow.zWindows){
        if(zWindow != this){
            var item:NativeMenuItem = event.target.addItem(new NativeMenuItem(zWindow.title));
            item.data = zWindow;
        }
    }
}

为使访问菜单中所列窗口的 ZWindow 对象更轻松, 将该窗口对象赋给菜单项的 data 属性。data 属性是对象类型, 因此可以将任何对象赋给它。这样可以在处理菜单项的 select 事件时通过 event 对象的 target 属性访问被分配的对象。例如, Order in front of 菜单中命令的处理函数调用 orderInFront() 方法, 如下所示:

private function orderInFrontCommand(event:Event):void{
    orderInFrontOf(event.target.data as ZWindow);
}

关于作者

Charles Ward 是一名技术作者, 它喜欢钻研新技术。在之前的 (专业) 职业生涯中, 他曾参与创建开拓性的计算机游戏, 如 Falcon 3.0 和 4.0 以及 Star Trek: A Final Unity。在闲暇时间, Charles 喜欢自由潜水以及和他的孩子们玩耍。