管理窗口

Adobe AIR 1.0 和更高版本

使用 NativeWindow 类的属性和方法可管理桌面窗口的外观、行为和生命周期。

注: 当使用 Flex 框架时,通常最好使用框架类来管理窗口行为。通过 mx:WindowedApplication 类和 mx:Window 类可访问大多数 NativeWindow 属性和方法。

获取 NativeWindow 实例

若要操作窗口,必须首先获取窗口实例。可以从以下任一位置获取窗口实例:

  • 用于创建窗口的本机窗口构造函数:

    var win:NativeWindow = new NativeWindow(initOptions);
  • 窗口舞台的 nativeWindow 属性:

    var win:NativeWindow = stage.nativeWindow;
  • 窗口中显示对象的 stage 属性:

    var win:NativeWindow = displayObject.stage.nativeWindow;
  • 由窗口调度的本机窗口事件的 target 属性:

    private function onNativeWindowEvent(event:NativeWindowBoundsEvent):void 
    { 
        var win:NativeWindow = event.target as NativeWindow; 
    }
  • 窗口中显示的 HTML 页的 nativeWindow 属性:

    var win:NativeWindow = htmlLoader.window.nativeWindow;
  • NativeApplication 对象的 activeWindowopenedWindows 属性:

    var nativeWin:NativeWindow = NativeApplication.nativeApplication.activeWindow; 
    var firstWindow:NativeWindow = NativeApplication.nativeApplication.openedWindows[0];

    NativeApplication.nativeApplication.activeWindow 引用应用程序的活动窗口(但如果该活动窗口不是此 AIR 应用程序的窗口,则返回 null)。NativeApplication.nativeApplication.openedWindows 数组包含 AIR 应用程序中尚未关闭的所有窗口。

由于 Flex mx:WindowedApplication 和 mx:Window 对象都是显示对象,因此使用 stage 属性即可轻松地在 MXML 文件中引用应用程序窗口,如下所示:

<?xml version="1.0" encoding="utf-8"?> 
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" applicationComplete="init();"> 
    <mx:Script> 
        <![CDATA[ 
            import flash.display.NativeWindow; 
 
            public function init():void{ 
                var appWindow:NativeWindow = this.stage.nativeWindow; 
                //set window properties 
                appWindow.visible = true; 
            } 
        ]]> 
    </mx:Script> 
</WindowedApplication
注: 在 Flex 框架将 WindowedApplication 或 Window 组件添加到窗口舞台后,该组件的 stage 属性为 null。此行为与 Flex Application 组件的行为一致,但并不意味着不能访问舞台或 WindowedApplication 和 Window 组件初始化周期中较早出现事件(例如 creationComplete)的侦听器中的 NativeWindow 实例。在调度 applicationComplete 事件后,访问舞台和 NativeWindow 实例是安全的。

激活、显示和隐藏窗口

若要激活窗口,请调用 NativeWindow activate() 方法。激活窗口会将该窗口置于前面,为其提供键盘和鼠标焦点,并在必要时通过还原窗口或将 visible 属性设置为 true 来使其可见。激活窗口不会更改应用程序中其他窗口的顺序。调用 activate() 方法会导致窗口调度 activate 事件。

若要在不激活的情况下显示隐藏窗口,请将 visible 属性设置为 true。此操作使该窗口置于前面,但不会向它分配焦点。

若要从视图中隐藏窗口,请将其 visible 属性设置为 false。隐藏窗口会禁止窗口和任何相关任务栏图标的显示,并且在 Mac OS X 中还会禁止窗口菜单中条目的显示。

更改窗口的可见性时,该窗口所拥有的所有窗口的可见性也将发生更改。例如,如果隐藏窗口,则该窗口所拥有的所有窗口也将隐藏。

注: 在 Mac OS X 中,无法完全隐藏在停靠栏的窗口部分拥有图标的最小化窗口。如果最小化窗口上的 visible 属性设置为 false,则仍然显示该窗口的停靠栏图标。如果用户单击该图标,则会将该窗口还原为可见状态并显示该窗口。

更改窗口显示顺序

AIR 提供几种方法来直接更改窗口的显示顺序。可以将窗口的显示顺序向前或向后移动;可以将窗口移动到其他窗口的前面或后面。同时,用户可以通过激活窗口来对窗口进行重新排序。

可以通过将窗口的 alwaysInFront 属性设置为 true 来使该窗口位于其他窗口的前面。如果多个窗口都具有此设置,则这些窗口的显示顺序是它们相互之间的排序顺序,而且它们始终排序在 alwaysInFront 设置为 false 的窗口前面。

即使 AIR 应用程序未处于活动状态,最上面组中的窗口也显示在其他应用程序中窗口的前面。由于此行为会阻碍用户查看其他窗口,因此应仅在必要和适当时才能将 alwaysInFront 设置为 true。经调整的使用示例包括:

  • 工具提示、弹出列表、自定义菜单或组合框等控件的临时弹出窗口。 由于这些窗口在失去焦点后将关闭,因此可以避免阻碍用户查看其他窗口的不便。

  • 极其紧急的错误消息和警告。在可能发生不可撤销的更改时,如果用户未及时响应,则可能调整为将警告窗口置于最前面。但是,可以按正常的窗口显示顺序处理大多数错误消息和警告。

  • 短期弹出式窗口。

注: AIR 不强制要求 alwaysInFront 属性的正确使用。但是,如果应用程序打断了用户的工作流,则可能将其传递到同一用户的垃圾桶。

如果窗口拥有其他窗口,则这些窗口始终按顺序显示在该窗口前面。如果对拥有其他窗口的某个窗口调用 orderToFront(),或者在该窗口上将 alwaysInFront 设置为 true,则所有者窗口将显示在其他窗口前面,该窗口所拥有的窗口随该窗口一起重新排序,且所拥有的窗口仍显示在所有者的前面。

在同一窗口所拥有的窗口中,对拥有的窗口调用窗口顺序方法可正常工作,但同时会更改整个拥有的窗口组相对于该组之外的其他窗口的排序顺序。例如,如果对某个拥有的窗口调用 orderToFront(),则该窗口、其所有者以及同一所有者所拥有的所有其他窗口都将移动到窗口显示列表的前面。

NativeWindow 类提供以下属性和方法来设置一个窗口相对于其他窗口的显示顺序:

成员

说明

alwaysInFront 属性

指定窗口是否显示在最上面的窗口组中。

几乎在所有情况下,false 都是最佳设置。将值从 false 更改为 true 会将窗口置于所有其他窗口的前面(但不会激活该窗口)。将值从 true 更改为 false 会将窗口的顺序排在最上面组中其余窗口的后面,但仍位于其他窗口的前面。将窗口的该属性设置为其当前值不会更改窗口显示顺序。

alwaysInFront 设置对其他窗口所拥有的窗口没有任何影响。

orderToFront()

将窗口置于前面。

orderInFrontOf()

将窗口置于紧靠特定窗口前面。

orderToBack()

将窗口发送到其他窗口后面。

orderBehind()

将窗口发送到紧靠特定窗口后面。

activate()

将窗口置于前面(同时使该窗口可见并分配焦点)。

注: 如果窗口处于隐藏(visiblefalse)或最小化状态,则调用显示顺序方法无效。

在 Linux 操作系统中,不同的窗口管理器对于窗口显示顺序实施不同的规则:

  • 在某些窗口管理器中,实用程序窗口始终显示于普通窗口之前。

  • 在某些窗口管理器中,将 alwaysInFront 设置为 true 的全屏窗口始终显示于其他同样将 alwaysInFront 设置为 true 的窗口之前。

关闭窗口

若要关闭窗口,请使用 NativeWindow.close() 方法。

关闭窗口会卸载该窗口的内容,但如果其他对象引用了此内容,则不会破坏内容对象。NativeWindow.close() 方法以异步方式执行,该窗口中包含的应用程序在关闭过程中继续运行。该 close 方法在关闭操作完成时调度 close 事件。从技术角度而言,NativeWindow 对象仍然有效,但访问已关闭窗口上的大多数属性和方法会生成 IllegalOperationError。不能重新打开已关闭窗口。检查窗口的 closed 属性以测试窗口是否已关闭。若要仅从视图中隐藏窗口,请将 NativeWindow.visible 属性设置为 false

如果 Nativeapplication.autoExit 属性为 true(默认情况),则应用程序在其最后一个窗口关闭后退出。

当所有者关闭时,该所有者所拥有的所有窗口也将同时关闭。所拥有的窗口不会调度关闭事件,因此无法阻止关闭这些窗口。已调度 close 事件。

允许取消窗口操作

在窗口使用系统镶边时,可以通过侦听和取消相应事件的默认行为来取消用户与该窗口的交互。例如,在用户单击系统镶边关闭按钮后,将调度 closing 事件。如果任何已注册的侦听器调用了事件的 preventDefault() 方法,则该窗口不会关闭。

在窗口不使用系统镶边时,不会在执行预期更改之前自动调度这些更改的通知事件。因此,如果调用关闭窗口、更改窗口状态的方法,或者设置任何窗口范围属性,则无法取消更改。若要在执行窗口更改前通知应用程序中的组件,则应用程序逻辑可以使用窗口的 dispatchEvent() 方法调度相关的通知事件。

例如,以下逻辑实现窗口关闭按钮的可取消事件处理函数:

public function onCloseCommand(event:MouseEvent):void{ 
    var closingEvent:Event = new Event(Event.CLOSING,true,true); 
    dispatchEvent(closing); 
    if(!closingEvent.isDefaultPrevented()){ 
        win.close(); 
    } 
} 

如果侦听器调用事件的 preventDefault() 方法,则 dispatchEvent() 方法返回 false。但是,由于其他原因,它还可以返回 false,因此最好显式使用 isDefaultPrevented() 方法来测试是否应取消更改。

最大化、最小化和还原窗口

若要最大化窗口,请使用 NativeWindow maximize() 方法。

myWindow.maximize(); 

若要最小化窗口,请使用 NativeWindow minimize() 方法。

myWindow.minimize(); 

若要还原窗口(即,使其返回最小化或最大化操作之前的大小),请使用 NativeWindow restore() 方法。

myWindow.restore(); 

当所有者窗口最小化或还原时,所拥有的窗口也将最小化和还原。所拥有的窗口在最小化时不会调度任何事件,因为是对其所有者执行的最小化操作。

注: 最大化 AIR 窗口导致的行为与 Mac OS X 标准行为不同。AIR 窗口不是在应用程序定义的“标准”大小和用户最后设置的大小之间切换,而是在应用程序或用户最后设置的大小和屏幕的完整可用区域之间切换。

在 Linux 操作系统中,不同的窗口管理器对于设置窗口显示状态实施不同的规则:

  • 在某些窗口管理器中无法将实用程序窗口最大化。

  • 如果为窗口设置了最大大小,则某些窗口不允许将窗口最大化。某些其他窗口管理器将显示状态设置为最大化,但不调整窗口大小。在这两种情况下,都不会调度显示状态更改事件。

  • 某些窗口管理器不遵守窗口的 maximizableminimizable 设置。

注: 在 Linux 中,更改窗口属性是异步进行的。如果在程序的一行中更改窗口的显示状态,并在下一行读取该值,则对值的读取仍将受旧的设置影响。在所有平台上,当显示状态发生更改时,NativeWindow 对象将调用 displayStateChange 事件。如果您需要根据窗口的新状态执行某种动作,始终在 displayStateChange 事件处理函数中执行。请参阅侦听窗口事件

示例:最小化、最大化、还原和关闭窗口

以下简短的 MXML 应用程序演示 Window maximize()minimize()restore()close() 方法:

<?xml version="1.0" encoding="utf-8"?> 
 
<mx:WindowedApplication  
    xmlns:mx="http://www.adobe.com/2006/mxml"  
    layout="vertical"> 
     
     
    <mx:Script> 
    <![CDATA[ 
    public function minimizeWindow():void 
    { 
        this.stage.nativeWindow.minimize(); 
    } 
 
    public function maximizeWindow():void 
    { 
        this.stage.nativeWindow.maximize(); 
    }           
     
    public function restoreWindow():void 
    { 
        this.stage.nativeWindow.restore(); 
    }           
 
    public function closeWindow():void 
    { 
        this.stage.nativeWindow.close(); 
    } 
    ]]> 
    </mx:Script> 
 
    <mx:VBox> 
        <mx:Button label="Minimize" click="minimizeWindow()"/> 
        <mx:Button label="Restore" click="restoreWindow()"/> 
        <mx:Button label="Maximize" click="maximizeWindow()"/> 
        <mx:Button label="Close" click="closeWindow()"/> 
    </mx:VBox> 
 
</mx:WindowedApplication>

以下用于 Flash 的 ActionScript 示例创建四个可单击的文本字段,这些字段分别触发 NativeWindow minimize()maximize()restore()close() 方法:

package 
{ 
    import flash.display.Sprite; 
    import flash.events.MouseEvent; 
    import flash.text.TextField; 
     
    public class MinimizeExample extends Sprite 
    { 
        public function MinimizeExample():void  
        { 
            var minTextBtn:TextField = new TextField(); 
            minTextBtn.x = 10; 
            minTextBtn.y = 10; 
            minTextBtn.text = "Minimize"; 
            minTextBtn.background = true; 
            minTextBtn.border = true; 
            minTextBtn.selectable = false; 
            addChild(minTextBtn); 
            minTextBtn.addEventListener(MouseEvent.CLICK, onMinimize); 
         
            var maxTextBtn:TextField = new TextField(); 
            maxTextBtn.x = 120; 
            maxTextBtn.y = 10; 
            maxTextBtn.text = "Maximize"; 
            maxTextBtn.background = true; 
            maxTextBtn.border = true; 
            maxTextBtn.selectable = false; 
            addChild(maxTextBtn); 
            maxTextBtn.addEventListener(MouseEvent.CLICK, onMaximize); 
         
            var restoreTextBtn:TextField = new TextField(); 
            restoreTextBtn.x = 230; 
            restoreTextBtn.y = 10; 
            restoreTextBtn.text = "Restore"; 
            restoreTextBtn.background = true; 
            restoreTextBtn.border = true; 
            restoreTextBtn.selectable = false; 
            addChild(restoreTextBtn); 
            restoreTextBtn.addEventListener(MouseEvent.CLICK, onRestore); 
             
            var closeTextBtn:TextField = new TextField(); 
            closeTextBtn.x = 340; 
            closeTextBtn.y = 10; 
            closeTextBtn.text = "Close Window"; 
            closeTextBtn.background = true; 
            closeTextBtn.border = true; 
            closeTextBtn.selectable = false; 
            addChild(closeTextBtn); 
            closeTextBtn.addEventListener(MouseEvent.CLICK, onCloseWindow); 
        } 
        function onMinimize(event:MouseEvent):void 
        { 
            this.stage.nativeWindow.minimize(); 
        } 
        function onMaximize(event:MouseEvent):void 
        { 
            this.stage.nativeWindow.maximize(); 
        } 
        function onRestore(event:MouseEvent):void 
        { 
            this.stage.nativeWindow.restore(); 
        } 
        function onCloseWindow(event:MouseEvent):void 
        { 
            this.stage.nativeWindow.close(); 
        } 
    } 
}

调整窗口大小和移动窗口

在窗口使用系统镶边时,该镶边提供用于调整窗口大小和在桌面范围内移动窗口的拖动控件。如果窗口不使用系统镶边,则必须添加您自己的控件以允许用户调整窗口大小和移动窗口。

注: 若要调整窗口大小或移动窗口,必须首先获取对 NativeWindow 实例的引用。有关如何获取窗口引用的信息,请参阅获取 NativeWindow 实例

调整窗口大小

若要使用户可以交互地调整窗口大小,请使用 NativeWindow startResize() 方法。如果此方法是从 mouseDown 事件中调用的,则调整大小操作由鼠标驱动并在操作系统收到 mouseUp 事件时完成。在调用 startResize() 时,传入用于指定所调整窗口大小的起始边或角的参数。

若要以编程方式设置窗口大小,请将窗口的 widthheightbounds 属性设置为所需尺寸。设置范围时,可以同时更改窗口的大小和位置。但是,无法保证发生更改的顺序。某些 Linux 窗口管理器不允许窗口扩展到桌面屏幕范围之外。在这些情况下,即使更改的最终效果以其他方式产生了合法的窗口,最终窗口大小也可能因属性的设置顺序而受到限制。例如,如果同时更改靠近屏幕底部的窗口的高度和 Y 轴位置,那么在 Y 轴位置更改之前应用高度更改时,可能不会进行完整的高度更改。

注: 在 Linux 中,更改窗口属性是异步进行的。如果在程序的一行中调整窗口大小,并在下一行读取尺寸,则这些尺寸仍将受旧的设置影响。在所有平台上,当调整窗口大小时,NativeWindow 对象将调用 resize 事件。如果您需要根据窗口的新大小或状态执行某种动作(如设置窗口中控件的布局),始终在 resize 事件处理函数中执行。请参阅侦听窗口事件

舞台的缩放模式确定调整窗口大小时窗口舞台及其内容的行为方式。请记住,舞台缩放模式旨在用于应用程序不控制其显示区大小或高宽比的情况,例如 Web 浏览器。通常,通过将舞台的 scaleMode 属性设置为 StageScaleMode.NO_SCALE 来获得最佳效果。如果要缩放窗口的内容,则仍可以根据窗口范围的更改来设置内容的 scaleXscaleY 参数。

移动窗口

要移动窗口而不调整其大小,请使用 NativeWindow startMove() 方法。与 startResize() 方法相似,在从 mouseDown 事件调用 startMove() 方法时,移动过程由鼠标驱动并在操作系统收到 mouseUp 事件时完成。

有关 startResize()startMove() 方法的详细信息,请参阅用于 Adobe Flash Platform 的 ActionScript 3.0 参考

若要以编程方式移动窗口,将窗口的 xybounds 属性设置为所需的位置。设置范围时,可以同时更改窗口的大小和位置。

注: 在 Linux 中,更改窗口属性是异步进行的。如果在程序的一行中移动窗口,并在下一行读取该位置,则对值的读取仍将受旧的设置影响。在所有平台上,当更改位置时,NativeWindow 对象将调用 move 事件。如果您需要根据窗口的新位置执行某种动作,始终在 move 事件处理函数中执行。请参阅侦听窗口事件

示例:调整窗口大小和移动窗口

以下示例说明如何对窗口启动调整大小和移动操作:

package 
{ 
    import flash.display.Sprite; 
    import flash.events.MouseEvent; 
    import flash.display.NativeWindowResize; 
 
    public class NativeWindowResizeExample extends Sprite 
    { 
        public function NativeWindowResizeExample():void 
        { 
            // Fills a background area. 
            this.graphics.beginFill(0xFFFFFF); 
            this.graphics.drawRect(0, 0, 400, 300); 
            this.graphics.endFill(); 
     
            // Creates a square area where a mouse down will start the resize. 
            var resizeHandle:Sprite =  
                createSprite(0xCCCCCC, 20, this.width - 20, this.height - 20); 
            resizeHandle.addEventListener(MouseEvent.MOUSE_DOWN, onStartResize); 
     
            // Creates a square area where a mouse down will start the move. 
            var moveHandle:Sprite = createSprite(0xCCCCCC, 20, this.width - 20, 0); 
            moveHandle.addEventListener(MouseEvent.MOUSE_DOWN, onStartMove); 
        } 
     
        public function createSprite(color:int, size:int, x:int, y:int):Sprite 
        { 
            var s:Sprite = new Sprite(); 
            s.graphics.beginFill(color); 
            s.graphics.drawRect(0, 0, size, size); 
            s.graphics.endFill(); 
            s.x = x; 
            s.y = y; 
            this.addChild(s);     
            return s;         
        } 
     
        public function onStartResize(event:MouseEvent):void 
        { 
            this.stage.nativeWindow.startResize(NativeWindowResize.BOTTOM_RIGHT); 
        } 
 
        public function onStartMove(event:MouseEvent):void 
        { 
            this.stage.nativeWindow.startMove(); 
        } 
    } 
}