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

False. 0.

true);

}

После выполнения предыдущего кода единственной ссылкой на анонимную функцию в программе является ссылка, хранящаяся в экземпляре Stage. Поскольку анонимная функция была зарегистрирована с использованием параметра использоватьСлабуюСсылку, для которого было установлено значение true, она сразу же становится пригодной для сборки мусора. Таким образом, сборщик мусора по своему усмотрению может впоследствии автоматически исключить анонимную функцию из списка приемников экземпляра Stage и удалить ее из памяти.

Безусловно, тот факт, что анонимная функция пригодна для сборки мусора, совершенно не означает, что она будет удалена из памяти. На самом деле в случае с предыдущим простым примером, функция, скорее всего, не будет удалена из памяти, поскольку объем используемой приложением памяти недостаточен для запуска механизма сборки мусора. В результате функция будет продолжать выполняться при получении события MouseEvent. MOUSE_MOVE экземпляром Stage, хотя теоретически она может быть удалена из памяти в любой момент времени. Из этого следует, что вообще не следует полагаться на параметр исполь — зоватьСлабуюСсылку как на способ автоматического удаления приемников событий. Наилучшее решение — просто избегать появления заброшенных приемников событий.

*^ | Если вы регистрируете приемник события в каком-либо объекте, убедитесь, что ваша м& d m программа с течением времени также отменяет регистрацию этого приемника.

До сих пор в этой главе мы работали исключительно с предопределенными событиями языка ActionScript. Теперь рассмотрим процесс создания в программе своих собственных пользовательских событий.

Пользовательские события

Чтобы выполнить диспетчеризацию нового пользовательского события в языке ActionScript, достаточно расширить класс EventDispatcher, присвоить новому событию имя и вызвать метод экземпляра dispatchEvent ( ) класса EventDispatcher. Для изучения процесса создания пользовательских событий в программе мы рассмотрим два примера: в первом событие создается для игры, а во втором — для элемента пользовательского интерфейса.

‘ * . I Если вы хотите сделать получателем события экземпляр класса, который уже рас-м$4г« ширяет другой класс, используйте композиционный подход, рассмотренный в гл. 9: Яу непосредственно реализуйте интерфейс IEventDispatcher и используйте методы класса EventDispatcher не через наследование, а через композицию.

Пользовательское событие «gameOver»

Предположим, что мы создаем универсальный каркас для разработки видеоигр. Каркас включает в себя следующие два класса: класс Game, выполняющий основные функции, необходимые для любой видеоигры, и класс Console, который представляет панель для запуска новых игр. Каждый раз при запуске новой игры класс Console создает объект класса Game. Любой экземпляр класса Game, создаваемый классом Console, является получателем пользовательского события «gameOver», которое возникает после окончания игры.

Чтобы объекты класса Game могли выступать в роли получателей событий, класс Game расширяет класс EventDispatcher, как показано в следующем коде:

package { import flash. events.*;

public class Game extends EventDispatcher { }

}

Кроме того, в классе Game определена константа Game. GAME_OVER, значением которой является имя пользовательского события: «gameOver». По соглашению имена констант событий записываются полностью прописными буквами, а слова разделяются знаком подчеркивания, например: GAME_OVER. Константы пользовательских событий обычно определяются либо в классе получателя события (в данном случае в классе Game), либо, если используется подкласс класса Event, в этом подклассе (как показано в нашем следующем примере с элементом пользовательского интерфейса). Поскольку в нашем текущем примере подклассы класса Event не используются, определим константу для события «gameOver» в классе Game, как показано в следующем коде:

package { import flash. events.*;

public class Game extends EventDispatcher { public static const GAME OVER:String = «gameOver»;

}

}

Когда игра завершается, объект Game вызывает метод endGame ( ), который возвращает игровую среду в исходное состояние, что позволит начать новую игру. Вот код метода endGame ( ):

package { import flash. events.*;

public class Game extends EventDispatcher { public static const GAME_0VER:String = «gameOver»;

private function endGame ( ):void { // Выполнение действий для завершения игры (код не показан)

}

}

}

Когда все действия, завершающие игру, выполнены, метод endGame ( ) использует метод dispatchEvent ( ), чтобы приступить к диспетчеризации события Game. GAME_OVER, сигнализирующего об окончании игры:

package { import flash. events.*;

public class Game extends EventDispatcher { public static const GAME_0VER:String = «gameOver»;

private function endGame ( ):void { // Выполнение действий для завершения игры // (код не показан)

// …после чего просим среду Flash выполнить

// диспетчеризацию события, обозначающего окончание игры

dispatchEvent(new Event(Game. GAME_OVER));

}

}

}

Обратите внимание, что, поскольку метод dispatchEvent ( ) вызывается над

объектом Game, этот объект и является получателем события.

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

_

I Объект, над которым вызывается метод dispatchEvent(), является получателем собы-| тия.

Метод dispatchEvent ( ), продемонстрированный в предыдущем коде, принимает один параметр — объект Event, предоставляющий событие для диспетчеризации. Сам конструктор класса Event принимает три параметра — тип, всплывающее и отменяемое, как показано в следующем обобщенном коде:

Event(тип, всплывающее, отменяемое)

Тем не менее в большинстве случаев требуется только первый аргумент — тип; он определяет строковое имя события (в нашем случае Game. GAME OVER). Параметр всплывающее используется только в тех случаях, когда получателем события является отображаемый объект; этот параметр обозначает присутствие (true) или отсутствие (false) всплывающей фазы в цепочке диспетчеризации событий (дополнительную информацию можно найти в разд. «Пользовательские события и цепочка диспетчеризации события» гл. 21). Параметр отменяемое применяется для создания пользовательских событий с избегаемым стандартным поведением (этот вопрос рассматривается далее в подразд. «Отмена стандартного поведения для пользовательских событий» разд. «Пользовательские события»).

Чтобы зарегистрировать приемник события для нашего пользовательского события Game. GAME OVER, как и при регистрации приемника для предопределенного события, используется метод addEventListener ( ). Предположим, что по окончании игры мы хотим, чтобы класс Console выводил окно, позволяющее пользователю вернуться к панели запуска или снова сыграть в выбранную игру. Определить момент окончания игры в классе Console позволит регистрация приемника для событий Game. GAME_OVER, как показано в следующем коде:

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

public class Console extends Sprite {

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

public function Console ( ) { var game:Game = new Game( );

game. addEventLi stener(Game. GAME_0VER. gameOverLi stener);

private function gameOverListener (e:Event):void { traceCThe game has ended!»);

// Отображает пользовательский интерфейс «back to console» // (код не показан)

}

Обратите внимание, что тип данных событийного объекта, передаваемого в метод gameOverListener ( ), соответствует типу данных событийного объекта, изначально передаваемого в метод dispatchEvent ( ) внутри метода экземпляра endGame ( ) класса Game (как показано в предыдущем коде).

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

___«j

При создании приемника для пользовательского события указывайте тип данных параметра приемника в соответствии с типом данных событийного объекта, изначально передаваемого в метод dispatchEvent().

В листинге 12.4 полностью показан код для нашего пользовательского события Game. GAME_OVER, который также содержит таймер, вызывающий метод

endGame ( ), имитируя окончание реальной игры (подробную информацию по классу Timer можно найти в справочнике по языку ActionScript корпорации Adobe).

Листинг 12.4. Пользовательское событие «gameOver»

// Класс Game (получатель события) package { import flash. events.*;

import flash. utils.*; // Требуется для класса Timer

public class Game extends EventDispatcher { public static const GAME_0VER:String = «gameOver»;

public function Game ( ) { // Завершает игру спустя одну секунду var timer:Timer = new TimerdOOO. 1); timer. addEventListener(TimerEvent. TIMER. timerListener); timer. start( );

// Вложенная функция, которая выполняется через одну секунду // после создания данного объекта function timerListener (e:TimerEvent):void { endGame( );

}

}

private function endGame ( ):void { // Выполнение действий для завершения игры (код не показан)

// …после чего просим среду Flash // выполнить диспетчеризацию события. // обозначающего окончание игры di spatchEvent(new Event(Game. GAME_0VER));

}

}

}

// Класс Console (регистрирует приемник для события) package {

import flash. display.*;

import flash. events.*;

public class Console extends Sprite { // Конструктор

public function Console ( ) { var game:Game = new Game( );

game. addEventListener(Game. GAME_0VER. gameOverListener);

}

private function gameOverListener (e:Event):void { traceCThe game has ended!»);

// Отображает пользовательский интерфейс «back to console» (код не показан)

}

}

}

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

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

Пользовательское событие «toggle»

Предположим, что мы создаем кнопку-переключатель, которая может быть использована в пользовательском интерфейсе. Она может принимать два положения — включения и выключения. Наша кнопка-переключатель представлена классом ToggleSwitch. Всякий раз, когда кнопка включается или выключается, мы инициируем диспетчеризацию пользовательского события с именем «toggle».

В предыдущем разделе событийный объект для нашего пользовательского события Game. GAME OVER представлял собой экземпляр внутреннего класса Event. На этот раз наше пользовательское событие будет представлено своим собственным классом Toggle Event. Этот класс выполняет две следующие функции:

? определяет константу для события toggle (ToggleEvent. TOGGLE);

? задает переменную i sOn, которая будет использоваться приемниками для определения состояния объекта получателя ToggleSwitch.

Далее представлен код класса ToggleEvent. Обратите внимание, что каждый пользовательский подкласс класса Event должен переопределять методы clone ( ) и toString ( ), предоставляя версии методов, которые учитывают все пользовательские переменные данного подкласса (например, isOn).

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

package { import flash. events.*;

// Класс, представляющий пользовательское событие «toggle» public class ToggleEvent extends Event {

// Константа для типа события «toggle»

public static const TOGGLE;String = «toggle»;

// Обозначает, включен или выключен переключатель public var isOn:Boolean;

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

public function ToggleEvent (type:String.

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

Bubbles;Boolean = false.

cancel able:Boolean = false.

isOn:Boolean = false) { // Передаем параметры конструктора в конструктор суперкласса super(type. bubbles, cancelable);

// Запоминаем состояние переключателя, которое может быть использовано // в приемниках события ToggleEvent. TOGGLE this. isOn = isOn;

}

// Любой класс пользовательского события должен переопределить // метод clone( )

public override function clone( ):Event { return new ToggleEvent(type. bubbles, cancelable. isOn);

}

// Любой класс пользовательского события должен переопределить // метод toString( ). Обратите внимание, что «eventPhase» — это // переменная экземпляра, имеющая отношение к цепочке диспетчеризации // событий (гл. 21).

public override function toString( ):String { return formatToString(«ToggleEvent». «type», «bubbles».

«cancelable». «eventPhase». «isOn»);

}

}

}

Теперь перейдем к классу ToggleSwitch, который представляет кнопку-переключатель. Единственный метод toggle ( ) класса ToggleSwitch изменяет состояние кнопки-переключателя, а затем выполняет диспетчеризацию события ToggleEvent. TOGGLE, которое обозначает изменение состояния переключателя. Следующий код демонстрирует класс ToggleSwitch. Обратите внимание, что класс ToggleSwitch расширяет класс Sprite, предоставляющий возможности для отображения объекта на экране. Кроме того, класс Sprite, являясь потомком класса EventDispatcher, предоставляет необходимую функциональность для диспетчеризации событий:

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

// Представляет простой элемент-переключатель public class ToggleSwitch extends Sprite {

// Запоминает состояние переключателя

private var isOn:Boolean;

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

public function ToggleSwitch ( ) { // По умолчанию переключатель выключен isOn = false;

}

// Включает переключатель, если он был выключен, или // выключает его

public function toggle ( ):void { // Изменяет состояние переключателя isOn = MsOn;

// просим среду Flash выполнить диспетчеризацию // события ToggleEvent. TOGGLE, получателем которого // является данный объект ToggleSwitch dispatchEvent(new ToggleEvent(ToggleEvent. TOGGLE,

true.

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

False.

isOn));

}

}

}

Чтобы продемонстрировать использование события ToggleEvent. TOGGLE, создадим простой класс SomeApp. Этот класс определяет метод toggleListener ( ) и регистрирует его в объекте ToggleSwitch для событий ToggleEvent. TOGGLE. Кроме того, для демонстрационных целей класс SomeApp программным путем включает переключатель, вызывая событие ToggleEvent. TOGGLE.

package { import flash. display.*;

// Простое приложение, демонстрирующее применение // пользовательского события ToggleEvent. TOGGLE public class SomeApp extends Sprite { // Конструктор

public function SomeApp ( ) { // Создание объекта ToggleSwitch var toggleSwitch:ToggleSwitch = new ToggleSwitch( ); // Регистрация приемника для событий ToggleEvent. TOGGLE toggleSwi tch. addEventLi stener(ToggleEvent. TOGGLE.

toggleListener);

// Изменяем состояние переключателя (обычно состояние // изменяется пользователем, но для демонстрационных целей // мы изменяем состояние программным путем) toggleSwitch. toggle( );

}

// Приемник выполняется каждый раз при возникновении события // ToggleEvent. TOGGLE

private function toggleListener (e:ToggleEvent):void { if (e. isOn) {

traceCThe ToggleSwitch is now on.»); } else {

trace(«The ToggleSwitch is now off.»);

}

}

}

}

Теперь, когда мы приобрели опыт создания пользовательских событий, рассмотрим более сложный сценарий: пользовательское событие со стандартным поведением.

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

Отмена стандартного поведения для пользовательских событий

В предыдущем разделе рассказывалось, что некоторые предопределенные события характеризуются стандартным поведением. Например, стандартное поведение события TextEvent. TEXT INPUT заключается в добавлении текста в текстовое поле. Мы также знаем, что для предопределенных событий, которые относятся к категории отменяемых, избежать стандартного поведения можно с помощью метода экземпляра preventDefault ( ) класса Event.

Кроме того, пользовательские события могут характеризоваться определенным стандартным поведением, избежать которого можно также с помощью метода preventDefault ( ). Стандартное поведение пользовательского события полностью определяется и реализуется в программе. Общий подход, применяемый для создания событий с отменяемым стандартным поведением, заключается в следующем.

1. На этапе диспетчеризации события создать событийный объект, представляющий событие, передав в качестве параметра отменяемое конструктора класса Event значение true.

2. Использовать метод dispatchEvent ( ) для диспетчеризации события.

3. После завершения метода dispatchEvent ( ) использовать метод экземпляра isDef aultPrevented ( ) класса Event, чтобы определить, запрашивали ли приемники отмену стандартного поведения.

4. Если метод is Default Prevented ( ) событийного объекта вернет значение false, продолжать выполнение действий, относящихся к стандартному поведению; в противном случае не выполнять действий, относящихся к стандартному поведению.

Рассмотрим обобщенный код для создания события с отменяемым стандартным поведением:

// Создание событийного объекта с произвольными значениями для параметров // тип и всплывающее. Для параметра отменяемое (третий параметр) указывается // значение true.

var e:Event = new Event(7″*f/7. всплывающее, true);

// Диспетчеризация события dispatchEvent(e);

// Проверить, запрашивали ли приемники отмену стандартного поведения.

// Если приемники не вызывали метод preventDefault( )____

if (!e. isDefaultPrevented( )) {

// …выполняем действия, относящиеся к стандартному поведению } .

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

Рассмотрим описанные шаги на примере с кнопкой-переключателем. Предположим, мы используем нашу кнопку-переключатель в приложении с панелью управления, которое назначает различные привилегии своим пользователям в зависимости от их статуса. Пользователи-«гости» могут использовать только некоторые

кнопки на панели, в то время как пользователям-«администраторам» доступны все кнопки.

Для реализации различных уровней доступа в приложении мы определяем новый тип события кнопки-переключателя: ToggleEvent. TOGGLE_ATTEMPT. Это событие возникает всякий раз, когда пользователь пытается включить или выключить кнопку-переключатель. Стандартным поведением, характеризующим событие ToggleEvent. TOGGLE_ATTEMPT, является изменение состояния переключателя.

Для упрощения будем считать, что кнопку-переключатель можно включить или выключить только щелчком кнопки мыши (не используя клавиатуру). Всякий раз, когда пользователь щелкает на кнопке-переключателе, выполняется диспетчеризация события ToggleEvent. TOGGLE_ATTEMPT. Затем, если никакой приемник не отменяет стандартного поведения, мы изменяем состояние переключателя. Рассмотрим соответствующий код:

private function clickListener (e:MouseEvent):void { // Пользователь попытался включить или выключить переключатель, поэтому // просим среду Flash выполнить диспетчеризацию события // ToggleEvent. TOGGLE_ATTEMPT. получателем которого является данный объект // ToggleSwitch. Сначала создадим событийный объект… var toggleEvent:ToggleEvent =

new ToggleEvent(ToggleEvent. TOGGLE_ATTEMPT. true, true);

// … затем отправляем запрос на диспетчеризацию события dispatchEvent(toggleEvent);

// Диспетчеризация события Toggl eEvent. TOGGLE_ATTEMPT завершена. // Если никакой приемник не отменил стандартное поведение события… if (ItoggleEvent. isDefaultPrevented( )) {

// …изменяем состояние переключателя

toggle( );

}

}

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

// Приемник выполняется всякий раз. когда возникает событие // ToggleEvent. TOGGLE_ATTEMPT

private function toggleAttemptListener (e:ToggleEvent):void { // Если пользователь является «гостем»… if (userType == UserType. GUEST) {

// …запретить изменение состояния переключателя

e. preventDefaultC );

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

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

Листинг 12.5. Классы приложения с панелью управления

// Класс ToggleEvent package { import flash. events.*;

// Класс, представляющий пользовательское событие «toggle» public class ToggleEvent extends Event {

// Константа для типа события «toggle»

public static const TOGGLE:String = «toggle»;

// Константа для типа события «toggleAttempt»

public static const TOGGLE_ATTEMPT:String = «toggleAttempt»;

// Обозначает текущее состояние переключателя -// включен или выключен public var isOn:Boolean;

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

public function ToggleEvent (type:String.

bubbles’.Boolean = false.

cancelable:Boolean = false.

isOn:Boolean = false) { // Передаем параметры конструктора в конструктор суперкласса super(type, bubbles, cancelable);

// Запоминаем состояние переключателя, которое может быть использовано // в приемниках события ToggleEvent. TOGGLE this. isOn = isOn;

}

// Любой класс пользовательского события должен переопределить // метод clone( )

public override function clone( )’.Event { return new ToggleEvent(type, bubbles, cancelable. isOn);

}

// Любой класс пользовательского события должен переопределить // метод toString( )

public override function toString( ):String { return formatToString(«ToggleEvent». «type», «bubbles».

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

«cancelable». «eventPhase». «isOn»);

}

}

// Класс ToggleSwitch package {

import flash. display.*; import flash. events.*;

// Представляет простую кнопку-переключатель со стандартным поведением public class ToggleSwitch extends Sprite {

// Запоминает состояние переключателя.

private var isOn:Boolean;

// Содержит графическое изображение кнопки-переключателя private var icon.-Sprite;

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

public function ToggleSwitch ( ) { // Создаем объект Sprite, который будет содержать графическое // изображение кнопки-переключателя icon = new Sprite( ); addChild(icon);

// По умолчанию переключатель выключен isOn = false; drawOffState( );

// Регистрируем приемник для получения уведомлений всякий раз.



Полезные ссылки
Случайные записи
  • 09.03.2011">Руководство по actionscript. часть 4, стр. 067
  • 23.01.2011">Руководство по actionscript. часть 1, стр. 086
  • 10.05.2010">Самоучитель по креативному веб-дизайну. Книга 1, стр.85
  • 17.06.2010">Самоучитель по креативному веб-дизайну. Книга 4, стр.2
  • 10.05.2010">Самоучитель по креативному веб-дизайну. Книга 1, стр.86
  • 04.07.2012">Windows Phone 8 может обзавестись клавиатурой нового типа
  • 16.06.2010">Самоучитель по креативному веб-дизайну. Книга 4, стр.19
  • 13.03.2011">Руководство по actionscript. часть 3, стр. 089
  • 10.05.2010">Самоучитель по креативному веб-дизайну. Книга 1, стр.125
  • 08.03.2012">Новый рекорд Skype: 35 млн одновременных пользователей
  • 10.05.2010">Самоучитель по креативному веб-дизайну. Книга 1, стр.87
  • 11.05.2010">Самоучитель по креативному веб-дизайну. Книга 1, стр.37
  • 17.05.2010">Самоучитель по креативному веб-дизайну. Книга 2, стр.117
  • 14.03.2011">Руководство по actionscript. часть 3, стр. 068
  • 11.05.2010">Самоучитель по креативному веб-дизайну. Книга 1, стр.12
Опрос

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

View Results

Loading ... Loading ...