Управление окнами

Adobe AIR 1.0 и более поздних версий

При помощи свойств и методов класса NativeWindow можно управлять внешним видом, поведением и жизненным циклом окон рабочего стола.

Примечание. При использовании среды Flex, как правило, лучше управлять поведением окон с помощью классов среды. Доступ к большинству свойств и методов NativeWindow можно получить из классов mx:WindowedApplication и mx:Window.

Получение экземпляра NativeWindow

Для управления окном необходимо сначала получить экземпляр окна. Экземпляр окна можно получить следующим образом:

  • Для создания окна используется конструктор класса NativeWindow.

    var win:NativeWindow = new NativeWindow(initOptions);
  • Свойство nativeWindow рабочей области окна.

    var win:NativeWindow = stage.nativeWindow;
  • Свойство stage объекта display в окне.

    var win:NativeWindow = displayObject.stage.nativeWindow;
  • Свойство target события NativeWindow, размещенного в окне.

    private function onNativeWindowEvent(event:NativeWindowBoundsEvent):void 
    { 
        var win:NativeWindow = event.target as NativeWindow; 
    }
  • Свойство nativeWindow для страницы HTML, отображаемой в окне.

    var win:NativeWindow = htmlLoader.window.nativeWindow;
  • Свойства activeWindow и openedWindows объекта NativeApplication.

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

    NativeApplication.nativeApplication.activeWindow содержит ссылку на активное окно приложения (но возвращает null , если активное окно не является окном данного приложения AIR). Массив NativeApplication.nativeApplication.openedWindows содержит все окна приложения AIR, которые не были закрыты.

Поскольку объекты Flex mx:WindowedApplication и mx:Window являются экранными объектами, можно легко создать ссылку на окно приложения в MXML-файле при помощи свойства stage , как показано ниже:

<?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
Примечание. Пока компонент WindowedApplication или Window не будет добавлен в рабочую область окна при помощи платформы Flex, свойство stage этого компонента будет иметь значение null . Такое поведение соответствует поведению компонента Flex Application, но подтверждает тот факт, что невозможно получить доступ к рабочей области или к экземпляру NativeWindow через прослушивателей событий, которые произошли ранее в цикле инициализации компонентов WindowedApplication и Window, например creationComplete . Доступ к рабочей области и экземпляру NativeWindow при отправке события applicationComplete безопасен.

Активация, отображение и скрытие окон

Для активации окна необходимо вызвать метод NativeWindow activate() . Активация окна переносит его на передний план, окно получает фокус клавиатуры и мыши и при необходимости становится видимым за счет восстановления или присвоения свойству visible значения true . Активация окна не меняет порядок других окон в приложении. При вызове метода activate() окно отправляет событие activate .

Для отображения скрытого окна без его активации задайте для свойства visible значение true . При этом окно переходит на передний план, но не получает фокус.

Чтобы скрыть окно, задайте для свойства visible значение false . Скрывание окна подавляет отображение как самого окна, так и соответствующих значков панели задач, а также, в Mac OS X, входа в меню Windows.

При изменении видимости окна видимость всех остальных окон, также изменяется. Например, если окно было скрыто, все принадлежащие ему окна также скрываются.

Примечание. В 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()

Перемещает окно на передний план (при этом окно становится видимым и получает фокус).

Примечание. Если окно скрыто ( visible имеет значение false ) или свернуто, то методы определения порядка отображения не действуют.

В операционной системе Linux различные диспетчеры окон реализуют различные правила в отношении порядка отображения окон:

  • В некоторых таких диспетчерах окна служебных программ всегда отображаются поверх нормальных окон.

  • В некоторых диспетчерах окон полноэкранные окна, в которых для свойства alwaysInFront установлено значение true , всегда отображаются поверх других окон, которые также имеют в свойстве alwaysInFront значение true .

Закрытие окна

Чтобы закрыть окно, используйте метод NativeWindow.close() .

При закрытии окна выгружается его содержимое, но если другие объекты содержат ссылку на это содержимое, такие объекты содержимого не будут разрушены. Метод NativeWindow.close() выполняется асинхронно, в процессе закрытия приложение, содержащееся в окне, продолжает работать. Метод close отправляет событие close по завершении операции закрытия. Объект NativeWindow остается технически действующим, но при попытке получить доступ к большинству свойств и методов при закрытом окне выдается ошибка IllegalOperationError. Закрытое окно нельзя снова открыть. Чтобы проверить, закрыто ли окно, нужно обратиться к свойству closed окна. Если требуется просто скрыть окно, установите свойство NativeWindow.visible на значение false .

Если свойство Nativeapplication.autoExit имеет значение true , которое является значением по умолчанию, то приложение закрывается при закрытии последнего окна.

Все окна, которые имеют владельца, закрываются при закрытии окна-владельца. Подчиненные окна не отправляют событие closing и, соответственно, не могут предотвратить закрытие. Отправляется событие закрытия.

Разрешение отмены операций с окном

Если окно использует системный Chrome, действия с окном, совершаемые пользователем, можно отменить, прослушав и отменив поведение по умолчанию соответствующих событий. Например, при нажатии пользователем кнопки закрытия на системном Chrome отправляется событие closing . Если какой-либо зарегистрированный прослушиватель вызывает метод preventDefault() события, окно не закрывается.

Если окно не использует системный Chrome, перед изменением уведомляющие об этих изменениях события не отправляются автоматически. Следовательно, при вызове методов для закрытия окна, изменения состояния окна или при задании свойств границ окна такое изменение невозможно отменить. Для уведомления компонентов приложения о предстоящих изменениях окна логикой приложения может быть предусмотрена отправка соответствующего уведомляющего события при помощи метода dispatchEvent() окна.

Например, следующая логика реализует отменяемый обработчик событий, вызванных кнопкой закрытия окна:

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

Метод dispatchEvent() возвращает false , если прослушиватель вызывает метод события preventDefault() . Однако этот метод может возвращать значение false и по другим причинам, поэтому рекомендуется использовать метод isDefaultPrevented() явным образом, чтобы проверить, действительно ли отменяется изменение.

Разворачивание, сворачивание и восстановление окна

Чтобы развернуть окно, используйте метод NativeWindow maximize() .

myWindow.maximize(); 

Чтобы свернуть окно, используйте метод NativeWindow minimize() .

myWindow.minimize(); 

Чтобы восстановить окно (т. е. восстановить его размер до сворачивания или разворачивания), используйте метод NativeWindow restore() .

myWindow.restore(); 

Окно, которое имеет владельца, сворачивается и восстанавливается при минимизации и восстановлении окна-владельца. При сворачивании подчиненное окно не отправляет никаких событий, так как сворачивается его владелец.

Примечание. Поведение при разворачивании окна AIR отличается от подобного стандартного поведения в Mac OS X. Вместо переключения между «стандартным» размером, определенным приложением, и последним размером, заданным пользователем, окна AIR переключаются между размером, который был последним задан приложением или пользователем, и общей площадью экрана, доступной для использования.

В операционной системе Linux различные диспетчеры окон реализуют различные правила в отношении установки состояния отображения окон:

  • В некоторых диспетчерах окон нельзя развернуть до максимального размера окна служебных программ.

  • Если для окна задан максимальный размер, то некоторые окна не позволяют окну развернуться до максимального размера. Некоторые другие диспетчеры окон устанавливают максимальное состояние отображения, но не изменяют размер окна. В любом из случаев событие изменения состояния отображения отправляться не будет.

  • Некоторые диспетчеры окон не учитывают параметры окон maximizable или minimizable .

Примечание. В Linux свойства окна изменяются асинхронно. Если состояние отображения изменяется в одной строке программы, а значение считывается в другой строке, считываемое значение будет соответствовать старому значению. На всех платформах объект NativeWindow отправляет событие displayStateChange при изменении состояния отображения. Если необходимо выполнить какое-либо действие в зависимости от нового состояния, для этого всегда следует использовать обработчик событий displayStateChange . См. раздел « Прослушивание событий окна ».

Пример: сворачивание, разворачивание, восстановление и закрытие окна

Следующее небольшое MXML-приложение иллюстрирует методы 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>

Следующий пример сценария ActionScript для Flash создает четыре гипертекстовых поля, инициирующих методы 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(); 
        } 
    } 
}

Изменение размера и перемещение окна

Если окно использует системный Chrome, то Chrome предоставляет элементы управления изменением размера окна и его перемещением на рабочем столе. Если окно не использует системный Chrome, необходимо добавить собственные элементы управления, при помощи которых пользователь может изменять размер окна и перемещать его.

Примечание. Для изменения размера или перемещения окна необходимо сначала получить ссылку на экземпляр NativeWindow. Сведения о том, как получить ссылку на окно, см. в разделе « Получение экземпляра NativeWindow ».

Изменение размера окна

Чтобы позволить пользователю интерактивно изменять размер окна, используйте метод startResize() класса NativeWindow. Когда этот метод вызывается событием mouseDown , операция изменения размера осуществляется при помощи мыши и завершается при получении операционной системой события mouseUp . При вызове метода startResize() ему передается аргумент, задающий край или угол, от которого осуществляется изменение.

Чтобы установить размер окна программно, установите желаемые размеры для свойств окна: width , height или bounds . При установке границ размер и позиция окна также могут одновременно измениться. Но порядок, в котором произойдут изменения, не гарантирован. Некоторые диспетчеры окон Linux не позволяют окнам расширяться за пределы экрана рабочего стола. В этих случаях размер окон может быть ограничен порядком, в котором устанавливались свойства. Хотя их совокупный эффект мог бы привести к допустимому изменению окна. Например, если изменяется одновременно высота и положение по оси Y окна в нижней части экрана, то изменение полной высоты может не произойти в том случае, когда изменение высоты было выполнено до изменения положения по оси Y.

Примечание. В Linux свойства окна изменяются асинхронно. Если размер окна изменяется в одной строке программы, а размеры считываются в следующей строке, считанные значения будут соответствовать старым настройкам. На всех платформах объект NativeWindow отправляет событие resize при изменении размера окна. Если необходимо выполнить какое-либо действие, например размещение элементов управления в окне, в зависимости от нового размера или состояния окна, для этого всегда необходимо использовать обработчик событий resize . См. раздел « Прослушивание событий окна ».

Режим масштабирования рабочей области определяет поведение рабочей области окна и его содержимого при изменении размера окна. Следует иметь в виду, что режимы масштабирования рабочей области предназначены для работы, например, в веб-обозревателе, когда приложение не может управлять размером и пропорциями области отображения. В общем, наилучшие результаты достигаются при установке свойства scaleMode на значение StageScaleMode.NO_SCALE . Если требуется масштабирование содержимого окна, можно задать параметры scaleX и scaleY содержимого в ответ на изменение границ окна.

Перемещение окна

Чтобы переместить окно, не меняя его размера, используйте метод NativeWindow startMove() . Как и в случае с методом startResize() , при вызове метода startMove() событием mouseDown перемещение осуществляется при помощи мыши и завершается при получении операционной системой события mouseUp .

Дополнительные сведения о методах startResize() и startMove() см. в cправочнике ActionScript® 3.0 для платформы Adobe® Flash® Platform .

Чтобы переместить окно в программном коде, задайте для свойств x , y или bounds окна необходимое расположение. При установке границ размер и расположение окна также могут одновременно измениться.

Примечание. В 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(); 
        } 
    } 
}