четверг, февраля 21, 2008

Внутренности Flex Framework. Обработка клавиатуры/фокуса. Flex

Продолжаем знакомиться с "внутренностями" Flex.
Статья посвящается обработке клавиатуры и фокуса. Если с клавиатурой всё ясно, то про фокус можно сказать, что речь идет не о фокусах и трюках, а о понятии активности или готовности в данный момент времени какого-либо элемента интерфейса принимать события от клавиатуры.
Всё в чём я сомневаюсь, буду помечать знаком (#?) где #- ID сомнения (для последующего комментирования).

Обработка клавиатуры/фокуса


  • В Flash Player предусмотренны свойства, методы и события для обработки клавиатуры и фокуса. Однако он не имеет встроенных средств, реализующих:
    - составные интерактивные элементы
    - модальность
  • Flex берет на себя (или перекрывает) большую часть возможностей Flash Player по обработке клавиатуры/фокуса
  • Flex добавляет новые интерфейсы и свойства для обработки клавиатуры/фокуса
    - интерфейс IFocusManagerComponent
    - свойство focusEnabled
  • UIComponent обладает всеми свойствами IFocusManagerComponent но не реализует его. Это нужно для того, чтобы можно было разделить компоненты на интерактивные (например, TextInput, DataGrid) и не интерактивные (такие как Label, ProgressBar)

Обработка клавиатуры/фокуса. Основы

  • В обработке клавиатуры/фокуса нет ничего сложного:
    - “implements IFocusManagerComponent”
    - UIComponent.keyDownHandler

public class RandomWalk implements IFocusManagerComponent {
override protected function keyDownHandler(event:KeyboardEvent):void {
switch (event.keyCode) {
case Key.DOWN:
}

  • Если компонент не реализует интерфейс IFocusManagerComponent, то его свойства, относящиеся к обработке фокуса, не имеют никакого действия.
    - Компоненты-контейнеры должны контролировать свое свойство tabChildren (контейнер может не реализовывать интерфейс IFocusManagerComponent, но это свойство позволит обрабатывать изменение фокуса по клавише TAB у вложенных в него объектов)
  • Свойство focusEnabled компонента устанавливает, будет ли FocusManager обрабатывать другие свойства, связанные с фокусом для этого компонента.
    - Используется для выключения обработки фокуса вложенных компонентов, а также для обозначения составных компонентов
  • Свойство tabEnabled компонента устанавливает, будет ли FocusManager, при нажатии клавиши TAB, передавать фокус этому компоненту.
    - при этом необходимо, чтобы у всех компонентов-контейнеров, в которые данный компонент вложен), свойство tabChildren==true
  • Свойство mouseFocusEnabled компонента устанавливает, будет ли FocusManager передавать фокус этому компоненту при клике на него мышью.
    - Если false, то проверяется свойство mouseFocusEnabled компонентов-родителей.

Обработка клавиатуры/фокуса. Композиция

  • Большинство компонентов не являются составными (не используют композицию):
    - Button
    - CheckBox
    - ButtonBar! (3?)
  • У составных компонентов может быть несколько внутренних компонентов с реализацией IFocusManagerComponent.
    Кроме того, составные компоненты могут генерировать внутренние компоненты IFocusManagerComponent динамически.
    При нажатии клавиши TAB, осуществляется навигация между внутренними компонентами IFocusManagerComponent.
    - Например, составными компонентами являются редакторы элементов DataGrid/List/Tree
  • Некоторые компоненты, с точки зрения FocusManager, действительно являются контейнерами.
    - Slider является контейнером бегунков, способных обрабатывать фокус

Обработка клавиатуры/фокуса. Композиция. Slider

  • Не реализует IFocusManagerComponent
  • Устанавливает tabChildren = true
  • Вложенные компоненты - бегунки - реализуют IFocusManagerComponent
  • Предполагается, что легче все же реализовать IFocusManagerComponent чем использовать композицию, и, вероятно, в будущем будет что-то переработано и диалоги tabIndex во FlexBuilder не будут поддерживать такую конфигурацию.(4?)

public class Slider {
public function Slider() {
tabChildren = true;
}
}

public class SliderThumb implements
IFocusManagerComponent


Обработка клавиатуры/фокуса.Реализация композиции

  • Реализовать IFocusManagerComponent
  • В focusInHandler, подписаться на прослушивание события "keyFocusChange"
  • В keyFocusChangeHandler:
    - вызывать preventDefault(), чтобы focusManager не обрабатывал это событие
    - обработать нажатие клавиши TAB и установить фокус внутренним компонентам

public class DataGrid implements IFocusManagerComponent {

override protected function focusInHandler(event:FocusEvent):void {
addEventListener(“keyFocusChange”, keyFocusChangeHandler);
}

protected function keyFocusChangeHandler(event:FocusEvent):void {
event.preventDefault();
itemEditor.setFocus();
}

Обработка клавиатуры/фокуса. Подведение итогов

  • Почти все компоненты, с точки зрения FocusManager были реализованы без композиции.
  • Исключение составляют:
    - Slider
    - List/Tree
    - DataGrid
  • Вероятно, большинство ваших компонентов также не будет иметь дела с композицией.

В статье, у меня возникло одно непонимание - (4?) связанное с композицией Slider. Поэтому фразы "Easier to implement than composites" и "We will probably re-implement as composite in future..." я выразил своими словами. Возможно, я ошибаюсь.

1 комментарий:

Igor Zenkin комментирует...

Есть платное решение проблемы с фокусом при загрузке Flex приложения для всех браузеров (фокус на login), внутри описание и исходники. Использует JavaScript. Сам лично проверял на IE, Chrome и Mozilla. Табом можно переходить по форме. Все корректно работает. http://www.oplata.info/asp/pay_wm.asp?id_d=1609239&ai=324445