Автор неизвестен - Платформа J2Me
public void commandAction(Command c, Displayable d)
if (c == showAlert)
{
alert = new Alert("Button pressed", «The» + ALERT_LABEL +
" button was pressed", null, AlertType.INFO);) else if (c == sayHi)
alert = new Alert("Button pressed", «The» +
"'Say Hi' button was pressed", null, AlertType.INFO);
}
alert.setTimeout(Alert.FOREVER); display.setCurrent(alert, form);
}
Здесь все еще только один CommandListener на Screen — и может быть только один. Его метод commandAction () вызывается в ответ на нажатие любой клавиши. Но теперь он проверяет контекст уведомления объекта Command и выдает различные уведомления соответственно.
Экранная навигация
Пример HelloWorld2 демонстрирует центральную абстракцию MIDP — Screen. Вы, несомненно, уже обратили внимание, что. можете отображать одновременно только один Displayable — один Screen. Когда приложению необходимо отобразить Alert, ему приходится заменять основной экран.
Причина этой одноэкранной абстракции кроется в ограниченности экранных ресурсов устройства. В отличие от инструментов графических пользовательских интерфейсов для настольных компьютеров, таких, как J2SE Swing toolkit, вы не можете иметь большое количество накладываемых друг на друга окон, всплывающих уведомлений, диалоговых окон и так далее. Хотя внедрение этих абстракций и не невозможно, требования памяти и ЦП на современных мобильных устройствах таковы, что фактически запрещают это. Более того, жидкокристаллические дисплеи с низким разрешением, низким потреблением энергии и маленькой площадью, характерные для большинства мобильных устройств, не приспособлены для этих абстракций. Даже дисплеи «карманных компьютеров» имеют минимально приемлемые характеристики для наложения окон, всплывающих окон и тому подобного. Однако очень вероятно, что примерно через год эти устройства будут иметь значительно большие мощности, порядка 50 МГц и 32 Мб RAM.
Существует простая идиома экранной навигации, связанная с этой абстракцией экранов дисплея. Если вы хотите отобразить новый экран, просто установите, что экран является отображаемым в настоящий момент (current displayable). Чтобы сделать это, вы запрашиваете. объект Display вашего MID-лета на отображение Screen. Вспомните, в главе 2 вы узнали, что каждому MID-лету при запуске присваивается уникальный объект Display реализацией MIDP. Вы никогда не создаете объект Display, но вы можете получить ссылку на него, сделав следующий вызов со ссылкой на ваш MID-лет как на аргумент: Display.getDisplay(midlet);
Затем вы просто делаете вызов метода, показанный далее, с аргументом, который ссылается на Displayable, который вы хотите отобразить:
display.setCurrent(nextDisplayable)
Вы можете найти эти две строчки кода в методе startApp() обеих версий приложения HelloWorld.
Разработка навигации и перемещений в вашем МЮ-лете включает следующие этапы:
1. Создание экранов.
2. Создание команд, которые вам нужны для каждого экрана.
3. Присвоение команд экранам.
Для каждой команды каждого экрана определите следующий экран для отображения результата выполнения каждой команды.
Важным атрибутом успешных приложений MIDP является легкая, интуитивная навигация между окнами. Анализ задач пользователя является темой отдельной книги и лежит за пределами темы данной книги. Самым важным, однако, является умение думать с точки зрения пользователя. Делайте все простым. Не путайте ваших пользователей, прыгая с места на место, так что пользователь не сможет следовать навигации. Слишком легко пользователю потеряться при просмотре на маленьком экране без контекстной привязки ко всему приложению. И никогда не создавайте ваши экраны, приспосабливая их к внутренней организации вашего приложения, его структуре данных, классам и так далее. Наоборот, позвольте дизайну вашего приложения следовать расположению, дизайну, навигации, последовательности экранов и так далее.
Организация команд
Взглянув более внимательно на пример, приведенный в предыдущем разделе, вы можете догадаться, что на самом деле вы не можете контролировать то, где появляется каждая из меток Command на экранных клавишах. Как-никак, я не указывал левую или правую экранную клавишу для размещения обеих Command. Приложение HelloWorld2 добавило клавиши «Alert Me!» и «Say Hi», в таком порядке. Первая появилась на правой экранной клавише, вторая — на левой.
В действительности реализация управляет размещением меток Command на ваших отображаемых объектах Displayable в соответствии с некоторой политикой, зависящей от реализации. Вы можете познакомиться с различными политиками, просмотрев различные эмуляторы в беспроводном инструментарии. Вы сможете увидеть, что эмулятор Motorola размещает клавиши не так, как эмуляторы стандартных черно-белого и цветного телефонов.
Следующая версия нашей программы HelloWorld, HelloWorldS, добавляет третью команду к главному экрану. Вместо того чтобы приводить вновь весь MID-лет целиком, я просто покажу части, которые отличаются от предыдущего примера.
В масштабах класса HelloWorld3 определяет три объекта Command:
/**
Третья версия приложения HelloWorld.
Эта версия встраивается поверх HelloWorld2 с помощью добавления нескольких команд к компоненту Displayable. Здесь демонстрируется, что ComraandListener должен определять, какая из команд была активирована на экране.
Вы также можете видеть, как реализация расставляет команды на экранных клавишах и как она создает меню и упорядочивает команды в меню в соответствии с типом команды.
*/
public class HelloWorld3 extends MIDlet,
{
Command showAlert= new Command("Alert Me!", Command.SCREEN, 1);;
Command sayHi = new Command("Say Hi", Command. SCREEN, I);-;
Command cancel = new Command("Cancel", Command.CANCEL, 1);
public HelloWorld3()
{
super ();
}
.
}
В методе startApp() эти объекты Command добавляются к главному экрану следующим образом:
form.addComraand(showAlert);
form.addCommand(sayHi);
form.addCommand(cancel);
Создание и запуск этой новой версии в эмуляторе J2ME Wireless Toolkit Emulator отражен в главном экране, показанном на рисунке 4.7.
Во-первых, обратите внимание, посмотрев на рисунок 4.7, что вы видите метку «Меню» на правой экранной клавише при запуске этого последнего MID-лета с помощью эмулятора стандартного черно-белого телефона. В программном коде определенно нигде нет определения меню.
Рисунок 4.7. Реализация добавляет экранную клавишу «Меню», когда она обнаруживает более, двух команд, добавленных к текущему Displayable
Устройства имеют только две экранные клавиши, но мы вставили три команды в наш главный экран. Реализация обнаружила это и создала меню, которое содержит вторую, третью и другие команды. На рисунке 4.8 показан дисплей после того, как вы выбрали клавишу «Меню».
Запустите эту последнюю немодифицированную версию с помощью эмулятора Motorola iS5s, и вы увидите, что ключ «Меню» появится на левой экранной клавише, что отражено на рисунке 4.9. В действительности рисунки 4.8 и 4.9 демонстрируют, что конкретное поведение и политика размещения меню зависят от реализации.
Рисунок 4.8. Выбор кнопки «Меню» отображает список элементов в экранном меню
Рисунок 4.9. Размещение меток — команд- зависит от реализации
Упорядочивание команд
Вы, должно быть, удивлены, почему команда «Cancel» (Отмена) была помещена на экранную клавишу, даже несмотря на то, что бна была добавлена на экран последней. Интуитивно вы можете предположить, что она должна добавляться последней в меню. Вы бы предположили, конечно, что клавиша «Alert Me!», которая была добавлена первой, должна быть на экранной клавише.
Объяснение этого очевидного отклонения заключается в том, что команды организуются в соответствии с их типом. Вспомните из предыдущего раздела этой главы, что одной из трех частей информации, которые определяют Command, является тип команды. Класс Command определяет константы, которые представляют собой действующие типы. Вы видели перечисление этих констант в таблице 4.1.
Теперь я добавляю следующие объекты Command в пример HelloWorld3. На уровне классов я определяю следующие новые команды:
…
public class HelloWorid3 extends MIDlet
private Command exit = new Command("Exit", Command.EXIT, 2);
private Command help = new Command ("Help", Command.HELP, 3);
private Command item. = new Command ("Item", Command. ITEM, 4);
private Command ok = new Command("OK", Command.OK, 5);
private Command screen = new Command("Screen", Command.SCREEN, 6);
private Command stop = new Command("Stop", Command.STOP, 7);
…
}
Обратите внимание, что каждая из команд имеет определенный тип. Эти различия дают вам возможность видеть, как реализация размещает команды на экране в соответствии с их типом.
В методе startApp() я добавляю эти новые объекты команд к главному экрану. Новая версия startApp() выглядит таким образом: