Навигация
Рассмотренный пример из листинга 5.2 раскрыл суть перехода с одного экрана на другой. Как вы заметили, принцип смены экраны довольно прост - достаточно добавить необходимую команду с помощью метода addCommand (), установить обработчик событий для этого экрана и создать код в методе commandAction () , адекватно реагирующий на заданные действия.
Познакомившись с моделью смены экранов и закрепив свои знания на практике, можно переходить к более осмысленной навигации в приложении. В предыдущем примере происходила последовательная смена экранов без возможности возврата либо перехода на необходимый экран. Такая структура хороша для изучения, но абсолютно не годится для серьезного приложения. Телефоны различных марок имеют собственные механизмы перехода, предоставляемые операционной системой или прошивкой мобильного телефона. Механизм, использованный в Java 2 ME для приложений созданных на этом языке, предоставляет не менее мощные, а главное, простые средства для навигации в программе. Самый простой и, как мне кажется, эффективный способ - это использовать автоматически созданное меню при помощи сервиса телефона. Когда вы добавляете к заданному экрану с присоединенным к нему объектом Displayable команды обработки в виде двух подэкранных клавиш, вы имеете всего два видимых варианта клавиш -слева и справа. Как только вы добавите с помощью функции addCommand () более двух команд, сервис телефона автоматически создаст на правой или левой подэкранной клавише телефона (в зависимости от марки производителя), выпадающее меню. При нажатии клавиши, отвечающей за меню, появится меню, отображающее полный список имеющихся команд. На рис. 5.7 изображено контекстное меню, созданное эмулятором телефона среды программирования J2ME Wireless Toolkit 2.1.
Рис. 5.7. Автоматически созданное меню
Задав нужные команды для конкретного объекта Displayable, и создав код их обработки, вы получаете отличный механизм навигации. Но это не единственный способ перехода с экрана на экран. Каждый из четырех классов Form, List, TextBox и Alert имеет свои встроенные средства для создания списков, меню, таблиц, полей, загрузки изображений и так далее. При знакомстве с каждым из классов мы обязательно рассмотрим имеющиеся возможности. А пока давайте разберем механизм автоматического создания меню и обработки имеющихся команд.
Итак, к каждому из задействованных классов нам надо добавить набор команд для перехода на нужный экран и обработать, а точнее, создать код, реагирующий на назначенные команды. Рис. 5.8 живописно изображает и отчасти решает поставленную перед нами задачу.
Теперь сосредоточимся на одном из вариантов программного кода, решающего проблему с навигацией. Первым делом создадим класс, назвав его Navigator.
public class Navigator extends MIDlet implements CommandListener
Рис. 5.8. Схема перехода с экрана на экран
В исходном коде до строк вызова конструктора класса Navigator, добавим объект, содержащий команду Выход.
private Command exitMidlet = new Command("Выход", Command.EXIT, 1);
Потом необходимо создать четыре объекта для каждого из задействованных классов Form, TextBox, List и Alert, Созданные объекты будут отвечать за обработку команд перехода на экран, представленные соответствующими классами.
private Command perexodTextBox = new Command("В TextBox", Command. SCREEN, 2) ; private Command perexodList = new CommandC'B List", Command.SCREEN, 2); private Command perexodAlert = new CommandC'B Alert", Command.SCREEN, 2) ; private Command perexodForm = new CommandC'B Form", Command.SCREEN, 2) ;
Информативные названия всех объектов понятны, но, естественно, выбранные мною названия ни к чему вас не обязывают. Созданные объекты являются объектами класса Command, отвечающего за создание команд, которые в последствии можно определить для каждого из классов Form, TextBox, List и Alert. Позже, в коде мидлета, мы будем задавать соответствующие блоки обработки событий непосредственно в методе commandAction () при помощи оператора if и созданных объектов.
Теперь нам нужно объявить и инициализировать объекты четырех классов Form, TextBox, List и Alert.
private Form my form = new Рогт.("Это объект класса Form") ; private List mylist = new List("Это объект класса List", List.IMPLICIT); private TextBox mytextbox = new TextBox("Это TextBox", "Текст", 256, 0); private Alert myalert = new Alert("Это Alert","Alert исчезнет",null,null); private Display mydisplay;
В конструкторе класса Navigator происходит инициализация объекта
mydisplay. public Navigator() { mydisplay = Display.getDisplay(this); }
Следующая наша задача - это реализация метода startApp (). Сейчас необходимо решить какой из классов будет первым появляться на экране и добавить к нему команды перехода в другие классы, а также команду выхода из приложения. В предыдущем примере первым появлялся класс Form. Его и определим как основной объект, в который попадет пользователь, запускающий приложение.
public void startApp() { myform.addCommand(exitMidlet); myform.addCommand(perexbdTextBox); myform.addCommand(perexodList); myform.addCommand(perexodAlert); myform.setCommandListener(this); mydisplay.setCurrent(myform); }
Последняя строка метода startApp() отображает объект myform на дисплее со всеми имеющимися командами. Как уже говорилось, командам, которым не хватит телефонных клавиш, будет автоматически создано свое собственное меню.
После того как вы попадете в основное окно приложения, которое мы определили для объекта myform, над левой или правой подэкранной клавишей появится команда выхода из приложения и команда Menu. При нажатии на клавишу Menu, на экране телефона появится всплывающее Меню с добавленными ранее командами перехода на экраны, представленные классами TextBox, List и Alert.
Следующей нашей задачей является написание кода для обработки событий созданных команд в методе commandAction (). Код, обрабатывающий команду Выход из приложения, идентичен коду из примера в листинге 5.2 и в большинстве рассматриваемых впоследствии примеров останется таковым. Дальнейшие действия состоят в обработке команды перехода на экран, представленный классом TextBox.
if (с == perexodTextBox) { mytextbox.addCommand(exitMidlet); mytextbox.addCommand(perexodForm); mytextbox.addCommand(perexodList); mytextbox.addCommand(perexodAlert); mytextbox.setCommandListener(this); mydisplay.setCurrent(mytextbox); }
Сразу после того, как пользователь попадет на экран, представленный классам Form, и в контекстном меню выберет команду Перейти в TextBox, произойдет обработка блока команд perexodTextBox. Добавляются все команды к объекту mytextbox, устанавливается обработчик событий и в итоге отображается текущий экран, содержащий все созданные компоненты объекта mytextbox. Точно так же как и на экране с объектом myform существует меню перехода и кнопка выхода.
Обработка событий для объекта mylist происходит с помощью команды perexodList и аналогично рассмотренному коду для объекта mytextbox. С той лишь разницей, что используются соответствующие команды для объекта mylist. В итоге листинг 5.3 связывает все разрозненные фрагменты кода этого подраздела, собирая воедино очень простую и в то же время, мощную программу отличной системы навигации.
/ * * Листинг 5.3 Навигация в приложении */ import javax.microedition.midlet.*; import javax.microedition.Icdui.*; public class Navigator extends MIDlet implements CommandListener { // команда выхода из приложения private Command exitMidlet = new Command("Выход", Command.EXIT, 1); // команда перехода в TextBox private Command perexodTextBox = new Command("B TextBox", Command.SCREEN, 2); // команда перехода в List private Command perexodList = new Command("B List", Command.SCREEN, 2); // команда перехода в Alert private Command perexodAlert = new Command("B Alert", Command.SCREEN, 2); // команда перехода в Form private Command perexodForm= new Command("B Form", Command.SCREEN, 2); // объект класса Form private Form myform = new Form("Это объект класса Form"); // объект класса List private List mylist = new List("Этообъект класса List", List.IMPLICIT); // объект класса TextBox private TextBox mytextbox = new TextBox("Это TextBox", "Текст", 256, 0); // объект класса Alert private Alert myalert = new Alert("Это Alert","Alert исчезнет",null,null); // объект mydisplay представляет экран телефона private Display mydisplay; public Navigator() { mydisplay = Display.getDisplay(this); } public void startApp() { // добавить команды перехода в Form myform.addCommand(exitMidlet); myform.addCommand(perexodTextBox); myform.addCommand(perexodList); myform.addCommand(perexodAlert); У/ установка обработчика событий для Form myform.setCommandListener (this); // отразить текущий дисплей mydisplay.setCurrent(myform); } public void pauseApp() {} public void destroyApp(boolean unconditional) {} public void commandAction(Command c, Displayable d) { // выход из приложения if (с = = exitMidlet) { destroyApp(false); notifyDestroyed(); } // переход в TextBox if (с == perexodTextBox) { mytextbox.addCommand(exitMidlet); mytextbox.addCommand(perexodForm); mytextbox.addCommand(perexodList); mytextbox.addCommand(perexodAlert); mytextbox.setCommandListener(this); mydisplay.setCurrent(mytextbox); } // переход в List if (c == perexodList) { mylist.addCommand(exitMidlet); mylist.addCommand(perexodForm); mylist.addCommand(perexodAlert); mylist.addCommand(perexodTextBox); mylist.setCommandListener(this); mydisplay.setCurrent(mylist); } // переход в Alert if (c == perexodAlert) { mydisplay.setCurrent(myalert); } // переход в Form if (c == perexodForm) mydisplay.setCurrent(myform); } }
В следующей главе будут изучаться классы высокоуровневого интерфейса, с помощью которых создаются списки, группы элементов, текстовые поля и множество других элементов пользовательского интерфейса.