Руководство по actionscript. часть 3, стр. 146

Когда отображаемый объект (или один из его предков) добавляется в список отображения, Flash выполняет диспетчеризацию события Event. ADDED_TO_STAGE, получателем которого является данный объект. С другой стороны, когда отображаемый объект (или один из его предков) удаляется из списка отображения, среда Flash выполняет диспетчеризацию события Event. REMOVED_FROM_STAGE, получателем которого является данный объект.

г*

В отличие от событий Event. ADDED и Event. REMOVED, у событий Event. ADDED_TO_STAGE и Event. REMOVED_FROM_STAGE отсутствует фаза всплытия. Для получения события 3f Event. ADDED_TO_STAGE или Event. REMOVE_FROM_STAGE через предка объекта зарегистрируйте приемник в этом предке для фазы захвата события.

Обобщенный код, который необходим для регистрации приемника события Event. ADDED_TO_STAGE в экземпляре класса DisplayOb j ect, выглядит следующим образом:

отображаемыйОбъект. addEventListener(Event. ADDED_T0_STAGE.

приемникСобытияАс1с1ес1То5Ьаде);

Код, необходимый для приемника события Event. ADDED_TO_STAGE, выглядит таким образом:

private function приемникСобытияАс1с1ес1То5Ьаде (e:Event):void { }

Обобщенный код, который необходим для регистрации приемника события Event. REMOVED_FROM_STAGE в экземпляре класса DisplayObject, выглядит следующим образом:

отображаемыйОбъект. addEventListener(Event. REMOVED_FROM_STAGE,

npHeMHHt Теперь рассмотрим обобщенный код, необходимый для приемника события

Event. REMOVED_FROM_STAGE:

private function npHeMHHKCo6biTHnRemovedFromStage (e:Event):void { }

Отображаемые объекты обычно используют событие Event. ADDED TO STAGE, чтобы убедиться в доступности объекта Stage перед обращением к его методам, переменным или событиям. Предположим, что мы создаем класс CustomMousePointer, который представляет пользовательский указатель мыши. Наш класс CustomMousePointer расширяет класс Sprite, поэтому его экземпляры могут добавляться в список отображения. Мы хотим, чтобы наш класс был зарегистрирован в экземпляре класса Stage для получения событий MouseEvent. MOUSE_EVENT, благодаря чему мы сможем синхронизировать позицию пользовательского указателя мыши с позицией системного указателя мыши.

Руководство по actionscript. часть 3, стр. 147

Однако после создания новый объект CustomMousePointer не находится в списке отображения, поэтому не имеет доступа к экземпляру класса Stage и не может зарегистрироваться для получения события MouseEvent. MOUSE MOVE. Вместо этого объект должен ожидать уведомления о том, что он был добавлен в список отображения (через событие Event. ADDEDTOSTAGE). Как только объект CustomMousePointer будет добавлен в список отображения, его переменная stage будет ссылаться на экземпляр класса Stage и он сможет успешно зарегистрироваться для получения события MouseEvent. MOUSE_MOVE. Следующий код демонстрирует соответствующий фрагмент кода, относящийся к событию Event. ADDED_TO_STAGE, из класса CustomMousePointer. Полный листинг кода класса CustomMousePointer можно найти в подразд. «Определение позиции указателя мыши» разд. «События мыши» гл. 22.

package {

public class CustomMousePointer extends Sprite { public function CustomMousePointer ( ) { // Просим сообщить, когда этот объект будет добавлен // в список отображения

addEventListener(Event. ADDED_TO_STAGE, addedToStageListener);

}

// Вызывается, когда этот объект добавляется в список отображения

private function addedToStageLi stener (e: Event) -.void { // Теперь можно безопасно регистрироваться в экземпляре класса Stage // на получение событий MouseEvent. M0USE_M0VE stage. addEventLi stener(MouseEvent. M0USE_M0VE, mouseMoveLi stener);

}

}

}

Собственные события Event. ADDED_TO_STAGE и Event. REMOVE_FROM_ STAGE. Первая версия приложения Flash Player 9 не содержала ни события Event. ADDED_TO_STAGE, ни события Event. REMOVED_FROM_STAGE. Тем не

менее, воспользовавшись обычным интерфейсом API отображения и проявив немного изобретательности, мы можем вручную определить, что данный объект был добавлен в список отображения или удален из него. Для этого мы должны отслеживать состояние предков данного объекта с помощью событий Event. ADDED и Event. REMOVED.

В листинге 20.8 демонстрируется данный подход. В этом примере пользовательский класс StageDetector следит за отображаемым объектом, чтобы определить, когда он добавляется в список отображения или удаляется из него. Класс StageDetector рассылает пользовательское событие:

? StageDetector. ADDED TO STAGE — когда объект добавляется в список отображения;

? StageDetector. REMOVED_FROM_STAGE — когда объект удаляется из списка отображения.

Руководство по actionscript. часть 3, стр. 148

Вы вполне можете применять пользовательские события ADDED TO STAGE и REMOVED_FROM_STAGE, даже не имея ни малейшего представления о том, как устроен и функционирует класс StageDetector. Однако он позволяет провести интересный обзор методик программирования, относящихся к списку отображения, которые были рассмотрены в этой главе, поэтому посмотрим, как он работает.

В классе StageDetector объект, для которого отслеживаются пользовательские события ADDED_TO_STAGE и REMOVED_FROM_STAGE, присваивается переменной watchedRoot. Рассмотрим общий подход, применяемый в классе StageDetector для определения присутствия объекта watchedOb j ect в списке отображения.

? Нужно отслеживать события Event. ADDED и Event. REMOVED для объекта watchedRoot.

? Когда объект watchedRoot добавляется в объект DisplayOb j ectContainer, проверять, находится ли watchedOb j ect в настоящий момент в списке отображения (он находится в списке отображения, если значение его переменной stage не равно null). Если в настоящий момент объект watchedOb j ect находится в списке отображения, то следует выполнить диспетчеризацию события StageDetector. ADDED_TO_STAGE. Если нет, то приступить к отслеживанию событий Event. ADDED и Event. REMOVED для нового объекта watchedRoot. t

? Когда объект watchedOb j ect есть в списке отображения, если watchedRoot или любой из его потомков удаляется из объекта DisplayOb j ectContainer, проверять, является ли удаленный объект предком watchedOb j ect. Если да, то выполнить диспетчеризацию события StageDetector. REMOVED_FROM_STAGE и приступить к отслеживанию событий Event. ADDED и Event. REMOVED для нового корня иерархии отображения объекта watchedOb j ect.

Теперь рассмотрим код класса StageDetector.

Листинг 20.8. Пользовательские события ADDED_TO_STAGE и REMOVED_FROM_STAGE

package { import flash. display.*: import flash. events.*:

// Наблюдает за указанным отображаемым объектом, чтобы определить,

// когда этот объект добавляется или удаляется из экземпляра класса Stage,

// и рассылает соответствующие пользовательские события

// StageDetector. ADDED_TO_STAGE и StageDetector. REMOVED_FROM_STAGE.

// ИСПОЛЬЗОВАНИЕ:

// var StageDetector:StageDetector = new StageDetector(someDisplayObject); // StageDetector. addEventListener(StageDetector. ADDED_TO_STAGE, // addedToStageListenerFunction);

// stageDetector. addEventLi stener(StageDetector. REMOVED_FROM_STAGE, // removedFromStageListenerFunction);

public class StageDetector extends EventDispatcher { // Событийные константы

public static const ADDED_TO_STAGE:String = «ADDED_TO_STAGEH: public static const REMOVED_FROM_STAGE:String = «REMOVED_FROM_STAGE»;

// Объект, для которого будут генерироваться события ADDЕD_TO_STAGЕ // и REMOVED_FROM_STAGE

private var watchedObject:DisplayObject = null:

// Корень иерархии отображения, содержащей объект watchedObject private var watchedRotit.’D'is’f&layObject = null:

// Флаг, который говорит, находится ли объект watchedObject // в настоящий момент в списке отображения private var onstage:Boolean = false:

// Конструктор

public function StageDetector (objectToWatch:DisplayObject) {

// Приступаем к мониторингу указанного объекта

setWatchedObject(obj ectToWatch); } ‘

// Приступает к мониторингу указанного объекта, чтобы определить,

// добавлен объект в список отображения или удален из него

public function setWatchedObject (objectToWatch:DisplayObject):void {

// Сохраняем отслеживаемый объект

watchedObject = objectToWatch:

// Помечает, находится ли объект watchedObject в настоящий момент // в списке отображения if (watchedObject. stage!= null) { onstage = true:

}

// Находит корень иерархии отображения, содержащей объект

// watchedObject, и регистрируем в найденном объекте приемники

// для событий ADDED/REMOVED. Проверяя, добавлен или удален

// корень объекта watchedObject, мы сможем определить,

// находится объект watchedObject в списке отображения или нет.

Руководство по actionscript. часть 3, стр. 149

SetWatchedRoot(findWatchedObjectRoot( ));

// Возвращает ссылку на отслеживаемый объект public function getWatchedObj ect ( ):DisplayObject { return watchedObject;

}

// Освобождает ресурсы данного объекта StageDetector. Вызываем этот // метод перед уничтожением объекта StageDetector. public function dispose ( ):void {

clearWatchedRoot( );

watchedObject = null;

}

// Обрабатывает события Event. ADDED, получателем которых является // корневой объект иерархии отображения — объекта watchedObject private function addedListener (e:Event):void { // Если текущий объект watchedRoot был добавлен… if (е. eventPhase == EventPhase. AT_TARGET) { // …проверяем, находится ли объект watchedObject в настоящий // момент в списке отображения if (watchedObject. stage!= null) { // Помечаем, что объект watchedObject теперь находится // в списке отображения onStage = true;

// Сообщаем приемникам, что объект watchedObject теперь

// находится в списке отображения

dispatchEvent(new Event(StageDetector. ADDED_TO_STAGE));

}

// Объект watchedRoot был добавлен в другой контейнер, поэтому // сейчас корнем иерархии отображения объекта, содержащей объект // watchedObject, является новый объект. Находим этот новый корень // и регистрируемся в нем для получения событий ADDED и REMOVED. setWatchedRoot(findWatchedObjectRoot( ));

}

}

// Обрабатывает события Event. REMOVED для корневого объекта иерархии // отображения объекта watchedObject private function removedListener (e;Event):void { // Если объект watchedObject находится в списке отображения… if (onStage) { // …проверяем, был ли удален объект watchedObject // или один из его предков var wasRemoved:Boolean = false; var ancestor;DisplayObject = watchedObject; var target;DisplayObject = DisplayObject(e. target); while (ancestor!= null) { if (target == ancestor) { wasRemoved = true; break;

}

ancestor = ancestor. parent;

// Если объект watchedObject или один из его предков был удален… if (wasRemoved) {

// …регистрируемся для получения событий ADDED и REMOVED

// от удаленного объекта (который является новым корнем

// иерархии отображения объекта watchedObject).

Руководство по actionscript. часть 3, стр. 150

SetWatchedRoot(target);

// Помечает, что объект watchedObject больше не находится // в списке отображения onStage = false;

// Сообщаем приемникам, что объект watchedObject был удален // из объекта Stage

dispatchEvent(new Event(StageDetector. REMOVED_FROM_STAGE));

}

}

}

// Возвращает корневой’ объект иерархии отображения, в настоящий момент // содержащий объект watchedObject

private function findWatchedObjectRoot ( );DisplayObject { var watchedObjectRoot:DisplayObject = watchedObject; while (watchedObjectRoot. parent!= null) { watchedObjectRoot = watchedObjectRoot. parent;

}

return watchedObjectRoot;

}

// Начинает отслеживание событий ADDED и REMOVED, получателем // которых является корневой объект иерархии отображения // объекта watchedObject

private function setWatchedRoot (newWatchedRoot.-DisplayObject) :void { clearWatchedRoot( ); watchedRoot = newWatchedRoot; regi sterLi steners(watchedRoot);

}

// Удаляет приемники событий из объекта watchedRoot и ссылку // на объект watchedRoot из данного объекта StageDetector private function clearWatchedRoot ( );void { if (watchedRoot!= null) {

unregi sterLi steners(watchedRoot);

watchedRoot = null;

}

}

// Регистрирует приемники событий ADDED и REMOVED в объекте watchedRoot private function regi sterLi steners (target; DisplayObject)-.void {

target. addEventLi stener(Event. ADDED, addedLi stener);

target. addEventLi stener(Event. REMOVED, removedLi stener);

// Отменяет регистрацию приемников событий ADDED и REMOVED // в объекте watchedRoot

private function unregisterListeners (target:DisplayObject):void { target. removeEventLi stener(Event. ADDED, addedLi stener); target. removeEventLi stener(Event. REMOVED, removedLi stener);

}

}

}

О том, как пользовательские события StageDetector. ADDED_TO_STAGE и Stage. REMOVED_FROM_STAGE применяются в классе CustomMousePointer, будет рассказано в гл. 22.

Руководство по actionscript. часть 3, стр. 151

Мы завершили изучение интерфейса API, связанного с контейнерами. Напоследок рассмотрим одну небольшую, но очень важную тему в программировании экранного вывода: пользовательские графические классы.

Пользовательские графические классы

В этой главе мы нарисовали множество прямоугольников, окружностей и треугольников. Так много, что некоторые из рассмотренных примеров содержали «код с погрешностями»: код повторялся и, как результат, способствовал ошибкам.

Дополнительную информацию о «коде с погрешностями» (общие признаки потенциальных м?. 4 • проблем в коде) можно найти по адресу http.7/xp. c2.com/CodeSmell. html.

4 дк—

Чтобы обеспечить возможность повторного применения и модульность при работе с примитивными фигурами, мы можем перенести повторяющиеся процедуры рисования в пользовательские классы, которые расширяют класс Shape. Начнем с пользовательского класса Rectangle, применив чрезвычайно простой подход, который предоставляет весьма ограниченный набор вариантов контура и заливки и не позволяет изменять прямоугольник после того, как он будет нарисован (мы расширим возможности класса Rectangle в гл. 25). Этот код продемонстрирован в листинге 20.9.

Листинг 20.9. Rectangle — простой подкласс класса Shape

package { import flash. display. Shape:

public class Rectangle extends Shape { public function Rectangle (w:Number,

h:Number,

lineThickness:Number, lineColor:uint, fillColonuint) { graphi cs.1i neStyle(1i neThi ckness, 1i neColor);

graphics. beginFill(fill Col or. 1); graphics. drawRect(0, 0, w, h);

}

}

}

Поскольку класс Rectangle расширяет класс Shape, он наследует переменную graphics класса Shape и может использовать ее для рисования прямоугольника.

Руководство по actionscript. часть 3, стр. 152

Для создания нового экземпляра класса Rectangle применяется следующий знакомый нам код:

var rect:Rectangle = new RectangledOO. 50. 3. OxFFOOOO. OxOOOOFF):

Поскольку класс Shape является потомком DisplayObject, класс Rectangle наследует возможность быть добавленным в список отображения (как и любой другой потомок класса DisplayOb j ect), наподобие следующего кода:

некийКонтейнер. addChi 1 d(rect);

Являясь потомком класса DisplayObject, объект Rectangle может быть позиционирован, повернут и подвергнут другим действиям, как и любой другой отображаемый объект. Например, следующий код устанавливает горизонтальной позиции объекта Rectangle значение 15, а вертикальной — значение 30:

rect. x = 15: rect. у = 30:

Однако развлечения на этом не заканчиваются. Любой класс API отображения может быть расширен. Например, приложение может расширить класс TextField для отображения специализированной текстовой формы. Это демонстрирует код из листинга 20.10, который представляет подкласс класса TextField, создающий текстовый заголовок с возможностью перехода по ссылке.

Листинг 20.10. ClickableHeading — подкласс класса TextField

package { import flash. display.*:

public class ClickableHeading extends TextField { public function ClickableHeading (headText:String. URLString) { html = true:

autoSize = TextFieldAutoSize. LEFT:

htmlText = «» + headText + ««;

border = true:

background = true:

}

}

}

Вот как можно использовать класс ClickableHeading в приложении:

var head.-ClickableHeading = new ClickableHeading(

«Essential ActionScript 3.0″. «http://www. moock. org/eas3″);

addChild(head):

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

Руководство по actionscript. часть 3, стр. 153

Essential ActionScript 3.0 Рис. 20.17. Экземпляр класса ClickableHeading

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

Переходим к цепочке диспетчеризации событий

После прочтения этой главы вы должны чувствовать себя достаточно комфортно, создавая отображаемое содержимое и выводя его на экран. Многие примеры, представленные далее в» книге, опираются на принципы, рассмотренные в этой главе, поэтому у вас появится масса возможностей, чтобы вспомнить пройденный материал и расширить полученные знания. Из следующей главы мы узнаем, как событийная архитектура языка ActionScript 3.0 применяется к объектам в списке отображения.

Руководство по actionscript. часть 4, стр. 001

ГЛАВА 21

События и иерархии отображения

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

Система диспетчеризации событий через иерархию объектов языка ActionScript, о кото-л ч рой пойдет речь в этой главе, основана на спецификации Document Object Model (DOM) За’ Level 3 Events Specification консорциума W3C, доступной по адресу http://www. w3.org/

TR/DOM-Level-3-Events.

Иерархическая диспетчеризация событий

Как мы уже видели в гл. 12, когда среда Flash выполняет диспетчеризацию события, получателем которого является объект, не входящий в состав иерархии отображения, этот получатель будет единственным, кто узнает о возникновении события. Например, когда завершается воспроизведение звукового файла в объекте Sound, среда Flash выполняет диспетчеризацию события Event. COMPLETE, получателем которого выступает соответствующий объект SoundChannel. Этот объект не входит в состав иерархии отображения, поэтому он будет единственным объектом, который узнает о возникновении этого события.

В отличие от этого, когда среда Flash выполняет диспетчеризацию события, получателем которого является объект, входящий в состав иерархии отображения, этот получатель и все его предки в иерархии отображения узнают о возникновении события. Например, если объект Sprite содержит объект TextField и пользователь щелкает кнопкой мыши на втором объекте, то и TextField (получатель события), и Sprite (предок получателя события) узнают о том, что произошел щелчок кнопкой мыши.

Система иерархической диспетчеризации событий языка ActionScript позволяет каждому контейнеру отображаемых объектов регистрировать приемники для обработки событий, получателями которых являются отображаемые объекты-потомки этого контейнера. Например, объект Sprite, представляющий окно, может зарегистрировать приемник, обрабатывающий события о щелчке кнопкой мыши, получателем которых является вложенный элемент управления «кнопка ОК». Или объект Sprite, представляющий форму для авторизации, может зарегистрировать приемник, обрабатывающий события фокуса, получателями которых являются вложенные поля ввода.

Продолжение:

1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,

41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,

77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,

109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,

135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155

Руководство по actionscript. часть 4, стр. 002

Такая централизованная архитектура позволяет сократить объемы повторяющегося кода, особенно реагирующего на события пользовательского ввода. Далее, в разд. «Использование цепочки диспетчеризации события для централизации кода», мы рассмотрим пример, который демонстрирует преимущества централизованной обработки событий. Но для начала познакомимся с основами иерархической диспетчеризации событий и регистрации.

В этой главе термины «предок» и «потомок» в основном используются для обозначения объектов в иерархии отображения, а не суперклассов и подклассов в иерархии наследования. Чтобы избежать путаницы, в этой главе иногда используются неофициальные термины «отображаемый предок» и «отображаемый потомок» для обозначения объектов-предков и объектов-потомков в иерархии отображения.

Фазы диспетчеризации событий

Как уже известно, когда среда Flash выполняет диспетчеризацию события, получателем которого является объект в иерархии отображения, о возникновении события узнает не только данный получатель, но и все его отображаемые предки. Процесс, в результате которого о возникновении события узнают получатель и все его предки, разбивается на три отдельные фазы. На первой фазе процесса диспетчеризации события, называемой фазой захвата, уведомление о возникновении события получают все предки объекта-получателя. Как только все предки объекта-получателя получат уведомление о возникновении события, начинается вторая фаза процесса диспетчеризации события, называемая фазой получения. На этой фазе среда выполнения Flash уведомляет объект-получатель о возникновении события.

Для некоторых типов событий процесс диспетчеризации завершается сразу после окончания фазы получения. Для остальных типов событий процесс диспетчеризации переходит в третью фазу, называемую фазой всплытия. На этой фазе предки объекта-получателя узнают о том, что получатель был успешно уведомлен о возникновении события. События, имеющие фазу всплытия, называются всплывающими] события, не имеющие фазу всплытия, называются невсплывающими.

У четырех типов событий — Event. ACTIVATE, Event. DEACTIVATE, Event. ENTER_FRAME и Event. RENDER — есть только фаза получения. Процесс диспетчеризации всех остальных событий, получателем которых является объект в иерархии отображения, включает фазу захвата и фазу получения. Некоторые типы событий также имеют фазу всплытия.

Порядок, в котором объекты узнают о возникновении события в процессе диспетчеризации, зависит от фазы события. На фазе захвата уведомление предков начинается от корневого объекта иерархии отображения объекта-получателя и, проходя вниз по всем потомкам, завершается на непосредственном родителе объекта-получателя. На фазе захвата уведомление самого получателя не происходит. На фазе всплытия уведомление предков происходит в порядке, обратном порядку на фазе захвата, — начинается от непосредственного родителя объекта-получателя и, проходя вверх, заканчивается на корневом объекте иерархии. Процесс, в результате

которого уведомление о событии передается вниз через предков объекта-получателя (фаза захвата) к объекту-получателю (фаза получения) и обратно через его предков (фаза всплытия), называется цепочкой диспетчеризации события. Когда уведомление о событии проходит по цепочке диспетчеризации события, говорят, что событие передается от объекта к объекту.

Рассмотрим простой пример цепочки диспетчеризации события. Предположим, что экземпляр класса Stage содержит объект Sprite, который, в свою очередь, содержит объект TextField, как показано на рис. 21.1. Видно, что корнем иерархии отображения объекта TextField является экземпляр класса Stage, а непосредственным родителем объекта TextField — объект Sprite.



Полезные ссылки
Случайные записи
  • 06.03.2011">Руководство по actionscript. часть 4, стр. 132
  • 12.03.2011">Руководство по actionscript. часть 3, стр. 126
  • 11.07.2010">Работаем над идеей
  • 10.05.2010">Самоучитель по креативному веб-дизайну. Книга 1, стр.100
  • 12.03.2011">Руководство по actionscript. часть 3, стр. 121
  • 15.07.2012">Англоязычные статьи Wikipedia можно будет комментировать
  • 18.05.2010">Самоучитель по креативному веб-дизайну. Книга 2, стр.88
  • 04.03.2011">Руководство по actionscript. часть 5, стр. 051
  • 25.08.2011">Выбирайте только лучших дизайнеров
  • 07.09.2012">В Facebook запущена компания по переименованию города Хатчинсон в Смолвиль, родину Супермена
  • 06.03.2011">Руководство по actionscript. часть 4, стр. 148
  • 25.02.2011">Руководство по actionscript. часть 6, стр. 094
  • 10.05.2010">Самоучитель по креативному веб-дизайну. Книга 1, стр.69
  • 03.03.2011">Руководство по actionscript. часть 5, стр. 065
  • 19.03.2011">Руководство по actionscript. часть 2, стр. 109
Опрос

Какие цвета вы предпочитаете?

View Results

Loading ... Loading ...