Оглавление

Самоучитель по программированию мобильных телефонов

    • Введение
    • Глава 1. Устройство мобильных телефонов
    • Глава 2. Платформа Java 2 Micro Edition
    • Глава 3. Средства разработки мобильных приложений
    • Глава 4. Телефонные эмуляторы
    • Глава 5. Механизм работы приложений Java 2 ME
    • Глава 6. Классы пользовательского интерфейса
    • Глава 7. Программирование графики
    • Глава 8. Техника создания игр
    • Глава 9. Мобильная мультимедиа-библиотека
    • Заключение
    • Приложение 1. Основы языка Java
    • Приложение 2. Справочник по Java 2 Micro Edition


Заключение

Технология Java 2 Micro Edition предоставляет разработчику программного обеспечения широкий спектр хорошо продуманных интерфейсов, классов, методов и констант, на основе которых происходит построение приложений для телефонов, КПК, телевизионных приставок, органайзеров, пейджеров и других мобильных устройств. Платформа Java 2 Micro Edition - это стандарт программирования мобильных телефонов, признанный такими известнейшими компаниями как Nokia, Siemens, Sony Ericsson, Motorola, Samsung, Symbian, Palm Computing, Sharp, Mitsubishi, NEC и так далее.

В книге вы изучили практически все компоненты платформы Java 2 Micro Edition, за исключением ряда специфических свойств, ознакомиться с которыми можно с помощью справочника, находящегося в приложении 2 этой книги.


Глава 1. Устройство мобильных телефонов

  • В этой главе...
  • 1.1. Стандарт GSM
  • 1.2. Архитектура телефонов
  • 1.3. Прошивка и операционная система
  • 1.4. Инфракрасный порт
  • 1.5. Технология Bluetooth
  • 1.6. Протокол WAP
  • 1.7. Протокол GPRS
  • 1.8. Карта SIM


В этой главе ...

Прежде чем приступить к изучению особенностей программирования мобильных телефонов на Java 2 ME, необходимо познакомиться с общей схемой устройства телефона.

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

Первая представляет собой мобильные телефоны с набором простейших функций, такие телефоны часто называют «звонилка». Функциональность подобных телефонов сводится только к их прямому назначению. С такого устройства можно произвести или принять вызов и воспользоваться услугами SMS (Short Message Service - служба коротких сообщений). Сам телефон, как правило, имеет монохромный дисплей небольшого размера, а из пользовательских программ доступны только простейшие, такие как калькулятор, таймер, диктофон, телефонная книга и так далее.

Вторая категория мобильных телефонов имеет более широкий круг возможностей. Дисплей таких телефонов обычно цветной, разрешение варьируется от 80 до 130 пикселей с глубиной цвета около пяти тысяч цветов. Телефоны этой категории обычно содержат те же возможности, что и у аппаратов первой категории и ряд дополнительных функций. Одна из них - это возможность загрузки приложений написанных на языке Java. Из всех дополнительных функций стоит выделить возможность работы с WAP (Wireless Application Protocol - протокол беспроводной передачи данных) и GPRS (General Packet Radio Service - радио сервис пакетной передачи данных). Принципы работы этих протоколов описывается в разделах 1.6 и 1.7 этой главы.

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

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


1.1. Стандарт GSM

Цифровой стандарт GSM (Global System Mobile Communication - система мобильной глобальной связи), на основе которого происходит связь между телефонами, - самый распространенный стандарт во всем мире, обеспечивающий диапазон работы мобильных телефонов на частотах 900/1800/1900 МГц. Стандарт GSM обладает качественными и безопасными характеристиками связи, что и повлияло на его популярность во всем мире. В нашей стране это основной стандарт, использующийся всеми крупными операторами связи.


1.2. Архитектура телефонов

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

Телефон имеет процессор, память, приемо-передатчик, систему контроллеров для дисплея, клавиатуры, аккумулятора и карту SIM (Subscriber identification module - идентификационный модуль абонента). Процессор вкупе с памятью является сердцем телефона. Он имеет более скромные характеристики, чем процессор компьютера. Приемо-передатчик служит для приема и передачи сигнала и включает в себя различные фильтры, кодеры, декодеры речи и сигналов. Система контроллеров для клавиатуры (клавиш телефона) и дисплея позволяет вводить информацию в телефон посредством клавиш и выводить ее на дисплей. Контроллер аккумулятора производит управление процессом зарядки аккумуляторных батарей телефона.

Все аппаратное обеспечение телефона (железо) безусловно, само по себе функционировать не может, и работа осуществляется на основе прошивки или операционной системы.


1.3. Прошивка и операционная система

Все имеющиеся мобильные телефоны можно разделить еще на два типа - это телефоны, работающие под управлением прошивки и телефоны, использующие операционную систему. Телефоны с операционной системой также носят название смартфоны. На рынке сейчас имеются две операционные системы, адаптированные под нужды телефонов, это Windows Mobile и Symbian.

Операционная система Windows Mobile, за которой стоит, как не трудно догадаться, софтверный гигант Microsoft предъявляет достаточно высокие требования к аппаратной части телефона. Соответственно, высокая цена на такие устройства никак не способствует популяризации этой операционной системы. Но стоит признать тот факт, что операционная система Windows Mobile- очень мощная и хорошо продуманная система, которая в будущем возможно сможет занять одно из ведущих мест в этом сегменте рынка.

Операционная система Symbian является открытой системой и предъявляет значительно меньше требований к аппаратному устройству телефона. В акционерное общество Symbian Ltd. (разработчик операционной системы Symbian) входят все мировые лидеры производителей телефонов. Эта операционная система на данный момент занимает доминирующее положение в мобильной промышленности.

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

Прошивка телефона — это программа, управляющая работой телефона, но вшитая в сам телефон. Каждый из производителей создает свои прошивки для конкретных моделей, предопределяя тем самым функциональность телефона. Операционная система разрешает осуществлять загрузку созданных программ . в телефон, а в прошивке такая возможность не предусмотрена. Точнее сказать, не была предусмотрена до появления платформы Java 2 ME. Для работы приложений написанных на Java, необходима виртуальная Java машина или среда исполнения приложений. Виртуальная Java машина, адаптированная специально для телефонов, настолько компактна по размеру, и, что самое главное, безопасна, что практически все производители телефонов стараются создать поддержку Java программ, то есть встроить среду исполнения Java программ в телефон. Загрузка сторонних приложений дала очень мощный импульс мобильной игровой индустрии, что, как мне кажется, вывело телефон на новый более качественный уровень. Единственное что необходимо понимать в этом аспекте, это то, что среда исполнения Java-приложений в телефоне реализована таким образом, что не позволяет написать «вредные» программы портящие аппаратную часть телефона. Модель работы Java-программ реализована как бы в виде закупоренной бочки, в которой и происходит работа всех Java приложений. Из этой бочки программы выбраться не могут, а соответственно не могут и нанести ущерб телефону.

Загрузка Java программ в телефон происходит при помощи программного обеспечения и кабеля, соединяющего телефон с компьютером. Также можно загрузить в телефон программы при помощи инфракрасного порта, технологии Bluetooth, либо непосредственно из Интернета с помощью протоколов WAP и GPRS. Все программы, загружаемые в телефон, распространяются в виде двух файлов, JAD - это дескриптор приложения и JAR - архив программы. Более подробно процесс загрузки программ рассматривается в главе 3.


1.4. Инфракрасный порт

Инфракрасный порт имеют не все телефоны. В основном это модели, относящиеся ко второй и третьей условной ценовой категории, о которых мы говорили в начале этой главы. С помощью инфракрасного порта можно произвести соединение с компьютером, другим телефоном или любым иным устройством имеющим инфракрасный порт. Принцип работы инфракрасного порта очень прост: имеются светодиод и фотодиод, соответственно для передачи и приема сигнала. Поместив два устройства на расстоянии не более полутора метров в зоне прямой видимости можно осуществить связь между этими устройствами. Что касается связи телефона с компьютером посредством инфракрасного порта, то это происходит при помощи программного обеспечения поставляемого производителями телефонов. В частности на компакт диске можно найти программы для телефонов Sony Ericsson, Nokia и Siemens, подробный анализ этих программ вы найдете в главе 3.


1.5. Технология Bluetooth

Название этой сравнительно новой технологии (Bluetooth - голубой зуб) позаимствовано из истории - так некогда звали датского короля Гарольда второго, стремящегося объединить все датские земли в одно королевство Дания.

С помощью технологии Bluetooth можно осуществлять соединение сразу с множеством устройств и организовывать небольшие локальные сети. Связь с использованием Bluetooth происходит на частоте 2,4 ГГц с расстояния порядка 10 метров и что самое главное, не требует прямого соединения, то есть устройства могут находиться вне зоны видимости друг друга. Приемопередатчик сигнала выполняется в виде микросхемы и может связать в сеть около десятка разнообразных устройств.

Сейчас технология Bluetooth очень активно используется производителями мобильных телефонов для создания беспроводных гарнитур, например наушника и микрофона.


1.6. Протокол WAP

Протокол WAP (Wireless Application Protocol) - это протокол беспроводного соединения с сетью Интернет. Имея поддержку WAP в мобильном телефоне, появляется возможность выхода в Интернет для просмотра специально адаптированных web-страниц на телефоне. Также с помощью WAP можно скачать или купить игру или приложение, написанное на языке Java. Стоимость таких программ обычно не превышает 1-2 доллара. Однако пользоваться WAP можно только в том случае, если ваш оператор сотовой связи предоставляет WAP услуги. Телефон, имеющий поддержку WAP, снабжен и WAP-браузером, что и делает возможным просмотр WAP страниц в Интернете.

Если обобщить все выше сказанное, то работу телефона с протоколом WAP, можно сравнить с обыкновенным компьютером, связывающимся с сетью Интернет. Все Интернет-страницы, используемые компьютерными системами написаны на языке HTML или XML, а страницы для WAP-соединения созданы с помощью своего языка WML (Wireless Markup Language - беспроводной язык разметки). Для того чтобы через WAP выйти в Интернет с мобильного телефона, необходимо обязательно произвести соответствующие настройки в телефоне. Сделать это можно вручную, а можно воспользоваться услугами своего оператора, предоставляющего мобильную связь. Для этого необходимо позвонить по соответствующему номеру или отправить SMS, в зависимости от оператора связи указанного в инструкции, прилагающейся к SIM-карте. Если есть желание настроить WAP самостоятельно, то можно воспользоваться значениями, приведенными в таблице 1.1.

Таблица 1.1.

Операторы | БиЛайн | Мегафон | МТС
URL | "http://wap.beeline.ru" | http://wap.megawap.ru | http://wap.mts.ru
Защита связи | отключить | отключить | отключить
Канал | GPRS | GPRS | GPRS
Входная точка | http://wap.beeline.ru | http://wap.megawap.ru | http://wap.mts.ru
Адрес IP | 192.168.017.001 | 010.010.001.002 | 212.44.140.13
Логин | beeline | wap | mts
Пароль | beeline | wap | mts

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

Единственная проблема WAP-сервиса - это высокая цена соединения, поскольку оплата происходит поминутно, а платите вы практически как за минуту разговора по телефону. Это получается весьма дорогое удовольствие. Отчасти эту проблему решает протокол GPRS.


1.7. Протокол GPRS

Связь телефона по протоколу GPRS (General Packet Radio Service - радио сервис пакетной передачи данных) осуществляется в куда более щадящем режиме. Используя соединение WAP, вы фактически звоните по другому номеру, занимая тем самым один из многочисленных каналов связи, поэтому и оплата взимается поминутно. С использованием GPRS оплата происходит только за количество скачанных данных, измеряемое в байтах, килобайтах или мегабайтах. Например, оператор мобильной связи Би Лайн за один мегабайт изымает 6 рублей 60 копеек с вашего счета (по состоянию на 2004 год). Лучше использовать WAP соединение, то есть просматривать WAP-сайты, через протокол GPRS, значительно экономя средства. Все это происходит благодаря тому, что GPRS использует пакетную передачу данных и не задействует какой-то конкретный канал связи, он вклинивается в свободные зоны различных каналов, передавая информацию в виде небольших пакетов. Скорость связи может доходить до 115 кбит/с, но полагаю, что таких показателей никто не видел, а вот цифра в 30-40 кбит/с вполне реальна. Связь через GPRS можно использовать и на компьютере, для выхода в Интернет через мобильный телефон. Такая услуга связи носит название мобильный Интернет.


1.8. Карта SIM

После приобретения телефона необходимо позаботиться о покупке SIM-карты одного из операторов мобильной связи. Купив SIM-карту, вы становитесь полноценным абонентом выбранного вами оператора связи.

Сама SIM-карта выполнена в виде небольшого по размерам пластмассового прямоугольника, с контактной полосой на поверхности для стыковки с идентичным разъемом на телефоне. Каждая SIM-карта, содержит свой уникальный идентификационный номер, что в конечном итоге решает проблему одинаковых номеров. В SIM-карте также находится простейший процессор, и вы можете сохранять на SIM-карте записи, как правило, это обычная телефонная книга, примерно на 200-300 записей. Более подробно об установке SIM-карты в телефон и другой информации можно узнать из инструкции к вашему телефону.

Таким образом, устройство мобильного телефона отдаленно напоминает устройство компьютерных систем. Поэтому адаптация платформы Java 2 ME, для телефонов, произошла абсолютно безболезненно, переведя виток развития мобильной индустрии на новый, до настоящего времени неведомый уровень. Следующая глава раскрывает теорию строения платформы Java 2 Micro Edition.


Глава 2. Платформа Java 2 Micro Edition

  • В этой главе...
  • 2.1. Конфигурация CDC
  • 2.2. Конфигурация CLDC
    • 2.2.1. Свойства языка Java
    • 2.2.2. Виртуальная машина
  • 2.3. Профиль
  • 2.4. Профиль MIDP 2.0 и конфигурация CLDC 1.0
    • 2.4.1. Пакет java.lang
    • 2.4.2. Пакет java.util
    • 2.4.3. Пакет java.io
    • 2.4.4. Пакет javax.microedition.io
    • 2.4.5. Пакет javax.microedition.lcdui
    • 2.4.6. Пакет javax.microedition.lcdui.game
    • 2.4.7. Пакет javax.microedition.media
    • 2.4.8. Пакет javax.microedition.media.control
    • 2.4.9. Пакет javax.microedition.midlet
    • 2.4.10. Пакет javax.microedition.pki
    • 2.4.11. Пакет javax.microedition.rms


В этой главе...

Прежде чем мы приступим к знакомству с платформой Java 2 ME, следует определиться с основами программирования на Java. Эта и все дальнейшие главы рассчитаны на пользователя, имеющего самые минимальные представления о языке программирования Java. Если вы не относите себя к таковым, то перейдите в конец книги к приложению 1 и ознакомьтесь с основами языка Java. Информации присутствующей в приложении, будет достаточно для прочтения этой книги.

История языка программирования Java насчитывает более десяти лет. Вначале, при создании Java, планировалось использовать этот язык для программирования микроконтроллеров бытовых устройств. Поэтому язык Java, тогда он, правда, имел другое название, изначально создавался независимым от архитектуры, компактным и безопасным, что в последствии сыграло решающую роль в его широком распространении. Однако, в тот момент язык программирования Java не смог обрести популярности. Более того, он оказался совершенно невостребованным. И только благодаря появлению сети World Wide Web, язык программирования Java получил настоящее признание, но уже в сфере Интернет-программирования. За этот десяток лет компанией Sun Microsystems было создано несколько платформ для различных сфер деятельности.

  • Java 2 Enterprise Edition - эта платформа необходима при создании серверных приложений;
  • Java 2 Standard Edition - используется для работы на простых компьютерных системах;
  • Java 2 Micro Edition - ориентирована на работу с портативными устройствами.

Все три платформы занимают свои ниши и решают круг определенных задач. Но если платформы Java 2 ЕЕ и Java 2 SE испытывают жесткую конкуренцию в своем секторе рынка со стороны других технологий, то Java 2 ME находится вне конкуренции и является фактически стандартом в разработке программ для портативных устройств. Можно с уверенностью сказать: то, для чего изначально создавался язык программирования Java, а именно, создание программ для бытовых устройств, в итоге и стало его стихией.

Так что такое платформа Java 2 ME, для чего она нужна и как устроена? На эти и другие вопросы мы попытаемся дать ответ в этой главе.

Язык программирования Java независим от архитектуры, в силу того, что используется интерпретатор, переводящий байт-код, сгенерированной компилятором в машинно-независимый код. Интерпретация кода осуществляется под управлением системы выполнения, носящей название виртуальная Java машина. Такой механизм образует среду исполнения приложений. Среда исполнения, в свою очередь, предъявляет определенные требования, к свойствам языка программирования Java, построенные на основе спецификации Java Language Specification, разработанной компанией Sun Microsystems. При написании программ на Java активно используются библиотека Java API, без которых написать приложение практически невозможно. Библиотека Java API содержит огромное количество предопределенных интерфейсов, классов, методов, констант помогающих программисту в минимальные сроки создавать рабочее приложение.

Подобный механизм создания и выполнения программ характерен для всех трех имеющихся платформ Java 2 ЕЕ, Java 2 SE и Java 2 ME. Платформы Java 2 ЕЕ и Java 2 SE можно признать почти одинаковыми, однако Java 2 ЕЕ несколько мощнее и содержит ряд библиотек позволяющих производить разработку программного обеспечения для серверов, а вот платформа Java 2 ME ориентирована именно на работу с портативными устройствами. В связи с этим Java 2 ME предъявляет уже свои требования к виртуальной Java машине, свойствам языка Java и библиотекам, поскольку системные ресурсы портативных устройств ограничены в силу своей спецификации аппаратного обеспечения. Небольшие размеры портативных устройств накладывают значительные ограничения на процессор, память, дисплей, устройство ввода, но платформа Java 2 ME разработана специально для того, чтобы создавать программы, ориентированные именно на такие портативные устройства.

Среда исполнения приложений Java, должна находиться внутри портативных устройств. За это отвечает их производитель, и это как раз и характеризует конкретное устройство, как устройство, поддерживающее технологию Java.

Количество портативных устройств поддерживающих Java достаточно большое, но мощность и, соответственно, возможности устройств различны. Поэтому платформа Java 2ME разработана в виде блочной модели надстраиваемых модулей, конфигураций и профилей.

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

Платформа Java 2 ME состоит из двух конфигураций: CDC (Connected Device Configuration - конфигурация подключаемых устройств) и CLDC (Connected Limited Device Configuration - конфигурация подключаемых устройств с ограничениями). Каждая из конфигураций определяет свое семейство портативных устройств. При программировании мобильных телефонов используется конфигурация CLDC. Каждая из конфигураций содержит свои профили, которые надстраиваются над своей конкретной конфигурацией. Когда программист создает программное обеспечение для портативных устройств, он обязан четко осознавать под какой профиль и конфигурацию он пишет программу, а производитель устройства должен осуществить поддержку того или иного профиля в связке со своей конфигурацией.

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

Рис. 2.1. Блочная схема построения платформы Java 2 ME

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

Цель этой книги научить вас создавать приложения для мобильных телефонов с применением конфигурации CLDC и профиля MIDP. Вся концепция книги построена на использовании связки MIDP/CLDC, но несколько слов стоит сказать о конфигурации CDC и доступных для этой конфигурации профилях.


2.1. Конфигурация CDC

Конфигурация CDC объединяет в себе ряд устройств имеющих постоянное сетевое соединение, таких как двунаправленные пейджеры, телевизионные приставки, автомобильные системы навигации, интеллектуальные коммуникаторы. Данные устройства характеризуются более мощными системными ресурсами, они имеют обычно 16 или 32-разрядные процессоры и как минимум 2 мегабайт памяти. В этой связи обе конфигурации CDC и CLDC, имеют свой набор свойств, определяющих поддержку библиотек Java API, виртуальную машину, свойства самого языка Java. Эти свойства и отличают разные конфигурации.

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

Конфигурация может содержать несколько профилей. Конфигурация CDC имеет два профиля - это Foundation Profile и Personal Profile и PDA. Смысл и устройство этих профилей мы рассматривать не будем, они не имеют никакого отношения к теме этой книги и были приведены лишь для понимания общей идеи конфигурации. При желании в документации по Java 2 ME вы сможете найти необходимую информацию и изучите ее самостоятельно.


2.2. Конфигурация CLDC

Конфигурация CLDC рассчитана на семейство мобильных устройств, таких как телефоны, органайзеры, КПК. Мобильные устройства, для которых предназначена конфигурация CLDC, характеризуются следующими параметрами:

  • процессор 16 или 32-разрядный;
  • память от 160 до 512 килобайт, для всей платформы Jауа 2 ME;
  • беспроводное сетевое соединение;
  • питание от аккумуляторов.

Все перечисленные характеристики, несомненно, накладывает определенные ограничения на создаваемое приложение. Конфигурации CDC и CLDC независимы друг от друга и не могут использоваться вместе. Вся концепция конфигурации CLDC была разработана дочерней группой Java Community Process, компании Sun Microsystems, которая включает в себя множество известных компаний:

  • America Online;
  • Bull;
  • Ericsson;
  • Fujitsu;
  • Matsushita;
  • Mitsubishi;
  • Motorola;
  • Nokia;
  • NTT DoCoMo;
  • Oracle;
  • Palm Computing;
  • RIM;
  • Samsung;
  • Sharp;
  • Siemens;
  • Sony;
  • Sun Microsystems;
  • Symbian.

Конфигурация CLDC содержит ряд классов, интерфейсов, методов платформы Java 2 SE, но в урезанном виде. Это и не мудрено, компьютерная платформа превосходит по мощности мобильные телефоны во много раз. С другой стороны, та простота, с которой можно за несколько недель создать среднее по сложности приложение, подкупает и даже возвращает нас во времена шестнадцатибитных приставок. На самом деле общая масса игр, написанных на Java 2 ME, по своему игровому процессу напоминает именно те старые добрые времена.

Конфигурация CLDC также определяется своим набором свойств состоящих из языка Java, виртуальной Java машины и библиотек API. В данный момент имеется две версии этой конфигурации - это CLDC 1.0 и CLDC 1.1. Конфигурация CLDC 1.1 имеет больше возможностей, например поддержку чисел с плавающей точкой, что соответственно предъявляет более серьезные требования к аппаратной части телефона. В момент написания книги таких телефонов не было, поэтому вся книга построена на конфигурации CLDC 1.0. К слову сказать, конфигурация CLDC 1.1 построена на первой версии и просто имеет ряд улучшений. Остановимся на каждом свойстве конфигурации CLDC 1.0 подробней. В последствии при упоминании конфигурации, будет иметься в виду CLDC 1.0.


2.2.1. Свойства языка Java

Все свойства языка Java в конфигурации CLDC должны, насколько это возможно, соответствовать спецификации языка Java, но в силу ограниченности системных ресурсов мобильных устройств, не поддерживаются следующие 'свойства доступные в платформах Java 2 ЕЕ и Java 2 SE:

1) операции с дробными числами (floating point);

2) финализация (finalization);

3) отсутствует восстановление ошибок после сбоя (error handling).


2.2.2. Виртуальная машина

Виртуальная машина, используемая в конфигурации CLDC, несколько отличается от обычной виртуальной машины задействованной в Java, но обязана оставаться совместимой со спецификацией этой виртуальной машины (Java Virtual Machine Specification). Виртуальная машина находится непосредственно в телефоне и за совместимостью с общепринятой спецификацией обязаны следить производители мобильных телефонов. Сама же виртуальная машина носит название Kilobyte Virtual Machine (KVM) из-за своей компактности и также имеет ряд недоступных свойств:

1) не поддерживаются операции с дробными числами (floating point);

2) нельзя создать класс загрузчик (class loader);

3) отсутствует механизм отражения (reflection);

4) не реализован Java Nativ интерфейс (Java Native Interface);

5) не поддерживается финализация (finalization);

6) отсутствует восстановление ошибок после сбоя (error handling);

7) не поддерживается работа с групповыми потоками (Thread group).

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


2.3. Профиль

Как уже не раз отмечалось, профиль содержит предопределенные требования к аппаратной части устройства, а так же включает в себя минимальный набор API используемый в программировании мобильных устройств. Единственно доступный рабочий профиль в конфигурации CLDC имеет название MIDP (Mobile Information Device Profile - информационный профиль мобильных устройств). Спецификация профиля разработана экспертной группой MIDP Expert Group, в состав которой входят следующие компании:

  • America Online;
  • DDI;
  • Ericsson;
  • Espial Group, Inc.;
  • Fujitsu;
  • Hitachi;
  • J-Phone;
  • Matsushita;
  • Mitsubishi;
  • Motorola, Inc.;
  • NEC;
  • Nokia;
  • NTT DoCoMo;
  • Palm;
  • Research In Motion;
  • Samsung;
  • Sharp;
  • Siemens;
  • Sony;
  • Sun Microsystems, Inc.;
  • Symbian;
  • Telcordia Technologies.

Профиль MIDP был создан специально для поддержки мобильных устройств и задает следующие технические характеристики для мобильных устройств:

  • разрешение экрана минимум 96x54 пикселя с глубиной экрана минимум 1 бит;
  • устройством ввода может быть клавиатура или сенсорный экран;
  • 32 килобайта динамической памяти;
  • 128 килобайт под компоненты MIDP;
  • 8 килобайт для хранения постоянных данных;
  • беспроводная сеть;
  • питание от аккумулятора.

Такое сочетание конфигурации и профиля CLDC/MIDP используется в программировании мобильных телефонов и будет основным сочетанием при рассмотрении примеров из книги.

На данный момент профиль MIDP имеет две версии: MIDP 1.0 и MIDP 2.0. До последнего времени первая версия MIDP была основным профилем при создании приложений для телефонов. Все телефоны, поддерживающие Java, имеют совместимость с профилем MIDP 1.0. Этот профиль был сформирован при начальном создании платформы Java 2 ME и имеет в своем составе определенный набор API,

С выходом профиля MIDP 2.0 добавилось ряд новых библиотек, значительно улучшающих создание приложений для мобильных телефонов. Но самое главное это то, что у него имеется полная совместимость с профилем MIDP 1.0. Профиль MIDP 2.0 содержит большое количество новых дополнительных библиотек, отсутствующих в составе MIDP 1.0, но при создании приложений под профиль MIDP 2.0, можно пользоваться библиотеками профиля MIDP 1.0. Если же вы пишите программу под профиль MIDP 1.0, то библиотеки профиля MIDP 2.0 вам будут недоступны. В книге будут рассмотрены оба профиля как единое целое. Подытожив все вышесказанное о профилях и конфигурациях необходимых для программирования мобильных телефонов, можно резюмировать: программный продукт создаваемый разработчиками ориентирован на конкретный профиль, который является, спецификацией устанавливающей определенные требования к аппаратной части телефона, а1 также содержит дополнительные библиотеки. Каждый конкретный профиль надстраивается над своей и только ему доступной конфигурацией. Конфигурация предъявляет требования к виртуальной Java машине и свойствам языка Java, используемым в этой конфигурации. Далее идет плотное взаимодействие с аппаратным обеспечением телефона, через имеющиеся сервисы, которые предоставляются операционной системой либо прошивкой телефона. Благодаря такой цепочке взаимодействий, любое программное обеспечение, написанное на Java под конкретный профиль, будет работать на телефоне с поддержкой Java. На рис. 2.2 хорошо прослеживается общая схема взаимодействия приложения с мобильным телефоном.

Рис 2.2. Схема взаимодействия приложений с аппаратным обеспечением телефона

Такая модульность в построении Java 2 ME дает неограниченную возможность в модернизации всей платформы и написанию действительно аппаратно-независимого кода программы. Люди, знакомые с моей книгой «DirectX 9. Уроки программирования на C++», обязательно найдут много общего в подходе реализации двух платформ DirectX и Java 2 ME. Оставшаяся часть этой главы целиком посвящена рассмотрению пакетов и классов доступных в MIDP 2.0/CLDC 1.0. Будут затронуты практически все имеющиеся компоненты данного профиля и конфигурации.


2.4. Профиль MIDP 2.0 и конфигурация CLDC 1.0

Язык Java самый «библиотечный язык», такого количества продуманных классов, наверное, нет ни в одном языке программирования. С другой стороны, простота в использовании Java, по всей видимости, поспособствовала определенной популярности этого языка. С точки зрения программиста, обилие готовых классов гораздо упрощает разработку программного продукта, и что самое главное, уменьшает сроки создания программ.

Профиль MIDP 2.0 и конфигурация CLDC 1.0, содержит большое количество интерфейсов и классов, использование которых в программировании приложений, пожалуй, сможет удовлетворить любого разработчика. Часть классов было взято из Java 2 SE с некоторыми усечениями, а часть была специально написана под Java 2 ME. Вся библиотека доступная для профиля MIDP 2.0 и конфигурации CLDC 1.0, состоит из одиннадцати пакетов. По традиции каждый отвечает за свою определенную область.

  • java.lang;
  • java.util;
  • java.io;
  • javax.microedition.lcdui;
  • javax.microedition.lcdui.gamer
  • javax.microedition.io;
  • javax.microedition.media;
  • javax.microedition.media.control;
  • javax.microedition.pki;
  • javax.microedition.midlet;
  • javax.microedition.rms.

Все пакеты с префиксами javax.microedition.*, написаны специально для Java 2 ME профиля MIDP 2.0. Пакеты с префиксом Java.*, взяты из Java 2 SE версии 1.4, в урезанном виде, и имеет полную совместимость с оригиналом и определенны в конфигурации CLDC 1.0.


2.4.1 Пакет java.lang

Этот пакет содержит системные классы или основы языка Java и исключения. Имеется также один единственный интерфейс Runnable. На рис. 2.3 изображена иерархия классов пакета java.lang.

Рассмотрим имеющиеся компоненты пакета java.lang и дадим краткую характеристику каждому из них.

Рис 2.3. Иерархия классов пакета java.lang

Интерфейс:

  • Runnable - создает поток в приложении.

Классы:

  • Boolean - объектно-ориентированный класс, оболочка или как еще говорят «обвертка», для простого типа Boolean;
  • Byte - объектно-ориентированный класс для простого типа Byte;
  • Character - объектно-ориентированный класс для простого типа Char;
  • Class - виртуальная машина создает объекты этого класса, которые представляют интерфейсы и классы языка Java;
  • Integer - объектно-ориентированный класс для простого типа int;
  • Long - объектно-ориентированный класс, оболочка для простого типа;
  • Math - класс, содержащий математические методы;
  • Object - суперкласс для всех классов Java. Все классы наследуются от класса Object и являются его подклассами;
  • Runtime - класс времени исполнения;
  • Short - объектно-ориентированный класс, оболочка для простого типа Short;
  • string — создает строки символов;
  • StringBuffer - содержит строку символов любого размера;
  • System - содержит ряд системных методов;
  • Thread - создает поток в работе приложения;
  • Throwable - суперкласс для всех подклассов, предназначенных для работы с ошибками и исключениями.

Исключения:

  • Exceptions - исключения для классов и подклассов;
  • ArithmeticException - арифметическое исключение;
  • ArrayIndexOutOfBoundsException - исключение обрабатывающее неправильный индекс в массиве данных;
  • ArrayStoreException - исключение обрабатывающее неправильно заданный тип объекта в массиве объектов;
  • ClassCastException - неправильно указан подкласс объекта;
  • ClassNotFoundException - класс не найден;
  • IllegalAccessException - нет доступа к классу;
  • IllegalArgumentException - указан неправильный аргумент;
  • IllegalMonitorStateException - мониторинг объектов;
  • IllegalStateException - неправильно вызванный метод;
  • IllegalThreadStateException - неправильные установки потока;
  • IndexOutOfBoundsException-исключает неверный указанный индекс;
  • InstantiationException - исключает ситуацию в создании или вызове членов абстрактного класса;
  • InterruptedException - исключает прерывание потока находящегося в состоянии ожидания:
  • NegativeArraySizeExcept'ion - исключает ситуацию в создании большего размера массива данных, чем было указано при инициализации;
  • NumberFormatException — неправильное преобразование строки в целочисленный тип данных;
  • Runt imeException - суперкласс исключений времени исполнения виртуальной машины Java;
  • SecurityException - менеджер безопасности;
  • StringlndexOutOfBoundsException - выход индекса за приделы строки.

Ошибки:

  • Error - обобщенная модель ошибок;
  • OutOf MemoryError - ошибки связанные с выходом за пределы памяти;
  • VirtualMachineError — ошибка времени исполнения.


2.4.2. Пакет Java.util

В этом пакете содержатся классы стандартных утилит упрощающих работу программиста. Пакет сильно урезан по сравнению со стандартным пакетом Java 2 SE. На рис. 2.4 представлена иерархия классов пакета jova.util.

Рис 2.4. Иерархия классов пакета Java.util

Интерфейс:

  • Enumeration - декларирует возможность доступа к элементам.

Классы:

  • Calendar - выполняя функции обыкновенного календаря;
  • Date - реализует возможность работы с датой и временем;
  • Hashtable -имеет возможность в сохранении объектов с доступом к ним по определенно заданному ключу;
  • Random - генератор случайных чисел;
  • Stack - реализует функциональность стека;
  • Timer — реализует возможность работы со временем;
  • TimerTask - планировщик задач;
  • TimeZone - дает возможность в определении временного пояса;
  • Vector - класс для создания и содержания массивов любого размера.

Имеет возможность изменять размер заданного массива.

Исключения:

  • EmptyStackException - указывает на пустой стек;
  • NoSuchElementException - исключение указывает на отсутствие элементов в определенном перечислении.


2.4.3. Пакет Java.io

Классы этого пакета отвечают за работу с входными и выходными потоками данных. На рис. 2.5 показана иерархия наследования классов пакета java.io.

Рис2.5. Иерархия пакета java.io

Интерфейсы:

  • Datalnput - декларирует методы для чтения простых типов во входной поток данных;
  • DataOutput - декларирует методы для записи простых типов в выходной поток данных.

Классы:

  • ByteArraylnputStream - необходим при чтении входного потока байт из массива данных, для дальнейшего размещения их в памяти;
  • ByteArrayOutputStream - необходим при записи потока байт из памяти в массив выходных данных;
  • DatalnputStream - этот класс должен наследоваться от интерфейса Datalnput, реализуя при этом все его методы;
  • DataOutputStream - класс Должен наследоваться от интерфейса Data-Output, реализуя при этом все его методы;
  • InputStream - абстрактный класс, предназначенный для работы с входным потоком байтов;
  • InputStreamReader - наследуется от класса Reader, реализуя методы для чтения символьных данных входного потока с перекодировкой;
  • OutputStream - абстрактный класс, предназначенный для работы с выходным потоком байт;
  • OutputStreamWriter -наследуется от класса Writer, реализуя методы для записи символьных данных в выходной поток с перекодировкой;
  • PrintStream - расширяет выходной поток способностью печати данных;'
  • Reader - абстрактный класс, предназначенный для чтения символьных данных входного потока;
  • Writer - абстрактный класс, предназначенный для записи символьных данных в выходной поток.

Исключения:

  • EOFException - сигнализируете конце файла;
  • InterruptedlOException — сигнализирует о прерванном действии по вводу выводу;
  • IOException - указывает на исключение ввода вывода;
  • UnsupportedEncodingException - указывает на невозможность перекодировки;
  • UTFDataFormatException - сигнализирует о прочтении строки формата UTF-8.


2.4.4. Пакет javax.microedition.io

Этот пакет содержит множество интерфейсов и всего два класса обеспечивающих связь с сетью. На рис. 2.6 и рис. 2.7 приводится общая схема наследования соответственно интерфейсов и классов пакета javax.microedition.io.

Рис 2.6. Иерархия интерфейсов пакета javax.microedition.io

Интерфейсы:

  • CommConnection - находит последовательный порт;
  • Connection - общий тип всей связи сети;
  • ContentConnection - находит связь с потоком;
  • Datagram - общий интерфейс дейтограммы;
  • DatagramConnection - определяет возможность связи дейтограммы;
  • HttpConnection - декларирует методы константы для http-соединения;
  • HttpsConnection - декларирует методы константы для безопасного http-соединения;
  • InputCdnnection - интерфейс для создания входной связи с сетью;
  • OutputConnection - интерфейс для создания выходной связи с сетью;
  • SecureConnection - определяет безопасную связь с сетью;
  • Securitylnfo - располагает методами для получения информации сетевой связи;
  • ServerSocketConnection - реализует связь с сервером;
  • SocketConnection - находит socket (сокет) для потока связи;
  • StreamConnection - связь с потоком;
  • StreamConnectionNotifier - определяет возможность всей связи;
  • UDPDatagramConnection - реализует связь с дейтограммой.

Рис 2.7. Иерархия классов пакета javax.microedition.io

Классы:

  • Connector - класс для создания объектов связи;
  • PushRegistry - класс дляподдержания списков связей.

Исключение:

  • ConnectionNotFoundException - указывает на отсутствие связи.


2.4.5. Пакет javax.microedition.lcdui

Данный пакет имеет разнообразные классы для реализации пользовательского интерфейса в мобильных приложениях. Существует большое количество классов, благодаря которым можно создать действительно красивое интерактивное приложение. На рис. 2.8 изображена иерархия классов пакета javax.microedition.lcdui.

Рис 2.8. Иерархия классов пакета javax.microedition.lcdui

Интерфейсы:

  • Choice - содержит набор библиотек создающих возможность выбора заданных элементов;
  • CommandListener - реализует возможность получения событий;
  • ItemCommandListener - реализует возможность получения событий от объектов класса Item;
  • ItemStateListener - используется при получении событий о состоянии объектов класса Item встроенных в Form.

Классы:

  • Alert - этот класс необходим при создании уведомлений об ошибках либо информационных сообщений;
  • AlertType — отображает тип ошибки;
  • Canvas - абстрактный класс, обеспечивает графическую прорисовку различных элементов на экране телефона;
  • ChoiceGroup - встраиваемая группа выбираемых элементов. Интегрируется в класс Form, наследуется от класса Item и реализует интерфейс Choice;
  • Command - инкапсулирует командные действия, при этом, не определяя фактические действия команды, а лишь содержит информацию;
  • Customltem- создает возможность в отображении новых графических , элементов встроенных в класс Form;
  • DateField - класс представляющий работу с датой и временем. Интегрируется в класс Form, наследуется от класса Item;
  • Display — этот класс-диспетчер, отвечающий за экран телефона;
  • Displayable - абстрактный класс, содержит иерархию классов пользовательского интерфейса;
  • Font - класс шрифтов;
  • Form - этот класс создает пустую форму в которую в последствии, можно встраивать ряд классов задающих пользовательский интерфейс всего приложения;
  • Gauge — показывает графическое течение процесса;
  • Graphics - предоставляет возможность в рисовании на экране телефона;
  • Image - класс, отвечающий за загрузку и отображение любых видов изображений формата PNG;
  • Imageltem - контейнер для загруженных в приложение изображений;
  • Item - суперкласс, содержащий ряд классов для их дальнейшей интеграции в класс Form;
  • List - создает список группы элементов;
  • Screen - суперкласс для всех высокоуровневых классов определяющих пользовательский интерфейс приложения;
  • Spacer - создает заданное пространство на экране;
  • Stringltem - дает возможность в создании массивов строк;
  • TextBox - создает редактируемый текстовый контейнер;
  • TextField- создает редактируемый текстовый контейнер, который встраивается в класс Form;
  • Ticker - создает в приложении бегущую строку текста.


2.4.6. Пакет javax.microedition.lcdui.game

Это новый игровой пакет добавлен в профиль MIDP 2.0. В состав пакета входит пять мощных и хорошо продуманных классовое помощью которых можно достаточно легко создавать игры для мобильных устройств. На рис. 2.9 показана иерархия классов пакета javox.microedition.lcdui.game.

Рис 2.9. Иерархия классов пакета

Классы:

  • GameCanvas - абстрактный класс, содержащий основные элементы игрового интерфейса;
  • Layer - абстрактный класс, отвечающий за уровни представляемые в игре;
  • LayerManager - менеджер уровней;
  • Sprite - создает анимационные фреймы;
  • TiledLayer - отвечает за создание фоновых изображений.


2.4.7. Пакет javax.microedition.media

Пакет добавлен в профиль MIDP 2.0 и служит для создания звукового сопровождения в приложении. Пакет разработан специальной экспертной группой (MMAPI Expert Group), в состав которой входят такие известные компании:

  • Nokia (Specification Lead);
  • Aplix Corporation;
  • Beatnik. Inc.;
  • France Telecom;
  • Insignia Solutions;
  • Mitsubishi Electric Corp.;
  • Motorola;
  • Netdecisions Holdings United;
  • NTT DoCoMo. Inc.;
  • Openwave Systems Inc.;
  • PacketVideo Corporation;
  • Philips;
  • Siemens AC ICMMPTI;
  • Smart Fusion;
  • Sun Microsystems. Inc.;
  • Symbian Ltd;
  • Texas Instruments Inc.;
  • Vodafone;
  • Yamaha Corporation;
  • Zucotto Wireless.

В профиле MI DP 1.0 отсутствует возможность полноценной работы со звуком, и каждый из производителей предоставлял свои библиотеки для этих целей. В профиле MIDP 2.0 такой необходимости уже нет и можно воспользоваться любым необходимым классом и интерфейсом из пакета javax.microedition.mediu. На рис. 2.10 приводится наследование интерфейсов этого пакета.

Рис 2.10. Иерархия интерфейсов из пакета javax.microedition. media.

Интерфейсы:

  • Control - осуществляет контроль над процессами;
  • Controllable - осуществляет контроль над объектами;
  • Player - реализует контроль над воспроизведением;
  • PlayerListener - необходим для получения асинхронных событий : принятых от проигрывателя.

Классы:

  • Manager - менеджер системных ресурсов.

Исключение:

  • MediaException - исключает ошибки в работе методов этого пакета.


2.4.8. Пакет javax.microedition.media.control

С помощью пакета javax.microedition.media.control определяется контроль над воспроизведением заданных звуковых данных. Это небольшой пакет, имеющий в своем составе всего два интерфейса, а на рис. 2.11 дается схема наследования интерфейсов.

Рис.2.11. Иерархия интерфейсов пакета javax.microedition.media.control

Интерфейсы:

  • ToneControl - воспроизведение однотональных звуков;
  • VolumeControl - регулирует громкость воспроизведения.


2.4.9. Пакет javax.microedition.midlet

Сам по себе пакет небольшой, но он играет ключевую роль при создании приложений на Java 2 ME. С помощью этого пакета происходит связь между приложением и мобильным информационным профилем устройства (MIDP). Рисунок 2.12 отражает полную иерархию пакета javax.microedition.midlet.

Рис. 2.12. Иерархия пакета javax.microedition.midlet

Класс:

  • MIDlet - основной класс программы должен наследовать класс MIDlet, для управления работой приложения.

Исключение:

  • MIDletStateChangeException - исключает неправильную работу с классом MIDlet.


2.4.10. Пакет javax.microedition.pki

Пакет javax.microedition.pki сертифицирует информацию для безопасной связи. Рисунок 2.13 содержит иерархию этого пакета.

Рис.2.13. Иерархия пакета javax.microedition.pki

Интерфейс:

  • Certificate - общий сертификат.

Исключение:

  • CertificateExceptio - обобщенный вид ошибок, возникший при использовании данного сертификата.


2.4.11. Пакетjavax.microedition.rms

Этот пакет предназначен для создания механизма хранения и извлечения данных из памяти устройства. Хранение и запись данных происходит на основе менеджера системной записи (Record MaAagement System), что дает возможность удалять, добавлять, просматривать, изменять или составлять список всех имеющихся записей. Имеется один класс и несколько интерфейсов реализующих механизм сохранения и извлечения данных. На рис. 2.14 представлена иерархия пакета javax.microedition.rms.

Рис 2.14. Иерархия пакета javax.microedition.rms

Интерфейсы:

  • RecordComparator - осуществляет сравнение двух записей;
  • RecordEnumeration - реализует двунаправленный список записи;
  • RecordFilter - определяет различные совпадения в записях;
  • RecordListener - прослеживает события записи данных.

Класс:

  • RecordStore - производит запись данных.

Исключения:

  • InvalidRecprdlDException - исключает запись данных в неправильно указанный адрес;
  • RecordStoreException - индикатор ошибки записи данных;
  • RecordStoreFullException - указывает на переполнение системных ресурсов для записи данных;
  • RecordStoreNotFoundException - показывает, что указанное место для записи данных не было обнаружено;
  • RecordStoreNotOpenException - указывает на невозможность записи.

В этой главе мы рассмотрели состав одиннадцати пакетов, давая краткую характеристику имеющимся интерфейсам, классам и исключениям. В конце книги в приложении 2, вы найдете справочник по Java 2 ME, где рассматриваются более подробно все составляющие CDLC/MIDP.

В следующей главе будет изучены интегрированные средства разработки приложений, бесплатно предоставляемые компанией Sun Microsystems.


Глава 3. Средства разработки мобильных приложений

  • В этой главе...
  • 3.1. Установка Java 2 SDK SE
  • 3.2. Среда программирования SUN ONE Studio 4 Mobile Edition
    • 3.2.1. Настройка SUN ONE Studio 4 Mobile Edition.
    • 3.2.2. Создание проекта в SUN ONE Studio 4 Mobile Edition
    • 3.2.3. Создание приложений в SUN ONE Studio 4 Mobile Edition
    • 3.2.4. Компиляция и запуск программ в SUN ONE Studio 4 Mobile Edition
  • 3.3. Среда программирования J2ME Wireless Toolkit 2.1
    • 3.3.1. Установка J2ME Wireless Toolkit 2.1
    • 3.3.2. Создание проекта в J2ME Wireless Toolkit 2.1
    • 3.3.3. Компиляция и запуск программы в J2ME Wireless Toolkit 2.1
  • 3.4. Упаковка программ
    • 3.4.1. Файл манифеста
    • 3.4.2. Файл JAD
    • 3.4.3. Файл JAR


В этой главе...

В предыдущей главе вы познакомились с общей архитектурой платформы Java 2 ME, в этой главе вашему вниманию будут представлены две интегрированные среды для разработки мобильных приложений - это SUN ONE Studio 4 Mobile Edition и J2ME Wireless Toolkit 2.1. Обе среды распространяется бесплатно и разработаны в недрах компании Sun Microsystems. Данные инструментарии можно скачать с сайта самой компании. Предлагаемые к изучению инструментарии, в отличие от других сред программирования, адаптированы именно для создания приложений для мобильных устройств, поэтому будут рассмотрены и использованы в этой книге.

Прежде чем приступить к инсталляции SUN ONE Studio 4 Mobile Edition и J2ME Wireless Toolkit 2.1, необходимо установить набор инструментальных средств Java 2 SDK, SE vl.4.2_03 (Software Development Toolkit Standard Edition). Это последняя на данный момент версия библиотеки, предоставляющая программные средства для создания приложений на Java. В состав этой библиотеки также входит Java 2 Runtime Environment, SE vl.4.2_03, котораянеобходима для работы приложений написанных на Java.


3.1. Установка Java 2 SDK SE

Двойной щелчок левой кнопки мышки на файле j2sdk-1_4_2_03-windows-i586-p из каталога \SDK, приведет к распаковке архива. Далее появится окно с лицензионным соглашением, нажав на кнопку Next, вы попадете в окно Java 2 SDK SE vl.4.2_03 - Custom Setup, изображенное на рис. 3.1.

В этом диалоговом окне вам будет предложено выбрать каталог и тип установки. Нам нужны все компоненты, поэтому нажмите кнопку Next. В следующем окне вам необходимо выбрать браузер для интеграции Java, остановите свой выбор на необходимом и подтвердите свои действия, после чего начнется процесс установки, в конце которого вам предложат перезагрузить компьютер. После установки Java 2 SDK, можно приступать к инсталляции SUN ONE Studio 4 Mobile Edition и J2ME Wireless Toolkit.

Сразу хотелось бы остановиться на некоторых особенностях возникающих при инсталляции. Обе среды программирования независимы друг от друга, но в составе, а точнее в комплекте с SUN ONE Studio 4 Mobile Edition, входит J2ME Wireless Toolkit версии 1.0.4 01, но изданный момент уже имеется J2ME Wireless Toolkit версии 2.1. Такая путаница обусловлена как раз тем, что оба продукта независимы друг от друга и развиваются параллельно. Начнем установку с более мощной среды SUN ONE Studio 4 Mobile Edition.

Рис. 3.1. Окно Java 2 SDK, SE v1.4.2_03 - Custom Setup


3.2. Среда программирования SUN ONE Studio 4 Mobile Edition

В директории \SDK находится файл ffj_me_win32 - это программа установки интегрированной среды разработки SUN ONE Studio 4 Mobile Edition. После двойного нажатия левой кнопки мыши на этом файле, вы увидите окно с приветствием, нажав на кнопку Next, вы попадете в окошко с лицензионным соглашением. Ознакомившись с соглашением и нажав на кнопку Next, на экране монитора появится диалоговое окно SUN ONE Studio 4 update 1, Mobile Edition Setup, изображенное на рис. 3.2.

Рис. 3.2. Окно SUN ONE Studio 4 update 1, Mobile Edition Setup

В этом и следующем окне необходимо определиться с директорией, в которой будет размещаться устанавливаемый инструментарий, после чего появится диалоговое окно, показанное на рис. 3.3, где перечисляются компоненты установки. Путь, задающий директорию для установки SUN ONE Studio 4 Mobile Edition не должен содержать пробелов.

Окно выбора компонентов содержит элементы для установки. Как видно из рис. 3.3 инсталлируется не только J2ME Wireless Toolkit, но и Java 2iPlatform Micro Edition, которая также может поставляться отдельно и лежит на компакт-диске в каталоге \SDK (в том случае если вы предпочитаете работать с командной строкой).

Рис. 3.3. Окно выбора компонентов к установке

Два последующих окна носят скорее информационный характер, просто на жмите кнопку Next и мастер установки начнет свою работу по инсталляции cреды программирования SUN ONE Studio 4 Mobile Edition на компьютер.


3.2.1. Настройка SUN ONE Studio 4 Mobile Edition

После установки среды программирования SUN ONE Studio 4 Mobile Edition на рабочем столе появится иконка быстрого старта, При первом вызове инстру ментария SUN ONE Studio 4 Mobile Edition, необходимо настроить некоторые параметры. В первом появившемся окне, изображенном на рис. 3.4 надо выбрал директорию, где будет располагаться ваш рабочий каталог, содержащий исходные коды создаваемых программ.

Рис. 3.4. Выбор рабочей директории

Выберите любой устраивающий вас каталог, или создайте новый и нажмите кнопку Next. Следующее окно, показанное на рис. 3.5, предложит сохранить настройки от предыдущих версий.

Рис. 3.5. Окно Setting Import Wizard

Если у вас были установлены ранние версии SUN ONE Studio, воспользуйтесь этим мастером, если нет, нажмите кнопку Finish. В cледующем появившемся окне, показанном на рис. 3.6, будет предложено сконфигурировать установленную среду программирования при помощи мастера конфигурации.

Рис. 3. 6. Окно Setup Wizard

Настройка с помощью мастера Setup Wizard происходит в три этапа. На первом этапе, в окне, показанном на рис. 3.6, можно установить режим отображения инструментария, выбрать web-браузер, а также по необходимости задать используемый прокси сервер (Proxy Server). Задайте необходимые настройки и нажмите кнопку Next. Следующее диалоговое окно изображенное на рис. 3.7, показывает перечень инсталлируемых модулей.

Рис. 3.7. Инсталлируемые модули

Настройки по умолчанию в этом окне целесообразно оставить без изменений. Далее, нажав кнопку Next, вы попадете в последнее диалоговое окно Update Center, изображенное на рис. 3.8, с помощью которого можно обновить установленные компоненты через Интернет.

Рис. 3.8. Окно Update Center

Если вы имеете подключение в Интернет, то можно обновить некоторые из компонентов, процедура абсолютно бесплатна. Для отказа от обновления нажмите кнопку Finish. После чего перед вами появиться рабочая поверхность SUN ONE Studio 4 Mobile Edition, а на ее фоне окно Registration Wizard, показанное на рис. 3.9. С помощью этого окна необходимо зарегистрировать установленный продукт на сайте производителя.

Рис. 3.9. Окно Registration Wizard

Рекомендую вам зарегистрировать этот инструментарий, тем более что это бесплатно и в будущем может принести вам немалую пользу, например обновление установленных компонентов. После регистрации вы попадете непосредственно в главное окно SUN ONE Studio 4 Mobile Edition, где перед вами появится диалоговое окно Welcome SUN ONE Studio 4 update 1, Mobile Edition, показанное на рис. ЗЛО, благодаря которому можно создать проект или открыть необходимый файл.

Рис. 3.10. Окно Welcome SUN ONE Studio 4 update 1, Mobile Edition

С помощью окна Welcome можно осуществить так называемый быстрый старт, выбрав необходимое действие. По размеру окно довольнo таки большое и разделено на две части. В его нижней области имеется возможность отключения появления этого окна при открытии среды программирования SUN ONE Studio 4 Mobile Edition. Произведя таким образом настройку инструментария при первом старте, вы получите все рабочее окно SUN ONE Studio 4 Mobile Edition, изображенное на рис. 3.11.

Рис. 3.11. Рабочее окно SUN ONE Studio 4 Mobile Edition

Главное окно инструментария выполнено в лучших традициях подобных средств программирования, предоставляя большое количество разнообразных панелей инструментов, меню, кнопок, текстовых полей, а также окно Explorer (обозреватель), которое находится с левой стороны рабочей поверхности SUN ONE Studio 4 Mobile Edition. Окно Explorer состоит из трехвкладок: Файловые системы, Выполнение и Javadoc. Они находятся в нижней части окна Explorer.

Вкладка Файловые системы дает возможность подключить к проекту рабочую директорию, где, впоследствии, будут находиться исходные коды, то есть произвести монтаж файловой системы. Там же происходит подключение архивов Archive (JAR, Zip), о чем подробно будет рассказано в разделе 3.2.2.

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

Вкладка Javadoc содержит сгенерированную документацию к проекту в виде HTML страниц.

Линейка меню, в верхней части среды программирования SUN ONE Studio 4 Mobile Edition, содержит множество команд. Щелкнув мышью на одном из названий, откроется выпадающее меню, содержащее список новых команд. Некоторые команды имеют выпадающие подменю. Рассмотрим ряд основных команд среды программирования SUN ONE Studio 4 Mobile Edition. Напротив каждой из команд в скобках находятся названия «горячих клавиш» для быстрой работы с системой.

Меню File

  • New (Ctrl+N) - создает новый файл.
  • Mount Filesystem - осуществляет монтирование файловой системы.
  • Unmount Filesystem - удаляет файловую систему.
  • Open File (Ctrl+O) - открывает файл.
  • Save (Ctrl+S) - сохраняет открытый файл.
  • Save All - сохраняет все открытые файлы.
  • Print (Ctrl+P) - печать.
  • Page Setup - предварительный просмотр.
  • Exit - выход из SUN ONE Studio 4 Mobile Edition.

Меню Edit

  • Undo (Ctrl+Z) - возврат произведенной операции на шаг назад.
  • Redo (Ctrl+Y) - переводк произведенной операции на шаг вперед.
  • Cut (Ctrl+X) - вырезает часть кода, текста и так далее.
  • Copy (Ctrl+C) - копирует информацию в буфер обмена.
  • Paste (Ctrl+V) - вставка.
  • Delete (Delete) - удаление информации.
  • Find (Ctrl+F) - поиск.
  • Replace (Ctrl+H) - повтор.
  • Search Filesystem - поиск файловой системы. х

Меню View

  • Explore From Here (Ctrl+O) - открывает окно обозревателя в главном окне.
  • Properties (Ctrl+1) - свойства файла.
  • Explorer (Ctrl+2) - обозреватель.
  • Source Editor (Ctrl+3) - текстовый редактор.
  • Output Window (Ctrl+4) - окно вывода, показывает результат работы программы.
  • Debugger Window (Ctrl+5) - окно отладчика.
  • Web Browser (Ctrl+7) - Интернет-браузер.
  • Javadoc Index Search (Shift+Fl) - поиск по индексу в документации.
  • Workspaces - рабочее окно.

Меню Project

  • Project Manager (Ctrl+Shift+F9) - открывает окно менеджера проекта.
  • Compile Project (Ctrl+Shift+Fl 1) - компилирует весь проект.
  • Build Project (Ctrl+Shift+Fl 1) - компонует весь проект.
  • Set Project Main Class (Ctrl+Shift+M) - устанавливает выбранный файл с кодом - главным классом всей программы.
  • Debug Project (Ctrl+Shift+F5) - отладчик проекта.
  • Import Project - импортирует выбранный проект.

Меню Build

  • Compile (F9) - компилирует выбранный файл.
  • Compile All (Shift+F9) - компилирует все файлы проекта.
  • Build (F11) - компонует выбранный файл.
  • Build All (Shift+FH) - компонует все файлы проекта.
  • Stop Compile (Alt+Shift+C) - остановка компиляции.
  • Next Error (F12) - следующая ошибка.
  • Previous Error (Shift+F12) - предыдущая ошибка.

Меню Debug

  • Start (Alt+F5) - запуск откомпилированной программы.
  • Finish (Shift+F5) - остановка работы программы.
  • Add Breakpoint (Ctrl+Shift+F8) - установка точки прерывания.
  • Debugger Window (Ctrl+FS) - окно отладчика.

Меню Help

  • Contents - содержание справки.
  • Наборы Справок - открывает подменю с набором имеющихся справок.


3.2.2. Создание проекта в SUN ONE Studio 4 Mobile Edition

Для создания проекту в среде SUN ONE Studio 4 Mobile Edition, необходимо выбрать в меню команду Project => Project Manager, в появившемся окне менеджера проектов изображенного на рис. 3.12, нажмите кнопку New.

Рис. 3.12. Окно менеджера проектов

Вместо окна менеджера проектов появится небольшое диалоговое окно Create New Project, где в поле Project Name необходимо задать имя проекту, например Demo и нажать на кнопку ОК. После этих действий на экране появится окно конфигурации созданного проекта показанное на рис. 3.13.

В окне конфигуратора проектов есть два пункта: Java 2 Standard Edition (J2SE) и Mobile Information Device Profile (CLDC\MIDP), выполненные в виде списка выбираемых элементов. Выбрав один из двух пунктов можно сконфигурировать проект для создания стандартной программы на Java 2 SE, либо приложение для мобильных телефонов если избрать пункт Mobile Information Device Profile (CLDC\MIDP). Выбираем пункт для создания мобильных приложений

Рис. 3.13. Окно конфигуратора проекта

и нажимаем кнопку Finish. После чего в нижней части окна Explorer, к вкладкам Файловые системы, Выполнение и Javadoc, добавится еще одна вкладка Project Demo. Затем необходимо произвести монтирование файловой системы для сконфигурированного проекта. В нижней части окна Explorer, перейдите на вкладку Файловые системы и в появившемся окне нажмите правой кнопкой мыши на надписи Файловые системы. В ответ на эти действия появится череда выпадающих меню, выберите команду Mount => Archive (JAR, Zip), изображенную на рис. 3.14.

Рис.3.14. Вкладка Файловые системы

Выбрав команду Archive (JAR, Zip), вы перейдете к окну New Wizard -Archive (JAR, Zip), с помощью которого производится монтаж необходимой для проекта библиотеки Java API. Все библиотеки скомпонованы в виде архивов, например библиотека для профиля MIDP 1.0, содержится в архиве midpapi.zip. Ситуация здесь несколько запутанная. Как уже говорилось в состав инструментария SUN ONE Studio 4 Mobile Edition входит также среда J2ME Wireless Toolkit версии 1.0.4 01, содержащая архив API для профиля MIDP 1.0. На рис. 3.15 показано окно New Wizard -Archive (JAR, Zip) и подключаемый архив API, находящийся в папке lib среды J2ME Wireless Toolkit 1.0.

Рис. 3.15. Окно New Wizard - Archive (JAR, Zip)

При установке более поздней версии этой интегрированной среды вы сможете подключать API и для профиля МШР 2.0, выбрав соответствующий файл из директории, в которую была установлена среда J2ME Wireless Toolkit 2.1 более поздней версии. Также существует возможность Выбора и других API, предоставляемых конкретным производителем телефонов, в том случае, если вы желаете использовать библиотеку сторонних производителей. В следующей главе будет рассмотрена установка и настройка различных телефонных эмуляторов и программного обеспечения для программирования телефонов разнообразных марок.

После монтирования файловой системы., необходимо также произвести монтаж директории, где будет содержаться исходный код созданного проекта. Монтаж директории происходит по той же схеме, что и монтаж файловой системы, но в выпадающем меню нужно выбрать команду Mount => Local Directory и в появившемся окне New Wizard - Local Directory указать место, где будет храниться исходный код программы, поле чего нажмите кнопку Finish. Создав рабочий каталог для приложения, его необходимо добавить в проект. Нажмите правой кнопкой мыши на только что добавленной директории во вкладке Файловые системы окна Explorer и в появившемся меню выберете команду Tools => Add to Project. Для каждого нового создаваемого проекта, необходимо произвести все выше описанные действия из раздела 3.2.2.


3.2.3. Создание приложений в SUN ONE Studio 4 Mobile Edition

Завершив создание проекта, можно переходить к написанию кода приложения. Для этого перейдите на закладку созданного проекта Demo, в окне Explorer и выберете команду меню File => New File, либ9 воспользуйтесь горячими клавишами Ctrl+N. На экране появится окно New Wizard, представленное на рис. 3.16, где происходит выбор шаблона создаваемого приложения.

Рис. 3.16. Окно New Wizard

В качестве создаваемой демонстрационной программы произведем выбор шаблона HelloMIDlet, который формирует код простой программы, имеющей название мидлет и позиционирующейся в Java 2 ME как приложение, написанное специально для мобильного устройства. В главе 5 будет дано подробное объяснение сути мидлета. Нажав на кнопку Next, вы попадете в следующее окно New Wizard - HelloMIDlet, где необходимо указать будущую директорию нахождения мидлета и задать имя пакету, либо воспользоваться стандартным пакетом, предоставляемымпо умолчанию. На рис. 3.17 показано окно New Wizard -HelloMIDlet с выбранной директорией и пакетом по умолчанию.

Рис. 3.17. Окно New Wizard - HelloMIDIet

Указав пакет и выбрав директорию, нажмите на кнопку Finish. После этого будет автоматически сгенерирован простейший код примера HelloMIDlet проекта Demo, который появится в текстовом редакторе Source Editor, с правой стороны в свободном до этого времени пространстве главного окна среды SUN ONE Studio 4 Mobile Edition, представленного на рис. 3.18.

Рис. 3.18. Окно проекта Demo

Работа с кодом в текстовом редакторе Source Editor, осуществляется обычным образом, характерным практически для всех сред программирования.


3.2.4. Компиляция и запуск программ в SUN ONE Studio 4 Mobile Edition

В результате всех вышеперечисленных действий вы получили код простого примера HelloMIDlet выводящего на экран телефона информационную надпись Test string. Но сначала необходимо откомпилировать и собрать программу. Для компиляции исходного кода выберете в меню команду Build => Compile или используйте «горячую» клавишу F9. Откомпилировав рассматриваемый пример, произведите компоновку всего проекта путем выбора команды из меню Build => Build или нажмите клавишу F11. После этих действий у вас появится возможность запуска созданной программы на эмуляторе телефона предоставляемого средой программирования SUN ONE Studio 4 Mobile Edition. Для этого в меню выберете команду Debug => Start или воспользуйтесь сочетанием клавиш Alt+F5. После запуска откомпилированной и скомпонованной программы на экране появится эмулятор телефона изображенный на рис. 3.19.

Рис. 3.19. Эмулятор телефона, демонстрирующий работу примера HelloMIDIet

Эмуляторы телефона, существующие в составе SUN ONE Studio 4 Mobile Edition, представлены встроенной средой программирования J2ME Wireless Toolkit 1.0. Имеется несколько эмуляторов мобильных устройств:

  • DefaultColorPhone - простой телефон с цветным дисплеем;
  • DefaultGrayPhone — телефон с монохромным дисплеем;
  • MinimumPhone - телефон с минимальными техническими характеристиками;
  • Motorola_i85s - эмулятор телефона i85s компании Motorola;
  • PalmOS_Device - представляет устройство фирмы Palm;
  • RIMJavaHandheld - представляет устройство фирмы Blackberry.

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

Рис. 3.20. Вкладка Выполнение Окна Explorer

Для того чтобы посмотреть доступные эмуляторы, откройте подкаталог Installed Emulators каталога Device Emulator Registry, нажав на ключик с левой стороны подкаталога. Раскрыв подкаталог Installed Emulators, вы увидите вложенную папку J2ME Wireless Toolkit 1.0, содержащую выше перечисленные в этом разделе эмуляторы. Для того чтобы выбрать эмулятор из папки J2ME Wireless Toolkit 1.0, щелкните правой кнопкой мыши на необходимом эмуляторе, например Motorola_j85s и в появившемся меню выберете команду Set As Default, назначив этот эмулятор текущим для данного проекта. Чтобы протестировать созданную программу на новом эмуляторе, запустите программу снова, выбрав в меню команду Debug => Start или используйте сочетание клавиш Alt+F5. На рис. 3.21 изображен эмулятор телефона i85s фирмы Motorola.

Рис. 3.21. Эмулятор телефона i85s

Впоследствии при установке эмуляторов и средств программирования сторонних производителей, можно подключать новые эмуляторы в инструментарий SUN ONE Studio 4 Mobile Edition. Для этого необходимо выбрать вкладку Выполнение в окне Explorer и нажать на ключ с левой стороны каталога Device Emulator Registry раскрыв ветку дерева этого каталога и правой кнопкой мыши щелкнуть на подкаталоге Installed Emulators. В появившемся меню выберете команду Add emulators. Затем появится диалоговое окно Select emulator installation directory, где нужно указать директорию, в которой установлен необходимый эмулятор, и нажать на кнопку Add. Некоторые производители телефонов позаботились об интеграции своих программных продуктов в среду SUN ONE Studio 4 Mobile Edition и на начальном этапе установке этих средств, можно указать, желаете ли вы встроить устанавливаемую программу в SUN ONE Studio 4 Mobile Edition или нет. В следующей главе будут рассматриваться множество программ от различных производителей, где мы обязательно рассмотрим возможность добавления эмуляторов в среду программирования SUN ONE Studio 4 Mobile Edition.


3.3. Среда программирования J2ME Wireless Toolkit 2.1

Программный продукт J2ME Wireless Toolkit 2.1 компании Sun Microsystems распространяется бесплатно и представляет упрощенную среду программирования. Механизм работы J2ME Wireless Toolkit 2.1 очень прост: вы создаете проект, размещаете файлы исходного кода в директории J2ME Wireless Toolkit 2.1 и компилируете весь проект. Файлы исходного кода могут быть написаны в любом текстовом редакторе. Потом запускаете готовое приложение на эмуляторах доступных в этой среде программирования и тестируете созданную программу.


3.3.1. Установка J2ME Wireless Toolkit 2.1

В папке \SDK находится файл j2me_wireless_toolkit-2_1-windows. Двойной щелчок на этом файле приведет вас в программу установки среды программирования J2МЕ Wireless Toolkit. В первом появившемся окне программы установки Java Virtual Machine Location, показанном на рис. 3.22, необходимо указать путь в директорию, где у вас установлена виртуальная Java машина.

Рис. 3.22. Окно программы установки Java Virtual Machine Location

Если при установке пакета Java 2 SDK SE, вы не изменяли директорию для виртуальной машины, то оставьте прописанный путь, указанный в окне программы установки Java Virtual Machine Location и нажмите кнопку Next. В следующем окне Choose Destination Location, изображенном на рис. 3.23, нужно выбрать место для установки среды программирования J2ME Wireless Toolkit 2.1.

Рис. 3.23. Окно Choose Destination Location

При задании директории нельзя прописывать путь с пробелами, а лучше оставить директорию по умолчанию, выбранную программой установки, иначе в последствии у вас возникнет масса проблем при компиляции исходных кодов. Нажав на кнопку Next в окне Choose Destination Location, подождите конца установки среды программирования J2ME Wireless Toolkit 2.1.

После установки программы, зайдите в меню ПУСК => Все программы => J2ME Wireless Toolkit 2.1 => KToolbar и у вас на экране появится рабочее окно J2ME Wireless Toolkit, показанное на рис. 3.24, где и происходит основная работа над проектами по созданию приложений для мобильных устройств.

Рис. 3.24. Рабочее окно J2ME Wireless Toolkit

Линейка меню среды программирования J2ME Wireless Toolkit, содержит четыре команды, щелкните мышей на названии любой из команд и вы откроете выпадающее меню. Каждое из выпадающих меню содержит ряд команд, разберем основные из них.

Меню File

  • New Project - создает новый проект;
  • Open Project - открывает проект;
  • Save Console - сохраняет информацию с консоли;
  • Utilities - утилиты;
  • Exit - выход.

Меню Edit

  • Preferences - свойства проекта;
  • Clear Console - отчистить консоль.

Меню Project

  • Build - компиляция проекта;
  • Clean - закрывает открытый проект;
  • Run - запуск откомпилированной программы;
  • Package - упаковка проекта;
  • Debug - отладка;
  • Settings - установки проекта.


3.3.2. Создание проекта в J2ME Wireless Toolkit 2.1

Рабочее окно среды J2ME Wireless Toolkit, выглядит на много проще чем SUN ONE Studio 4 Mobile Edition. Для создания нового проекта нажмите на панели инструментов кнопку New Project, либо выберете в меню команду File => New Project. В появившемся окне New Project, показанном на рис. 3.25, в поле Project Name дайте имя всему проекту, например Demo и в поле MIDlet Class Name, задайте название основному классу мидлета приложения.

Рис. 3.25. Окно New Project

Чтобы было понятно, о чем идет речь, забегая вперед, поясню: мидлет в Java 2 ME - это вся программа в целом, а с основного класса мидлета начинается работа всего приложения. Поэтому названия данное в поле MIDlet Class Name должно соответствовать названию основного класса мидлета, нельзя не задавать название основному классу мидлет либо использовать несуществующее название, иначе при компиляции возникнет масса ошибок. В главе 5, вы найдете более подробное объяснение модели работы и построения программ в Java 2 ME. При знакомстве с инструментарием SUN ONE Studio 4 Mobile Edition, был создан проект Demo, основной класс мидлета имел название HelloMIDlet; воспользуемся этим исходным кодом и дадим название классу мидлета HelloMIDlet в поле MIDlet Class Name, и нажмем после этого кнопку Create Project. Вслед за этим появится диалоговое окно Settings for project «Demo», показанное на рис. 3.26, где нужно произвести ряд установок для настройки нового проекта.

Диалоговое окно Settings for project «Demo» разделено на семь вкладок, в каждой из которых можно задавать различные установки для создаваемого проекта. Первая вкладка API Selection, изображенная на рис. 3.26, позволяет задавать конфигурацию и профиль создаваемого проекта. И здесь необходимо быть аккуратным: если вы планируете разрабатывать приложение только под профиль MIDP 1.0, то в поле Target Platform (выбор платформы), нужно указать соответствующий профиль.

Рис. 3.26. Диалоговое окно Settings for project «Demo»

Вторая вкладка Required (Атрибуты), изображенная на рис. 3.27, содержит мета информацию создаваемой программы в виде семи различных значений, которые можно устанавливать должным образом.

  • MIDlet -Jar - Size - размер всего создаваемого приложения;
  • MIDlet -Jar - URL - местонахождение проекта;
  • MIDlet - Name - имя проекта;
  • MIDlet - Vendor - создатель программы;
  • MIDlet - Version - версия программы;
  • MicroEdition - Configuration - конфигурация;
  • MicroEdition - Profile - выбранный профиль.

Вся заданная информация для мидлета будет находиться в JAD файле. По ходу работы над проектом имеется возможность изменения заданных атрибутов с помощью кнопки Settings на панели инструментов рабочего окна J2ME Wireless Toolkit 2.1. Подробно о файлах JAD и JAR будет рассказано в конце этой главы' в разделе 3.4. Все оставшиеся вкладки имеют различные дополнительные свойства и заданные на этих вкладках значения почти всегда можно оставлять по умолчанию. Нажав на, кнопку ОК после всех установок, в окне Settings for project «Demo» будет создан новый проект Demo.

Рис. 3.27. Вклакда Required

Среда программирования J2ME Wireless Toolkit 2.1, к сожалению, не имеет своего текстового редактора. Для создания исходного кода приложения вам необходимо написать код программы в любом удобном текстовом редакторе и поместить этот код в директории J2ME Wireless Toolkit 2.1. Как это делается? В тот момент, когда вы нажмете на кнопку ОК, в окне Settings for project -«Demo» будет создан новый проект, в нашем случае это Demo. А в консоли главного окна среды программирования J2ME Wireless Toolkit 2.1 появятся примерно следующие строки:

Creating project "Demo"

Place Java source files in "C:\WTK21\apps\Demo\src"

Place application resource files in

"C:\WTK21\apps\Demo\res"

Place application library files in

"C:\WTK21\apps\Demo\lib"

Из этих строк следует, что файлы исходного кода (это, как правило, файлы с расширением *.java), необходимо поместить в директорию C:\WTK21\apps\Demo\src. Файлы ресурсов, иконки, изображения и так далее помещаются в директорию C:\WTK21\apps\Demo\res; и файлы библиотек, если таковые используются в C:\WTK21\apps\Demo\lib. То есть, создав исходный код приложения в текстовом редакторе, просто сохраните код в директорию: C:\WTK21\apps\Demo\src. Кроме трех перечисленных папок, созданных в рабочем каталоге проекта Demo, будут автоматически сгенерированно ещё четыре папки:

  • bin - содержит файлы: jar, jad и файл манифеста. Более подробно об этих файлах рассказывается в разделе 3.4, где будет рассматриваться упаковка программ;
  • classes - хранит проверенные откомпилированные классы;
  • tmpclasses - хранит непроверенные откомпилированные классы;
  • tmplib - временная папка для хранения фалов.


3.3.3. Компиляция и запуск программы в J2ME Wireless Toolkit 2.1

В качестве демонстрационного примера мы используем проект Demo, созданный автоматически SUN ONE Studio 4 Mobile Edition в разделе 3.2.3. Найдите исходный код HelloMIDlet проекта Demo в директории, которую вы задали для размещения программ в SUN ONE Studio 4 Mobile Edition или возьмите код HelloMIDlet с компакт диска в папке \Code\ HelloMIDlet, поместите его в директорию C:\WTK21\apps\Demo\src. Затем нажмите кнопку Build на панели инструментов для компиляции и компоновки всего проекта. В рабочее окно J2ME Wireless Toolkit 2.1, добавятся две строчки:

Building "Demo"

Build complete

Здесь я, конечно, исключаю возможность появления ошибок при компиляции, но в реальном программировании приложений без этого не обойтись, программист где-нибудь да забудет поставить точку с запятой. После компиляции и компоновки проекта, нажмите кнопку Run, и на экране появится эмулятор по умолчанию DefaultColorPhone, предоставляемый J2ME Wireless Toolkit 2.1 и изображенный на рис. 3.28.

Рис. 3.28. Эмулятор телефона DefaultColorPhone

На экран эмулятора будет выведено имя проекта, нажав на клавишу эмулятора Select или Launch, вы попадете в рабочий цикл программы, и на экране эмулятора появится надпись Test string. Нажав на клавишу Exit можно выйти из приложения. По окончанию работы эмулятора, в консоли рабочего окна J2ME Wireless Toolkit 2.1, появятся примерно следующие надписи:

Running with storage root DefaultColorPhone

Execution completed.

493084 bytecodes executed

57 thread switches

487 classes in the system (including system classes)

2844 dynamic objects allocated (92068 byte,s)

2 garbage collections (61976 bytes collected)

Это строки информационного характера, которые знакомят вас 6 произошедшими процессами в момент работы приложения. Для того чтобы протестировать созданную программу на других телефонных эмуляторах, необходимо в поле Device среды разработки приложений J2ME Wireless Toolkit 2.1, выбрать из списка нужный эмулятор. В составе J2ME Wireless Toolkit 2.1 имеются следующие эмуляторы телефонов:

  • DefaultColorPhone - простой телефон с цветным дисплеем;
  • DefaultGrayPhone - телефон с монохромным дисплеем;
  • MinimumPhone - телефон с минимальными техническими характеристиками;
  • MediaControlSkin — простейший эмулятор телефона контролирующий воспроизведение звуков;
  • QwertyDevice - портативное устройство с клавиатурой.

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


3.4. Упаковка программ

При создании проекта и последующей компиляции исходного кода, у вас появятся два файла: JAD-файл и файл манифеста. Если вы работаете с Sun ONE Studio, то оба файла будут находиться в рабочем каталоге проекта. Если вы используете среду программирования J2ME Wireless Toolkit, то JAD-файл и файл манифеста будут помещены в папку \bin рабочего каталога приложения. Давайте отталкиваться от созданного в разделах 3.2.3 и 3.3.2 проекта Demo и мидлета HellpMIDlet. В этом случае в соответствующих директориях двух средах программирования будут находиться два файла: Demo.jad и MANIFEST.MF.


3.4.1. Файл манифеста

Файл манифеста MANIFEST.MF описывает возможные атрибуты создаваемого приложения. Откройте файл манифеста программы HelloMIDlet с помощью любого текстового редактора, например блокнота и вы увидите следующие строки:

MIDlet-1: Demo, Demo.png, HelloMIDlet

MIDlet-Name: Demo

MIDlet-Vendor: Unknown

MIDlet-Version: 1.0

MicroEdition-Configuration: CLDC-1.0

MicroEdition-Profile: MIDP-1.0

Эти строки описывают атрибуты приложения. При создании проекта с J2ME Wireless Toolkit в разделе 3.3.2 этой главы упоминалось о диалоговом окне Settings for project «Demo» изображенном на рис. 3.26. Это окно разделено на семь вкладок, в каждой из которых указываются различные атрибуты создаваемого приложения. На основе заданных атрибутов в диалоговом окне Settings for project «Demo», и происходит генерация файла манифеста, а так же JAD-файла.


3.4.2. Файл JAD

Как уже упоминалось, в рабочем каталоге проекта «Demo» будет находиться еще один файл Demo.jad. JAD-файл в мобильных приложениях еще называют дескриптором приложения Qava Application Descriptor). Этот файл используется телефоном во время работы программы для получения информации об имеющихся классах, изображениях, пиктограммах и звуковых файлах всей программы. На основе полученной информации происходит управление внутренними ресурсами приложения. Если вы переместитесь в рабочий каталог проекта «Demo» и найдете сгенерированный файл Demo.jad, то увидите иконку в виде телефона с левой стороны от названия файла. Сделав двойной щелчок левой кнопкой мыши на файле Demo.jad, вы запустите эмулятор телефона вне зависимости от того, открыта ли в данный момент одна из сред программирования или нет. Это еще раз указывает на то, что JAD-файл используется для управления работой программы. Но есть и еще одна интересная особенность JAD-файла. Откройте файл Demo.jad с помощью любого текстового редактора и вы увидите следующие строки:

MIDlet-1: Demo, Demo.png, HelloMIDlet

MIDlet-Jar-Size: 30

MIDlet-Jar-URL: Demo.jar

MIDlet-Name: Demo

MIDlet-Vendor: Unknown

MIDlet-Version: 1.0

MicroEdition-Configuration: CLDC-1.0

MicroEdition-Profile: MIDP-1.0

JAD-файл тоже содержит описание атрибутов приложения и они во многом дублируются в файле манифеста MANIFEST.MF. В программах Java 2 ME, JAD-файл - это дескриптор приложения и используется для управления работой программы. Сервис телефона перед запуском программы обращается именно к JAD-файлу, определяя тем самым возможность работы всей программы на этом телефоне. Если один из параметров будет не допустимым для этой модели телефона, то приложение не будет запущено. Например, телефон не поддерживает ту или иную версию конфигурации и профиля, или размер JAR-файл, больше допустимой памяти в телефоне выделенной для Java программ (правда в этом случае вы вообще не сможете загрузить приложение в телефон).


3.4.3. Файл JAR

В языке Java существует возможность архивации файлов приложения в один файл с расширением *.jar. Файл JAR - это архив, содержащий сопутствующие классы и графические изображения всего приложения. JAR-архив основан на обыкновенном zip-формате, использующемся повсеместно. При написании программ на Java под различные компьютерные операционные системы, программист волен сам выбирать, будет ли он распространять свое приложение в заархивированном виде или в оригинальном. Ситуация с распространением-переносом программ под мобильные телефоны радикально противоположная. Телефоны ограничены в своих ресурсах и в среднем память, отведенная под Java программу, колеблется от 30 до 80 килобайт. Эти цифры обязательно надо учитывать при создании мобильных приложений. Размер в 40-50 килобайт считается оптимальным. В связи с этим все мобильные программы обязаны распространяться в заархивированном виде, то есть в JAR-файле. Написав программу для телефона необходимо ее упаковать в jar-архив. Вернемся к примеру HelloMIDlet проекта Demo и рассмотрим на практике создание JAR-файла.

При использовании Sun ONE Studio 4 Mobile Edition создание JAR-файла происходит автоматически после компиляции и компоновки всего проекта и созданный архив помещается в рабочий каталог.

В среде J2ME Wireless Toolkit 2.1 после компиляции исходного кода необходимо произвести явную упаковку программы. Выберете в меню среды J2ME Wireless Toolkit опцию Project => Package => Create Package. На несколько секунд в рабочем окне появится небольшое диалоговое окно, показывающее процесс упаковки программы в JAR-файл. После чего в каталоге проекта Demo в папке \Ып появится файл Demo.jar. А теперь перейдите в рабочий каталог проекта Demo и найдите сформированный архив Demo.jar. Затем воспользуйтесь любым архиватором, поддерживающим zip-формат, например WinRar или WinZip и откройте файл Demo.jar. Вы увидите файл HelloMIDlet.class и папку META-INF, открыв которую обнаружите файл манифеста MANIFEST.MF.

Что происходит при создании архива? В момент упаковки приложения в JAR-файл, происходит копирование всех имеющихся откомпилированных и проверенных классов и графических изображений (если таковые имеются) и размещение их в JAR-файл, то есть происходит архивация всей программы. В рассматриваемом примере HelloMIDlet существует всего один класс, но если программа имеет большое количество классов, то все они помещаются в JAR-файл. Также происходит копирование файла манифеста MANIFEST.MF в папку META-INF. После упаковки в рабочем каталоге приложения будут находиться два файла с расширением JAR и JAD и именно в таком виде можно перенести программу в мобильный телефон посредством Интернета или компьютера связанного с мобильным телефоном любым из способов. Все приложения и игры, написанные на Java 2 ME, распространяются именно таким образом. Файл с расширением JAR содержит упакованную программу, а файл с расширением JAD описывает содержимое JAR-файла. При загрузке программ в телефон необходимо указывать путь к JAD файлу, то есть дескриптору приложения и на основании атрибутов JAD-файла происходит работа Java программы. Единственное исключение - это телефоны марки Siemens. При загрузке программ в телефон этой марки нужно указывать путь к JAR-файлу, о чем подробно будет рассказано в следующей главе, в которой будет рассматриваться программное обеспечение, поставляемое производителями мобильных телефонов для эмуляции работы мобильных телефонов различных моделей.


Глава 4. Телефонные эмуляторы

  • В этой главе...
  • 4.1. Программное обеспечение телефонов Nokia
    • 4.1.1. Инструментарий Nokia Developer's Suite 2.0 for J2ME
    • 4.1.2. Программа Nokia PC Suite 5.1
    • 4.1.3. Дополнительные пакеты Nokia
  • 4.2. Программное обеспечение телефонов Siemens
    • 4.2.1. Пакет Siemens Mobility Toolkit
    • 4.2.2. Программа Siemens Date Suite
    • 4.2.3. Дополнительные пакеты Siemens
  • 4.3. Программное обеспечение телефонов Sony Ericsson
  • 4.4. Программное обеспечение телефонов Motorola
  • 4.5. Программное обеспечение телефонов Samsung


В этой главе...

Интегрированные средства разработки приложений для мобильных телефонов рассмотренные в предыдущей главе имеют в своем составе несколько эмуляторов мобильных устройств несуществующих марок телефонов. Эмулятор телефона -это приложение, программно эмулирующее работу реального телефона, учитывая все технические характеристики этого устройства. Большинство производителей мобильных телефонов имеют в своем арсенале наборы инструментальных средств для программирования телефонов называемых SDK (Software Developer Kit) и множество встраиваемых модулей для эмуляции определенных моделей. Самое большое количество программного обеспечения предоставляется компанией Nokia. Сайт этой компании просто «ломится» от изобилия всевозможных программ.

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

  • наличие или отсутствие операционной системы в телефоне;
  • возможность работы с приложениями написанными на Java 2 ME и C++;
  • количество памяти;
  • разрешение дисплея телефона.

В связи с этим очень полезно иметь как можно больше программных средств, эмулирующих реальные мобильные устройства, для того чтобы можно было протестировать создаваемую программу. Если вы программируете приложение на Java 2 ME, используя профиль MIDP 2.0 или MIDP 1.0, то на всех имеющихся моделях телефонов, где предусмотрена поддержка Java с соответствующим профилем, ваше приложение будет работать. Но, к сожалению, могут возникнуть проблемы в графическом отображении элементов пользовательского интерфейса, вследствие того, что присутствует ряд очевидных различий в визуальном представлении этих элементов. Также каждый из производителей телефонов придерживается своей системы навигации, что, безусловно, усложняет разработку программного обеспечения. Поэтому имеющиеся наборы SDK и эмуляторов отдельно взятых моделей телефонов, намного облегчают работу программиста.

В своем большинстве программное обеспечение различных производителей интегрируется в визуальные среды от компании Sun Microsystems и Borland, либо существуют в виде отдельных программ. Со следующей главы мы начнем подробное изучение специфики создания приложений с помощью классов имеющихся в составе Java 2 ME.

К сожалению, в контексте этой книги невозможно рассмотреть все нюансы, возникающие при использовании различных телефонных эмуляторов. Количество различных моделей поддерживающих технологию Java 2 ME сейчас велико и переключаться от модели к модели будет сложно. Вследствие этого, за основу всех рассматриваемых программ в книге взят нейтральный эмулятор телефона DefaultColorPhone (простой телефон с цветным дисплеем) из состава инстру-ментариев корпорации Sun, рассмотренных в главе 3. Но, безусловно, очень часто ваше внимание будет акцентироваться и на различных проблемах возникающих при реализации тех или иных программ. Вам же необходимо самим отслеживать имеющиеся различия в рассматриваемых примерах. Эта глава поможет разобраться в тонкостях установки, настройки и работы с программным обеспечением от различных производителей.


4.1. Программное обеспечение телефонов Nokia

Компания Nokia имеет, пожалуй, самое впечатляющее количество программного обеспечения. Многие программы даже не поместились на компакт-диск! Если вы не нашли на диске необходимые вам средства программирования, то посетите сайт компании Nokia: http://forum.nokia.com. Все программное обеспечение, находящееся на компакт-диске или на сайте компании Nokia доступно бесплатно, но на основе регистрации, без которой вы не сможете установить ни один программный продукт этой компании. Поэтому первым делом необходимо посетить сайт этой компании, где, перейдя по ссылке Registration, вам будет предоставлена регистрационная форма, изображенная на рис. 4.1.

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

Весь процесс регистрации происходит в несколько этапов. После того как вы заполните регистрационную форму, изображенную на рис. 4.1, на ваш e-mail придет письмо. Текст письма будет, естественно, на английском языке, в нем вам предложат подтвердить свои намерения в регистрации, для чего необходимо будет перейти по ссылке, имеющейся в этом письме. Перейдя по ссылке, вы попадете на страницу, регистрирующую вас и отсылающую вам еще одни послание. Это письмо будет содержать еще одну ссылку, по которой также надо будет перейти, уже для конечной регистрации в системе. Дальше на ваш домашний адрес, будет выслана бандероль с последней моделью телефона Nokia N-Gage QD (шутка). После двух писем и подтверждений регистрации вы станете зарегистрированным пользователем, и вам будут доступны любые ресурсы с сайта компании Nokia.

Рис. 4.1. Регистрационная форма

Получив доступ в систему, вы сможете заказать необходимый серийный номер, который будет выслан на ваш e-mail, указанный при регистрации. Процесс получения серийного номера очень прост. Зайдя на сайт компании Nokia: http://forum.nokia.com, с правой стороны Интернет страницы вы найдете ряд ссылок. Ссылка Tools&SDK приведет на страницу, отображающую все доступные на этот момент программные средства. Выбрав необходимый вам программный продукт, например Nokia Developer's Suite 2:0 for J2ME, вы попадете на страницу изображенную, на рис. 4.2.

На этой странице вы можете, как скачать этот продукт (в том случае если вы утеряли, подарили или продали компакт диск к книге), так и заказать серийный номер. Под большой, красочно оформленной ссылкой Download now, имеется ссылка Serial number for this product, перейдя по которой вы сможете заказать серийный номер к этому продукту. Заказ серийных номеров других программ происходит таким же образом. Ниже перечислены названия всех имеющихся программных средств компании Nokia находящихся на компакт диске в папке \Nokia:

Рис.4.2. Окно заказа серийного номера

  • Nokia Developer's Suite 2.0 for J2ME;
  • Series 40 Developer Platform 2.0 SDK;
  • Series 60 MIDP 2.1 SDK;
  • Series 90 MIDP 1.0 SDK;
  • Nokia 5100 SDK 1.0;
  • Nokia 3410 SDK 1.0;
  • Nokia PC Suite 5.1.

Программная архитектура всех телефонов Nokia делится на серии платформ (Series Developer Platform): серии 40,60,80 и 90. Раньше еще существовала платформа тридцатой серии, но сейчас она объединена в сороковую серию. Запомнить какие из моделей телефонов принадлежат соответствующим сериям тяжело, но очень легко различать модели по сериям с помощью разрешения дисплея, разбив их на четыре категории:

  • серия 40 - телефоны, входящие в эту серию имеют разрешение дисплея 96x65, 128x128 и 128x160 пикселей;
  • серия 60 - разрешение дисплея 176x208 пикселей;
  • серия 80 - разрешение дисплея 640x200 пикселей;
  • серия 90 - разрешение дисплея 640x320 пикселей.

Телефоны, принадлежащие к серии 40, не имеют полноценной операционной системы и работают на основе прошивки. Для этой серии телефонов доступно программирование приложений только на языке Java 2 ME, при условии поддержки самой технологии Java конкретной моделью телефона. Серии 60, 80 и 90 построены на операционной системе Symbian и кроме возможности программирования на языке Java, дают возможность в создании приложений на языке C++. Издательство ДМК Пресс готовит к выходу книгу по программированию мобильных телефонов на базе операционной системы Symbian.

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

Прежде чем устанавливать эмуляторы телефонов Nokia, необходимо установить основной пакет Nokia Developer's Suite 2.0 for J2ME. Все телефонные эмуляторы встраиваются в этот пакет.


4.1.1. Инструментарий Nokia Developer's Suite 2.2 for J2ME

Перед тем как вы начнете устанавливать пакет Nokia Developer's Suite 2.2 for J2ME, позаботьтесь о получении серийного номера для этого продукта с сайта компании Nokia: http: //forum.nokia.com. На компакт-диске в папке \Nokia, находится файл nds_jme_v_2_0.zip. Распакуйте этот архив в любую удобную директорию. После распаковки архива найдите файл setup.exe и нажмите на нем два раза левой кнопкой мыши, вызвав тем самым программу установки пакета. В первом появившемся окне Welcome программы установки пакета изображенном на рис. 4.3, от вас потребуют ввода серийного номера.

Рис. 4.3. Окно Welcome программы установки пакета Nokia Developer's Suite 2.2 for J2ME

Окно Welcome программы установки содержит два поля: Forum Nokia Username - для ввода «логина» под которым вы зарегистрированы на сайте компании Nokia и поле Product Serial Number где необходимо ввести серийный номер полученный по электронной почте, Если вы еще не заказывали серийный номер для устанавливаемого пакета, но являетесь зарегистрированным пользователем, то можно указать только свой логин в поле Forum Nokia Username и нажать на кнопку Next. После чего произойдет соединение с сайтом forum.nokia.com, где вы сможете заказать серийный номер. После ввода серийного номера и логина, нажмите кнопку Next для перехода в окно Choose install set, изображенное на рис. 4.4.

Рис. 4.4. Окно Choose install set программы установки пакета Nokia Developer's Suite 2.2 for J2ME

Окно программы установки Choose install set имеет три варианта выбора для последующей установки пакета Nokia Developer's Suite 2.0 for J2ME:

  • Standard installation. Производит стандартную установку в виде отдельно существующего пакета без интеграции в какую-либо среду программирования;
  • Integration with Borland JBuilder. Интегрирует пакет Nokia Developer's Suite 2.0 for J2ME в интегрированную среду программирования Borland , JBuilder;
  • Integration with Sun™ ONE Studio. Происходит интеграция с визуальной средой программирования Sun ONE Studio.

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

В предыдущей главе были рассмотрены средства программирования от компании Sun Microsystems, поэтому в дальнейшем при установке пакетов всех имеющихся производителей мы будем придерживаться программных средств компании Sun Microsystems. После того, как вы нажмете кнопку Next в окне Choose install set, вы попадете в окно Select the installation directory of your Sun. IDE, показанное на рис. 4.5.

Рис. 4.5. Окно Select the installation directory of your Sun IDE

Убедитесь, что в поле Please choose a directory прописан правильный путь в директорию с инструментарием Sun ONE Studio 4 Mobile Edition и нажмите кнопку Next. Дождитесь конца инсталляции, и не забудьте после всех действий перезагрузить компьютер.

После удачной установки запустите программу из меню ПУСК => Все программы => Nokia Developer Tools => Nokia Developer's Suite2.0 for J2ME => Run as a Standalone и вам откроется основное окно программы, Nokia Developer's Suite2.0 for J2ME, изображенное на рис. 4.6.

Рис. 4.6. Окно Nokia Developer's Suite for the Java™ 2 Platform, Micro Edition

С левой стороны основного окна программы имеется вкладка расположенная вертикально вдоль всего экрана дисплея. Эта вкладка состоит из шести больших интерактивных кнопок:

  • Create Class - создание класса;
  • Create Application Package- создание пакета;
  • Sign Application Package - проверка сигнатуры приложения;
  • Deployment - показывает подключенный к компьютеру телефон и предоставляет связь с сервером;
  • Start Emulators - запуск эмуляторов;
  • Audio Converter - аудио-конвертер для конвертации звуковых файлов.

Нажав на кнопку Start Emulators, вам откроется окно, изображенное на рис. 4.7.

Рис. 4.7. Окно выбора телефонных эмуляторов

В состав пакета Nokia Developer's Suite2.0, входит два эмулятора - это эмулятор телефона Nokia 7210 сороковой серии и эмулятор телефонов шестидесятой серии, который представляет некий собирательный образ телефонов этой серии. Для того чтобы запустить на эмуляторах, приложение, необходимо в поле Application, указать путь до JAR-файла, а в поле Select Emulators, выбрать телефонный эмулятор с помощью галочки с левой стороны названия эмулятора. Здесь нет ограничений и можно выбрать сразу оба эмулятора. После чего нажмите на кнопку Emulate, и на экране появится выбранный эмулятор телефона. На рис. 4.8 показан эмулятор Nokia 7210 сороковой серии показывающий работу проекта Demo, созданного в главе 3 и выводящего на экран строку текста Test string.

В окне Nokia Developer's Suite for the Java™ 2 Platform, Micro Edition, где перечислены доступные эмуляторы, с правой стороны имеется кнопка Configure, нажав на эту кнопку, вы попадете в окно, в котором можно задать ряд установок, осуществляющих конфигурацию доступных на данный момент эмуляторов. В частности в поле Select language, можно выбрать язык для меню телефона, а в поле Emulators, добавить или удалить эмуляторы телефонов с помощью кнопок Add (добавить) и Remove (удалить).

Если при инсталляции пакета Nokia Developer's Sui-te2.0 вы указали интеграцию с визуальной средой программирования Sun ONE Studio в окне Choose install показанное на рис 4.4, то при работе с Sun ONE Studio 4 Mobile Edition, вы сможете запускать соответствующие эмуляторы. Для этого необходимо в Sun ONE Studio 4 Mobile Edition выбрать команду в меню Tools =>Nokia => Developer's Suite for J2ME => Start Emulators, после чего появится диалоговое окно Start Emulators. В этом окне нужно указать путь к приложению в поле Application и в поле Select Emulators выбрать необходимый эмулятор телефона Nokia.

Пакета Nokia Developer's Suite2.0 представляет собой некую базу, в которую в последствии встраивается основная часть имеющихся телефонных эмуляторов и SDK компании Nokia. Проинсталлируйте все имеющиеся SDK находящиеся на компакт-диске в папке \Nokia самостоятельно, теперь этот процесс не должен вызвать никаких трудностей.

Рис 4.8. Телефонный эмулятор Nokia 7210


4.1.2. Программа Nokia PC Suite 5.1

В качестве приятного бонуса в папке \Nokia на компакт-диске к книге вы сможете также обнаружить бесплатно распространяемую программу Nokia PC Suite 5.1, обеспечивающую связь телефона с компьютером и содержащую в своем составе большое количество разнообразных утилит.

  • Nokia Application Installer - помогает устанавливать Java 2МE приложения на телефоны Nokia;
  • Nokia Content Copier - производит резервное копирования информации с телефона на компьютер и удаляет файлы с телефона;
  • Nokia Image Converter - преобразует изображения в форматах *.bmp, *.gif, *.ipg, *.ipeg, *.png, *.otb, *.wbmp, в фоновое изображение для телефона Nokia;
  • Nokia PC Sync - синхронизирует телефон с компьютером;
  • Nokia PC WAP Manager - изменяет установленные WAP настройки телефона через компьютер;
  • Nokia Phone Browser - осуществляет управление папками телефона через проводник операционной системы Windows;
  • Nokia Phone Editor - производит управление различными функциями телефона через компьютер;
  • Nokia Sound Converter - конвертирует файлы MIDI для последующего воспроизведения их на телефоне.

Программа Nokia PC Suite 5.1 русифицирована и вы всегда сможете обратиться к контекстной справке, если возникнут осложнения с использованием одной из утилит.


4.1.3. Дополнительные пакеты Nokia

В профиле MIDP 1.0 не доступна работа со звуком и рядом других возможностей, поэтому каждый из производителей телефонов поставляет свои пакеты с дополнительными классами. Для телефонов Nokia доступно два дополнительных пакета.

  • com. nokia. mid. sound - содержит класс и интерфейс обеспечивающие работу со звуком.
  • SounListener - этот интерфейс используется для получения событий связанных с воспроизведением;
  • Sound - обеспечивает работу со звуком.
  • com. nokia. mid. ui - графические расширения для классов Java 2 ME;
  • DirectGraphics - интерфейс расширяющий графические классы;
  • DeviceControl - имеет методы контролирующие ряд функций телефона;
  • DirectUtils - содержит дополнительные утилиты;
  • FullCanvas - обеспечивает работу в полноэкранном режиме.

По мере прочтения этой книги вам станет понятно назначение перечисленных классов.


4.2. Программное обеспечение телефонов Siemens

Компания Siemens тоже имеет не малое количество моделей телефонов, которые поддерживают технологию Java 2 ME. Все средства программирования распространяются бесплатно, но требуют предварительной регистрации на сайте компании Siemens www.siemens-mobile.com/developer. Вы найдете следующие программы:

  • Siemens Mobility Toolkit for Java Development;
  • SMTK Emulator Pack for MC60;
  • SMTK Emulator Pack for C60;
  • SMTK Emulator Pack for M55;
  • SMTK Emulator Pack for M50;
  • SMTK Emulator Pack for S57; .
  • SMTK Emulator Pack for S55;
  • SMTK Emulator Pack for SL55;
  • SMTK Emulator Pack for SL45;
  • SMTK Emulator Pack for C55;
  • SMTK Emulator Pack for 2128;
  • Siemens Date Suite.

В качестве основного пакета выступает программа Siemens Mobility Toolkit for Java Development, в которую происходит интеграция имеющихся телефонных эмуляторов различных моделей.


4.2.1. Пакет Siemens Mobility Toolkit

B папке \Siemens находится файл smtk_0_13_2_59, нажав два раза левой кнопкой мыши на этом файле, вы запустите программу установки пакета Siemens Mobility Toolkit. Установка инструментария достаточно проста и вам необходимо в появляющихся окнах, лишь задавать нужные директории для установки пакета. Сам пакет не содержит телефонных эмуляторов, но является основным и первым пакетом, который необходимо установить на компьютер. Все последующие программные средства компания Siemens, а это телефонные эмуляторы и всевозможная документация, встраиваются в пакет Siemens Mobility Toolkit. На рис. 4.9 показаны все имеющиеся эмуляторы.

Рис 4.9. Эмуляторы телефонов Siemens

Эмуляторы, находящиеся на компакт-диске в папке \Siemens, устанавливаются автоматически встраиваясь в пакет Siemens Mobility Toolkit. После установки всех имеющихся программных средств, на рабочем столе компьютера должны появится два ярлыка: SMTK Emulator Launcher и SMTK Manager. Запустив утилиту SMTK Manager, вы увидите небольшое диалоговое окно, изображенное на рис. 4.9.

Рис. 4.10. Диалоговое окно SMTK Manager

Диалоговое окно SMTK Manager состоит из трех вкладок:

  • Select target emulator - позволяет выбрать эмулятор по умолчанию, который будет запускаться при каждом старте SMTK Emulator Launcher. Так- же имеется кнопка Device info для просмотра справочной информации по выбранному эмулятору;
  • SMTK management — на этой вкладке при помощи кнопки Remove можно удалить выбранный из списка эмулятор;
  • Integration with IDE's - производит интеграцию со средой программирования Borland JBulder с пятой по девятую версии.

Установленные телефонные эмуляторы фирмы Siemens вы также можете подключить в среду программирования SUN ONE Studio 4 Mobile Edition. Для этого в среде программирования SUN ONE Studio 4 Mobile Edition выберете вкладку Выполнение в окне Explorer и перейдите по каталогам Device Emulator => Registry Installed Emulators, а в появившемся меню изберете команду Add emulators. В следующем диалоговом окне Select emulator installation directory укажите директорию, в которой установлены эмуляторы телефонов компании Siemens. Если вы установили программу Siemens Mobility Toolkit по умолчанию в корневой каталог то, например путь к телефонному эмулятору М55, будет таким: C:\siemens\SMTK\emulators\M55.

Второй ярлык появившейся на рабочем столе запускает непосредственно программу SMTK Emulator Launcher. После запуска программы появится небольшое диалоговое окно, показанное на рис. 4.11.

Рис. 4.11. Диалоговое окно SMTK to Launcher

В диалоговом окне SMTK to Launcher, можно выбрать телефонный эмулятор необходимый вам для работы. После этого появится -эмулятор телефона и окно команд (commands), изображенное на рис. 4.12.

В окне Commands имеется ряд команд, нас интересует команда Start Java Application с помощью которой можно запустить упакованную Java программу. После двойного щелчка на команде Start Java Application, появится диалоговое окно, в котором нужно указать путь к JAR файлу. Замете, что в телефонных эмуляторах Nokia указывался путь к JAD файлу, а в эмуляторах Siemens к JAR файлу. Выбрав JAR-файл нажмите на кнопку ОК и произойдет запуск выбранного приложения на эмуляторе.

Рис. 4.12. Окно Commands


4.2.2. Программа Siemens Date Suite

В папке \Siemens можно найти программу Siemens Date Suite обеспечивающую связь телефона с компьютером, которая состоит из следующих утилит:

  • Управление контактами - позволяет управлять контактами на карте SIM и телефонной памяти;
  • Управление сообщениями SMS и EMS - осуществляет передачу сообщений SMS и EMS с компьютера;
  • Редактор мелодий - создает новые мелодии или импортирует имеющиеся в телефон;
  • Редактор рисунков - конв'ертирует изображения форматов: *.jpg, *.tif, *.gif, *.bmp, в фоновый рисунок для телефона;
  • XTNDConnect PC - производит автоматическую синхронизацию с программами Outlook и Lotus Notes;
  • Data Exchange Software- позволяет производить обмен данными между телефоном и компьютером;
  • GPRS Modem Assistant - настраивает GPRS соединение, для работы - с компьютера.


4.2.3. Дополнительные пакеты Siemens

Компания Siemens имеет десять больших пакетов призванных расширить функциональность классов платформы Java 2ME. Существуют следующие пакеты:

  • com. Siemens .mp - пакет расширения имеющий один класс.
  • MIDlet - абстрактный класс идентичный классу MIDlet в Java 2 ME.
  • com. Siemens .mp.color_game - содержит классы для создания мобильных игр.
  • GameCanvas - абстрактный класс, содержащий основные элементы игрового интерфейса;
  • Layer - абстрактный класс, отвечающий за уровни представляемые в игре;
  • LayerManager - менеджер уровней;
  • Sprite - создает анимационные изображения;
  • TiledLayer - отвечает за создание фоновых изображений в игре.
  • com. Siemens . mp. game - имеет ряд игровых специфических классов;
  • Extendedlmage - улучшает работу с изображениями;
  • GraphicObject - суперкласс для классов Sprite и TiledBackground;
  • GraphicObj ectManager - менеджер графических объектов;
  • Light - класс работы со светом;
  • Melody - воспроизводит мелодии;
  • MelodyComposer - обеспечивает компрессию мелодии;
  • Sound - работает с телефонными звуками;
  • Sprite - создает анимационные последовательности;
  • TiledBackground - создает фоновые изображения;
  • vibrator - обеспечивает вибрацию телефона.
  • com. Siemens .mp. gsm - снабжает дополнительными функциями связь GSM;
  • Cal - класс, обеспечивающий вызов исходящих звонков на номер телефона;
  • PhoneBook - класс, осуществляющий доступ к телефонной книге;
  • SMS - класс, предоставляющий возможность посылки SMS сообщений.
  • com. Siemens .mp. io - сетевой пакет.
  • ConnectionListener - интерфейс, определяющий возможности в получении связи;
  • Connection - поддерживает передачу данных через SMS иIrD А;
  • File - обеспечивает доступ к файловой системе телефона.
  • com. Siemens .mp. Icdui - улучшает функциональность класса Image в Java 2 ME.
  • Image - класс, позволяющий загружать дополнительные графические форматы.
  • com. Siemens .mp. m5 5 - пакет для модели телефона Siemens m55 имеющий один класс.
  • Ledcontrol - позволяет управлять дополнительными клавишами телефона;
  • com. Siemens .mp .media - добавляет возможность работы с библиотекой Mobile Media API.
  • Control - интерфейс, декларирующий контроль над объектами;
  • Controllable - интерфейс, обеспечивающий управление элементов;
  • Player - интерфейс, регулирующий представления медиа-данных;
  • PlayerListener - интерфейс, обеспечивающий получение асинхронных данных;
  • TimeBase - интерфейс, реализующий таймер.
  • com. Siemens .mp.media.control - содержит два специфических интерфейса управления.
  • ToneControl - реализует тональные звуки;
  • VolumeControl-определяетгромкость воспроизведения.
  • com. Siemens .mp.ui - улучшает функциональность класса Image из пакета com. Siemens .mp. Icdui.
  • Image - класс, улучшающий аналогичный класс Image из пакета com. Siemens .mp. Icdui, содержит множество конструкторов и методов.


4.3. Программное обеспечение телефонов Sony Ericsson

Множество телефонов компании Sony Ericsson поддерживают технологию Java 2 ME. Пакет инструментальных средств для программирования мобильных телефонов Sony Ericsson выполнен в виде одного файла и включает в себя все имеющиеся телефонные эмуляторы. Кроме того, после установки инструментария необходимо воспользоваться небольшим по размеру патчем. B папке \Sony Ericsson находится следующие бесплатно распространяемые программы:

  • Sony Ericsson J2ME SDK 2.1;
  • Sony Ericsson SDK 2.1 Patch;
  • Sony Ericsson, Communication Suit.

Копания Sony Ericsson, по всей видимости, удачно сотрудничает с компанией Sun Microsystems. Весь пакет инструментальных средств Sony Ericsson J2ME SDK 2.1 основан на среде программирования J2ME Wireless Toolkit. Причем при инсталляции происходит установка сразу двух версий J2ME Wireless Toolkit. Первая версия J2ME Wireless Toolkit 1 предназначена для написания программ под профиль MIDP 1:0, а вторая версия J2ME Wireless Toolkit 1 для создания приложений под профиль MIDP 2.0. В итоге получается, что весь пакет инструментальных средств Sony Ericsson J2ME SDK 2.1 содержит полноценную среду программирования с набором телефонных эмуляторов. Работа в обеих средах программирования, идентична работе со средой J2ME Wireless Toolkit 2.1 рассмотренной в главе 3.

Установка пакета Sony EricssonJ2ME SDK 2.1 происходит просто: вы должны указать необходимую директорию для инсталляции программы и лучше, если это будет корневой каталог, не содержащий пробелов в названии папки. Единственный возникающий нюанс при инсталляции программы - это выбор устанавливаемых компонентов. На рис 4.13, изображено диалоговое окно Custom Setup.

Рис 4.13. Окно Custom Setup

В этом окне нужно выбрать среду J2ME Wireless Toolkit 1 или J2ME Wireless Toolkit 2, но если вы планируете писать программы под профиль MIDP 1.0 и MIDP 2.0 можно избрать обе среды программирования.

Среда программирования J2ME Wireless Toolkit 1 имеет эмуляторы телефонов поддерживающих создание программ под профиль MIDP 1.0, и содержит следующие модели:

  • Р800;
  • Т610;
  • Т616;
  • Т630;
  • Z6.00.

Доступны и нейтральные телефонные эмуляторы, поставляемые вместе со средой программирования J2ME Wireless Toolkit:

  • DefaultColorPhone - простой телефон с цветным дисплеем;
  • DefaultGrayPhone - телефон с монохромным дисплеем;
  • MinimumPhone - телефон с минимальными техническими характеристиками.

В среде программирования J2ME Wireless Toolkit 2 доступно только три эмулятора - это:

  • Z1010;
  • Z500;
  • К700.

Все три эмулятора поддерживают профиль MIDP 2.0, как и сами телефоны этих трех марок компании Sony Ericsson.

Если вы работаете в интегрированной среде программирования SUN ONE Studio 4 Mobile Edition, то можете подключить имеющиеся телефонные эмуляторы компании Sony Ericsson. В среде программирования SUN ONE Studio 4 Mobile Edition, выберите вкладку Выполнение в окне Explorer и нажмите на знак ключа с левой стороны каталога Device Emulator Registry. Раскроется ветка дерева этого каталога, выберите подкаталог Installed Emulators и в появившемся меню изберете команду Add emulators. Затем появится диалоговое окно Select emulator installation directory, где необходимо указать директорию, в которой установлены эмуляторы телефонов компании Sony Ericsson и нажать на кнопку Add. Если вы не изменяли директорию при инсталляции пакета Sony Ericsson J2ME SDK 2.1, то нужно выбрать следующий путь в диалоговом окне Select emulator installation directory для J2ME Wireless Toolkit 1: C:\SonyEricsson\J2ME_SDK\ PC_Emulation\WTKl. И путь для J2ME Wireless Toolkit 2: C:\SonyEricsson\ J2ME_SDK\PC_Emulation\WTK2. Затем выбираете необходимый эмулятор из списка и тестируете создаваемое приложение на телефонах Sony Ericsson. Также в папке \Sony Ericsson находится программа Sony Ericsson Communication Suite осуществляющая связь телефонов Sony Ericsson с компьютером.


4.4. Программное обеспечение телефонов Motorola

Программное обеспечение фирмы Motorola находится в папке \Motorola и состоит всего из одной, но довольно функциональной программы. После ее установки на рабочем столе появится ярлык Motorola Lanchpad. Запустив программу Motorola Lanchpad, вы увидите диалоговое окно, показанное на рис. 4.14.

Рис. 4.14. Программа Motorola Lanchpad for J2ME

В диалоговом окне Motorola Lanchpad for J2ME в поле Handset представлены все имеющиеся телефоны с поддержкой Java 2 ME в виде эмуляторов. Надо сказать, что количество мобильных устройств, где используется Java технология достаточно велико, посмотрите на список доступных моделей:

  • 388 Simp. Chinese;
  • 388 Trad. Chinese;
  • 6288 Trad. Chinese;
  • 6288 Simp. Chinese;
  • A008 East Europe;
  • A008 North Europe;
  • A008 Simp. Chinese;
  • А008 South Asia;
  • A835;
  • C353t;
  • C370/C450/C550;
  • E380;
  • T280;
  • T720;
  • A830;.
  • v60;
  • v66;
  • A760;
  • A630;
  • C650;
  • E398;
  • T725;
  • V80;
  • V189;
  • V220;
  • V300/V400/V500;
  • V600.

Выберите из выпадающего списка в поле Handset телефонный эмулятор и далее укажите путь к приложению в поле Application. Путь можно задать вручную, а можно воспользоваться кнопкой Browse, выбрав директорию нахождения JAD и JAR файла, то есть программы написанной на Java. Путь нужно указывать к JAD-файлу. Затем нажмите на кнопку Lanch, на экране монитора появится выбранный телефонный эмулятор, а программа Motorola Lanchpad for J2ME автоматически закроется. Для того чтобы программа Motorola Lanchpad for J2ME не закрывалась каждый раз при запуске нового эмулятора, нужно поставит галочку в поле Keep Launchpad open after MIDlet Launch, после того как вы откроете программу Motorola Lanchpad for J2ME.


4.5. Программное обеспечение телефонов Samsung

В папке \Samsung найдите файл JSDKvl_0 - это программа установки. Инсталлируйте программу SamsungJSDK 1.0 на компьютер, а затем откройте установленную программу. Откроется основное окно Samsung JSDK1.0, изображенное на рис. 4.15.

Рис 4.15. Программа Samsung JSDK 1.0

Для того чтобы запустить упакованную Java программу на телефонном эмуляторе поставляемом в пакете Samsung JSDK 1.0, выберите команду File => Import MIDlet и приложение будет запущенно.

Очевидно, что телефонные эмуляторы значительно упрощают процесс разработки приложений, предоставляя разработчику универсальные средства для тестирования создаваемых программ. Представьте, какое количество денег нужно было потратить, для того чтобы приобрести несколько различных моделей телефонов. Но самое главное, пожалуй, это бесплатно распространяемое программное обеспечение, а также отсутствие дорогого лицензирования при создании программ на Java 2 ME. Любой программист из любого региона может бесплатно скачать необходимое программное обеспечение и заниматься разработкой своих собственных проектов при минимальных материальных затратах.

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


Глава 5. Механизм работы приложений Java 2 ME

  • В этой главе...
  • 5.1. Мидлет
    • 5.1.1. Модель работы мидлета
  • 5.2. Пользовательский интерфейс
  • 5.3. Переход с экрана на экран
  • 5.4. Навигация


В этой главе...

С этой главы начинается непосредственно описание работы с кодом. Специфика Java 2 ME приложений несколько своеобразна, но совсем несложная. Достаточно разобраться в общей модели построения программ и все сразу станет понятно.

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


5.1. Мидлет

Приложение, написанное для мобильного телефона, может состоять из различного количества классов. Одни классы, отвечают за загрузку ресурсов, другие за обработку данных, третьи выполняют еще какие-то дополнительные функции, как программист вы вправе выбирать любую удобную для вас модель построения программы. В итоге, созданные вами классы, объединенные в одно целое, будут составлять одну программу или приложение. Все приложения, сформированные для работы в среде Java мобильных телефонов, носят название мидлет. Мидлет -это программа, написанная для мобильного телефона с использованием платформы Java 2 ME. Определять количество классов программы привилегия программиста, но среди всех классов одной программы существует один основной класс, с которого начинается работа всей программы. Этот основной класс мидлета, сердце приложения, он наследуется от класса javax.microedition.midlet. MI Diet. В этом классе описывается код, отвечающий за управление процессом создания интерфейса пользователя, объявления набора данных необходимых для работы всего приложения, создаются объекты имеющихся классов, и что самое главное, он является отправной точкой в работе приложения. Такой класс в Java 2 ME носит название основной класс мидлета.

Рабочие функции, выполняемые этим классом, практически идентичны методу main (). Помните запись, с которой начинался рабочий процесс приложений написанных на Java 2 SE:

public static void main ( String[] args )

На мобильных устройствах аналогичные действия возложены на подкласс класса MIDlet, производящий управление рабочим процессом всего приложения. В дополнение к основному классу, может создаваться ряд классов необходимых для реализации поставленной перед вами задачи. Также имеется возможность собирать несколько мидлетов в один архив. Такая комплектация программ или мидлетов помещенных в один JAR-файл носит название MIDlet suite (набор мидлетов).

В главе 2, когда объяснялась работа в среде Sun ONE Studio 4 Mobile Edition и J2ME Wireless Toolkit 2.1, в частности момент создания проекта Demo, был сформирован простейший код мидлета с названием HelloMIDlet. Этот код был сгенерирован автоматически Sun ONE Studio 4 Mobile Edition, он очень простой и дает хорошую возможность разобраться в структуре мидлета. Посмотрите на листинг 5.1, где приведен код примера HelloMIDlet проекта Demo, созданный в главе 2.
/** Листинг 5.1 Класс HelloMIDlet.java

*/

 import javax.microedition.midlet.*;

import javax.microedition.lcdui.*;

 public class HelloMIDlet extends MIDlet implements CommandListener

 {

 private Command exitCommand;

 private Display mydisplay;

    public HelloMIDlet()

    {

 mydisplay = Display.getDisplay(this);

exitCommand = new Command("Выход", Command.EXIT, 1);

    }

 public void startApp() {

TextBox t = new TextBox("

", "Строка текста", 256, 0);

 t.addCommand(exitCommand);

 t.setCommandListener(this);

 mydisplay.setCurrent(t);

  }

 public void pauseApp() {  }

 public void destroyApp(boolean unconditional) { }

 public void commandAction(Command c, Displayable s)

{

 if (c == exitCommand)

 {

 destroyApp(false);

notifyDestroyed();

 }

 }

}

Первое, что бросается в глаза при детальном рассмотрении кода мидлета - это три метода: startApp (), pauseApp () и destroyApp (). Программисты, которые знакомы с аплетами, найдут явное сходство в структуре мидлета и аплета, даже названия в некоторой степени схожие. В аплете также имеются подобные методы: start (), stop () и destroy (). Можно сказать, что основной класс мидлета - это некий симбиоз аплета и метода main(), играющего основную и управляющую роль в приложении для мобильных устройств. Создавая свои классы и реализуя их код, вы должны возложить основные рабочие функции на основной класс мидлета. На рис. 5.1 показан принцип работы мобильных приложений.

Рис. 5.1. Принцип работы приложения

Сейчас мы вкратце разберем код примера HelloMIDlet проекта Demo, а потом перейдем к более детальному анализу схемы работы приложений в Java 2 ME. Первые две строки кода из листинга 5.1 - это библиотеки импорта.

import javax.microedition.midlet.*;

import javax.microedition. Icdui.*;

В этих строках происходит импорт двух пакетов платформы Java 2 ME. Первый пакет javax.microedition.midlet.* содержит класс MIDlet, с помощью которого происходит связь с MIDP. Каждый код создающий основной класс мидлета обязан импортировать этот пакет. Второй пакет содержит классы, позволяющие создавать пользовательский интерфейс приложения. В следующей главе будут подробно рассмотрены все классы пользовательского интерфейса. Импорт двух пакетов дает возможность задействовать все имеющиеся в этих пакетах интерфейсы, классы, методы и константы, необходимые для работы всего создаваемого приложения. Следующая строка кода:

public class HelloMIDlet extends MIDlet implements

CommandListener

создает основной класс мидлета, наследуемый от суперкласса MIDlet, реализуя при этом методы startApp(), pauseApp() и destroyApp(). Также задействуется интерфейс CommandListener, необходимый для обработки событий происходящих в приложении при помощи метода commandAction(). Далее идут две строки создающие объекты классов Command и Display.

private Command exitCommand;

private Display mydisplay;

С помощью переменной exitCommand осуществляется выход из приложения посредством метода commandAction (). Переменная mydisplay будет представлять дисплей телефона при помощи абстрактного класса Display, играющего роль диспетчера телефонных экранов. В конструкторе класса HelloMIDlet инициализируются объекты exitCommand и mydisplay.

public HelloMIDlet()

{

mydisplay = Display.getDisplay(this);

exitCommand = new Command("Выход",Command.EXIT, 2);

}

В конструкторе класса HelloMIDlet, переменная mydisplay получает ссылку на объект Display при помощи метода getDisplay (). Давайте разберемся эти действия подробно. Вы наверно заметили, что объект Display явно не создается при помощи ключевого слова new. Если быть совсем точным, вы просто не можете этого сделать. Объект класса Display создается автоматически с помощью сервисов телефона для каждого мидлета. Класс Display играет роль диспетчера телефонных экранов, на которые проецируется в итоге все то, что вы будете видеть на дисплее телефона. В телефоне существует всего один основной экран и поэтому в отдельный промежуток времени может быть отражен только один экран, за который отвечает класс Display. С помощью метода getDisplay (), основной класс мидлета получает ссылку на класс Display и содержит ее в переменной mydisplay. В последствии, для того чтобы отразить содержимое текущего дисплея, необходимо воспользоваться методом setCurrent (), например следующим образом:

mydisplay.setCurrent();

Вторая и последняя строка кода в конструкторе класса HelloMIDlet () создает экземпляр класса Command и инициализирует созданный ранее объект exitCommand. Класс Command создает набор информации или набор команд, которые можно отобразить на экране телефона для обработки событий полученных от пользователя. На основе определенного набора команд с помощью интерфейса CommandListener происходит обработка фактических действий пользователя. Посмотрите на рис. 5.2, где на дисплее показана команда Выход, расположенная под экранной клавишей телефона.

Рис. 5.2. Команда выхода из программы

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

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

public Command( String label, int commandType, int priority )

Параметры конструктора класса Command:

  • label - это переменная типа String, содержащая метку в виде простого текста. В примере использовалась команда Выход. Эта строка текста может находиться под кнопками дисплея, либо в виде элемента меню. Обычно команда - это короткое слово. Если необходимо использовать длинное слово, то нужно вызвать конструктор класса Command с четырьмя параметрами;
  • commandType - тип команды соответствующей выбранным действиям. Имеются команды BACK, CANCEL, EXIT, HELP, ITEM, SCREEN, STOP.
  • BACK - возврат к предыдущему экрану;
  • CANCEL - отмена произведенных действий;
  • EXIT - выход из приложения;
  • HELP - вызов справки;
  • ITEM - обычно используется для работы с классом Choice, и производит выбор элемента из группы элементов;
  • SCREEN - представление нового экрана;
  • STOP - остановка выполняемых действий.
  • priority - это приоритет, назначенный для данной команды относительно других команд, имеющихся на дисплее. Приоритет задается целым числом, где более низкое число указывает на более высокое значение.

За конструктором класса HelloMIDlet () следует ключевой метод основного класса мидлета startApp ().

public void startApp()

 {

TextBox t=new TextBox("HelloMIDlet","Текст",256,0);

t.addCommand(exitCommand);

t.setCommandListener (this) ;

mydisplay.setCurrent(t) ;

 }

Метод startApp() вводит приложение в активное состояние и является своего рода входной точкой для всей программы. В рассматриваемом примере для вывода текста на экран используется класс TextBox. Чтобы разобраться, как это происходит, необходимо рассмотреть конструктор класса TextBox:

public TextBox (String title,

 String text,

int naxSize,

int constraints)

Параметры конструктора класса TextBox:

  • title - это титл или основное название, размещенное в верхней части дисплея;
  • text - текст, выводящийся непосредственно на экран. Текст, выводимый на экран можно редактировать и даже не выводить вовсе, выставив значение этого параметра в значение null;
  • maxSize - максимальное количество символов выводимого на экран текста;
  • constraints - с помощью этого параметра можно производить специальные ограничения, но пока рекомендую выставить параметр в 0.

То есть, создав объект класса TextBox, вы задаете область экрана, в которой существует свое название и количество выводимых символов. В следующих двух строках кода:

t.addCommand(exitCommand) ;

 t.setCommandListener(this) ;

сначала добавляется команда Выход, к текущему экрану телефона представленному классом TextBox, а затем с помощью метода setCommandListener () устанавливается обработка событий для этой команды Выход, используя метод интерфейса GoimandListener . Самая последняя строка кода:

mydi splay. setCurrent (t);

отражает текущую информацию на экране. Этот метод подобен кнопке Обновить в Internet Explorer. Вызывая каждый раз метод setCurrent (), вы будете обновлять информацию на дисплее телефона. Следующий метод в примере:

public void pauseAppf)

Тело этого метода пока отсутствует, но с его помощью можно поместить мидлет в состояние паузы и освободить часть используемых ресурсов приложения. Дальше идет метод destroyApp (), освобождающий захваченные мидлетом ресурсы и удаляющий сам мидлет из памяти, то есть закрывает работу приложения. И самый последний метод основного класса мидлета conimandAction () интерфейса CommandListener обрабатывает назначенные события.

public void commandAction(Command c, Displayable s)

 {

if (c ==? exitCommand)

{

destroyApp(false);

notifyDestroyed();

}

 }

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


5.1.1. Модель работы мидлета

После успешной компиляции примера HelloMIDlet и запуска на любом понравившемся вам эмуляторе, на дисплее эмулятора в верхнем левом углу появится надпись HelloMIDlet. В нашем случае мидлет всего один, ни возможна ситуация когда будет несколько мидлетов, то есть MIDlet suite (набор мидлетов), тогда сервис телефона автоматически создаст меню выстроив все имеющиеся мидлеты друг под другом, предоставляя возможность в выборе программы. Но это не значит, что после того, как вы войдете в ваше приложение, сервис телефона и далее будет так же создавать за вас меню. Нет, действия по структуризации приложения, созданию списков и меню лежит на плечах программиста. На рис. 5.3 изображено Меню телефона с набором различных программ.

Для того чтобы запустить программу на эмуляторе, необходимо нажать кнопку Select (выбор), после чего вы попадаете непосредственно в рабочий цикл приложения. После нажатия клавиши Select, то есть подачи команды активизации приложения, в мидлете происходит поиск метода startApp(), который является начальной и входной точкой всех программ. И уже в методе startApp () идет обработка соответствующего программного кода и как следствие, выполнение работы приложения. Конечно, код находящийся до метода startApp (): объекты, конструктор и так далее, так же инициализируются, но активизация рабочего процесса мидлета происходит с вызовом метода startApp ().

Рис. 5.3. Меню в телефоне

В рассматриваемом примере мы воспользовались классом TextBox, который создает область для вывода текста. В связи с этим, на экране появится текстовая строка, изначально прописанная в программном коде в параметре text конструктора класса TextBox. Этот . текст на дисплее можно отредактировать как угодно, воспользовавшись клавишами эмулятора телефона. В нижнем левом углу экрана, вы увидите надпись Выход. Нажав на клавишу телефона под этой надписью, вы автоматически выйдете из программы. При нажатии подэкранной клавиши Выход, происходит запуск метода commandAction (), реакция которого на команду ' Выход, равносильна обработке событий для переменной exitCommand. Обработка события в данном случае подразумевает вызов двух методов - destroyApp () и notifyDestroyed(), благодаря которым происходит обнуление ссылок, если таковые имеются, и выгрузка мидлета и всего приложения из памяти телефона, возвращая- вас в меню телефона, откуда производился запуск рассматриваемой программы. В итоге весь жизненный цикл работы приложения сводится к периоду активизации программы до выхода из нее. На рис. 5.4 показана общая модель работы мидлета.

Рис. 5.4. Модель работы мидлета

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


5.2. Пользовательский интерфейс

Когда мы рассматривали механизм работы примера из листинга 5.1, я думаю, вы подметили некий поэкранный принцип отображения информации на дисплее. Первый экран показывал список доступных приложений, после выбора одного из них вы попадали на экран этого приложения. Нажав кнопку Выход, происходило возвращение к экрану выбора. В Java 2 ME программах такая схема поэкранного отображения информации является основной. Если вы никогда не обращали на это внимания при работе со своим телефоном, то самое время взять его и пощелкать джойстиком. В приложениях для мобильных телефонов основанных на экранах в Java 2 ME отсутствуют окна и фреймы в отличие от Java 2 SE. Телефоны ограничены в системных ресурсах и разнообразная красивая роскошь, к сожалению не позволительна для этих маленьких устройств. Поэтому при создании конечного продукта стоит с особой тщательностью продумывать основные составляющие будущего приложения. Основываясь на поэкранном отображении информации, необходимо создавать интуитивно понятную структуру приложения, образуя при этом четкую экранную навигацию. Если пользователь заблудится в вашей программе, он просто удалит ее из памяти телефона и никогда к ней больше не вернется, а вы потеряете потенциального покупателя.

Как уже отмечалось, экран телефона представлен классом Display. Каждый мидлет может иметь только один объект класса Display, возвращаемый мидлету при помощи метода getDisplay (), определяя тем самым текущий дисплей телефона для мидлета.

Платформа Java 2 ME обладает пакетом javax.microedition.lcdui, включающим в себя классы для работы с пользовательским интерфейсом UI (user interface). Большое количество классов, входящих в этот пакет, будут подробно рассматриваться в следующей главе. Самым главным классом пользовательского интерфейса является класс Displayable. С основы абстрактного класса Displayable происходит построение основной части графического интерфейса приложения. На рис. 5.5 показана структура пользовательского интерфейса пакета javax.microedition.lcdui.

Рис. 5.5. Структура пользовательского интерфейса

От класса диспетчера Display зависит, какой из классов Displayable будет отображен на экране. В свою очередь только один класс Displayable может быть единовременно показан на экране. То есть, объект класса TextBox, грубо говоря, существует в своем экране, объект класса List - в своем и оба объекта не могут существовать вместе на одном экране, определяя тем самым правило поэкранного отражения информации на дисплее телефона.

Далее в иерархии структуры пользовательского интерфейса, показанного с помощью рис. 5.5, идут два абстрактных класса: Screen и Canvas. На этой стадии происходит разделение классов пользовательского интерфейса на высокоуровневый класс, назначенный классу Screen и всей его дальнейшей иерархии наследования и низкоуровневый класс Canvas. Оба класса создают структуру интерфейсов, разделенную на высокоуровневый и низкоуровневый пользовательский интерфейсы.

Высокоуровневый интерфейс содержит средства для работы с пользовательским интерфейсом, созданные на основе классов шаблонов, использование которых приводит к построению жестко заданного интерфейса. Например, задействованный в исходном коде HelloMIDlet проекта Demo класс TextBox, не может никаким образом изменить экран телефона. Экран представленный классом TextBox - это текстовый контейнер, в котором можно осуществлять вывод, удаление и редакцию текста и не более того. То есть классы высокоуровневого интерфейса - это жестко заданная модель отображения пользовательского интерфейса на экране телефона, с помощью которых программист организует навигацию, списки, меню, текстовые контейнеры, группы выбираемых элементов и так далее.

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

На рис. 5.5 была дана часть пакета javax.microedition.lcdui.*, потому что классы Canvas и GameCanvas будут подробно рассматриваться соответственно в главах 7 и 8. Рассмотрим некоторые характеристики классов Alert, TextBox, Form и List представляющие высокоуровневый интерфейс:

  • Alert - предоставляет возможность в создании уведомлений или сообщений об ошибках в виде отдельных экранов;
  • TextBox - массив данных содержащий текстовую информацию с возможностью ее редакции;
  • Form - экранный контейнер, в котором можно разместить различные элементы интерфейса с помощью дополнительных подклассов класса Item;
  • List - список элементов, позволяющий производить выбор различных операций.


5.3. Переход с экрана на экран

Прежде чем мы приступим к изучению основ перехода в приложении с одного экрана на другой, хочу обозначить стоящие перед нами задачи в рассмотрении средств по созданию пользовательского интерфейса. Сейчас вы имеете некоторое представление о модели работы программ для мобильных телефонов. Далее вы изучите основной способ перехода от экрана к экрану внутри приложения на простом примере. Потом код несколько усложнится и будет показан механизм навигации в программах на Java 2 ME. И уже в главе 6 будут изучены все классы пользовательского интерфейса для создания действительно красивых программ. Сейчас мы идем от простого к сложному и я хочу предложить вам новый пример кода, на основе которого будет изучена схема перехода с одного экрана на другой. Попутно мы задействуем все четыре высокоуровневых класса TextBox, Form, List и Alert.

Прежде чем коснуться непосредственно программирования любого приложения, нужно уделить внимание теоретической части создаваемой программы. Лично я, когда разрабатываю некую программу для мобильного телефона, беру чистый листок бумаги, карандаш и рисую предполагаемый набор экранов, указывая на связь между ними с помощью стрелочек. Это, конечно, не язык UML, но достаточно просто и эффективно. На рис. 5.6 даются все четыре дисплея и связь между ними.

Рис. 5.6. Переход с экрана на экран

Идея этого показательного примера очень проста. Первым делом после входа в приложение вы попадаете в класс Form, являющимся неким контейнером для элементов пользовательского интерфейса. В этом примере классы Form, List, TextBox и Alert не задействованы в полном объеме, а только показывают информативную надпись названия класса. После попадания на экран представленного классом Form, появятся две кнопки: выхода из программы и переход на следующий экран представленный классом TextBox. После перехода с экрана представленного классом Form в TextBox, на экране появится две кнопки: выход из приложения и переход. Кнопка перехода приведет вас на экран представленный классом List, дав аналогичную возможность выбора перехода. Выбрав переход на экран представленный класс Alert, вы увидите на некоторое время экран с надписью Alert и автоматически возвратитесь в List. По своей специфики класс Alert предназначен для сообщения информации об ошибке или исключительной ситуации, этим объясняются и соответствующие действия этого класса. Приступим к написанию кода этого примера. Первым делом импортируем две библиотеки:

import javax.microedition.midlet.*;

import javax.microedition.Icdui.*.

Затем создаем класс Perexod, наследуемый от класса MIDlet.

public class Perexod extends MIDlet implements

CommandListener

Теперь необходимо создать объекты класса Command. Объект exitMidlet нужен для выхода из программы. Код, реализующий это событие аналогичен коду из предыдущего примера, рассмотренного в листинге 5.1. И еще три объекта будут служить для перехода от экрана к экрану:

private Command exitMidlet;

private Command perexodTextBox;

private Command perexodList;

private Command,perexodAlert;

private Display mydisplay;

Названия этих объектов достаточно информативны и в объяснении не нуждаются. Далее очередь подошла к конструктору класса Perexod. Первым делом сохраним ссылку на Display в переменной mydisplay:

mydisplay = Display.getDisplay(this);

Следующим шагом создадим два объекта класса Command, один для выхода из программы, другой для перехода на экран представленный классом TextBox.

exitMidlet = new Command("Выход",Command.EXIT,1);

perexodTextBox = new Command("Перейти",Command.SCREEN,2);

Создание этих объектов в конструкторе - не обязательное условие. Просто я основывался на предыдущем примере и оставил примерную структуру приложения для понимания. На самом деле все четыре объекта класса Command можно было инициализировать еще при их объявлении .в начале класса MainMidlet, что более читабельно. Следующим кодом за конструктором идет метод startАрр (), внутри которого создается объект класса Form. Добавим при помощи метода addCommand () команду Выход - это выход из приложения и команду Переход - это переход на экран представленный классом TextBox. 'Назначим обработчик событий классу Form методом setCommandListener () и присоединим объект myform класса Form к текущему дисплею при помощи метода setCurrent().

public void startApp()

{

Form myform = new Рогт("Это объект класса Form");

myform.addCommand(exitMidlet);

myform.addCommand(perexodTextBox);

 myform.setCommandListener(this);

 // отражает текущий экран

mydisplay.setCurrent(myform); }

Когда вы запустите программу или войдете в рабочий цикл мидлета, то автоматически инициализируются объекты классов и конструктор класса Perexod, а работа программы начнется с вызова метода startApp (). Теперь необходимо назначить соответствующие действия клавишам перехода в методе commandAction () интерфейса CommandListener для обработки пользовательских команд. Переход по кнопке Выход вам уже знаком из предыдущего примера, поэтому оставим все почти без изменения, за исключением информационной команды exitMidlet.

if (с == exitMidlet)

 {

destroyApp(false);

notifyDestroyed();

}

А теперь вплотную займемся командой Перейти. Что от нас требуется? В момент запуска программы мы попадаем на экран представленный классом Form посредством команды perexodTextBox, а требуется прейти на экран представленный классом TextBox. Для создания обработчика событий команды Перейти нужно сформировать объект класса TextBox, позаботиться о следующей кнопке перехода perexodList для перехода на экран, представленый классом List, добавить команду Выход для выхода из программы и команду Перейти. Осталось добавить обработчик событий и присоединить созданный TextBox к текущему экрану. Смотрим, что у нас получилось:

if (с == perexodTextBox)

{

TextBox tb = new TextBox("TextBox", "Текст", 256, 0);

perexodList = new Command("Перейти", Command.SCREEN, 2)*;

tb.addCommand(exitMidlet);

tb.addCommand(perexodList);

tb.setCommandLi'stener (this) ;

Display.getDisplay(this).setCurrent(tb);

}

Обратите внимание на последнюю строку кода в теле условного оператора:

Display.getDisplay.(this) . setCurrent (tb) ;

В данном случае присоединяется созданный объект tb класса TextBox к текущему экрану. Мы говорим о смене экранов для создания четкого и информативного пользовательского интерфейса, на самом деле смены экранов в буквальном смысле не происходит. Существует только один дисплей, назначенный для класса Displey, который отвечает за то, что будет нарисовано на экране телефона, а именно, какой из объектов Displayable. Только один объект Displayable может быть отображен за один раз на экране. То есть существует всего один физический дисплей, к которому присоединяются необходимые объекты классов пользовательского интерфейса через обработку событий. Имеющийся экран просто постоянно перерисовывается, отображая тот или иной объект востребованного класса, а иначе говоря, к текущему дисплею присоединяется объект класса, создавая иллюзию смены экранов. Системные ресурсы телефонов пока малы, поэтому приходится идти на такие хитрости.

Затем в рассматриваемом примере необходимо перейти на экран представленный классом List. Поскольку мы имеем аналогичные требования к экземпляру этого класса, то обработка событий и создание класса List будут идентичными классу TextBox.

if (с == perexodList)

 {

List mylist = new List("List", List.IMPLICIT);

perexodAlert = new Command("Перейти", Command.SCREEN, 2);

mylist.addCommand(exitMidlet);

mylist.addCoiranand(perexodAlert);

mylist.setCommandListener(this);

Display.getDisplay(this).setCurrent(mylist);

}

Позаботившись о переходе на экран представленный классом Alert и о выходе из приложения, можно создать код для объекта Alert, который впоследствии можно присоединить к текущему экрану. Класс Alert несколько специфичен, это вам станет понятно как только вы откроете окно, отвечающее за отображение объекта. Попробуйте после компиляции рассмотренного примера сделать для Alert команду Выход, и посмотрите, что получится. Теперь соединим рассмотренный код в одно целое, получив готовую программу, представленную в листинге 5.2. Пример также можно найти на прилагаемом к книге компакт-диске в папке \Code\Listing5_2\src.

/**

Листинг 5.2

Переход с экрана на экран

*/

// подключаем пакеты

import javax.microedition.midlet.*;

import javax.microedition..lcdui. *;

// создаем класс Perexod

public class Perexod extends MIDlet implements

CommandListener

{

// команда выход из программы

 private Command exitMidlet;

// команда перехода в программе

 private Command perexodTextBox;

private Command perexodList;

 private Command perexodAlert;

// дисплей

private Display mydisplay;

// конструктор класса

 Perexod public Perexod()

 {

mydisplay = Display.getDisplay(this);

// выход из приложения

exitMidlet = new Command("Выход", Command.EXIT, 1);

// переход

TextBox

perexodTextBox = new Command("Перейти", Command.SCREEN, 2);

}

// входная точка всей программы

 public void startApp()

{

// создаем объект класса Form

Form myform = new Form("Это объект класса Form");

// добавляем команду выхода из программы

myform.addCommandfexitMidlet);

// добавляем команду перехода в TextBox

myform.addCommand(perexodTextBox);

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

класса 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)

{

TextBox tb = new TextBox("TextBox", "Текст", 256, 0);

perexodList = new Command("Перейти",Coramand.SCREEN, 2);

tb.addCommand(exitMidlet);

tb.addCommand(perexodList);

tb.setCommandListener(this);

Display.getDisplay(this).setCurrent(tb);

 }

// обработка команды перехода в List

 if (с == perexodList)

{

List mylist = new List("List", List.IMPLICIT);

perexodAlert = new Command("Перейти", Command.SCREEN, 2);

mylist.addCommand(exitMidlet);

mylist.addCommand(perexodAlert);

mylist.setCommandListener(this);

Display.getDisplay(this).setCurrent(mylist);

 }

// обработка команды перехода в Alert

 if (с == perexodAlert)

{

Alert myalert = new Alert("Alert","Текст",null,null);

Display.getDisplay(this).setCurrent(myalert);

}

}

}

После компиляции примера пройдите по всей программе и убедитесь, что вам понятна общая идея и принцип работы смены экранов, на которых строятся все приложения в Java 2 ME.


5.4. Навигация

Рассмотренный пример из листинга 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);

}

}

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


Глава 6. Классы пользовательского интерфейса

  • В этой главе...
  • 6.1. Класс Form
    • 6.1.1. Методы класса Form
  • 6.2. Класс Item
    • 6.2.1. Класс ChoiceGroup
    • 6.2.2. Класс DateField
    • 6.2.3. Класс TextField
    • 6.2.4. Класс Stringitem
    • 6.2.5. Класс Spacer
    • 6.2.6. Класс Imageitem
    • 6.2.7. Класс Gauge
  • 6.3. Класс Alert
    • 6.3.1. Методы класса Alert
  • 6.4. Класс List
    • 6.4.1. Методы класса List
  • 6.5. Класс Ticker
    • 6.5.1. Методы класса Ticker
  • 6.6. Класс Image
    • 6.6.1. Методы класса Image
  • 6.7. Класс Font


В этой главе...

В Java 2 ME имеется пакет javax.microedition.lcdui, определенный для классов пользовательского интерфейса. Как уже отмечалось в главе 5, классы пользовательского интерфейса разделены на высокоуровневый и низкоуровневый интерфейсы. В этой главе будут последовательно рассмотрены все классы высокоуровневого пользовательского интерфейса. Каждый из разделов содержит информацию об одном конкретном классе, предоставляющем ряд возможностей в оформлении интерфейса пользователя. Используя возможности этих классов, вы сможете создавать в приложении списки, группы элементов, загружать в программу изображения, использовать бегущую строку, назначать шрифт текста и многое другое. В разделах по каждому классу пользовательского интерфейса, анализируются конструкторы, основные методы и константы класса, с помощью которых в конце каждого раздела создается приложение, иллюстрирующее раббту этого класса, и приводится листинг всей программы. При рассмотрении методов и констант классов используется только основные компоненты. Для детального анализа составляющих одного из классов обратитесь к приложению 2, которое выполнено в виде справочника по Java 2 ME.

Единственное, о чем необходимо помнить при проектировании и создании пользовательского интерфейса приложения - это об используемом профиле MIDP. В некоторые классы, имеющиеся в составе профиля MIDP 1.0, были добавлены новые методы, константы и даже классы из профиля MIDP 2.0. Например, в классе ChoiceGroup для профиля MIDP 1.0 доступно тринадцать методов, а уже в профиле MIDP 2.0 их насчитывается семнадцать, то есть, добавлено еще четыре новых. В той же документации по Java 2 ME какой-то четкой грани разделяющей два профиля не существует, но при рассмотрении методов и констант упоминается о принадлежности к одному из профилей. Поэтому при создании приложений, например под профиль, MIDP 1.0, необходимо внимательно планировать разработку программ и не задействовать компоненты профиля MIDP 2-0. Если вы разрабатываете программу для профиля MIDP 2.0, то можете пользоваться всеми имеющимися компонентами вне зависимости от принадлежности к одному из профилей.


6.1. Класс Form

Основным экранным классом примеров из главы 5 служил экран, представленный классом Form. Как вы понимаете это не обязательное условие, но я выбрал класс Form не случайно. Дело в том, что реализация класса Form выполнена в виде контейнера, позволяющего встраивать в себя различные компоненты пользовательского интерфейса. Это, пожалуй, единственный и самый мощный по своим возможностям класс. Само по себе название Form подразумевает создание некой формы для заполнения экрана телефона. В предыдущих примерах мы использовали,- так называемую, пустую форму этого класса в виде чистого экрана. Впоследствии, при упоминании термина форма, будет подразумеваться экран телефона, представленный объектом класса Form для интеграции классов пользовательского интерфейса.

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

public Form (String title)

Параметры конструктора класса Form:

  • title — заголовок появляется в верхней части созданного окна.

Второй конструктор класса Form имеет уже два параметра, и позволяет встроить компоненты интерфейса в пустую форму, public Form (String title, Item[] items)

Параметры конструктора класса Form:

  • title - заголовок окна;
  • items - массив компонентов размещаемых в классе Form.

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


6.1.1. Методы класса Form

  • int append (Image img) - добавляет в форму одно изображение. Класс Image дает возможность загрузить изображение на экран телефона, это может быть фон дисплея, элемент интерфейса;
  • int append (Item item) - этот метод добавляет любой из доступных компонентов класса Item в созданную форму;
  • int append(String str) - добавляет в форму строку текста;
  • void delete (int itemNum) - удаляет компонент, ссылающийся на параметр itemNum;
  • void deleteAll () - удаляет все компоненты из имеющейся формы;
  • Item get (int itemNum) - получает позицию выбранного компонента;
  • int getHeight () - возвращает высоту экрана в пикселях доступную для встраиваемых компонентов;
  • int getwidth () - возвращает ширину экрана в пикселях доступную для встраиваемых компонентов;
  • void insert (int itemNum, Item item) — вставляет компонент в форму до определенного компонента;
  • void set (int itemNum, Item item) - устанавливает компонент, ссылающийся на компонент itemNum, заменяя при этом предшествующий компонент;
  • void setltemStateListener(ItemStateListener iListener) -устанавливает переменную iListener для формы, заменяя при этом предыдущую переменную iListener;
  • int size ()-получает количество компонентов в форме.

Благодаря вышеперечисленным методам все компоненты находящиеся в форме, могут быть отредактированы надлежащим образом, например:

Form myform = new Form("Пример");

 myform.append (iteml);

myform.append (item2);

В этом примере в созданную пустую форму добавляются два объекта. Оба объекта, разумеется, должны быть созданы в коде. Точно так же можно воспользоваться всеми методами класса Form для редактирования создаваемой формы. Добавленные в форму компоненты организованны в виде колонок и обычно располагаются по ширине всего экрана. На рис. 6.1 изображен эмулятор с несколькими компонентами интерфейса.

Рис. 6.1. Расположение элементов в форме

Все компоненты, встроенные в форму, жестко закреплены и не перемещаются. Редактировать компоненты можно при помощи методов класса Form, причем присоединенные компоненты располагаются друг под другом, выравниваясь горизонтально. Пользователь может перемещаться по компонентам формы с помощью клавиш Вверх и Вниз. Когда количество добавленных компонентов больше видимой части экрана телефона, то автоматически создается прокрутка. Внизу или вверху экрана появляется стрелочка, сигнализирующая об имеющихся компонентах, выпадающих из зоны видимости. При переходе в нижнюю > часть экрана, как только верхний компонент выйдет из зоны видимости, стрелочка автоматически развернется на 180°, указывая в направлений новых компонентов, выпадающих из зоны видимости. Такой механизм реализован в любом телефоне вне зависимости от производителя. Можно добавлять любое количество компонентов в форму, но очевидно, что необходимо задуматься и о дизайне пользовательского интерфейса и не валить все «в кучу». Наилучшим решением будет продуманная структура переходов с экрана на экран.


6.2. Класс Item

Абстрактный суперкласс Item имеет иерархию из восьми подклассов. Каждый подкласс представляет один из элементов пользовательского интерфейса, например, класс Text Field, создает текстовые поля для ввода пароля, адреса электронной почты или просто числовых значений. Все восемь классов, по сути, устанавливают компоненты пользовательского интерфейса, которые встраиваются в форму определенную классом Form. На рис 6.2 изображена иерархия абстрактного суперкласса Item.

Рис. 6.2. Иерархия суперкласса Item

  • ChoiceGroup - это группа связанных, элементов для дальнейшего выбора предполагаемых действий;
  • Gustomitem - с помощью этого класса можно добавлять различные графические элементы в форму;
  • DateField- класс, с помощью которого имеется возможность редактировать время и дату;
  • Gauge- допускает графическое отображение диаграмм, процессов загрузки;
  • ImageItem - осуществляет показ изображения на экране телефона;
  • Spacer - задает определенное по размеру пространство;
  • Stringltem- с помощью этого класса можно создать произвольный текст. Этот класс не допускает редактирования, он лишь отображает информацию;
  • TextField - предоставляет текстовые поля для редакции.

Любой из рассмотренных классов наследуется из суперкласса Item и может быть добавлен на экран, созданный классом Form. Каждый компонент класса Item содержит с левой стороны область; где при желании можно отобразить изображение в виде иконки. При перемещении компонента, иконка также перемещается вместе с компонентом. Класс Item с помощью имеющихся вcего составе директив задает, в основном, формат отображения для любого компонента. Формат определяет заданную ширину, высоту или выравнивание компонентов в форме, а также класс Item имеет множество методов осуществляющих контроль над компонентами.

Методы класса Item

  • voidaddCommand (Command cmd) - добавляет команду к компоненту;
  • String getLabel () - получает метку объекта Item;
  • int getLayout () - использует следующие директивы для размещения компонентов в форме:
  • LAYOUT_LEFT - выравнивание по левой стороне;
  • LAYOUT_RIGHT - выравнивание по правой стороне;
  • LAYOUT_CENTER - выравнивание по центру;
  • LAYOUTJTOP - выравнивание к верхней области формы;
  • LAYOUT_BOTTOM - выравнивание по нижней стороне экрана;
  • LAYOUT_VCENTER - вертикальное выравнивание по центру. Горизонтальная и вертикальная директивы могут комбинироваться при помощи оператора «|».
  • int getMinimumHeight() -получает минимальную высоту для компонента;
  • int getMinimumWidth () - получает минимальную ширину для компонента;
  • int getPreferredHeight () - получает предпочтительную высоту компонента;
  • int getPreferredWidth() - получает предпочтительную ширину компонента;
  • void notifyStateChanged() - компонент, содержащийся в форме. Уведомляет объект ItemStateListener о своем состоянии;
  • void removeCommand {Command cmd) - удаляет команду из компонента;
  • void setDefaultCommand (Command cmd) - встроенная команда по умолчанию для данного компонента;
  • void setltemCommandListener(ItemCommandListener 1)-устанавливает обработку событий для компонента;
  • void set Label (String label) - устанавливает назначенную метку для компонента;
  • void setLayout (int layout) - устанавливает директивы для форматирования компонента;
  • void setPreferredSize(int width, int height) -устанавливает оптимальную высоту и ширину компонента.

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


6.2.1. Класс ChoiceGroup

С помощью класса ChoiceGroup можно встраивать в форму группу элементов. Группы элементов делятся на три типа: эксклюзивный (EXCLUSIVE), множественный (MULTIPLE) и всплывающий (POPUP). Посмотрите на рис 6.3, где показан эмулятор мобильного телефона, показывающий все три группы элементов.

Рис 6.3. Типы группы элементов ChoiceGroup

Первый тип группы элементов на рис 6.3, выполнен в виде выпадающего меню и спрограммирован на основе типа POPUP. В данном случае это список из четырех флажков, с помощью которых можно выбрать заданные действия. Четыре флажка в меню были созданы абсолютно произвольно. Количество флажков и как следствие, количество вариантов выбора зависит от задачи поставленной перед программистом. Следующая группа, изображенная на рис. 6.3 представлена типом MULTIPLE. В этой группе элементов пользователь имеет возможность многократного выбора, т.е. можно выбрать сразу несколько вариантов. Обычно такая группа элементов используется при настройке различных опций, где возможно указать сразу несколько вариантов выбора. Третья и последняя группа элементов задается типом EXCLUSIVE, и возможен лишь один вариант выбора заданного флажка. Чтобы создать в приложении необходимую группу элементов нужно воспользоваться конструктором класса ChoiceGroup. Всего имеется два конструктора. Первый конструктор с двумя параметрами:

public ChoiceGroup(String label, int choiceType)

Параметры конструктора ChoiceGroup:

  • label - это строка текста или информационная метка;
  • choiceType - тип, указывающий на создаваемую группу элементов. Его можно задавать, например, следующим образом: Choice.EXCLUSIVE, Choice .MULTIPLE или Choice. POPUP.

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

public ChoiceGroup(String label,

int choiceType,

String[] stringElements,

Image[] imageElements)

Параметры конструктора ChoiceGroup:

  • String — строка текста;
  • choiceType - тип, указывающий на создаваемую группу элементов;
  • stringElements - заданный массив текста для каждого элемента группы;
  • imageElaments - заданный массив изображений для каждого элемента группы.

Два последних параметра конструктора класса ChoiceGroup предназначены для создания массива названий и изображений для элементов группы, например, таким образом:

String[]

string = {"Флаг 0","Флаг 1","Флаг 2","Флаг 3"}

Для того чтобы добавить в пустую форму класса Form все три имеющиеся группы элементов, нужно создать три объекта класса ChoiceGroup и воспользоваться методом append () класса Form, например:

ChoiceGroup groupMultiple=new ChoiceGroup("Группа
Multiple",ChoiceGroup.MULTIPLE);

ChoiceGroup groupPopup=new ChoiceGroup("Группа
Popup",ChoiceGroup.POPUP);

ChoiceGroup groupExclusive=new ChoiceGroup("Группа
Exclusive", ChoiceGroup.EXCLUSIVE);

Form myform = new,Form("Встроенный ChoiceGroup");

myform.append(groupPopup);

myform.append(groupMultiple);

myform.append(groupExclusive);

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

Методы класса ChoiceGroup

Всего имеется семнадцать методов, ознакомимся с основными и наиболее используемыми методами.

  • int append (String stringPart, Image imagePart) -добавляет элемент в группу;
  • void delete (int elementNum) -удаляет заданный элемент из группы;
  • void deleteAll() - удаляет все элементы;
  • Font getFont(int elementNum) - получает используемый шрифт элемента группы;
  • Image getlmage(int elementNum) - получает изображение для элемента группы;
  • int getSelectedFlags(boolean[]selectedArray_return) -возвращает значение Boolean для группы элементов. Обычно эта функция используется с эксклюзивным типом элементов группы;
  • int getSelectedlndexl) - возвращает индекс выбранного элемента группы;
  • void insert(int elementNum,String stringPart,Image imagePart) - вставляет элемент в группу;
  • boolean isSelected(in't elementNum) - получает выбранную логическую величину.
  • void set(int elementNum, String stringPart, Image imagePart) - устанавливает текст и изображения в заданный элемент группы, при этом удаляя предыдущую запись;
  • void setFont(int elementNum, Font font) - устанавливает шрифт заданному элементу;
  • void setSelectedlndexfint elementNum, boolean selected) -устанавливает особое состояние для элемента группы при использовании множественного типа;
  • int size ()-возвращает количество используемых элементов группы.

Прежде чем рассматривать практическую часть раздела, давайте разберемся, что именно от нас требуется чтобы воспользоваться компонентами класса ChoiceGroup. Итак, сначала необходимо создать объект класса Form или. пустую форму, куда можно встроить объекты класса ChoiceGroup. Далее необходимо определить, что именно будет происходить при выборе элемента группы. Я предлагаю рассмотреть вариант перехода в новое окно после выбора конкретного элемента группы, где мы выведем простую информационную надпись. Для этого необходимо создать две команды перехода. Одна из команд будет реагировать на выбранный элемент группы, перемещая пользователя в новое окно, а другая команда перехода - возвращать в окно выбора. Пожалуй, это все что от нас 'сейчас требуется, поэтому давайте перейдем к реализации этого примера. Предлагаю не рассматривать по отдельности каждый кусок кода всей программы, а проанализировать весь пример целиком, поле чего остановиться на наиболее непонятных Местах программного кода. В листинге 6.1 показан исходный код рассматриваемого примера.

/**

Листинг 6.1 Класс ChoiceGroup

*/

import javax.microedition.midlet.*;

import javax.microedition.Icdui.*;

public class MainClassChoiceGroup extends MIDlet

implements CommandListener

{

// команда выхода, из приложения

private Command exitMidlet = new

Command("Выход", Command.EXIT, 0);

// команда выбора элемента группы

 private Command vibor = new

Command("Выбрать", Command.SCREEN, 1);

// команда возврата в главное окно

private Command vozvrat = new Command("Назад";
Command.BACK, 0);

// объект класса ChoiceGroup

private ChoiceGroup groupPopup;

// объект класса Form

private Form myform;

// объект mydisplay представляет экран телефона

private Display .mydisplay;

public MainClassChoiceGroup()

 {

mydisplay = Display.getDisplayfthis);

 }

// текст для элементов группы

private String[]

mygroup = {"Флаг 0","Флаг 1","Флаг 2" "Флаг 3"};

public void startApp()

{

// инициализируем объект groupPopup

groupPopup = new ChoiceGroup

("Группа Popup", ChoiceGroup.POPUP,mygroup,null) ;

// создаем форму при помощи объекта Form

myform = new Form(«Встроенный ChoiceGroup «) ;

// добавляем группу элементов

myform.append(groupPopup);

 myform.addCoInmand(exitMidlet) ;

myform.addCommand(vibor);

myform.setCommandListener(this);

// отражаем текущий дисплей

mydisplay.setCurrent(myform);

}

public void pauseAppf) {}

public void destroyApp(boolean unconditional) {}

public void commandAction(Command с, Displayable d)

{

// выход из приложения

 if(с == exitMidlet)

{

destroyApp(false) ;

notifyDestroyed() ;

}

// возврат в myform

if(с == vozvrat)

{

mydisplay.setCurrent(myform);

 }

// обработка выбранного элемента в группе

if(с == vibor)

{

int i = groupPopup.getSelectedlndex();

if(i ==0)

{

Form formPopup = new

Form("Это formPopup"+mygroup[0]);

formPopup.append(mygroup[0]);

formPopup.addCommand(vozvrat);

formPopup.addCommand(exitMidlet);

formPopup.setCorranandListener(this);

mydisplay.setCurrent(formPopup);

}

if(i = = 1)
{

Form formPopup = new

Form("Это formPopup"+mygroup[1]);

formPopup.addCommand(vozvrat);

formPopup.append(mygroup[1]);

formPopup.addCommand(exitMidlet);

formPopup.setCommandListener(this);

mydi splay.setCurrent(formPopup);

}

if(i == 2)

{

Form formPopup = new

Form("Это formPopup"+
mygroup[2]);

formPopup.append(mygroup[2]);

formPopup.addCommand(vozvrat);

formPopup.addCommand(exitMidlet);

formPopup.setCommandListener(this);

mydisplay.setCurrent(formPopup);

}

if(i = = 3)

{

Form formPopup = new

Form("Это formPopup"+mygroup[ 3 ] ) ;

formPopup.append(mygroup[3]);

formPopup.addCommand(vozvrat);

formPopup.addCommandtexitMidlet);

formPopup.setCommandListener(this) ;

mydisplay.setCurrent(formPopup);

}

}

 }

}

Вся программа основывается на классе MainClassChoiceGrop. К команде выхода exitMidlet добавлены еще две команды обработки событий - это vozvrat и vibor. Команда vozvrat возвращает,пользователя обратно в главное окно приложения, в которое он попадает при запуске программы. С помощью команды vibor, происходит выбор заданных действий, то есть отклик программы на выбранный элемент группы. Как мы уже договорились, каждый элемент группы POPUP (всего их будет четыре), должен привести пользователя в свой экран, установленный с помощью класса Form. Далее в листинге 6.1 идет объявление необходимых объектов для классов Form, ChoiceGrop и Display. После конструктора идет строка кода создающая текст для элементов группы:

private String[] mygroup = {"Флаг 0","Флаг'1","Флаг2","Флаг3"};

С помощью переменной mygroup создается массив текстовых данных для инициализации всей группы элементов. После создания переменной mygroup следует код метода startApp (). Первой строкой кода в методе startApp () инициализируется объект groupPopup класса ChoiceGroup. Конструктор этого класса мы подробно уже рассматривали, но небольших пояснений требуют два последних параметра. Оба параметра могут быть представлены в виде массива данных. Предпоследний параметр конструктора класса ChoiceGroup, инициализирующий объект mygroup, создает четыре строки текста в виде выпадающего меню (поскольку мы использовали значение POPUP во втором параметре конструктора класса ChoiceGroup). Все четыре строки текста и есть группа элементов, дающая пользователю выбор конкретных действий. Последний параметр в конструкторе класса ChoiceGroup служит для загрузки каждому элементу группы своего изображения или иконки, которая будет отображаться слева от" текста, назначенного для каждого элемента группы. Поскольку изображения вы еще загружать не умеете (чему мы, безусловно, научимся), то надо выставить это значение в null. После инициализации объекта groupPopup создается форма на основе класса Form, добавляются команды выхода и выбора, и самое главное, происходит встраивание объекта groupPopup класса ChoiceGroup в форму класса Form. После чего текущий экран дисплея отображается посредством строки кода:

mydisplay.setCurrent,(myform) ;

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

После того, как произведен выбор элемента группы и нажата клавиша с командой Выбор, программа попадает в обработчик событий этой команды, назначенный для переменной vibor. Далее используется метод getSelectedIndex() класса ChoiceGroup, с помощью которого происходит получение индекса выбранного элемента группы и помещение результата в переменную i. После чего происходит сравнение полученного индекса с четырьмя значениями, заданными для каждого элемента. Соответственно, после совпадения индекса и значения выбранного элемента, происходят действия заданные для этого выбора. В примере происходит создание нового экрана с информационной надписью о выбранном элементе группы, добавлением команд выхода из приложения и возврата в главное окно программы. В этой программе, в ответ на действия по выбору элемента группы, создается новый экран с объектом класса Form. В ваших программах это могут быть любые другие события, необходимые для решения конкретных задач.


6.2.2. Класс DateField

Это, пожалуй, самый простой класс из всех имеющихся в иерархии класса Item. С помощью класса DateField возможно произвести установку необходимой даты и времени. Используемый интерфейс для отображения даты и времени элементарный и практически все действия по установке заданных параметров даты и времени уже реализованы программно. На рис. 6.4 изображен эмулятор телефона, отображающий текущее время.

В составе класса DateField имеется в наличии два конструктора, для создания объектов этого класса, рассмотрим их. Первый конструктор:

public DateField(String label, int mode);

Параметры конструктора класса DateField:

  • label - строка текста;
  • mode — с помощью этого параметра конструктора, устанавливается, какой именно из компонентов класса DateField будет воссоздан на экране.

Имеется возможность вывести дату с помощью значения DATE, и время, задав значение TIME. Также можно пользоваться комбинированным способом DATE_TIME для отображения обоих компонентов вместе.

Второй конструктор содержит добавочный параметр и позволяет устанавливать время по часовому поясу.

public  DateField(String label, int mode, TimeZone timeZone)

Параметры конструктора класса DateField:

  • label - строка текста;
  • mode - установка заданных компонентов класса DateField;
  • timeZone - это объект класса TimeZone, с помощью которого можно определить часовой пояс. Например:

TimeZone v  =  TimeZone.getTimeZone("GMT");

Класс DateField содержит всего четыре метода:

  • Date getDate() - возвращает текущую дату;
  • void setDate(Date date) - устанавливает новую дату;
  • int get!nputMode() - получает установленные компоненты DATE, TIME или DATA_TIME;
  • void setlnputMode (int mode) - устанавливает компоненты DATE, TIME или DATE_TIME.

Рис 6.4. Текущее время на экране телефона

Перейдем к программному коду и рассмотрим пример, реализующий вывод на экран даты и времени одновременно. Все, что сейчас от нас требуется — это написание кода основного класса мидлета, создание пустой формы и встраивание в эту форму класса DateField. Также необходимо проследить наличие команды выхода из приложения. Все остальное за нас сделает Jауа 2 ME, создав кнопки перехода и команду сохранения настроек даты и времени. В листинге 6.2 дается полный код примера к этому разделу.

/**

Листинг 6.2 Класс DateField .

*/

import javax.microedition.midlet.*;

 import javax.microedition.Icdui.*;

public  class     MainClassDateField extends MIDlet   implements

CoramandListener

{

// команда выхода из приложения

private Command exitMidlet = new Command(«Выход»,
Command.EXIT, 0);

// объект класса DateField

private DateField dt;

// объект класса Form

private Form myform;.

// объект mydisplay представляет экран телефона

private Display mydisplay;

public MainClassDateField()

{

mydisplay = Display.getDisplay(this);

}

public void startApp()

{

//инициализируем объект dt

dt = new DateField("Дата и Время", DateField.DATE_TIME);

// создаем форму при помощи объекта Form

myform = new Form("Встроенный DateField");

// добавить объект dt

myform,append(dt);

myform.addCommand(exitMidlet);

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();

 }

}

 }

 }

В примере создан класс MainClassDateField, соответствующий названию разбираемого класса. Сам по себе пример очень легкий в силу простоты реализации самого класса DateField. Первоначально создается объект dt для класса DateField, после этого происходит его инициализация в методе startАрр (). Создается форма классом Form и объект dt интегрируется в эту форму. Все остальное, а именно: циферблат и календарь, показанные на рис. 6.4, создаются автоматически с помощью эмулятора телефона при выборе одного из элементов класса. В нашем примере был создан объект dt класса DateField, но можно было этого и не делать, а обойтись, например такой простой записью:

Form f = new.Form(new DateField("Дата и Время", DateField.DATE_TIME);

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

После того, как вы откомпилируете этот пример и запустите приложение, на экране появятся два элемента с надписями time и date. Выбрав один из элементов и нажав на кнопку Select, вы попадете, в зависимости от выбора, на экран с календарем или временем, изображенным на рис. 6.4. С помощью джойстика или клавиш перемещения, можно установить необходимые параметры для обоих элементов.


6.2.3. Класс TextField

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

public  TextField(String  label,

String text,

int maxSize, int  constraints)

Параметры конструктора класса Text Field:

  • label - метка, название для редактируемого поля;
  • text - строка текста. Поле может и не содержать текст;
  • maxSize - максимальное количество символов в поле;
  • constraints - входное ограничение, с помощью которого можно задавать, что именно должно принимать данное поле, например цифры, буквы или символы, задается ограничение с помощью следующих констант:
  • static int ANY - можно вводить любой текст;
  • static int DECIMAL - можно вводить дробные числа;
  • static int EMAILADDR - используется для адреса электронной почты;
  • static int NUMERIC-для ввода только целого числа;
  • static int PASSWORD - используется при вводе пароля;
  • static int PHONENUMBER - для ввода телефонного номера;
  • static int URL - адрес сайта в Интернет.

Как видите, предусмотрены практически все варианты, остается только подставлять требуемые значения и наслаждаться простотой программирования под Java 2 ME. Использование вышеперечисленных директив в Java 2 ME традиционно и, например, для ввода адреса сайта может быть следующая запись:

TextField tf  =  new TextField("Адрес","",20,TextField.URL);

Методы класса TextField

Класс TextField содержит четырнадцать методов, некоторые из них мы сейчас рассмотрим.

  • void delete (int offset, int length) - удаляет текст или заданный символ;
  • int ,getCaretPosition() - получает позицию каретки для печати символов;
  • int getChars (char [ ] data) - копирует текст в символьный массив данных;
  • int getMaxSize() - определяет максимально доступное количество символов для размещения в классе TextField;
  • String getString() - получает строку текста;
  • void insert (char [] data, int offset, int length, int position) - вставляет в заданную позицию массив символьных данных;
  • void insert (String src, int position) - вставляет в заданную позицию строку текста;
  • void setChars(char[] data, int offset, int length) —устанавливает из символьного массива данные в заданную позицию, при этом заменяя предыдущие данные;
  • int size ()-определяет размер содержимого в TextField на данный момент.

Теперь перейдем непосредственно к примеру, реализующему возможности класса TextField. Создадим пустую форму, и вставим в нее поля в виде адресной книги. В листинге 6.3 дается код всего примера.

/**

Листинг 6.3 Класс TextField

*/

import javax.microedition.midlet.*;

-import javax.microedition.Icdui.*;

public class MainClassTextField extends MIDlet

implements CommandListenef

{

// команда выхода -из приложения

private Command exitMidlet = new
Command("Выход",Command.EXIT, 0) ;

// объект класса Form

private Form myform;

// объект mydigplay представляет экран телефона

private Display mydisplay;

public MainClassTextFieldf)

{

mydisplay = Display.getDisplay(this);

}

public void startApp()

{

// создаем форму при помощи объекта Form

myform = new Form("Класс TextField");

 // добавить в форму поле для текста

myform.append(new TextField(

"Введите текст:","",20,TextField.ANY));

// добавить в форму поле для пароля

myform.append(new TextField(
"Введите пароль:","",20,TextField.PASSWORD));

 // добавить в форму поле для e-mail

myform.append(new TextField(
"Введите E-mail:","",20,TextField.EMAILADDR));

// добавить в форму поле для URL

myform.append(new TextField(
"Введите URL:","",20,TextField.URL));

// добавить в форму поле для телефонного номера

myform.append(new TextField(
"Телефонный номер:","",20,TextField.PHONENUMBER));

 myform.addCommand(exitMidlet);

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() ;

}

}

 }

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

myform.append(new TextField

("Введите текст:","",20,TextField.ANY));

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

Все созданные поля в листинге 6.3 используют, рассмотренную выше конструкцию программного кода и только в последнем параметре конструктора TextField, значение варьируется для пароля, e-mail, веб-сайта и телефонного номера. Задавая различные значения последнему параметру при создании объекта этого класса, вы можете создать набор необходимых полей. На рис. 6.5 изображен эмулятор, показывающий несколько полей класса TextField.

Рис. 6.5. Поля класса TextField


6.2.4. Класс Stringltem

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

public  StringItem(String  label,String text)

Параметры конструктора класса Stringltem:

  • label - метка для строки текста;
  • text - строка текста.

Второй конструктор класса Stringltem имеет три параметра и позволяет выбирать способ отображения текстовой информации.

public  Stringltem(String label, String text, int appearanceMode)

Параметры конструктора Stringltem:

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

Значения, устанавливающие выше перечисленные действия содержаться в пакете javax.microedition.lcdui.Item, рассмотрим несколько из них.

  • BUTTON - создает кнопку с текстом;
  • HYPERLINK - создает гиперссылку;
  • LAYOUT_BOTTOM - выравнивание к нижней части экрана;
  • LAYOUT_CENTER - выравнивание по центру экрана;
  • LAYOUT_TOP - выравнивание к верхней части экрана;
  • LAYOUT_LEFT - выравнивание к левой части экрана;
  • LAYOUT_RIGHT - выравнивание к правой части экрана.

При создании примера к классу Stringltem обязательно воспользуемся некоторыми значениями для параметра appearanceMode в конструкторе класса Stringltem.

Методы класса Stringltem

  • int getAppearanceMode () - возвращает заданный способ отображения текста на экране;
  • Font getFont () - получает шрифт текста;
  • String getText () - получает текст для класса Stringltem;
  • void setFont(Font font) - устанавливает шрифт текста;
  • void setPref erredSize (int width, int height) -задает ширину и высоту текста;
  • void setText (String text) - устанавливает текст для класса StringItem.

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

/ * *

Листинг 6.4 Класс Stringltem

*/

import javax.microedition.midlet.*;

 import javax.microedition.Icdui.*;

public class MainClassStringltem extends MIDlet

implements CommandListener, ItemCommandListener

{

// команда выхода из приложения

private Command exitMidlet = new Command("Выход", Command.EXIT, 0);

// команда перехода по нажатию кнопки private

Command perexodButton = new Command("Дальше",Command.ITEM, 1);

 // команда перехода по гиперссылке

private Command perexodHyperlink = new Command("Перейти", Command.ITEM, 1);

// команда возврата в основное окно private

Command vozvrat = new Command("Назад", Command.BACK, 1);

// объект класса Form private Form myform,

// объект mydisplay представляет экран телефона private Display mydisplay;

public void startApp()

{

mydisplay = Display.getDisplay (this) ;

myform = new Form("Класс Stringltem");

Stringltem si = new Stringltem("Метку", "Текст");

myform.append(si);

// создать гиперссылку

Stringltem s2 = new Stringltem("Гиперссылка", "www.dmk.ru",Item.HYPERLINK);

s2.setDefaultCommand(perexodHyperlink);

s2.setltemCommandListener(this);

myform.append(s2);

// создать текст в виде кнопки

Stringltem s3 = new

Stringltem("Кнопка","Опции",Item.BUTTON);

s3.setDefaultCommand(perexodButton);

s3.setltemCommandListener(this);

 myform.append(s3);

myform.addCommand(exitMidlet);

myform.setCommandListener(this);

mydisplay.setCurrent(myform);

 }

protected void destroyApp(boolean unconditional) {}

protected void pauseAppO {}

// обработчик класса ItemCommandListener

public void commandAction(Command c, Item i)

{

// переход в окно опций if (с = = perexodButton)

 {

Form f1 = new Form("Опции");

f1.append("Необходимые Опции");

f1.addCommand(exitMidlet) ;

f1.addCommand(vozvrat);

f1.setCommandListener(this) ;

mydisplay.setCurrent(f1) ;

}

// переход по гиперссылке

 if (c = = perexodHyperlink)

{

Form f2 = new Form("Издательство ДМК");

f2.append("Сайт издательства ДМК");

f2.addCommand(exitMidlet);

f2.addCommand(vozvrat);

f2.setCommandListener(this);

mydisplay.setCurrent(f2);

}

 }

public void commandAction(Command c, Displayable d)

{

// выход из приложения

if(с == exitMidlet)

{

destroyApp(false);

notifyDestroyed();

}

//   возврат  в основную форму

if(с  = = vozvrat)   mydisplay.setCurrent(myform);

}

}

В коде листинга 6.4 для наглядности не использовался конструктор основного класса мидлета MainClassStringltem, но добавлялся, как уже упоминалось новый интерфейс ItemCommandListener для установки обработки команд перехода в приложении. В методе startApp () происходит создание пустой формы для класса Form и интеграция класса Stringltem. В строке кода:

Stringltem si = new Stringltemf"Метку", "Текст");

Создается простой статический текст и выводится на дисплей телефона. Следующий блок кода:

Stringltem s2 =new Stringltem("Гиперссылка",

 "www.dmk.ru",Item.HYPERLINK);

s2.setDefaultCommand(perexodHyperlink);

s2.setItemCommandListener(this) ;

myform.append(s2) ;

Stringltem s3 = new

Stringltem("Кнопка","Опции"»,Item.BUTTON);

s3.setDefaultCommand(perexodButton);

s3.setltemCommandListener(this);

myform.append(s3);

формирует текст на экране телефона, назначив для него обработчик событий при помощи метода setltemCommandListener(). Можно получить текст в виде активной ссылки. При создании объекта s2 класса Stringltem использовался конструктор с тремя параметрами. Последний параметр этого конструктора как раз и отвечает за вид создаваемой ссылки. Была создана гиперссылка с помощью константы HYPERLINK. Блоком кода с объектом s3 уже создавалась кнопка. Эта кнопка является так же простым статическим текстом, но оформленным в виде прямоугольной кнопки. Объекту s3 так же назначается обработчик событий методом setltemCommandListener (), благодаря чему и получается активная ссылка. Выбрав ее можно перейти в нужное место в приложении.

Теперь наша программа имеет два одноименных обработчика событий с разными параметрами, представленными двумя интерфейсами CommandListener и ItemCommandListener. Обработчик событий созданный при помощи метода commandAction (Command с, Item i), следит за двумя активными ссылками, выполненными в виде гиперссылки и кнопки. Выбрав одну из активных ссылок и воспользовавшись соответственной командой перехода perexodButton - для кнопки и реrexodHyperlink, вы попадете на экран с новой формой и информационной надписью. Оба новых экрана созданы классом Form, где так же имеются две команды: exitMidlet -для выхода из приложения и vozvrat — для возврата в основное окно. Эти две команды обрабатываются своим методом commandAction(Command с, Displayable d) интерфейса CommandListener. Для того, чтобы создать активную ссылку, необходимо воспользоваться интерфейсом ItemCommandListener, реализовав метод commandAction () для обработки необходимых событий. Рис. 6.6 показывает экран эмулятора с несколькими элементами класса Stringltem.

Рис. 6.6. Элементы класса Stringltem


6.2.5. Класс Spacer

Класс Spacer подвигает элемент на экране телефона, создавая тем самым свободное пространство с указанными размерами. Именно за создание свободного пространства на экране отвечает класс Spacer. При создании объекта класса используется один конструктор с двумя параметрами, при помощи которых задается создаваемое пространство на экране. Конструктор класса Spacer выглядит следующим образом:

public  Spacer(int minWidth,int minHeight);

Параметры конструктора Spacer:

  • minWidth - ширина в пикселях;
  • minHeight - высота в пикселях.

Класс Spacer имеет четыре метода, все они просты и не нуждаются в пояснениях, в приложении 2 находится справочник по платформе Java 2 ME, в котором вы сможете найти описание существующих методов класса Spacer. Чтобы показать работу класса Spacer, рассмотрим простой пример, где создается область в пятьдесят пикселей по ширине и ноль по высоте, благодаря чему элемент, размещенный в форме, сдвигается на указанное пространство вправо. В качестве элемента встроенного .в форму используется класс TextField. В листинге 6.5 дается исходный код примера.

/**

Листинг  6.5

Класс Spacer

*/

import javax.microedition.midlet.*;

import javax.microedition.Icdui.*;

public class MainClassSpacer extends MIDlet implements

CorranandListener

{

// команда выхода из приложения

private Command exitMidlet = new Command("Выход",
Command.EXIT, 0);

// объект класса DateField

private Spacer sp;

// объект класса Form

private Form myform;

// объект mydisplay представляет экран телефона

private Display mydisplay;

public MainClassSpacer()

{

mydisplay = Display.getDisplay(this);

}

 public void startApp()

 {

// инициализируем объект sp

sp = new Spacer(50,0);

// создаем форму при помощи объекта Form

myform = new Form("Класс Spacer");

// добавить объект sp

myform.append(sp);

myform.append(new

TextField("Метку","Текст",20,TextField.ANY));

myform.addCommand(exitMidlet);

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();

 }

 }

 }

В листинге 6.5 создается рабочий класс MainClassSpacer и форма на основе класса Form. Объявляется объект sp для класса Spacer и инициализируется в методе startApp (). При инициализации объекта sp используются два значения для параметров, создавая тем самым пустое пространство с левой стороны от текстового поля, созданного при помощи класса TextField. Эмулятор изображенный на рис. 6.7 показывает работу программы из листинга 6.5.

Класс Spacer был добавлен в Java 2 ME для профиля MIDP 2.0, нельзя сказать, что этот элемент жизненно необходим, но бывают случаи, когда использование класса Spacer облегчает работу программиста.

Рис 6.7. Пространство созданное классом Spacer


6.2.6. Класс ImageItem

С помощью класса Imageltem возможна загрузка изображения в форму представленную классом Form. Изображением может быть любая картинка формата PNG (Portable Network Graphics - формат портативной сетевой графики), выполненная в виде иконки, фотографии, заставки, фона и так и далее. Имеются два конструктора класса Imageltem. Первый конструктор содержит четыре параметра, рассмотрим этот конструктор:

public ImageItem(String label, Image img,

int layout,

String alt Text)

Параметры конструктора ImageItem:

  • label - метка;
  • img - объект класса Image, содержащий изображение;
  • layout - форматирует загружаемое изображение на экране телефона, с помощью использование следующих директив:
  • public static final int LAYOUT_DEFAULT - размещение изображения по умолчанию;
  • public static final int LAYOUT_LEFT - размещение изображения со сдвигом к левой стороне экрана;
  • public static final int LAYOUT_RIGHT - размещение изображения со сдвигом к правой стороне экрана;
  • public static final int LAYOUT_CENTER - размещение изображения со сдвигом к центру экрана.
  • altText - информационный текст, используемый взамен загружаемого изображения. Если текст не используется - этот параметр нужно установить в значение null.

Второй конструктор класса Imageltem имеет на один параметр больше и выглядит следующим образом:

public  Imageltem(String  label,

 Image  img, int   layout,

String altText int  appearanceMode)

Параметры конструктора Imageltem:

  • label - метка;
  • img - объект класса Image, содержащий изображение;
  • layout-форматирование загружаемого изображения на экране телефона;
  • altText - текст, использующийся в замен загружаемого изображения;
  • appearanceMode - этот параметр содержит ряд значений:
  • BUTTON - создает кнопку с текстом;
  • HYPERLINK - создает гиперссылку;
  • LAYOUT_BOTTOM - выравнивание к нижней части экрана;
  • LAYOUT_CENTER - выравнивание по центру экрана;
  • LAYOUT_TOP - выравнивание к верхней части экрана;
  • LAYOUT_LEFT - выравнивание к левой части экрана;
  • LAYOUT_RIGHT - выравнивание к правой части экрана.

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

При загрузке изображений с помощью класса ImageItem существует ряд нюансов, на которые необходимо обратить внимание. Класс ImageItem является подклассом класса Image, прежде чем воспользоваться классом ImageItem, необходимо создать объект класса Image. Затем поместить или загрузить в объект класса Image изображение и только потом воспользоваться классом ImageItem для размещения изображения на экране представленного объектом класса Form. Создавая объект класса ImageItem, вы создаете своего рода контейнер для содержания ссылки на объект Image. Рассмотрим небольшой фрагмент кода, иллюстрирующий создание и загрузку изображения:

Image  a  =   Image.createlmage("/ris.png");

 Imageltem b  =  new  Imageltem("Рисунок",   а,

ImageItem.LAYOUT_CENTER,null);

Первым делом создается объект i класса Image, после чего происходит загрузка необходимого изображения посредством вызова метода createlmage () класса Image. Далее создается объект im класса ImageItem, который будет содержать ссылку на объект image.

Изображение, загружаемое в приложение, может находиться в любом месте рабочего каталога. При использовании, например J2ME Wireless Tollkit 2.1, изображение лучше поместить в папку \res. Эта папка по умолчанию для файлов ресурса к разрабатываемому приложению и в этом случае запись /ris.png будет обращаться к папке \res. Если вы хотите использовать другую папку, то необходимо указать весь путь при загрузке изображения, например:

Image  ikon1  = Image.createlmage("/Ikon/Leve12/ikon1.png"};

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

/**

Листинг 6.6

Класс Imageltem

*/

import javax.microedition.midlet.*;

 import javax.microedition.Icdui.* ;

public class MainClassImageltem extends MIDlet implements

CommandListener

{

// команда выхода из приложения

private Command exitMidlet = new Command("Выход",
Command.EXIT, 1);

// объект класса Form

private Form myform = new Form("Изображение");

// объект mydisplay представляет экран телефона

private Display mydisplay;

public MainClassImageItem()

{

mydisplay = Display.getDisplay(this);

}

public void startApp()

{

// перехватываем исключительную ситуацию

try{

//   загрузка изображения

Image  image  =   Image.createlmage("/gornakov.png");

//   создаем объект  класса  ItemImage

Imagelfcem  im =  new  ImageItem("Фотография",
image,   Imageltem.LAYOUT_CENTER,"");

//  добавляем изображение  в  форму

myform.append(im) ;

}

catch(Java.io.IOException ex){}

// установка  обработчика  событий для Form

myform.addCommand(exitMidlet);

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();

}

}

}

Рис 6.8. Изображение, загруженное при помощи класса Imageltem

Пример достаточно прост: происходит загрузка изображения на экран телефона представленного классом Form с добавлением команды выхода из приложения. Но после компиляции листинга 6.6 и запуска приложения на эмуляторе J2ME Wireless Toolkit 2.1, возникают цветовые дефекты в виде некачественного отображения фотографии. Это вызвано, прежде всего, минимальной цветовой гаммой, представляемой эмулятором J2ME Wireless Toolkit 2.1. Протестируйте код из листинга 6.6 на различных эмуляторах, рассмотренных в главе 4. На рис 6.8 показан эмулятор с изображением на экране фотографии.


6.2.7. Класс Gauge

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

Класс Gauge имеет всего один конструктор, необходимый при создании объекта этого класса. Разберем конструктор класса Gauge:

publicGauge(String label,

boolean interactive,

 int maxValue, int initialValue)

Рис 6.9. Эмуляторы телефонов, показывающие использование класса Gauge

Параметры конструктора Gauge:

  • label - метка или название процесса связанного с объектом Gauge;
  • interactive - имеются два значения: true для интерактивного режима и false — для не интерактивного режима;
  • maxValue - максимальное значение, задающее диапазон длительности всего процесса. Может быть установлено при помощи значения INDEFINITE;
  • static int INDEFINITE - специальное значение, устанавливающее максимальную величину при неизвестном диапазоне течения всего процесса;
  • initialValue - параметр может быть инициализирован значением от нуля и до значения в параметре maxValue. Этим значением инициализируется начальный отсчет, от которого происходит увеличение визуального представления работы процесса. Кроме числовых значений возможно применение заданных констант:
  • static int CONTINUOUS_IDLE - задает непрерывное циклическое течение процесса для не интерактивного режима при неопределенном диапазоне;
  • static int CONTINUOUS_RUNNING -задает непрерывное бегущее течение процесса для не интерактивного режима при неопределенном диапазоне;
  • static int INCREMENTAL_IDLE- задает пошаговое циклическое течение процесса для не интерактивного режима при неопределенном диапазоне; .
  • static int INCREMENTAL_UPDATING - задает пошаговое обновление течения процесса для не интерактивного режима при неопределенном диапазоне.

Методы класса Gauge

Методы, имеющиеся в составе класса Gauge, позволяют настраивать графическое отображение течение процесса на экране телефона, рассмотрим некоторые из методов.

  • void addCommand (Command cmd) — добавляет команду;
  • int getMaxValue () — получает значение максимального диапазона работы процесса;
  • int getValue ()-получает текущее значение в процессе работы;
  • void setltemCommandListener (ItemCommandListener 1) -устанавливает обработчик событий;
  • void setLabel (String label) - устанавливает метку для элемента;
  • void setLayout (int layout) - устанавливает директивы для элемента;
  • void setMaxValue (int maxValue) - устанавливает максимальное значение течения процесса;
  • void setPreferredSize(int width, int height) -задает ширину и высоту для графического представления всего течения процесса;
  • void setValue(int value) - устанавливает текущее значение процесса.

В примере создается простой измеритель течения процесса в виде прямоугольника, максимальный диапазон задан значением десять. В листинге 6.7 показано использование класса Gauge.

/ * *

Листинг 6.7 Класс Gauge

*/
import javax.microedition.midlet.*;

 import javax.microedition.Icdui.*;

public class MainClassGauge extends MIDlet implements CommandListener

{

// команда выхода из приложения

private Command exitMidlet = new Command!"Выход",
Command.EXIT, 1);

// объект класса Form

private Form myform = new Form("Класс Gauge");

// объект mydisplay представляет экран телефона

private Display mydisplay;

public MainClassGauge()

{

mydisplay = Display.getDisplay(this) ;

}

public void startApp()

 {

// добавить объект класса Gauge

myform.append(new Gauge("Прогресс:", true, 10, 5 ));

// установка обработчика событий для Form

myform.addCommand(exitMidlet);

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();

}

 }

}

Откомпилировав этот пример, вы увидите на экране прямоугольник, наполовину закрашенный темным цветом. Использование класса Gauge позволяет создавать экранные заставки отображающие, например, процесс загрузки Приложения. Для того чтобы пользователь не наблюдал за черным экраном телефона в момент загрузки очередного процесса, создайте класс Gauge и используйте его по назначению.


6.3. Класс Alert

Использование класса Alert в Java 2 ME приложениях обусловлено возникновением различных внештатных ситуаций. В основном класс Alert применяется для создания экрана, который информирует пользователя об ошибке произошедшей в приложении или любом другом уведомлении информационного характера. Экран, определенный классом Alert может содержать строковое уведомление о произошедшей ошибке либо текстовую строку с заданным изображением. В связи с этим, класс Alert имеет два конструктора, использующихся в создании объектов этого класса. Первый конструктор содержит один параметр типа String, задавая строку текста для уведомления. Рассмотрим первый конструктор класса Alert.

public Alert(String  title);

Параметры конструктора public Alert:

  • title - строка текста.

Второй конструктор класса Alert имеет уже четыре параметра, представляя более интересный вид создаваемого экрана.

public Alert(String  title, String alertText,

Image  alertlmage,

AlertType alertType)

Параметры конструктора public Alert:

  • title - название созданного экрана;
  • alertText - текст уведомления;
  • alertlmage - изображение;
  • alertType - тип уведомления, определяемый классом AlertType.

Существует пять типов уведомлений:

  • static AlertType ALARM - тревога;
  • static AlertType CONFIRMATION - предупреждение о возможном действии, которое пользователь должен произвести;
  • static AlertType ERROR - ошибка;
  • static AlertType INFO — информационное сообщение;
  • static AlertType WARNING - предупреждение.

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


6.3.1. Методы класса Alert

Существует множество методов класса Alert, все они призваны создавать более насыщенные и информационные сообщения. Рассмотрим методы класса Alert.

  • void addCommand(Command cmd) — добавляет команду;
  • int getDef aultTimeout () - получает время для представления уведомления. Можно воспользоваться переменной FOREVER для постоянного представления экрана с объектом класса Alert;
  • Image get Image () - получает изображение для экрана представленного классом Alert;
  • Gauge get Indicator () - этот метод позволяет воспользоваться графическим измерителем класса Gauge;
  • String getString() - получает текстовую строку;
  • int getTimeout () - получает заданное время для представления уведомления;
  • AlertType get Туре () - определяет тип используемого уведомления;
  • void removeCommand (Command cmd) - удаляет команду;
  • void setCommandListener(CommandListener 1) —.устанавливает обработчик событий;
  • void setlmage (Image img) - устанавливает изображение;
  • void setlndicator(Gauge indicator) - устанавливает индикатор измерителя для использования класса Gauge;
  • void setString(String.str) - устанавливает строку текста;
  • void setTimeout (int t ime)-устанавливает время;
  • void setType (AlertType type) - устанавливает тип уведомлений или информационных сообщений.

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

/**

Листинг 6.8

Класс Alert

*/

import javax.microedition.midlet.*;

 import javax.microedition.Icdui.*;

public class MainClassAlert

extends MIDlet implements CommandListener

{

// команда выхода из приложения

private Command exitMidlet = new Command("Выход",
Command.EXIT, 1);

// объект класса Alert

Alert a1;

// объект mydisplay представляет экран телефона

private Display mydisplay;

public MainClassAlert()

{

mydisplay = Display.getDisplay(this);

}

public void startApp()

{

// перехватываем исключительную ситуацию

try{

// загрузка изображения

Image image = Image.createlmage("/error.png");

// объект класса Alert

a1 = new Alert("Класс Alert",null, image, AlertType.ERROR);

} catch(Java.io.IOException ex){ }

al.addCommand(exitMidlet);

al.setCommandListener(this);

mydisplay.setCurrent(al);

 }

public void pauseApp() {}

public void destroyApp(boolean.unconditional) {}

public void commandAction(Command c, Displayable d)

{

// выход из приложения

if (с == exitMidlet)

{

destroyApp(false) ;

notifyDestroyed() ;

}

 }

 }

В листинге 6.8 создается класс MainClassAlert, являющийся основным классом мидлета. В самом начале всего кода происходит объявление необходимых переменных ив частности объекта a1 класса Alert. В методе startApp () создается объект класса Image, в котором будет содержаться загружаемое изображение. Изображение выполнено в виде информационной надписи об ошибке. На рис. 6.10 изображена работа класса Alert.

При загрузке изображения используется конструкция try {} catch () {} для обработки исключительных ситуаций. В остальном, я думаю, весь код ясен и каких-либо проблем с пониманием этой простой программы возникнуть не должно.

Рис 6.10. Информационное уведомление, созданное при помощи класса Alert


6.4. Класс List

Класс List не входит в иерархию класса Item. Использование класса List дает возможность создавать выбираемый список элементов, отображаемый на экране в виде одной или нескольких строк текста. Класс List наследуется от класса Screen и реализует возможности интерфейса Choice. При создании выбираемого списка элементов необходимо указать тип создаваемого списка. Существует всего три типа списков, реализация которых основана на использовании интерфейса Choiсе:

  • EXCLUSIVE-предоставляет эксклюзивный выбор элемента в списке;
  • MULTIPLE - множественный выбор элементов из списка;
  • IMPLICIT - выбирает из списка только один элемент, на котором сфокусировал свое внимание пользователь.

Конструкция применения типов EXCLUSIVE и MULTIPLE напоминает использование этих типов в классе ChoiceGroup, а вот применение типа IMPLICIT возможно только с использованием класса List. При создании объекта класса List можно воспользоваться двумя видами конструкторов. Рассмотрим их более подробно.

public List(String title, int listType);

Параметры конструктора List:

  • title- название создаваемого списка элементов;
  • listType - тип создаваемого списка, может быть одним из трех значений: IMPLICIT, EXCLUSIVE И MULTIPLE.

Этот конструктор с двумя параметрами создает пустой список с заданным типом в параметре listType. Второй конструктор класса List несколько сложнее. Он состоит из четырех параметров и создает многострочный список элементов с загрузкой иконки или изображения для каждого элемента.

public List(String title,

int listType,

String[] stringElements,

Image[] imageElements)

Параметры конструктора List:

  • title - название создаваемого списка элементов;
  • listType - может быть одним из трех значений IMPLICIT, EXCLUSIVE и MULTIPLE для определения типа создаваемого списка элементов;
  • stringElements - в этом параметре используется массив строк для создания списка элементов;
  • imageElements - с помощью этого параметра каждому из элементов можно загрузить свое изображение, чаще всего используются иконки маленьких размеров, например 10 на 10 пикселей.


6.4.1. Методы класса List

Класс List имеет множество методов, с помощью которых можно производить редакцию списка элементов, выбор заданного элемента и многое другое. Разберем часть методов класса List.

  • int append(String stringPart, Image imagePart) —добавление списка элементов;
  • void delete (int elementNum) - удаление заданного элемента из списка;
  • void deleteAll() - удаление всех элементов;
  • Font getFont(int elementNum) - получает шрифт для заданного элемента в списке;
  • Image getlmage(int elementNum) - получает изображение для заданного элемента в списке;
  • int getSelectedFlags(boolean[] selectedArray_return)-возвращает состояние всех элементов в виде массива данных;
  • int getSelectedlndext) - получает выбранный индекс элемента в списке;
  • String getString(int elementNum) - получает строку текста для выбранного элемента из списка;
  • void insert(int elementNum, String stringPart, Image imagePart) - вставляет элемент в список до указанного номера элемента в списке;
  • boolean isSelected(int elementNum) - получает выбранный элемент из списка;
  • void removeCommand (Command cmd) - удаляет команду для списка;
  • void set(int elementNum, String stringPart, Image imagePart) - вставляет новый элемент в список в замен предшествующего;
  • void setFont(int elementNum, Font font) - устанавливает шрифт заданному элементу в списке;
  • void setSelectCommand (Command command) - этот метод предназначен для работы с типом IMPLICIT. Когда используется такой тип списка, то выбирается элемент, на котором сфокусирована в данный момент строка состояния. Этот метод позволяет определить, на каком элементе сфокусировано внимание пользователя. При этом используется такая запись: List .SELECT_COMMAND. для определения выбранного элемента в списке;
  • void setSelectedFlags(boolean[] selectedArray)-устанавливает состояние выбранных элементов;
  • void setSelectedlndexfint elementNum, boolean selected) - устанавливает индекс выбранного элемента в списке;
  • void setTitle (String s) - добавляет название в список элементов;
  • int size () - с помощью этого метода можно узнать количество элементов в списке.

Теперь давайте создадим пример, описывающий основные возможности класса List. Класс List может создавать три списка элементов: Exclusive, Multiple и Implicit. Используем эту возможность и создадим код, реализующий все три типа. Основная идея создания примера для класса List сводится к следующему: при входе в приложение пользователь попадает в главное окно со списком из двух элементов Multiple и Implicit, а сам список этих двух элементов будет создан на основе типа Exclusive. Ко всем элементам списка будут загружаться свои иконки. Выбрав один из двух элементов списка курсором, пользователь должен нажать клавишу команды Выбор для перехода в программе. Оба элемента списка Multiple и Implicit будут представлять два разных типа списка. Выбрав один из элементов Multiple или Implicit, пользователь попадает на новый экран. Каждый из выбранных списков будет содержать ряд элементов иллюстрирующих работу типов Multiрlе и Implicit. Выбирая элементы из этих списков, пользователь будет получать информационное сообщение. В листинге 6.9 исходный код примера..

/**

Листинг 6.9

Класс List

*/

import javax.microedition.midlet. *;

 import javax.microedition.Icdui.*;

public class

MainClassList extends MIDlet implements . CommandListener

{

// команда выхода из приложения

private Command exitMidlet = new Command("Выход",
Command.EXIT, 0);

// команда выбора элемента из списка

private Command vibor = new Command!"Выбор",
Command.SCREEN, 1);

// команда возврата в главное окно

private Command vozvrat = new Command("Назад",
Command.BACK, 1};

// команда выбора элемента для типов Implicit и Multiple

private Command OK = new Command("OK", Command.OK, 1);

// массив, иконок для типа EXCLUSIVE

Image[] iconEx = null;

// массив иконок для типа Multiple

Image t ] iconMu = null;

// массив иконок для типа Implicit

Image[] iconlm = null;

// объект класса List для типа EXCLUSIVE

private List mylistEx;

// объект класса List для типа Multiple

private List mylistMu;

// объект класса List для типа Implicit

private List mylistlm;

// объект mydisplay представляет экран телефона

private Display mydisplay;

public MainClassList()

{

mydisplay = Display.getDisplay(this);

}

public void startAppf)

 {

 // перехватываем.исключительную ситуацию;

try

{

// загрузка изображения

Image imagel = Image.createlmage("/iconMu.png");

Image image2 = Image.createlmage("/iconlm.png");

// поместить загруженные изображения в массив iconEx

iconEx = new Image[]

{

image1, image2

};

// загрузка изображения

Image imageB = Image.createlmage("/Multiple.png");

// поместить загруженные изображения в массив iconMu

iconMu = new Image[]{image3, image3, image3, image3};

// загрузка изображения

Image image4 = Image.createlmage("/Implicit.png");

// поместить загруженные изображения в массив iconIm

iconIm = new Image[]{image4, image4, image4};

} catch(Java.io.IOException ex){ }

// текст для двух элементов списка

String[] st = {"Тип Multiple","Тип Implicit"};

// инициализация объекта mylistEx

mylistEx = new List("Тип EXCLUSIVE",

Choice.EXCLUSIVE, st, iconEx);

// добавить команды

 mylistEx.addCommand(exitMidlet);

 mylistEx.addCommand(vibor);

mylistEx.setCommandListener(this);

// отразить текущий дисплей mydisplay.setCurrent(mylistEx);

}

public void pauseApp() {}

public void destroyApp(boolean unconditional) {}

public void commandAction(Command c, Displayable d)

 {

// выход из приложения

 if(с == exitMidlet)

{

destroyApp(false); notifyDestroyedf);

}

// возврат в главное окно

 if(с = = vozvrat)

Display.getDisplay(this).setCurrent(mylistEx);

 // обработка команды OK if(с = = OK)

{

Alert a1 = new Alert(null,"Информационное уведомление",
null, null);

mydisplay.setCurrent(al);

 }

// обработка команды vibor

if(с == vibor)

{

// взять индекс выбранного элемента

int i = mylistEx.getSelectedlndex();

// события для элемента «Тип Multiple»

if(i = =0)

{

// текст для элементов списка

String[] string = {"Меч","Щит","Нож","Копье"};

// инициализация объекта mylistMu

mylistMu = new List("Тип MULTIPLE",

Choice.MULTIPLE, string, iconMu);

// добавить команду возврата

mylistMu.addCommand(vozvrat);

// добавить команду OK

mylistMu.addCommand(OK);

mylistMu.setCommandListener(this);

// отразить текущий дисплей

mydisplay. setCurrent (mylistMu)

}

// события для элемента «Тип Implicit»

if (i = = 1)

{

// текст для элементов списка

String[] string = {"Звук","Видео","Управление"};

// инициализация объекта mylistlm

mylistlm = new List("Тип IMPLICIT",

Choice.IMPLICIT, string, iconlm);

// добавить команду возврата

mylistlm.addCommand(vozvrat);

// добавить команду OK

mylistlm.addCommand(OK);

mylistlm. setCommandListener (this);

// отразить текущий дисплей

mydisplay.setCurrent(mylistlm);

}

}

 }

 }

В листинге 6.9 создан класс MainClassList, являющийся основным классом мидлета программы. В начале исходного кода создаются команды для выхода из приложения - exitMidlet, для выбора элемента из списка - vibor, для возврата в главное окно приложения - vozvrat и команда ОК, обрабатывающая выбранный элемент из группы. За командами обработки событий следует объявление трех переменных: iconEx, iconMu и iconIm. Все три переменные будут содержать массив изображений или иконок для трех рассматриваемых в этом примере типов Exclusive, Multiple и Implicit класса List. Затем в коде:

private List mylistEx; private List mylistMu;

private  List  mylistlm;

private Display mydisplay;

Создаются три объекта класса List, представляющие три имеющихся типа элементов списка и объект mydisplay класса Display. Метод startApp() производит загрузку всех имеющихся иконок из папки \Code\Listing6_9\res с помощью метода createImage класса Image. Все загруженные иконки содержатся в переменных image1, image2, image3 и image4. При загрузке изображений используется конструкция try{} catch {) {} для перехвата исключительной ситуации. Все иконки размещаются в массивах iconEx, iconMu и iconIm для каждого типа элементов списка. В сроке кода

mylistEx = new List("Тип EXCLUSIVE", Choice.EXCLUSIVE, st,

iconEx)

происходит инициализация объекта mylistEx. Используется конструктор класса из четырех параметров. Первый параметр конструктора класса List создает заголовок для всего экрана. Во втором параметре конструктора используется значение Choice.EXCLUSIVE. С помощью этого значения создается список элементов типа Exclusive, позволяющий выбрать только один элемент из всего списка. Третий параметр в конструкторе класса List принимает значение переменной st. Эта переменная содержит две строки текста, создавая тем самым только два элемента списка. Последний параметр загружает две иконки для обоих элементов списка.

В методе commandAction () происходит обработка всех .имеющихся команд созданных в приложении. Команда exitMidlet производит выход из приложения. Команда vozvrat возвращает пользователя в главное окно программы. Команда ОК показывает информационное сообщение, выполненное на основе класса Alert. Команда vibor осуществляет переход в выбранный экран представленный списком элементов двух различных типов Multiple и Implicit класса List. С помощью метода getSelectedIndex() берется индекс выбранного элемента из списка и на его основе в конструкции if /else происходит обработка выбранных событий. Два типа списков Multiple и Implicit создаются подобно списку типа Exclusive. Рис. 6.11 изображает эмулятор, на экране которого воспроизводится список элементов организованный с помощью класса List.

Рис. 6.11. Список элементов созданный классом List

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


6.5. Класс Ticker

Объект класса Ticker служит для создания в приложении подобие бегущей строки, располагающейся в верхней части экрана. Текст, выводимый на экран объектом класса Ticker, перемещается справа налево с одинаковой скоростью. При достижении конца текста бегущая строка появляется заново, обеспечивая тем самым цикличности перемещения текста. На рис. 6.12 изображен эмулятор с бегущей строкой в. верхней части экрана.

Класс Ticker имеет один конструктор, необходимый в создании объекта этого класса, рассмотрим этот конструктор:

public  Ticker(String  str);

Параметры конструктора класса Ticker:

  • str - строка текста появляющаяся в видебегущей строки.

Создавая объекта класса Ticker с помощью рассмотренного конструктора, вы задаете значение для параметра str и эта строка текста будет циклично прокручиваться в программе.

Рис. 6.12. Объект класса Ticker создает в верхней части экрана бегущую строку


6.5.1. Методы класса Ticker

В составе класса Ticker существует всего два метода для получения и установки необходимой строки текста для приложения.

  • String getstring () - получает строку текста, заданную для объекта класса Ticker;
  • void setstring (String str) - устанавливает строку текста для отображения ее на экране телефона с помощью объекта класса Ticker, заменяя ее новой строкой.

Также имеется возможность воспользоваться еще двумя методами абстрактного класса Displayable. Оба метода выполняют аналогичные действия методам класса Ticker, но при этом позволяют встраивать объект класса Ticker непосредственно в форму, то есть экран представленный классом Form. Разберем эти два метода:

  • void setTicker (Ticker ticker) - устанавливает новую бегущую строку, заменяя предыдущую;
  • Ticker getTicker () - получает используемую строку текста.

Оба этих метода дублируют по сути методы класса Ticker. В листинге 6.10 приводиться образец применения класса Ticker.

/**

Листинг 6.10

Класс Ticker

*/

import javax.microedition.midlet*;

 import javax.microedition.Icdui*;

public class MainClassTicker extends MIDlet

implements CommandListener

{

// команда выхода из приложения

private Command exitMidlet = new Command("Выход",
Command.EXIT, 0);

// объект класса Form

private Form myform;

// объект mydisplay представляет экран телефона

private Display mydisplay;

public MainClassTicker()

{

mydisplay = Display.getDisplay(this);

}

public void startApp()

 {

// создаем форму при помощи объекта Form

myform = new Form("Класс Ticker");

// создаем объект класса Ticker

Ticker myticker = new Ticker("Бегущая строка");

// добавляем бегущую строку в форму

myform.setTicker(myticker);

// добавить команду выхода

myform.addCommand(exitMidlet);

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() ;

}

 }

}

В листинге 6.10 создается пустая форма с помощью класса Form и объект класса Ticker с заданным текстом. Методом setTicker (), объект класса Ticker добавляется в форму, организовывая тем самым бегущую строку в верхней части экрана телефона.


6.6. Класс Image

При рассмотрении класса ImageItem мы уже использовали объекты класса Image, но тогда был рассмотрен только один метод и способ работы с классом Image. В этом разделе вы более подробно познакомитесь с этим классом. Класс Image необходим для загрузки и хранения изображений в формате PNG. Чаще всего загружаемые изображения находятся в рабочем каталоге приложения. Но могут находиться и где угодно, надо только правильно указать путь местонахождения для загрузки. При упаковке приложения в JAR-файл, все имеющиеся изображения автоматически копируются в архив, и при работе программы на телефоне, загрузка уже осуществляется из JAR-файла. Загружаемые изображения могут использоваться во время работы с классами Alert, Choice, ChoiceGroup, Form, ImageItem и Graphics. Качество воспроизведения изображения на экране всецело зависит от возможностей используемого телефона. Если изображение больше фактического размера дисплея, то сервис телефона организует прокрутку изображения и если это не входит в ваши планы, то следует придерживаться минимальных размеров ширины и высоты при создании изображений.


6.6.1. Методы класса Image

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

  • static Image createlmage(byte[] imageData, int imageOff-set, int imageLength) -загружает изображение учитывая смещение и длину f1 байтах;
  • static Image createlmage (Image source) - загружает изображение из файла;
  • static Image createlmage(Image image, int x, int y, int width, int height, int transform) - загружает изображение в заданное место, определенное координатами, с возможностью трансформации изображения. Параметр transform устанавливает необходимую трансформацию с помощью класса Sprite и константных значений:
  • Sprite. TRANS_NONE - изображение копируется без трансформации;
  • Sprite.TRANS_ROT90 - трансформирует изображение по часовой стрелке на 90°;
  • Sprite.TRANS_ROT180- трансформирует изображение по часовой стрелке на 180°;
  • Sprite.TRANS_ROT270 - трансформирует изображение по часовой стрелке на 270°;
  • static Image createlmage (InputStream stream) -загружает изображение из потока;
  • static Image createlmage(int width, int height) -загружает изображение в заданные размеры;
  • static Image createlmage (String name) - загружает изображение из ресурса;
  • static Image createRGBImage(int[] rgb, int width, int height, boolean processAlpha) - загружает изображение, учитывая цветовую компоненту ARGB;
  • Graphics getGraphics () - создает графический объект для представления изображения;
  • int getHeight () - получает высоту изображения;
  • int getwidth () — получает ширину изображения.

В листинге 6.11 происходит загрузка изображения в приложение, но без использования объекта класса ImageItem, который использовался при рассмотрений примера в листинге 6.6 из раздела 6.8. В листинге 6.6 применялась ссылка на объект класса Image, в этом примере объект классу Image используется напрямую

/**

Листинг 6.11

Класс Image

 */

import javax.microedition.midlet.*;

 import javax.microedition.Icdui.*;

public class  MainClassImage extends MIDlet implements CommandListener

 {

// команда выхода из приложения

private Command exitMidlet = new Command("Выход", Command.EXIT, 1) ;

// объект класса Form,

private Form myform = new Form("Класс Image");

// объект mydisplay представляет экран телефона

private Display mydisplay;

public MainClassImage()

 {

mydisplay = Display.getDisplay(this);

 }

public void startApp()

{

// перехватываем исключительную ситуацию

try

{

// загрузка изображения

Image im = Image.createlmage("Ygornakov.png");

// добавляем загружённый файл в форму

myform.append(im);

} catch(Java.io.IOException exp{ }

// Установка обработчика событий для Form

myform.addCommand(exitMidlet);

myform.setCommandListener(this);

// Отразить текущий дисплей

mydisplay .s'etCurrent (myform) ;

 }

public void pauseApp() {}

public void destroyApp(boolean unconditional) {}

public void сommandAction(Command c, Displayable*d)

{

// Выход из приложения if (с == exitMidlet)

 {

destroyApp(false); notifyDestroyedf);

 }

}

}

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


6.7. Класс Font

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

Рис 6.13. Загрузка изображения классом image

Размер шрифта устанавливается при помощи трех констант:

  • int SIZE_LARGE - большой шрифт;
  • static int SIZE_MEDIUM - средний шрифт;
  • static int SIZE_SMALL — маленький шрифт.

Cтиль можно задавать четырьмя константами:

  • static int STYLE_BOLD - жирный шрифт;
  • static int STYLE_ITALIC - курсив;
  • static int STYLE_PLAIN - обычный шрифт;
  • static int STYLE_UNDERLINED-подчеркнутый шрифт.

Начертание шрифта определяется тремя константами:

  • static int FACE_MONOSPACE - шрифт с небольшим интервалом;
  • static int FACE_PROPORTIONAL - пропорциональный шрифт;
  • static int FACE_SYSTEM - системный шрифт.

В профиле MIDP 1.0 возможность установки различных шрифтов в приложении имелась только при использовании класса Graphics и метода setFont (). В профиле MIDP 2.0, уже имеется возможность установки шрифта без использования класса Graphics, только при помощи методов из состава классов пользовательского интерфейса. Процесс назначения шрифта текста в программе происходит следующим образом. Вначале создается переменная, которая будет содержать размер, стиль и начертание шрифта, установленные при помощи метода getFont () класса Font например:

Font myFont = Font.getFont(Font.FACE_SYSTEM,

Font.STYLE_BQLD, Font. SI ZE_LARGE) ;

Переменная myFont теперь содержит шрифт, который можно назначит любому тексту в программе. В профиле MIDP 2.0 для этого достаточно вызвать метод setFont () с необходимыми параметрами. В профиле MIDP 1.0 для назначения шрифта тексту, необходимо использовать класс Graphics, в главе 6 рассматривается эта возможность.

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

/**

Листинг   6.12

Класс  Font

*/

 import   javax.microedition.midlet. *;

import* javax.microedition.Icdui.*;

public  class

 MainClassFont  extends MIDlet  implements
CommandListener

{

// команда выхода из приложения

private Command exitMidlet = new Command("Выход",
Command.EXIT, 0);

// массив иконок

Image[] icon = null; x

// объект класса List

private List mylist;

// объект mydisplay представляет экран телефона

private Display mydisplay;

public MainClassFont()

{

mydisplay = Display.getDisplay(this);

}

public void startApp()

{

// перехватываем исключительную ситуацию

try{

// загрузка изображения

Image imaged = Image.createlmage("/icon0.png");

Image imagel = Image.createlmage("/icon1.png");

Image image2 = Image.createlmage("/icon2.png");

Image image3 = Image.createlmage("/icon3.png");

// поместить загруженные изображения в массив icon

icon = new Image[]{ image0, image1, image2, image3};

}

catch(Java.io.IOException ex){ }

// текст для четырех элементов списка

String[] stroka = {"Синий","Красный","Зеленый",

"Оранжевый"};

// назначается шрифт нулевому элементу списка

Font f0 = Font.getFont(Font.FACE_PROP6RTIONAL,

Font.STYLE_PLAIN, Font.SIZE_SMALL);

// назначается шрифт первому элементу списка

Font f1 = Font.getFont(Font.FACE_SYSTEM,

Font.STYLE_BOLD,Font.SIZE_MEDIUM);

// назначается шрифт второму элементу списка

Font f2 = Font.getFont(Font.FACE_MONOSPACE,

Font.STYLE_ITALIC,Font.SIZE_LARGE);

// назначается шрифт третьему элементу списка

Font f3 = Font.getFont(Font.FACE_SYSTEM,

Font.STYLEJJNDERLINED, Font.SIZE_LARGE);

// инициализация объекта mylist

mylist = new List("Класс List",

Choice.EXCLUSIVE,

stroka, icon);

// устанавливается шрифт нулевому элементу списка

mylist. setFont (0 , f0), ;

// устанавливается шрифт первому элементу списка

mylist.setFont(I,f1);

// устанавливается шрифт второму элементу списка

mylist .setFont.(2 , f 2) ;

//устанавливается шрифт третьему элементу списка

mylist.setFont(3,f3);

// добавить команду выхода

mylist.addCommand(exitMidlet);

mylist.setCommandListener(this);

 // отразить текущий дисплей

mydisplay.setCurrent(mylist);

}

public void pauseApp() {}

public void destroyApp(boolean unconditional) {}

public void commandAction(Command c, Displayable d)

{
// выход из приложения

if(с == exitMidlet)

{
destroyАрр(false);

notifyDestroyed() ;

}

}

}

Основным классом в программе из листинга 6.13, иллюстрирующей работу со шрифтом, является класс MainClassFont. Весь код программы построен на использовании класса List создающем список элементов. В строке кода:

Image[]  icon =  null

создается переменная для хранения массива изображений. Конкретно в этом примере будут использованы маленькие иконки, загружаемые каждому элементу списка. Всю группу элементов представляет объект my list класса List. В методе startApp () происходят основные действия по созданию списка элементов, загрузке изображения и назначению шрифта каждом элементу списка. В четырех строках кода:

Image imaged = Image.createlmage("/icond.png");

Image imagel = Image.createlmage("/iconl.png");

Image image2 = Image.createlmage("/icon2.png");

Image image3 = Image.createlmage("/iconS.png");

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

icon = new Image[]{imaged, image1, image2, image3};

Далее в программном коде создается массив строковых значений:

String[] stroka = {"Синий","Красный","Зеленый","Оранжевый"}.

Теперь пришло время создать шрифты:

Font  f0 = Font.getFontfFont.FACE_PROPORTIONAL,

Font.STYLE_PLAIN, Font.SIZE_SMALL);

Font f1 = Font.getFont(Font.FACE_SYSTEM,Font.STYLE_BOLD,

Font.SIZE_MEDIUM);

Font f2 = Font.getFont(Font.FACE_MONOSPACE,

Font. STYLE_ITALIC, Font. SIZE_LARGE);

  Font f3 = Font.getFont(Font.FACE_SYSTEM,

Font.STYLE_UNDERLINED,Font.SIZE_LARGE);

В этих строках создаются четыре переменные f 0...f 3, содержащие различные по стилю, размеру и начертанию шрифты. С помощью созданных переменных впоследствии будет производиться установка шрифтов для каждого элемента списка. Список элементов представлен объектом mylist и выполнен по типу Exclusive (четыре элемента со своими иконками). В классе List имеется метод setFont () доступный в профиле MIDP 2.0, он и используется в примере.

Создав объект класса List, установим шрифт всем элементам списка:

mylist.setFont(0,f0);

mylist.setFont(1,f1);

mylist.setFont(2,f2);

mylist.setFont(3,f3);

С помощью метода setFont () происходит установка заданного шрифта, содержащегося в переменных f 0... f 3. Назначение шрифта происходит по индексам от 0 до 3 в массиве stroka [ ].

В конце кода происходит добавление команды выхода и отображение текущего экрана на дисплее телефона. На рис. 6.14 представлена работа программы из листинга 6.13.

Рис 6.14. Эмулятор телефона, на экране которого представлены разные шрифты

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


Глава 7. Программирование графики

  • В этой главе...
  • 7.1. Класс Canvas
    • 7.1.1. Методы класса Canvas
  • 7.2. Класс Graphics
    • 7.2.1. Методы класса Graphics
  • 7.3. Рисование линий
  • 7.4. Рисование прямоугольников
  • 7.5. Рисование дуг
  • 7.6. Вывод текста
  • 7.7. Механизм создания игрового цикла
  • 7.8. Перемещение квадрата
  • 7.9. Циклическое передвижение объекта по экрану
  • 7.10. Столкновение
  • 7.11. Перемещение объекта с помощью клавиш


В этой главе...

Высокоуровневые классы, изученные в главе 6, дают возможность создавать пользовательский интерфейс приложения. По сути, эти классы выполнены в виде шаблонов, используя которые вы мoжете создавать списки, формы, шрифт, группы элементов, бегущие строки. Но использование таких классов-шаблонов несколько упрощает интерфейс программы, лишая возможности использования графики в программах на Java 2 ME. Иногда в приложении необходимо нарисовать таблицу, линию, квадрат, то есть воспользоваться графикой для создания насыщенной и красочной программы. Для этих целей в платформе Java 2 ME существуют так называемые классы низкоуровневого интерфейса - это классы Canvas и GameCanvas (класс GameCanvas будет рассмотрен в следующей главе), а так же класс Graphics, с помощью которого осуществляется непосредственная прорисовка графики на экране телефона. В самом начале этой главы дается характеристика классам Canvas и Graphics, попутно рассматриваются имеющиеся в составе обоих классов методы, после чего мы приступим к практической части и создадим ряд примеров, иллюстрирующих работу обоих классов.


7.1. Класс Canvas

Класс Canvas - это абстрактный класс, поэтому необходимо создавать подклассы для работы с классом Canvas. Абстрактный класс Canvas представляет некий обобщенный графический контекст, что позволяет программе производить прорисовку графики при помощи класса Graphics. Кроме этого класс Canvas предоставляет возможность в обработке событий полученных с клавиш телефона. Если классы высокоуровневого интерфейса, рассмотренные в главах 5 и 6, обрабатывают команды перехода, то-с помощью класса Canvas можно получать события с любой нажатой клавиши телефона.

Существует ряд так называемых «ключевых кодов» в виде заданных констант, с помощью которых можно назначать игровые действия для клавиш телефона. Все ключевые коды соответствуют стандарту ITU-T и заданны в виде следующих констант:

  • static int DOWN — движение вниз;
  • static int FIRE - обычно используется в играх и реализует стрельбу из оружия;
  • static int GAME_A — игровая клавиша А;
  • static int GAME_B - игровая клавиша В;
  • static int GAME_C - игровая клавиша С;
  • static int GAME_D - игровая клавиша D;
  • static int KEY_NUMO - клавиша 0;
  • static int KEY_NUM1-клавиша 1;
  • static int KEY_NUM2 - клавиша 2;
  • static int KEY_NUM3 - клавиша 3;
  • static int KEY_NUM4 - клавиша4;
  • static int KEY_NUM5 - клавиша 5;
  • static int KEY_NUM6 - клавиша 6;
  • static int KEY_NUM7 - клавиша 7;
  • static int KEY_NUM8 - клавиша 8;
  • static int KEY_NUM9 - клавиша 9;
  • static int KEY_POUND - клавиша #;
  • static int KEY_STAR - клавиша *;
  • static int LEFT - движение влево;
  • static int RIGHT - движение вправо;
  • static int UP - движение вверх.

Ключевые коды GAME_A, GAME_B, GAME_C, GAME_D и FIRE предназначены специально для игровых действий и обычно задаются клавишам с цифрами соответственно 2,4,8,6 и 5, но зависят от реализации конкретных моделей телефонов.


7.1.1. Методы класса Canvas

Большинство методов класса Canvas обеспечивают обработку низкоуровневых событий. Абстрактный метод void paint (Graphics g) является основным методом, с помощью которого происходит прорисовка графики на экране телефона. Класс Graphics определяет, что именно необходимо рисовать на экране телефона. Разберем основную часть методов класса Canvas:

  • int getGameAction(int keyCode) - связывает игровые действия с заданным ключевым кодом;
  • int getKeyCode(int gameAction) - получает ключевой код игровых действий;
  • String getKeyName (int keyCode) - получает ключевой код для клавиши;
  • boolean hasPointerMotionEvents () - проверяет поддержку устройством перемещение указателя;
  • protected void keyPressed( int keyCode) - вызывается при нажатии клавиши;
  • protected void keyReleased(int keyCode) - вызывается при отпускании нажатой клавиши;
  • protected void keyRepeated(int keyCode) - повторное нажатие клавиши;
  • protected abstract void paint (Graphics g) - прорисовка графики на экране телефона;
  • protected void pointerDragged(int x, int у) - определяет перемещение курсора;
  • protected void pointerPressed(int x, int у) -определяет позицию курсора, при которой должно производится нажатие определенной клавиши;
  • protected void pointerReleased(int x, int у) -определяет Позицию курсора в момент отпускания определенной клавиши;
  • void repaint () - повторяет прорисовку;
  • void repaint(int x, int у, int width, int height)-повторяет прорисовку заданной области.


7.2. Класс Graphics

При помощи класса Graphics осуществляется двухмерное представление графики на экране телефона. Класс Graphics существует также в составе Java 2 SE, но в платформе Java 2 ME он сильно урезан, всвязи с ограниченными системными ресурсами телефонов. Поэтому имеется возможность рисовать только линии, прямоугольники, дуги и текст. Для окрашивания этих примитивов предусмотрена работа с цветовой компонентой.

Система координат, используемая для представления графики в Java 2 ME, перевернута по отношению к обычной Декартовой системе координат. Начало системы координат, находится в левой верхней точке экрана телефона. Положительная ость X проходит по верхней кромке экрана слева направо, а положительная ось Y- сверху вниз по левой стороне экрана, как изображено на рис. 7.1.

Такая система координат отнюдь не новшество в программировании двухмерной графики. Идентичная модель координат применяется так же в DirectX и OpenGL для представления двухмерных сцен, но уже в компьютерной графике.

Рис. 7.1. Система координат в Java 2 ME


7.2.1. Методы класса Graphics

Основные методы класса Graphics обеспечивают прорисовку двухмерной графики. Есть еще несколько методов, с помощью которых можно произвести перемещение системы координат и произвести отсечение (clipping). Основные методы класса Graphics:

  • void copyArea(int x_src, int y_src, int width, int height, int x_dest, int y_dest, int anchor)- копирует прямоугольную область из установленных значений в параметрах (x_src, y_src, width, height), в новую область (x_dest, y_dest);
  • void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) - рисует контур дуги в виде эллипса;
  • void drawChar(char character, int x, int y, int anchor) -рисует символ;
  • void drawChars(char[] data, int offset, int length, int x, int y, int anchor) - рисует массив символов:
  • void drawlmage (Image img, int x, int y, int anchor) -рисует изображение;
  • void drawLine(int x1, int y1, int x2, int y2) -рисуетлинию из точки x1и y1, до точки х2 и у2;
  • void drawRegion(Image src, int x_src, int y_src, int width, int height, int transform, int x_dest, int y_dest, int anchor) - копирует изображения в заданную область на экран телефона;
  • void drawRoundRect(int x, int у, int width, int height, int- arcWidth, int arcHeight) — рисует контур прямоугольника, используя закругленные углы;
  • void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) - рисует заполненную цветом дугу;
  • void fillRect(int x, int у, int width, int height)- рисует заполненный цветом прямоугольник;
  • void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) - рисует заполненный прямоугольник, используя закругленные углы;
  • void fillTriangle(int x1, int y1, int x2, int y2, int x3, int y3) - рисует заполненный цветом треугольник;
  • int getBlueComponent () - получает синий компонент цвета;
  • int getClipHeight () -получает высоту для текущей области отсечения;
  • int getClipWidth() -получает ширину для текущей области отсечения;
  • int getColor()- получает текущий цвет;
  • Font getFont()- получает текущий шрифт;
  • int getGreenComponent () -получает зеленный компонент цвета;
  • int getRedComponent ()- получает красный компонент цвета;
  • void setClip(int x, int y, int width, int height)-устанавливает отсечение заданной области экрана;
  • void setColor (int RGB) - устанавливает цвет при помощи значения RGB;
  • void setColor (int red, int green, int blue) - назначает цвет при помощи трех цветовых компонентов red, green и blue;
  • void setFont (Font font) - устанавливает заданный шрифт;
  • void setStrokeStyle (int style) - задает штриховой стиль рисуемому контексту, используя константы SOLID и DOTTED;
  • void translate (int x, int у) - перемещает систему координат в точку х и у.

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

Рис. 7.2. Техника прорисовки текста

Для этих целей в классе Graphics имеются константы, с помощью которых происходит выбор позиции:

  • static int BASELINE - задает базовую линию;
  • static int BOTTOM - сдвигает вниз;
  • static int HCENTER - центрирует;
  • static int LEFT - сдвигает влево; .
  • static int RIGHT - сдвигает вправо;
  • static int TOP - сдвигает вверх;
  • static int VCENTER - используется только при прорисовке изображений, производит вертикальную центровку всего изображения.

Можно использовать две константы для выбора позиции. Например, для того чтобы сдвинуть текст влево и вверх, используется комбинация Graphics. LEFT I Graphics .TOP.

Далее мы перейдем к практике и изучим модель программирования графики в приложении на Java 2 ME, рассмотрим создание и отрисовку линий, прямоугольников, дуг и текста. Главное о чем надо помнить при использовании графических элементов - это о размере экрана телефона. Разные модели телефонов имеют свои размеры дисплея, и если вы будете использовать большой по площади экран, например 128x128 пикселей, то на экране с разрешением 101У80, некоторые части графических элементов будут срезаны. Чтобы этого избежать, надо использовать методы класса Canvas, getwidth () и getHeight (), которые возвращают размеры ширины и высоты экрана и уже на основании этих данных производить построение графических элементов, производя тем самым адаптацию графического контекста к конкретной модели телефона. Например, чтобы нарисовать, горизонтальную линию, не выходящую из зоны видимости, можно воспользоваться следующим кодом:

int w = getWidth.{); drawLine(20, 20, w-20, w-20);

В своих примерах к этой главе я специально не использую оптимизации графики, для того чтобы исходный код был более понятен. Поэтому после компиляции всех примеров обязательно запустите получившиеся программы на максимальном количестве имеющихся эмуляторов. Особенно попробуйте работу этих программ на эмуляторе DefaultColorPhone из состава среды программирования J2ME Wireless Toolkit 2.1, меня лично очень сильно позабавил результат работы этого эмулятора, а вам, я думаю, предоставит некоторую пищу для размышлений.


7.3. Рисование линий

Для того чтобы нарисовать линию нужно воспользоваться методом draw-Line () класса Graphics. Рассмотрим прототип этого метода:

public void drawLine(int x1,

int y1,

 int x2,

 int y2)

Параметры метода drawLine ():

  • x1 - координата начальной точки отрезка по оси X;
  • у1 - координата начальной точки отрезка по оси Y;
  • х2 - координата конечной точки отрезка по оси X;
  • у2 - координата конечной точки отрезка по оси Y.

Задавая целочисленные координаты точек в методе drawLine () можно нарисовать любую линию заданного размера. Также можно воспользоваться методом setColor() для закрашивания линий цветом и методом setStrokeSty le () -для рисования линии в виде пунктира.

Рассмотрим пример кода находящийся в листинге 7.1, где с помощью линий рисуется система координат используемая в Java 2 ME.

/ * *

Листинг 7.1

Класс Main и класс Line

*/

import javax..microedition.lcdui .*;

 import javax.microedition.midlet.*;

public class Main extends MIDlet implements

 CommandListener

{

// команда выхода из программы

private Command

exitMidlet = new Command("Выход",Command.EXIT, 0);

public void startApp()

 {

// создаем объект класса Line

Line myline = new Line();

// добавляем команду выхода

 myline.addCommand(exitMidlet);

myline.setCommandListener(this);

Display.getDisplay(this).setCurrent(myline);

}

public void pauseApp() {}

public void destroyApp(boolean unconditional){}

public void commandAction(Command c, Displayable d)

{

if (c = = exitMidlet)

{

destroyApp(false); notifyDestroyed();

 }

 }

 }

/**

класс Line определен в файле Line.Java

*/

import javax.microedition.Icdui.*;

public class Line extends Canvas

{

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

public Line(){ super();

}

public void paint(Graphics g)

{

// устанавливается синий цвет для линий

g.setColor(0x0000ff);

// рисуется система координат

g.drawLine(20, 20, 90, 20);

g.drawLine(20, 20, 20, 90)

g.drawLine(90, 20, 80, 10)

g.drawLine(90, 20, 80, 30)

g.drawLine(20, 90, 10, 80)

g.drawLine(20, 90, 30, 80)

// устанавливается красный цвет для трех линий

g.setColor(0xffff0000);

// рисуем толстую линию, в три пикселя

g.drawLine(30, 30, 70, 30);

g.drawLine(30, 31, 70, 31);

g.drawLine(30, 32, 70, 32);

// устанавливаем пунктир

g.setStrokeStyle(Graphics.DOTTED) ;

// рисуем линию в два пикселя пунктиром

g.drawLine(30, 50, 70, 50);

g.drawLine(30, 51, 70, 51);

}

 }

В листинге 7.1 используются два класса: Main, являющийся основным классом мидлета приложения, и класс Line, в котором происходит работа с графикой. Подразумевается, что оба класса находятся в файлах Main.java и Line.java, это характерно для объектно-ориентированного программирования и в дальнейшем мы будем придерживаться именно такой модели построения изучаемых примеров. Основной класс мидлета Main очень прост. В этом классе создается объект класса Line, добавляется команда выхода из приложения и отражается текущий экран. Класс Line, находящийся в файле Line.java листинга 7.1, рисует набор различных линий. Сам класс Line наследуется от абстрактного класса Canvas. В более сложных программах может использоваться интерфейс Run-nable и метод run (). Такая техника программирования обычно используется при создании игр, и будет обсуждаться в конце этой главы.

Конструктор класса Line использует метод super () позволяющий обратиться к конструктору своего суперкласса Canvas. Основные же события происходят в методе paint () класса Canvas.

В строке кода:

g.setColor(OxOOOOff)

происходит назначение цвета для любого последующего отрисованного примитива. То есть вызов метода setColor () с заданным цветом действителен до момента последующего вызова метода setColor (), устанавливающего другой цвет. В этом примере используется метод setColor (RGB), поэтому значение цвета задается восьмеричным значением с помощью нулей и букв. В следующем примере из раздела 7.4 при рисовании прямоугольников будет показана работа метода setColor () с тремя целочисленными параметрами, задающими значение цвета.

В строках кода

g.drawLine(20, 20, 90, 20)

g.drawLine(20, 20, 20, 90)

g.drawLine(90, 20, 80, 10)

g.drawLine(90, 20, 80, 30)

g.drawLine(20, 90, 10, 80)

g.drawLine(20, 90, 30, 80)

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

g.drawLine(30, 30, 70, 30);

g.drawLine 30, 31, 70, 31);

g.drawLine(30, 32, 70, 32);

Этими строками кода рисуется одна толстая линия шириной в три пикселя.

В конце в методе paint () рисуется линия толщиной в два пикселя в виде пунктирной линии. Для этого используется метод setStrokeStyle () и константа DOTTER. На рис. 7.3 изображен эмулятор телефона с результатом работы программы из листинга 7.1.

Рис. 7.3. Рисование разноцветных линий


7.4. Рисование прямоугольников

При создании прямоугольников можно использовать два метода класса Graphics- это drawRect() и fillRect (). При помощи метода drawRect () рисуется только контур прямоугольника, а метод fillRect () позволяет нарисовать прямоугольник уже закрашенным каким-либо цветом (изначально по умолчанию цвет черный). Оба метода абсолютно идентичны по количеству и назначению параметров, поэтому рассмотрим прототип одного из них, а именно метода drawRect ().

public void drawRect(int x,

int y,

int width,

int height)

Параметры метода drawRect ():

  • x - координата точки по оси X для левого верхнего угла прямоугольника;
  • у - координата точки по оси Y для левого верхнего угла прямоугольника;
  • width - ширина рисуемого прямоугольника;
  • height - высота рисуемого прямоугольника.

В составе класса Graphics имеется еще один метод рисующий прямоугольник, но с закругленными углами - drawRoundRqct (). Этот метод имеет уже шесть параметров, где первые четыре параметра работают в том же ключе что и методы drawRect () и fillRect (), а два последних параметра определяют степень закругленности углов. В листинге 7.2 рисуется три разных по размеру прямоугольника, и закрашиваются тремя цветами: красным, зеленым и синим. Для закрашивания прямоугольников применяется метод setColor (int red, int green, int blue) с тремя параметрами. Выставляя любое целочисленное значение от 0 до 255 для каждого параметра можно создавать разнообразную цветовую гамму, естественно учитывая при этом цветовые возможности телефона, на котором будет работать эта программа. Для того чтобы определить доступную цветность дисплея телефона, необходимо воспользоваться методами класса Display:

  • isColor () - если телефон поддерживает цветовую гамму, то возвращает значение true;
  • numColor() - определяет количество доступных цветов.

/**

Листинг 7.2

Класс Main и класс Rectangles

*/

import javax. micro-edit ion. Icdui.*;

import javax.microedition.midlet.*;

public class Main extends MIDlet implements CommandListener

{

// команда выхода из программы

private Command exitMidlet = new Command("Выход", Command.EXIT, 0);

public void startAppO {

// создаем объект класса Rectangles

Rectangles myrec = new Rectangles();

// добавляем команду выхода

myrec. addCommand( exitMidlet);

myrec.setCommandListener(this);

Display.getDisplay(this).setCurrent(myrec);

}

public void pauseApp() {}

public void destroyApp(boolean unconditional){}

}

public void coiranandAction(Command c, Displayable d)

{

if (c == exitMidlet)

{

destroyApp (false) ,notifyDestroyed();

 }

}

}

/ * *

класс Rectangles определен в файле Rectangles.Java,

*/

import javax..microedition. Icdui ;

public class Rectangles extends Canvas

{

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

public Rectangles(){ super();

 }

public void paint(Graphics g)

{

// устанавливается красный цвет

g.setColor(255, 0,0);

// рисуем первый прямоугольник

g.fillRect(/*x*/ 15,/*у*/ 30,/*ширина*/ 15,/*высота*/ 20);

// устанавливается зеленный цвет

g.setColor(0, 255, 0);

// рисуем второй прямоугольник

g.fillRect(30, 30, 15, 45);

// устанавливается синий цвет

g.setColor(0, 0, 255);

// рисуем третий прямоугольник

g.fillRect(45, 30, 15, 60);

// устанавливается синий цвет

g.setColor(255, 0, 0);

// рисуем прямоугольник с закругленными углами

g.drawRoundRect(70, 30, 40, 40, 10, 10);

 }

 }

В этом примере также используются два класса - класс Main, играющий роль основного класса мидлета и класс Rectangles, где происходит отрисовка графики. Оба класса разделены на два файла Main.java и Rectangles.java. В классе Main создается объект класса Rectangles, добавляется команда выхода и показывается текущий экран. Класс Rectangles является подклассом класса Canvas. Прорисовка прямоугольников происходит в методе paint () класса Graphics.

g.setColor(255, 0, 0) ;

В этой строке кода устанавливается красный цвет для прямоугольника размером 15 на 20 пикселей, который рисуется с помощью метода fillRect ().

g.fillRect(/*x*/ 15,/*у*/30,/*ширина*/15,/*высота*/20);

Прямоугольник рисуется закрашенным в красный цвет. Дальше происходит прорисовка еще двух закрашенных в зеленый и синий цвет прямоугольников с размерами соответственно 15x45 и 15x60 пикселей.

В конце всего кода в классе Rectangles рисуется контур прямоугольника с закругленными углами. На рис. 7.4 изображен эмулятор телефона с четырьмя нарисованными прямоугольниками.

Рис. 7.4. Рисование четырех прямоугольников


7.5. Рисование дуг

В английском языке слово arc означает дугу, и именно это слово применяется в документации по Java 2 ME. Используя методы drawArc () и fillArc () можно нарисовать как дугу, так и полноценную окружность. Используя оба метода, как вы уже наверно заметили можно нарисовать контур дуги и закрашенную цветом дугу. Методы drawArc () и fillArc () имеют одинаковое количество параметров со сходными действиями. Рассмотрим один из методов - fillArc ().

public void fillArc(int x,

int y, int width,

 int height,

 int startAngle,

 int arcAngle)

Параметры метода fill Arc():

  • x - расстояние, откладываемое от оси X до мнимой вертикальной касательной к окружности;
  • у - расстояние, откладываемое от оси Y до мнимой горизонтальной касательной к окружности;
  • wight - ширина рисуемой дуги (горизонтальный радиус);
  • height - высота рисуемой дуги (вертикальный диаметр);
  • startAngle - стартовый угол для начала рисования дуги;
  • arcAngle - протяженность дуги (значение 360 замкнет дугу в окружность).

На рис. 7.5 изображена схематично техника создания дуги.

Рис. 7.5. Техника создания дуги

В листинге 7.3 приведен пример кода создающего три разноцветных сегмента круга, наложенных друг на друга, и дугу в виде контура.

/**

Листинг 7.3

Класс Main и класс Arc
*/

import javax.microedition. Icdui.*;

import javax.microedition.midlet.*;

public class Main extends MIDlet implements

CommandListener

{

// команда выхода из программы

private Command exitMidlet = new Command("Выход",
Command.EXIT, 0)

public void startApp()

 {

// создаем объект класса Arc

Arc myarc = new Arc();

// добавляем команду выхода

myarc.addCommand(exitMidlet);

myarc.setCommandListener(this);

Display.getDisplay(this).setCurrent(myarc);

}

public void pauseApp() {}

public void destroyApp(boolean unconditional){}

public void commandAction(Command c, Displayable d)

{

if (c = = exitMidlet)

{

destroyApp(false); notifyDestroyed();

}

}

/**

класс Arc определен в файле Arc.Java рисует дуги

*/

import javax.microedition.Icdui.*;

public class Arc extends Canvas

{

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

public Arc(){ super();

}

public void paint(Graphics g)

 {

// устанавливается красный цвет

g.setColor(255, 0, 0);

// рисуем первую заполненную цветом дугу

g.fillArc(15, 15, 60., 60, 45, 360);

// устанавливается зеленый цвет

g.setColor(0, 255, 0) ;

// накладываем вторую дугу поверх первой

g.fillArc(15, 15, 60, 60, 45, 180);

// устанавливается синий цвет

g.setColor(0, 0, 255);

// накладываем третью дугу поверх первых двух

g.fillArc(15, 15, 60, 60, 45, 90);

// устанавливается синий цвет для дуги в виде контура

g.setColor(0, 0, 255);

// рисуем контур дуги

g.drawArc(5, 5, 80, 80, 30, 180);

 }
 }

В листинге 7.3 используется тот же самый механизм, что и в примерах из листингов 7.2 и 7.1 - создаются два класса: Main и Arc, находящиеся в файлах Main.java и Arc.java. Все действия по прорисовке дуг осуществляются в методе paint().

g.setColor(255, 0,0);

g.fillArc(15, 15, 60, 60, 45, 360);

В этих строках кода происходит установка цвета для рисуемой дуги и происходит прорисовка самой дуги. Первые два значения в методе fillArc () - 15 и 15 пикселей задают координаты точки в пространстве, относительно которой будет происходить прорисовка дуги. Значения 60 и 60 пикселей задают ширину и высоту дуги. Значением 45 устанавливается угол для начала рисования дуги (со значением 360 будет нарисована замкнутая окружность). Затем в примере рисуются еще два сегмента зеленого и синего цвета, наложенные поверх первой нарисованной дуги.


7.6. Вывод текста

Для вывода текста на экран телефона можно воспользоваться методами drawstring () и drawChar (), рисующими соответственно строка-текста и любой назначенный символ. Текст можно выводить с любым цветом, а также использовать стили начертания, изученные в главе 6. Прототип метода drawstring () выглядит следующим образом:

public void drawstring (String str,

int x,

int y,

int anchor)

Параметры метода drawstring ():

  • str - строка текста;
  • x и у - задают размер невидимого прямоугольника, в котором происходит расположение текста;
  • anchor - в этом параметре задается выбор позиции текста внутри невидимого прямоугольника. Здесь используются константы класса Graphics, рассмотренные в разделе 7.2.

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

/**

Листинг 7.4

Класс Main и класс Text

*/

import javax.microedition.Icdui.*;

import javax.microedition.midlet.*;

public class Main extends MIDlet implements

CommandListener

{

// команда выхода из программы

private Command exitMidlet = new Command(«Выход»,
Command.EXIT, 0);

public void startApp()

{

// создаем объект класса Text

Text mytext = new Text();

// добавляем команду выхода

mytext.addCommand(exitMidlet);

 mytext.setCommandListener(this);

Display.getDisplay(this).setCurrent(mytext);

}

public void pauseApp() {}

public void destroyApp(boolean unconditional){}

public void сommandAction(Command c, Displayable d)

 {

if (c = = exitMidlet)

{

destroyApp(false) ;

notifyDestroyedf);

}

 }

 }

/**

класс Text определен в файле Text.Java рисует текст

 */

import javax.microedition.lcdui.*;

public class Text extends Canvas

{

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

public Text(){super();

}

public void paint(Graphics g)

 {

// устанавливается цвет

g.setColor(10, 80, 200);

// рисуем строку текста

g.drawstring(«Java 2 Micro Edition»,

80, 40, Graphics.TOP | Graphics.HCENTER);

}

}


7.7. Механизм создания игрового цикла

Для создания цикла классом Canvas используется интерфейс Runnable и его единственный метод run (), в котором реализуется цикл прорисовки графики. Рассмотрим в качестве примера класс DemoGraphics и проанализируем его.

public class DemoGraphics extends

Canvas implements Runnable

{

public void run()

{

while(true)

{

// обновление графических элементов repaint();

// задержка цикла на 20 миллисекунд для

обновления состояния дисплея

Thread.sleep(20);

} }

public void paint( Graphics g )

{

// код, создающий графические элементы

}

public void keyPressed( int keyCode )

{

// обработка событий с клавиш телефона

при помощи ключевых кодов

}

}

В классе DemoGraphics для упрощения опущен основной код, связанный с прорисовкой графики и обработкой событий, поступающих с клавиш телефона. Весь цикл прорисовки графики состоит из трех методов: run (), paint () и keyPressed().

В методе paint () происходит создание и отрисовка графических элементов программы на экране телефона, а метод run () создает цикл, в котором происходит постоянное обновление экрана телефона, связанное, например, с движением графического элемента. События, полученные в результате нажатия клавиш, поступают в метод key Pressed (), где обрабатываются заданным вами способом. На основании этих событий также может происходить обновление цикла прорисовки графики.

В методе run () создается бесконечный цикл while (true). В реальной программе необходимо, конечно, предусмотреть выход из бесконечного цикла. Метод repaint () постоянно обновляет графические элементы. Метод sleep () класса Thread останавливает системный поток на двадцать миллисекунд, для того чтобы отреагировать на все произошедшие изменения, а именно, произвести обработку событий с клавиш телефона и перерисовать графический элемент на экране телефона. Механизм прорисовки графики в профиле MIDP 1.0 строится именно по такому принципу , связанному с изменением состояния графических элементов и называмому игровым циклом.

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


7.8. Перемещение квадрата

Начнем с самого простого - выведем на экран синий квадрат, прорисованный с помощью метода fillRect() и заставим переместиться его через весь экран по горизонтали слева на право. Посмотрите на код из листинга 7.5, производящий перемещение квадрата на экране.

/ * *

Листинг 7.5

Класс Main и класс Draw

*/

import javax.micro-edition. Icdui .*;

import javax.microedition.midlet.*;

public class Main extends MIDlet implements

CommandListener

{

// команда выхода из программы

private Command

exitMidlet = new Command("Выход",

Command.EXIT, 0);

public void startApp()

{

// создаем объект класса Draw

Draw dr = new Draw();

// запускаем поток

dr.start();

// добавляем команду выхода

dr.addCommand(exitMidlet);

dr.setCommandListener(this);

Display.getDisplay(this).setCurrent(dr);

}

public void pauseApp() {}

public void destroyApp(boolean unconditional){}

public void commandAction(Command c, Displayable d)

 {

if (с == exitMidlet)

{

destroyApp(false) ;

notifyDestroyed() ;

}

 }

/**

класс Draw определен в файле Draw.Java
перемещает квадрат по экрану

*/

import javax.microedition.lcdui.*;

public class

Draw extends Canvas implements Runnable

{

// позиция для перемещения квадрата

int position =10;

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

public Draw()

{ super(); }

public void start()

{

// создаем и запускаем, поток

Thread t = new Thread(this);

 t.start();

}

// метод run() интерфейса Runnable

public void run()

{

// бесконечный цикл

while (true)

{

// увеличиваем позицию на 1

position ++;

// обновляем экран

repaint();

// останавливаем цикл на 20 миллисекунд

try { Thread.sleep(20);

}

catch (java.lang.InterruptedException zxz) {}

}

 }

public void paint(Graphics g)

{

// вычисляем область для перерисовки экрана

int x = g.getClipWidth();

int у = g.getClipHeight ()

// устанавливаем белый цвет фона

g.setColor(0xffffff);

// назначаем перерисовку всему экрану

 g.fillRect(0,0,х,у);

// устанавливается синий цвет квадрата

vg.setColor(0, 0, 200);

// рисуем квадрат

g.fillRect(position,40, 20, 20);

}

 }

Листинг 7.5 содержит два класса Main и Draw, находящиеся в файлах Main.java и Draw.Java. Основной класс мидлета Main содержит код создающий объект dr класса Draw. Затем он запускает системный поток с помощью метода start (), добавляет команду выхода из программы и отображает текущий дисплей с объектом dr. Класс Draw содержит код, создающий синий квадрат и перемещающий его по экрану. Прежде чем мы начнем рассмотрение кода класса Draw, давайте подумаем, как можно произвести перемещение объекта на экране. Самый простейший способ перемещения объекта по экрану вдоль оси X, заключается в постоянном увеличении, допустим на единицу, позиции этого объекта по оси X. При создании квадрата методом fillRect () задаются две координаты по оси X и по оси Y для первоначального вывода квадрата на экран. Поэтому достаточно создать переменную для координаты по оси X и затем в цикле прорисовки увеличивать ее на единицу, перемещая тем самым объект по экрану.

В листинге 7.5 класс Draw наследуется от класса Canvas, что дает возможность воспользоваться Методом paint (). для рисования графических элементов на экране и. реализации метода run () интерфейса Runnable. В методе run () создается цикл, постоянно обновляющий состояние графических элементов.

В начале кода класса Draw создается переменная position, отвечающая за координату по оси X для точки вывода квадрата на экран. Конструктор класса Draw вызывает метод super () для использования конструктора своего суперкласса Canvas.

В методе start () создается системный поток, который будет запущен в методе run (). Кстати, было бы не плохо предусмотреть выход из потока. Этот пример небольшой и проблем с ним не возникнет, а после разбора листинга 7.5, мы рассмотрим простой механизм, останавливающий системный поток и предусматривающий выход из бесконечного цикла while метода run (). В самом методе run () создается бесконечный цикл, в котором происходит постоянное увеличение переменной position на единицу, благодаря чему квадрат перемещается по оси X слева направо.

В методе paint () вас должны заинтересовать следующие строки кода:

int х = g.getClipWidthf);

int у = g.getClipHeight();

g.setColor(0xffffff);

 g.fillRect(0,0,x,y);

Здесь используется отсечение (clipping) необходимое для корректной прорисовки графики. Если не использовать отсечение, то после того как вы нарисуете квадрат и начнете передвигать его, на экране будет рисоваться слева на право одна толстая синяя линия. То есть будет происходить постоянная перерисовка квадрата в новой позиции по оси X, но при этом будет оставаться и предыдущий нарисованный квадрат. Чтобы этого избежать имеется два способа: можно стирать определенный участок экрана, а можно просто перерисовывать цвет фона всего экрана. Такая операция в Java 2 ME называется отсечением, и для произведения этой операции используются методы: getClipWigthf) и getClipHeight (), производящие отсечение поверхности всего экрана и методы getClipX () и getClipY () для более точного указания координат заданной области экрана для отсечения. По сути, использование этих методов приводит к простому обновлению всего экрана либо заданной области экрана. В этом примере мы будем использовать перерисовку всего фона экрана. Ширина и высота экрана узнается с помощью методов getClipWigth () и getClipHeight (), полученные значения сохраняются в переменных х и у. Вызовом метода setColor () устанавливается белый цвет фона и в следующей строке кода задается прямоугольник для области отсечения:

g.fillRect(0, 0, х, у );

В конце метода paint () рисуем синий квадрат:

g.fillRect(position, 40, 20, 20);

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

После компиляции примера из листинга 7.5, на экране появится синий квадрат и пересечет один раз дисплей телефона слева направо. Теперь что касается бесконечного цикла while. В методе run () в реальном приложении необходимо предусмотреть выход из него, а так же позаботиться о прекращений работы потока. Самый простой способ заключается в создании переменной отвечающей за состояние цикла в начале класса Draw, например:

boolean z;

Дальше в методе start () присвоить этой переменной значение true.

public void start()

{

z = true;

Thread t = new Thread();

 t.start();

}

А в методе run () использовать значение переменной z для входа в цикл

while

while(z)

{

// код цикла

}

Для логического конца создается новый метод stop () в классе Draw, назначая переменной z значения false.

public void stop()

 {

z = false;

}

Вызовем этот метод в классе Main в методе destroyApp ():

public void destroyApp(boolean unconditional)

{

z.stop ();

}


7.9. Циклическое передвижение объекта по экрану

В листинге 7.5 был нарисован синий квадрат и перемещен один раз вдоль оси X горизонтально слева направо. Но иногда в играх необходимо циклично передвигать объект, используя его, например, в качестве мишени.

Возьмем за основу код из листинга 7.5, где перемещается квадрат, и сделаем так, чтобы после пересечения всего экрана и исчезновения, он снова появлялся с другой стороны, создавая подобие циклического перемещения. Алгоритм решения этой задачи заключается в том, чтобы узнать, когда квадрат выйдет из области видимости и в тот же момент нарисовать его с другой стороны экрана и вновь переместить по экрану. Для этого создадим переменную end и присвоим ей значение окончания экрана найденное методом getwidth () (движение происходит по ширине экрана).

int.end = getwidth();

В методе run () в самом начале цикла while будем производить постоянное сравнение позиции квадрата с окончанием экрана:

if (position > end)

{

position = 0;

}

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

/**

Листинг 7.6

Класс Main и luiacq.Draw

*/

import javax.microedition.lcdui.*;

import javax.microedition.midlet.*;

public class Main

extends MIDlet implements CommandListener

 {

// команда выхода из программы

private Command

exitMidlet = new Command("Выход",Command.EXIT, 0);

public void startApp()

{

// создаем объект класса Draw

Draw dr = new Draw();

// запускаем поток

dr.start();

// добавляем команду выхода

dr.addCommand(exitMidlet);

dr.setCommandListener(this);

Display.getDisplay(this).setCurrent(dr);

}

public void pauseApp() {}

public void destroyApp(boolean unconditional){}

public void commandAction(Command c, Displayable d)

{

if (c == exitMidlet) {

destroyApp(false); notifyDestroyedt) ;

 }

}

}

/**

 класс Draw определен в файле

Draw.Java циклическое появление квадрата

*/

import javax.microedition.Icdui.*;

public class

Draw extends Canvas implements Runnable

{

// позиция для перемещения квадрата

int position = 10;

// узнаем ширину экрана

int end = getwidth();

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

public Draw()

{ super(); }

public void start ()

{

// создаем и запускаем поток

Thread t = new Thread(this);

t.start(); }

// метод run интерфейса Runnable

 public void run()

 {

// бесконечный цикл

while (true)

{

// сравниваем позицию квадрата

if(position > end)

{

// обнуляем позицию квадрата position = 0;

 }

// увеличиваем позицию на 1

position ++;

// обновляем экран

repaint() ;

// останавливаем цикл на 20 миллисекунд

try { Thread.sleep(20); }

catch (Java. lang. InterruptedException zxz) {}

) }

public void paint(Graphics g)

{

// вычисляем область для перерисовки экрана

int x = g.getClipWidth();

int у = g.getClipHeight();

// устанавливаем белый цвет фона

g.setColor(0xffffff);

// назначаем перерисовку всему экрану

g.fillRect(0,0,х,у);

//устанавливается синий цвет квадрата

g.setColor(0, 0, 200);

 // рисуем квадрат

g.fillRect(position,40, 20, 20);

}

 }


7.10. Столкновение

В предыдущем разделе 7.9 мы выведи на экран синий квадрат, задали ему вектор движения и перемещали квадрат горизонтально через весь экран. После того как квадрат исчезал, достигнув конца экрана, он циклично появлялся вновь с другой стороны. Следующий пример иллюстрирует столкновение круга и квадрата с препятствием, а именно, окончанием экрана телефона. Оба объекта рисуются независимо друг от друга по высоте экрана и перемещаются параллельно по горизонтали слева на право. По достижению конца экрана оба объекта отталкиваются от конца экрана и начинают движение в обратном направлении. Посмотрите на листинг 7.7, где приводится код программы осуществляющий эти действия. Эта программа состоит из двух файлов Main.java и Draw.java.

/**

Листинг 7.7

Класс Main и класс Draw

*/

import javax.microedition.Icdui.*;

import javax.microedition.midlet.*;

public class Main extends MIDlet implements.

CommandListener

{

//команда выхода из программы

private Command exitMidlet = new Command("Выход",
Command.EXIT, 0);

publicvoid startApp()

{

// создаем объект класса Draw Draw dr = new Draw();

// запускаем поток dr.start();

// добавляем команду выхода

dr.addCommand(exitMidlet) ;

dr.setCommandListener(this);

Display.getDisplay(this).setCurrent(dr);

}

public void pauseApp() {}

public void destroyApp(boolean unconditional)}

public void сommandAction(Command c, Displayable d)

{

if (c == exitMidlet)

{

 destroyApp(false); notifyDestroyed();

}

 }

 }

/**

класс Draw определен в файле Draw.Java
рисует круг и квадрат

*/

import javax.microedition.Icdui.*;

public class Draw extends Canvas implements Runnable

{

// позиция для перемещения квадрата и круга

int position = 0;

// узнаем ширину экрана

int endX = getWidth();

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

public Draw()

{ super();

}

public void start()

{

// создаем и запускаем поток

Thread t = new Thread(this);

t.start();

 }

//метод run интерфейса Runnable public void run()

 {

// бесконечный цикл

while (true)

{

// сравниваем позицию if(position > endX)

{

//уменьшаем позицию position = endX;

}

// увеличиваем позицию на 1 position ++;

// обновляем экран repaint();

// останавливаем цикл на 20 миллисекунд

try { Thread.sleep(20); }

catch (java.lang.InterruptedException zxz) {}

}

}

publie void paint(Graphics g)

{

// вычисляем область для перерисовки экрана

int х = g.getClipWidth() ;

int у = g.getClipHeight () ;

// устанавливаем желтый цвет фона

g.setColor(0xffff00);

// назначаем перерисовку всему экрану

g.fillRect(0,0,x,y);

// устанавливается синий цвет квадрата

g.setColor(0, 0, 200);

// рисуем квадрат

g.fillRect(position, 40, 20, 20);

// устанавливается красный цвет круга

g.setColor(250, 0,0);

// рисуем круг

fillArc(position, 10, 20, 20, 45, 360);

 }

}

В файле Main.java создается объект класса Draw, запускается системный поток и отражается текущий экран. Файл Draw.java содержит полную реализацию класса Draw. Начальные позиции квадрата и круга определяются переменной position, которой задано нулевое значение. Для того чтобы определить момент столкновения, необходимо знать точку или координаты препятствия. В этом примере как препятствие применяется конец экрана с правой стороны, поэтому с помощью метода getWidth () находится конец экрана.

int endX = getWidth();

В последствии значение переменной endx будет использовано для определения столкновения.

Конструктор, класса Draw обращается к конструктору своего суперкласса Canvas. В методе run() и цикле while с помощью оператора отношения if происходит сравнение текущей позиции двух объектов и конца экрана.

if (position > endX)

{

position = endX -;

 }

После того как позиция обоих объектов становится больше значения переменной endx, то есть квадрат и круг достигают конца экрана, то происходит уменьшение переменной position. Это приводит к движению объектов в обратном направлении.

После компиляции примера на экране появятся два движущихся слева направо объекта. Мы использовали препятствие в виде одной стороны экрана, но точно таким же образом можно определить столкновение для всех сторон экрана или просто для статических объектов. Выполните эти упражнения в качестве домашнего задания, а также внимательно посмотрите на процесс работы примера из листинга 7.7, квадрат и круг все-таки не отталкиваются от кромки экрана, а исчезают. Это происходит, потому что опорная позиция объектов находится в левом верхнем углу и столкновение происходит именно с позицией объектов* Вы знаете размер круга и квадрата, подумайте как можно определить более точную точку столкновения объектов и кромки экрана.


7.11. Перемещение объекта с помощью клавиш

Перемещение объекта по экрану телефона с помощью клавиш телефона, это, пожалуй, самое главное действие в играх. Для передвижения нужно воспользоваться методом key Pressed () и описать код производящий обработку событий получаемых с клавиш телефона. При реализации метода keyPressed (), сначала необходимо вызвать метод getGameAction () для получения ключевого код»! с последующей его обработкой. Для обработки полученного ключевого кода можно применить оператор switch и тогда метод keyPressed () может принять следующий вид:

protected void keyPressed(int keyCode)

{

// получаем игровые события

int act = getGameAction{keyCode);

// обработка событий

switch(act)

{

case Canvas.LEFT:

// движение влево break; case Canvas .RIGHT:

// движение вправо break;

case Canvas.UP:

 // движение вверх

break;

case Canvas.DOWN:

// движение вниз break; default: break;

}

}

}

Код обработки для клавиш зависит от того, что именно вы желаете сделать с объектом. Давайте возьмем за основу код из листинга 7.5, где был нарисован квадрат, и модернизируем его. Выведем синий квадрат на экран, для этого создадим две переменные positionX и positionY, отвечающие за точку вывода квадрата на экран и присвоим им значения близкие к центру экрана.

int positionX. = getWidth()/2;

 int positionY = getHeight()/2;

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

/** Листинг 7.8

Класс Main и класс Draw

*/

import javax.microedition.Icdui.*;

import javax.microedition.midlet.*;

public class Main

extends MIDlet implements CommandListener .

{

// команда выхода из программы

private Command

exitMidlet = new Command(«Выход», Command.EXIT, 0);

public void startApp()

 {

// создаем объект класса Draw

Draw dr = new Draw();

// запускаем поток

dr.start();

// добавляем команду выхода

dr.addCommand(exitMidlet);

dr.setCommandListener(this);

Display.getDisplay(this).setCurrent(dr);

}

public void pauseApp() {}

public void destroyApp(boolean unconditional){}

public void сommandAction(Command c, Displayable d)

{

if (c = = exitMidlet)

{

destroyApp(false); notifyDestroyed()

}

 }

 }

/**

класс Draw определен в файле Draw.Java

передвижение квадрата с помощью клавиш телефона

*/

import javax.microedition.Icdui.*;

public class Draw extends Canvas implements Runnable

{

// устанавливаем квадрат в центр экрана

int positionX = getwidth()/2;

// устанавливаем квадрат в центр экрана

int positionY = getHeight()/2;

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

public Draw()

{ super(); }

public void start()

{

// создаем и запускаем поток

Thread t = new Thread(this);

t.start();

}

// метод run интерфейса Runnable public void run()

{

// бесконечный цикл

while (true)

{

// обновляем экран

repaint();

// останавливаем цикл на 20 миллисекунд

try { Thread, sleep (20) ,- }

catch (Java.lang.InterruptedException zxz) {}

}

 }

public void paint(Graphics g)

{

// вычисляем область для перерисовки экрана

int x = g.getClipWidth();

int у = g.getClipHeight();

// устанавливаем белый цвет фона

g.setColor(0xffffff);

// назначаем перерисовку всему экрану

g.fillRect(0,0,х,у);

// устанавливается зеленный цвет квадрату

g.setColor(0, 0, 200);

7/ рисуем квадрат

g.fillRect(positionX, positionY, 20, 20);

projected void keyPressed(int keyCode)

// скорость передвижения

int speed = 3 ;

// получаем игровые события

int act = getGameAction(keyCode);

// обработка событий

switch(act)

{

// движение влево case Canvas.LEFT:

positionX -= speed;

 break;

// движение вправо case Canvas.RIGHT:

positionX += speed;

break;

// движение вверх case Canvas.UP:

positionY -= speed;

break;

// движение вниз case Canvas.DOWN:

positionY += speed;

break; default: break;

}

}

}

В следующей главе рассматриваются игровые классы, доступные в профиле MIDP 2.0 и значительно упрощающие создание игрового цикла, а также игровом графики.


Глава 8. Техника создания игр

  • В этой главе...
  • 8.1. Класс GameCanvas
  • 8.2. Класс Layer
  • 8.3. Класс TiledLayer
  • 8.4. Класс LayerManager
  • 8.5. Класс Sprite
  • 8.6. Создание фонового изображения
  • 8.7. Обработка событий с клавиш телефона
  • 8.8. Анимация в игровом процессе
  • 8.9. Столкновение объектов


В этой главе...

Рынок мобильных телефонов развирается стремительными темпами. Все больше телефонов имеют поддержку технологии Java. Веянье игровой индустрии захватило и мобильные телефоны, поэтому платформа Java 2 ME позиционируется в большей степени как игровая платформа Для мобильных телефонов. При разработке игр под профиль MIDP 1.0 программист сталкивается с массой проблем в виде написания большого количества собственных классов для создания игрового процесса, рисование графики, уровней и так далее. В профиль MIDP 2.0 добавлено пять игровых классов, значительно упрощающих создание мобильных игр, это:

  • GameCanvas - абстрактный класс, содержащий основные элементы игрового интерфейса;
  • Layer — абстрактный класс, отвечающий за уровни представляемые в игре;
  • LayerManager - менеджер уровней;
  • sprite - представляет на экране спрайтовое изображение;
  • TiledLayer - отвечает за создание фоновых изображений.

Все вышеперечисленные классы доступны только в профиле MIDP 2.0. Также можно воспользоваться этими классами и в программировании телефонов Siemens под профиль MIDP 1.0, импортировав пакет com.siemens.mp.color_game. Компания Siemens входит в экспертную группу MIDP Expert Group и, по всей видимости, на базе уже имеющихся игровых классов от компании Siemens были созданы игровые классы для профиля MIDP 2.0.

При использовании игровых классов профиля MIDP 2.0, построение мобильной игры основано на системе уровней. Формируя игру, программист создает необходимое ему количество уровней. Каждый из уровней содержит набор графических элементов, например; можно создать уровень с фоновым изображением, уровень с препятствиями, уровень с игровыми бонусами, уровень с главным персонажем игры. После этого все имеющиеся уровни компонуются воедино, накладываются один уровень на другой и прорисовываются на экране телефона. Контроль над всеми уровнями, осуществляется при помощи класса LayerManager -менеджера уровней. Обилие методов предоставляемых игровыми классами позволяет отслеживать всевозможные столкновения, перемещения, анимацию и множество других функций, что значительно упрощает процесс создания мобильных игр.

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


8.1. Класс GameCanvas

Абстрактный класс GameCanvas составляет основу интерфейса всей создаваемой игры. Этот класс отвечает за прорисовку экрана, улучшая механизм работы игрового цикла и не используя при этом входные системные потоки. Весь игровой процесс может быть сосредоточен в одном цикле метода run () интерфейса Runnable.

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

public void run()

 {

Graphics g = getGraphics();

while(true)

{

// метод, обрабатывающий нажатия клавиш с телефона

inputKey();

// метод, прорисовывающий графику

GameGraphics();

// копирует графические элементы

на экран из внеэкранного буфера

flushGraphics();

}

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

Сама же обработка событий с клавиш упрощена с помощью метода getKeyState (). Вы просто определяете нажатую клавишу пописываете соответствующие игровые действия для нее. Изменены некоторые названия констант для клавиш телефона. Обработка событий с клавиш телефона происходит с помощью следующих констант:

  • static int DOWN_PRESSED - движение.вниз;
  • static int FIRE_PRESSED - реализует стрельбу из оружия;
  • static int GAME_A_PRESSED - игровая клавиша A;
  • static int GAME_B_PRESSED - игровая клавиша В;
  • static int GAME_C_PRES.SED - игровая клавиша С;
  • static int GAME_D_PRESSED - игровая клавиша D;
  • static int LEFT_PRESSED - движение влево;
  • static int RIGHT_PRESSED-движение вправо;.
  • static int UP_PRESSED - движение вверх.

Использование констант значительно упрощает работу с объектом, а с помощью метода getKeyStates () класса GameCanvas, можно определить, какая именно клавиша нажата в данный момент. Проанализируем методы класса GameCanvas:

  • void f lushGraphics () - копирует изображение из внеэкранного буфера на экран;
  • void flushGraphics(int x, int y, int width, int height) -копирует изображение из внеэкранного буфера на экран в заданный по размеру прямоугольник;
  • protected Graphics getGraphics () - получает графические элементы для представления их в последствии классом GameCanvas;
  • int getKeyStates ()-определяет какая из клавиш нажата;
  • void paint (Graphics g) - рисует графические элементы, представленные классом GameCanvas.

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


8.2. Класс Layer

Абстрактный класс Layer задает основные свойства для всех созданных уровней игры.

Класс Layer имеет два подкласса TiledLayer и Sprite. При создании любых других подклассов класса Layer необходимо реализовать метод paint () в этих классах, чтобы иметь возможность рисовать созданные уровни на экране телефона, представляемом классом Graphics. С помощью методов класса Layer можно задавать размер и позицию уровня.

  • int getHeight() - получает высоту экрана;
  • int getwidth() - получает ширину экрана;
  • int getX () - получает горизонтальную координату уровня;
  • int getY () - получает вертикальную координату уровня;
  • void move (int dx, int dy) — перемещает уровень на dx и dy координаты;
  • abstract void paint (Graphics g) - рисует уровень;
  • void setPosition (int x, int у) - устанавливает уровень в позицию, обозначенную в координатах х и у.


8.3. Класс TiledLayer

С помощью класса TiledLayer создается фон игровой сцены. Фоновое изображение выполняется в виде одинаковых по размеру ячеек как показано на рис. 8.1.

Рис 8.1. Ячейки фонового изображения

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

TiledLayer(int columns, int rows, Image image,

 int tileWidth, int tileHeight)

  • columns-количество столбцов;
  • rows - количество строк;
  • image - исходное изображение;
  • tileWidth - размер ширины ячейки в пикселях;
  • tileHeigh - размер высоты ячейки в пикселях.

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

Image im = Image.createlmage("/fon.png");

TiledLayer tl =new TiledLayer(3, 2, im, 10, 15);

Загрузив изображение и создав объект класса TiledLayer, вы можете приступить к разметке фона па игровом ноле. Допустим, каждая из перечисленных по номеру ячеек обладает следующими характеристиками:

1) камни;

2) трава;

3) вода;

4) песок;

5) воздух;

6) заграждение.

А игровое поле разбито на пятнадцать столбцов и десять строк, тогда создав массив данных, очень легко выполнить разметку всего поля, например таким образом:

int[] pole =

{

5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,

 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,

1, 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,

1, 1, 1, 1, 5, 5, 5, 1, 1, .5, 1, 1, 5, 5, 5,

1, 1, 1, 1, 1, 5, 5, 1, 1, 1, 1, 1, 1, 5, 5, 1,

1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 6, 6, 6, 1,

1, 1,1, 1, 1, 4, 4, 4, 4, 6, 6, 6, 6, 6, 4, 4,

4,4,4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4,

4, 4, 4, 3, 3/3, 3, 3, 3, 3, 3, 3, 4, 4, 4,

4, 4, 4, 3, 3, 3, 3,,3, 3, 3, 3, 3,

 }

Затем весь имеющийся массив данных считывается с помощью цикла и рисуется методом paint () на экране телефона.

Познакомимся с методами класса TiledLayer:

  • int createAnimatedTilefint staticTilelndex) - создает анимационный фон и возвращает следующий индекс ячейки;
  • int getCellHeight () - получает высоту ячейки в пикселях;
  • int getCellWidth() - получает ширину ячейки в пикселях;
  • int getColumns () - получает количество колонок, на которое разбито изображение фона;
  • int getRows () - получает количество строк, на которое разбито изображение фона;
  • void paint (Graphics g) - рисует фон;
  • void setCellfint col, int row, int tilelndex) - рисует заданную ячейку.


8.4. Класс LayerManager

Менеджер уровней представлен классом LayerManager. Это класс осуществляет представление любого количества уровней на игровом поле. Для создания объекта нужно воспользоваться конструктором класса LayerManager.

  • LayerManager () - создает уровень.

А чтобы добавить уровни в игру необходимо использовать следующие методы:

  • void append (Layer 1) - добавляет уровень в менеджер уровнен;
  • Layer getLayerAt (int index) - получает уровень с заданным индексом;
  • int getsize ()-получает общее количество уровней;
  • void insert (Layer 1, int index) - подключает новый уровень в заданный индекс;
  • void paint (Graphics g, int x, int у)- представляет текущий менеджер уровней в заданных координатах;
  • void remove (Layer 1) - удаляет уровень из менеджера уровней.

Предположим, у вас имеется четыре уровня: фон, игрок, препятствия и артефакты. Для того чтобы связать все четыре уровня воедино, создается объект класса LayerManager и вызывается метод append (). Например:

LayerManager im = new LayerManager();

im.append(fon);

im.append(igrok);

im.append(prep); .

im. append (artf.) ;

И все! Четыре перечисленных уровня отражается на игровом поле.


8.5. Класс Sprite

Механизм работы с объектом класса Sprite идентичен модели работы с классом TiledLayer. Но если класс TiledLayer в основном отвечает за фоновое изображение, то с помощью класса Sprite рисуются на экране основные анимированные герои, космические корабли, машины, люди, звери, артефакты и так далее. Изображение, загружаемое в игру, может быть выполнено в виде анимационной последовательности. Количество рисунков в анимационной последовательности неограниченно, а отсчет происходит от нуля. Располагаться рисунки могут как в виде столбца, так и в виде колонки, в зависимости от ваших предпочтений. Каждый рисунок анимационной последовательности называется фреймом. Фрейм может быть любого размера по ширине и высоте, но все фреймы должны быть одинаковых размеров. Размер фрейма должен быть известен, потому что он используется при создании объекта класса Sprite. Есть три конструктора класса Sprite каждый из которых можно использовать при создании объекта класса Sprite.

  • Sprite (Image image) - создает не анимированный спрайт;
  • Sprite(Image image, int frameWidth, int frameHeight)—создает анимационный спрайт, взятый из заданного фрейма;
  • Sprite (Sprites)- создает спрайт из другого спрайта.

Для перехода по фреймам исходного изображения, а также определения столкновения между объектами используются методы класса Sprite.

  • boolean collidesWith(Sprite s, boolean pixelLevel) — определяет столкновение между спрайтами;
  • boolean collidesWith (TiledLayer t, boolean. pixelLevel) - определяет столкновение между спрайтом и препятствием, нарисованным при помощи класса TiledLayer;
  • int getFrame () - получает текущий фрейм;
  • void next Frame ()- осуществляет переход наследующий фрейм;
  • void paint (Graphics g) - рисует спрайт;
  • void prevFrame () - осуществляет переход на предыдущий фрейм;
  • void setFrame(int sequencelndex) - устанавливает заданный фрейм;
  • void setFrameSequence (int [ ] sequence) - устанавливает определенную фреймовую последовательность;
  • void set Image(Image img, int frameWidth, int frameHeight)-изменяет изображение спрайта на новое изображение;
  • void setTransform( int transform) - производит трансформацию спрайта.
  • public void defineReferencePixel (int x, int у)- изменяет опорную позицию спрайта, перенося ее в точку с координатами х и у.

Метод defineReferencePixel () изменяет опорную позицию спрайта, но для чего это нужно? Опорная позиция для спрайта задается левым верхним углом, но не всегда это удобно, поэтому опорную позицию можно перенести, в центр спрайта. Например, если спрайт сделан в виде машины, то при вращении вокруг своей оси, если опорная позиция перенесена в центр, вращение будет правдоподобным. Но если не переопределить позицию, то вращение произойдет в точке левого верхнего угла спрайта и выглядеть это будет не вполне естественно, как будто у машины пробито одно из колес. Для этого вызывается метод def ineReferencePixel () с заданными координатами и переопределяет опорную позицию, например в центр спрайта:

defineReferencePixel(frameWidth / 2, frameHeight / 2);

Метод setTransform() производит трансформацию спрайта, вращая или зеркально отображая спрайт вокруг своей оси с помощью следующих констант:

  • static1int TRANS_MIRROR;
  • static int TRANS_MIRROR_ROT180;
  • static int TRANS_MIRROR_ROT270;
  • static int TRANS_MIRROR_ROT90;
  • static int TRANS_NONE;
  • static int TRANS_ROT180;
  • static int TRANS_ROT270;
  • static int TRANS_ROT90.

Посмотрите на рис. 8.2, где очень привлекательно показаны константы для различных состояний спрайта.

Рассмотрев классы GameCanvas, Layer, Sprite, TiledLayer и LayerManager, перейдем к практическим занятиям этой главы.


8.6. Создание фонового изображения

С помощью класса TiledLayer можно создавать любое количество уровней, накладывая их друг на друга, а с помощью менеджера уровней, представленного классом LayerManager, отслеживать все имеющиеся уровни. В качестве примера будет создан фон на основе элементов разметки игрового поля. Фоновое изображение загружается из файла fon.png. Само изображение выполнено в виде шести ячеек размером 15x15 пикселей.

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

Рис. 8.2. Константы трансформации

/ * *

Листинг 8.1 класс MainGame

*/

import

javax.microedition.lcdui.* ;

import

javax.microedition.midlet.*;

public class MainGame extends

MIDlet implements CommandListener

{

//команда выхода

private Command exitMidlet = new Command!"Выход",

Command.EXIT, 0) ;

// объект класса MyGameCanvas

private MyGameCanvas mr;

public void startApp.{}

{

// обрабатываем исключительную ситуацию

try{

// инициализируем объект класса MyGameCanvas;

mr = new MyGameCanvas() ;

// запускаем поток

mr.start();

// добавляем команду выхода

mr.addCommand(exitMidlet);

mr.setCommandListener(this) ;

// отражаем текущий дисплей

Display .getDisplay (this) . setCurrent (mr-) ;

} catch (Java . io. ID-Exception zxz) {} ;

}

public void pauseApp() {}

public void destroyApp(boolean unconditional)

{

// останавливаем поток

if(mr != null) mr.stop'O; }

public void coramandAction(Command c, Displayable d)

{

if (c == exitMidlet)

{

destroyApp(false) ; notifyDestroyed() ;

}

}

 }

/ * *

Файл MyGameCanvas.Java класс MyGameCanvas

*/

import Java.io.IOException;

 import javax.microedition.Icdui.*;

import javax.microedition Nlcdui.game.* ;

public class MyGameCanvas extends GameCanvas implements

Runnable-

{

// создаем объект класса TiledLayer

private TiledLayer fonPole;

// создаем объект класса LayerManager

private LayerManager im;

// логическая переменная для выхода из цикла

boolean z;

public MyGameCanvas(), throws IOException

{

// обращаемся к конструктору суперклассаNCanvas

super(true);

// инициализируем fonPole

fonPole = Fon () ;

// создаем менеджер уровней

1m = new LayerManager();

// добавляем объект fonPole к уровню im.append (fonPole);

}

public void start()

{

z = true;

// создаем и запускаем поток

Thread t = new Thread(this);

t.start();

}

//* метод, создающий объект класса TiledLayer

и загружающий фоновое изображение

*/

 public TiledLayer Fon()throws IOException

{

// загрузка изображения из файла ресурса

Image im = Image.createlmage("/fon.png");

// создаем объект класса TiledLayer

fonPole = new TiledLayer(/*столбцы*/10,/*строки*/10,

/*изображение*/lm,/*ширина*/15,/*высота*/15);

// разметка игрового поля

int[] pole =

{

5, 5, 5, 5, 5, 5, 5, 5, 5, 5,

1, 5, 5, 5, 5, 5, 5, 5, 5, 5,

1, 1, 5, 5, 5, 5, 5, 5, 5, 5,

1, 1, 1, 1, 5, 5, 5, 1, 1, 5,

1, 1, 1, 1, 1, 5, 5, 1, 1, 1,

1, 1, 1, 1, 1, 1, 1, 1, 6, 6,

1, 1, 1, 1, 1, 1, 6, 6, 6, 6,

2, 4, 4, 4, 4, 4, 3, 3, 3, 3,

2, 2, 2, 4, 4, 4, 3, 3, 3, 3,

2, 2, 2, 4, 4, 4, 3, 3, 3, 3

 };

// цикл, считывающий разметку поля

for(int i = 0; i < pole.length; i + + )

{

/* присваиваем каждому элементу игрового

поля определенную ячейку изображения

 im*/ fonPole.setCell(i % 10, i / 10, pole[i]);

}

return fonPole;

}

public void stop(){ z = false;

 }

public void run()

{

// получаем графический контекст Graphics g = getGraphics();

 while (z)

{

// рисуем графические элементы

init(g) ;

// останавливаем цикл на 20 миллисекунд

try { Thread.sleep(20);

 }

catch (Java.lang.InterruptedExceptlori zx.z) {};

 }

 }

private void init(Graphics g)

{

// белый цвет фона для перерисовки экрана

g.setColor(0xffffff);

// размер перерисовки экрана

g.fillRect(0, 0, getWidth(), getHeight());

// рисуем уровень с левого верхнего угла дисплея

1m.paint(g, 0, 0) ;

// двойная буферизация

flushGraphics();

}

}

Листинг 8.1 состоит из двух классов MainCanvas и MyGameCanvas, находящихся в файлах MainCanvas.java и MyGameCanvas.java. Анализ листинга начнем с класса MyGameCanvas. В первых строках кода этого класса объявляются два объекта классов TiledLayer и LayerManager, атак же логическая переменная z.

private TiledLayer fonPole;

private LayerManager lm,

boolean z;

Объект fonPole класса TiledLayer будет отвечать за фоновое изображение. Объект im класса LayerManager является менеджером уровней. Логическая переменная z необходима для прерывания цикла в методе run () и для окончания системного потока, в котором происходит работа всего игрового цикла.

В конструкторе MyGameCanvas происходит инициализация объекта fonPole класса TiledLayer и объект im класса LayerManager. Инициализированный объект fonPole добавляется менеджером уровней к текущему уровню для представления на экране телефона. Обратите внимание, объект fonPole инициализируется с помощью метода Fon ().

Image im = Image.createlmage("/fon.png");

fonPole= new TiledLayer(/*столб*/10,/*строки*/10,im,

/*ширина*/15,/*высота*/15);

В этих двух строках происходит загрузка исходного изображения из файла ресурса и создание объекта fonPole с помощью конструктора класса TiledLayer.

Вся разметка игрового поля выполнена в виде десяти строк и десяти столбцов. Первые два параметра конструктора класса TiledLayer как раз и отвечают за количество столбцов и строк. Третий параметр конструктора - это исходное изображение, выполненное в виде шести ячеек, каждая размером 15x15 пикселей. Два последних параметра конструктора класса TiledLayer определяют ширину и высоту ячейки. При создании объекта класса TiledLayer необходимо быть внимательным и указывать реальные размеры одной ячейки. Если размер одной ячейки будет, предположим 20x20 пикселей, а вы обозначите как 15x15 пикселей, то в итоге ячейки изображения загружены не будут.

Дальше в методе Fon () происходит разметка игрового поля выполненного в виде десяти столбцов и десяти строк.

int[] pole =

{

5, 5, 5, 5, 5, 5, 5, 5, 5, 5,

1, 5, 5, 5, 5, 5, 5, 5, 5, 5,

1, 1, 5, 5, 5, 5, 5, 5, 5, 5,

1, 1, 1, 1, 5, 5, 5, 1, 1, 5,

1, 1, 1, 1, 1, 5, 5, 1, 1, 1,

1, 1, 1, 1, 1, 1, 1, 1, 6, 6,

1, 1, 1, 1, 1, 1, 6, 6, 6, 6,

2, 4, 4, 4, 4, 4, 3, 3, 3, 3,

2, 2, 2, 4, 4, 4, 3, 3, 3, 3,

2, 2, 2, 4, 4, 4, 3, 3, 3, 3,

 };

Все строки и столбцы состоят из элементов. Отсчет ячеек происходит от единицы и выше. Присвоение номера ячейки исходного изображения одному из элементов и организует разметку игрового поля, которое в последствии будет рисоваться на экране. Единственное О5чем нельзя забывать - это о размере дисплеев реальных телефонов. Если вы имеете десять столбцов и размер каждой ячейки 15 пикселей по ширине, то в итоге ваше игровое поле в ширину будет 10x15 = - 150 пикселей. Не каждый телефон может похвастаться таким разрешением, поэтому при создании игрового поля нужно учитывать эти нюансы. Вслед за разметкой игрового поля в методе Fon () происходит считывание всех элементов с помощью цикла for.

forfint i = 0; i < pole.length; i++)

{

fonPole.setCell(i % 10, i / 10, pole[i]);

}

Присвоение номера ячейки определенному элементу происходит при помощи метода setCell (). В этом методе первый параметр-номер столбца, второй - номер строки и последний - номер ячейки изображения. Здесь главное не запутаться, потому что номера столбцов и строк начинаются с нуля из-за того, что это обычный массив данных, а все массивы, как вы знаете, ведут свой отсчет с нуля, тогда как ячейка исходного изображения начинается с единицы. Сразу возникает вопрос, а почему не произвести отсчет тоже с нуля, чтобы не было путаницы? Дело в том, что отсчет и производится с нуля, но число ноль - это своего рода зарезервированное значение для ячеек изображения. Нулевое значение может использоваться, но оно не. загружает ничего, поэтому отсчет ячеек ведется с единицы. С методом Fon () мы разобрались, перейдем к методу init ().

g.setColor(0xffffff);

g.fillRect(0, 0, getWidth0, getHeight());

В этих строках кода происходит постоянная перерисовка фона экрана. Эти действия вы производили в главе 7, когда разбирали механизм отсечения.

С помощью метода paint () рисуется уровень. Начало точки вывода уровня задано точкой 0,0, что соответствует началу, системы координат.

И последний метод flushGraphics () осуществляет двойную буферизацию, копируя графические элементы из внеэкранного буфера на экран.

В методе run () происходит остановка игрового цикла. Перед тем как цикл создается с помощью оператора while, методом getGraphics () происходит получение графического контекста, что и является одним из достоинств механизма игрового цикла в профиле MIDP 2.0.

В файле MainGame.java создается основной класс мидлета MainGame. В методе startApp() производится создание объекта рассмотренного класса MyGameCanvas, добавляется команда выхода, запускается системный поток и отражается текущий дисплей. В методе destroyApp () происходит остановка потока методом stop () класса MyGameCanvas.


8.7. Обработка событий с клавиш телефона

В профиле MIDP 2.0 предусмотрена улучшенная обработка событий получаемых с клавиш телефона. Используя метод getKeyState () можно определять состояние клавиш телефона и действовать адекватным образом. 'В демонстрационном примере к этому разделу мы выведем на экран мячик, созданный при помощи класса MySprite являющимся подклассом класса Sprite. В листинге 8.2 представлен код примера, в котором на экране рисуется синий мяч, а с помощью клавиш телефона Up, Down, Left и Right этот мяч можно передвигать по экрану. Листинг 8.2 состоит из трех классов: MainGame. MyGameCanvas и MySprite, расположенных в трех разных файлах MainGame.java, MyGameCanvas.java и MySprite.java.

/**

Листинг 8.2 класс MainGame

*/

import javax.microedition.Icdui.*;

import javax.microedition.midlet.*;

public class MainGame extends MIDlet implements

CommandListener

{

// команда выхода

private Command exitMidlet = new Command("Выход",
Command.EXIT, 0);

// объект класса MyGameCanvas

private MyGameCanvas mr;

public void startApp()

{

// обрабатываем исключительную ситуацию

 try

{

// инициализируем объект класса

MyGameCanvas mr = new MyGameCanvas();

// запускаем поток mr.start();

// добавляем команду выхода

mr.addCommand(exitMidlet);

mr.setCommandLis'tener (this) ;

// отражаем текущий дисплей

Display.getDisplay(this).setCurrent(mr);

}

catch (Java.io.lOException zxz) {} ;

}

public void pauseApp() {}

public void destroyApp(boolean unconditional)

{

// останавливаем поток

if(mr != null) mr.stopt);

 }

public void commandAction (Command c, Displayable d;)

 {

if (с == exitMidlet)

{

destroyApp(false); notifyDestroyed();

}

}

}

/**

файл MyGameCanvas.Java класс MyGameCanvas

 */

import java.io.*;

import javax.microedition.Icdui.*;

import javax.microedition. Icdui .game .*;

public class MyGameCanvas extends GameCanvas implements

Runnable

{

// создаем объект класса MySprite

private MySprite bol;

// создаем объект класса Lay'erManager

private LayerManager lm;

// логическая переменная

boolean z;

public MyGameCanvas() throws IOException

{

// обращаемся к конструктору суперкласса Canvas

super(true);

// загружаем изображение

Image im = Image.createlmage("/bol.png");

// инициализируем объект bol

bol = new MySprite (itn, 23, 23);

// выбираем позицию в центре экрана

bol.setPosition(getWidth()/2, getHeight()/2);

// инициализируем менеджер уровней

1m = new LayerManager();

// добавляем объект bol к уровню

lm.append(bol); }

public void start()

{

z = true;

// создаем и запускаем поток

Thread t = new Thread(this);

t.start();

 }

// останавливаем поток

 public void stop()

{ z = false;

}

public void run()

{

// получаем графический контекст

Graphic's g = getGraphics () ;

while (z)

{

// обрабатываем события с клавиш телефона

 inputKey();

// рисуем графические элементы init(g);

// останавливаем цикл на 20 миллисекунд

 try { Thread.sleep(20);

}

catch (Java.lang.InterruptedException zxz) {};

 }

 }

private void inputKey()

{

// определяем нажатую клавишу

int keyStates = getKeyStates();

// код обработки для левой нажатой клавиши

-if ((keyStates & LEFT_PRESSED) != 0) bol.moveLeft();

// код обработки для правой нажатой клавиши

if ((keyStates & RIGHT_PRESSED) != 0) bol.moveRight();

// код обработки для клавиши вверх

if ((keyStates & UP_PRESSED) != 0) bol.moveUp();

// код обработки для клавиши вниз

if ((keyStates & DOWN_PRESSED) != 0) bol.moveDown();

}

private void init(Graphics g)

{

// белый цвет фона g.setColor(0xffffff);

// перерисовываем экран

g.fillRect (0 , 0, getWi.dth () , getHeight());

// рисем уровень в точке 0,0

lm.paint(g, 0, 0) ;

// двойная буферезация

flushGraphics();

};

}

/**

файл MySprite.Java
класс MySprite

*/

import javax.microedition.Icdui.*;

 import javax.microedition.Icdui.game.*;

public class MySprite extends Sprite

{

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

public MySprite(Image image, int fw, int fh)

{

// обращаемся к конструктору суперкласса

super (image, fw, fh);

}

// метод для клавиши Left public void moveLeft() ;

 {

// передвигаем спрайт

move(-1,0);

}

// метод для клавиши Right public void moveRight()

{

/ / передвигаем спрайт

move(1,0);

}

// метод для клавиши Up public void moveUp()

{

// передвигаем спрайт

move(0,-1);

}

// метод для клавиши Down public void moveDown()

{

// передвигаем спрайт

move(0,1);

'}

 }

В файле MySprite.java находится класс MySprite, с которого и начнем рассмотрение листинга. Конструктор класса MySprite обращается к конструктору своего суперкласса Sprite!

super(image, fw, fh);

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

Для передвижения спрайта по экрану телефона созданы методы moveLef t (), moveRight (), moveUp () и moveDowri (), в основу которых положены вызовы метода move (). Метод move () имеет два параметра - это координаты по осям X и Y. Задавая необходимое смещение на 1, 2, 3 и более пикселей по одной из осей, вы будете производить движение объекта по экрану.

Класс MyGameCanvas работает по схеме, использованной в разделе 8.6, с той лишь разницей, что вместо фонового изображения загружается спрайт в виде мячика. В конструкторе класса MyGameCanvas происходит загрузка исходного изображения bol.png, это и есть наш мячик или спрайт. Спрайт размером 23x23 пикселя. При создании объекта bol класса MySprite

bol = new MySprite(im, 23, 23)

используется изображение bol.png, затем, в конструкторе класса MyGameCanvas происходит выбор позиции для первоначальной отрисовки спрайта на экране с помощью метода setPosition (). Мячик рисуется в центре экрана и добавляется методом append () к уровню.

В методе run () в игровом цикле происходит вызов двух методов. Метод init () производит рисование всех графических элементов с помощью менеджера уровней, а метод input Key () осуществляет обработку нажатий клавиш телефона.

private void inputKey()

{

int keyStates = getKeyStates();

if ((keyStates & LEFT_PRESSED) != 0) bol.moveLeft();

if ((keyStates & RIGHT_PRESSED) !=0) bol.moveRight();

if ((keyStates & UP_PRESSED) != 0) bol.moveUp();

if ((keyStates & DOWN_PRESSED) != 0) bol.moveDown ();

}

В методе inputKey () происходит определение нажатой клавиши посредством метода getKeyState (). Весь остальной код в методе inputKey () использует оператор if для обработки нажатых клавши, вызывая соответствующие методы moveLeftO, moveRight (), moveUp ()или moveDown () для перемещения объекта по экрану.

В классе MainGame из файла MainGame.java создается объект класса MyGameCanvas, запускается системный поток и отражается текущий экран.

В этом примере использовался спрайт файла ресурса bol.png состоящий из одного фрейма размером 23x23 пикселя. В следующем разделе мы рассмотрим технику анимации спрайтов в играх, и будем исполВзовать спрайт, состоящий уже из нескольких фреймов.


8.8. Анимация в игровом процессе

Анимация в игровом процессе строится на основе последовательной цепочки рисунков. Как вы уже знаете, отдельно взятый рисунок из анимационной последовательности в Java 2 ME называется фреймом. Для того чтобы осуществить плавную анимацию в игре, необходимо выполнить ряд сменяющих друг друга рисунков. Посмотрите на рис. 8.3, где изображен матрос с флажками.

Рис. 8.3. Анимационная последовательность

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

Анимация повсеместно используется в компьютерных и мобильных играх. Вы наверно замечали, что при перемещении в игре персонажа, он производит ряд повторяющихся движений, создавая видимость игрового цикла. Такие элементарные движения следствие перехода" по имеющимся фреймам исходного изображения. Для этих целей в Java 2 ME имеются специальные методы класса Sprite.

Метод nextFrame () позволяет осуществить переход по всем имеющимся фреймам исходного изображения. Как только достигается последний фрейм, то автоматически происходит переход к первому фрейму с последующим переходом по всей имеющейся последовательности, что обеспечивает цикличность анимации.

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

В листинге 8.3, а так же на компакт-диске в папке \Code\Listing8_3\src дается код примера иллюстрирующего работу анимационной последовательности.

/**

Листинг 8.3

класс MainGame

*/

import javax.microedition.lcdui.*;

import javax.microedition.midlet. * ;

public class MainGame extends MIDlet implements

CornmandListener

{

// команда выхода

private Command exitMidlet = new Command(«Выход»,
Command.EXIT, 0);

// объект класса

 MyGameCanvas

private MyGameCanvas mr;

public void startApp()

{

// обрабатываем исключительную ситуацию

try{

// инициализируем объект класса MyGameCanvas

mr = new MyGameCanvas();

// запускаем поток

mr .start();

// добавляем команду выхода

mr.addCommand(exitMidlet);

mr:setCommandListener{this);

/7 отражаем текущий дисплей

Display.getDisplay(this).setCurrent(mr);

}catch (Java.io.lOException zxz) {}; }

public void pauseApp() {}

public void destroyApp(boolean unconditional)

{

// останавливаем потоку

if(mr != null) mr.stop();

}

public void commandAction(Command c, Displayable d)

{

if (с == exitMidlet)

{

destroyApp(false);

notifyDestroyedO ;

 }

}

}

/**

файл MyGameCanvas.java
класс MyGameCanvas

*/

import java.io.

import javax.microedition.Icdui.*;

 import javax.microedition.Icdui.game.*;

public class MyGameCanvas extends GameCanvas implements

Runnable

{

// создаем объект класса MySprite

private Matros matros;

// создаем объект класса LayerManager

private LayerManager lm;

// логическая переменная

boolean z;

public MyGameCanvas() throws IOException

{

// обращаемся к конструктору суперкласса Canvas

super(true);

// загружаем изображение

Image im = Image.createlmage(«/matros.png»);

// инициализируем объект matros

matros = new Matros(im, 94, 100);

// выбираем позицию

matros.setPosition(30, 30);

// инициализируем менеджер уровней

1m = new LayerManager();

// добавляем объект матроса к уровню

lm.append(matros); }

public void start()

{

{

z= true;

// создаем и згшускаем поток Thread t = new Thread(this);

t.start () ;

}

// останавливаем поток

public void stop()

{ z = false;

}

public void run()

{

// получаем графический контекст

 Graphics g = getGraphics();

while (z)

{

// рисуем графические элементы init(g)

// останавливаем цикл try { Thread.sleep(250);

}

catch (Java.lang.InterruptedException zxz) {};

}

 }

private void init(Graphics g)

 {

// белый цвет фона

g.setColor(0xffffff);

// перерисовываем экран

g.fillRect(0, 0, getWidth(),getHeight());

// рисуем уровень в точке 0,0

lm.paint(g, 0 , 0) ;

// рисуем анимацию

matros.Animation();

// двойная буферизация

iluGhGraphics();

}

}

/* *

файлMatros.Javaкласс
Matros * /

import- javax .rnicroedition. Icdui .* ;

import javax.microedition.lcdui.game.*;

public class Matros extends Sprite

{

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

public Matros(Image image, int fw, int fh)

{

// обращаемся к конструктору суперкласса

super(image, fw, fh) ;

}

// метод осуществляющий анимацию

public void Animation!)

{

// вызываем следующий фрейм

nextFrame();

}

}

В листинге 8.3 нам интересно несколько моментов. В классе Matros, являющимся подклассом класса Sprite, создается метод Animation (), который выглядит следующим образом:

public void Animation()

 {

nextFrame();

}

Метод Animation () осуществляет тот самый последовательный переход по имеющимся фреймам исходного изображения. В классе MyGameCanvas происходит создание объекта класса Matros:

private Matros matros;

Затем в конструкторе класса MyGameCanvas загружается изображение матроса и инициализируется объект matros.

Image im = Image.createlmage(«/matros.png»);

matros = new Matros(im, 94, 100);

Размер одного фрейма с матросом равен 94x100 пикселей, поэтому указывается размер именно одного фрейма. По умолчанию загружается самый первый фрейм изображения, но можно использовать метод setFrame () для установки необходимого фрейма из анимационной последовательности. В методе Graphics () класса MyGameCanvas происходит вызов метода Animation ():

matros.Animation();

Это в итоге приводит к цикличному перебору всех имеющихся фреймов. Откомпилируйте код из листинга 8.3 и посмотрите работу этого примера. На экране телефона матрос с помощью семафорной азбуки передает слово «анимация».


8.9. Столкновение объектов

Практически во всех играх приходится обрабатывать события связанные со столкновением двух объектов или с препятствием. В профиле MIDP 2.0 существует три отличных метода, отслеживающих факт столкновения. Все три метода определены в классе Sprite.

  • collidesWith(Image image, int x, int y, Boolean pixelLevel) - определяет факт столкновения со статическим изображением;
  • collidesWith (Sprite s, Boolean pixelLevel) - определяет столкновение между двумя объектами класса Sprite;
  • collidesWith(TiledLayer t. Boolean pixelLevel) -отслеживает столкновение между объектом класса Sprite и объектом класса TiledLayer.

Используя эти методы можно обрабатывать всевозможные ситуации, связанные со столкновением. Как правило, при столкновении должны произойти какие-то события, чаще всего связанные с изменением первоначального состояния объекта. Это может быть уничтожение объекта, его перемещение, уменьшение или увеличение. В основе изменения состояния объекта положен перебор имеющихся фреймов в анимационной последовательности или перерисовка изображения на новом месте. Для этих операций в классе Sprite имеется несколько методов. С одним из методов nextFrame (), вы уже познакомились в разделе 8.8, рассмотрим оставшиеся методы.

  • prevFrame () - с помощью этого метода происходит переход к предыдущим фреймам изображения. Этот метод подобен методу nextFrame (), только переход осуществляется в обратном порядке;
  • setFrame() - производит установку при помощи индекса заданного фрейма из всей имеющейся последовательности фреймов.
  • setFrameSequence () - устанавливает определенную фреймовую последовательность при помощи массива индексов в анимационной последовательности;
  • getFrame () - узнает, какой из фреймов исходного изображения используется в текущий момент;
  • set Image () - заменяет исходное изображение на новое. Можно использовать этот метод, например в том случае, если объект уничтожен, и его необходимо перерисовать заново.

Набора этих методов вполне достаточно для обработки различных ситуаций возникающих в игровом процессе. Однако необходимо очень тщательно разобраться в действии всех вышеперечисленных методов. Для этого был написан исходный код примера, иллюстрирующего работу методов nextFrame (), prevFrame (), setFrame () и setFrameSequence (). В этой программе на экран выводятся четыре бомбы и синий шарик, перемещая который в разные стороны можно произвести столкновение с четырьмя бомбами. Все бомбы являются объектами класса MySprite, являющимся подклассом класса Sprite. Метод, обрабатывающий столкновение мяча и бомбы, использует один из четырех методов nextFrame (), prevFrame.(), setFrame () и setFrameSequence () для каждой из бомб, что красочно иллюстрирует работу каждого метода. Исходные, изображения бомбы и мяча выполнены в виде последовательности четырех фреймов размером 23x23 пикселя. Первый фрейм мяча и бомбы является исходным изображением, а три последующих фрейма реализованы в виде взрыва. Переход по этим фреймам создает иллюзию взрыва мячика или бомбы. Но оттого, что для каждой бомбы как мы договорились, используются различные методы, то результат может оказаться неожиданным. Поэтому внимательно посмотрите на код примера в листинге 8.4 и запустите программу с помощью любого эмулятора, поддерживающего профиль MIDP 2.0. Либо откомпилируйте исходный код из листинга 8.4 и внимательно ознакомьтесь с работой этой программы. Я уверен, что вы без труда разберетесь, что именно нужно сделать для логического завершения взрывов бомб и мяча. Алгоритм действий очень прост и может быть следующим после столкновения мяча с одной из мин. Необходимо произвести взрыв, последовательно переходя по всем фреймам, после чего, например, нарисовать бомбу и мячик заново. В листинг 8.4 предложен исходный код примера.

/ * *

листинг 8.4

класс MainGame

*/

import javax.microedition.Icdui.*;

import javax.microedition.midlet.*;

public class MainGame extends MIDlet implements

CommandListener

{

// команда выхода

private Command

exitMidlet = new Command(«Выход»,Command.EXIT, 0);

// объект класса MyGameCanvas

private MyGameCanvas mr;

public void startApp()

{

// обрабатываем исключительную ситуацию.

try{

// инициализируем'объект класса MyGameCanvas

mr = new MyGameCanvas();

// запускаем поток

mr.start{};

// добавляем команду выхода

mr.addCommand(exitMidlet) ;

 mr.setCommandListener(this);

// отражаем текущий дисплей

Display.getDisplay(this).setCurrent(mr) ;

}

catch (Java . io. lOException zxz) {} ;

 }

public void pauseApp() {}

public void destroyApp(boolean unconditional)

{

// останавливаем поток

if(mr != null) mr.stopf);

 }

public void commandAction(Command c, Displayable d)

{

if (c = = exitMidlet)

{

destroyApp (false);

notifyDestroyed(); }

 }

  }

}

/**

файл MyGameCanvas.Java

класс MyGameCanvas

*/

import java.io.*;

import javax.microedition.Icdui.*;

import javax.microedition.Icdui.game.*;

public class MyGameCanvas

extends GameCanvas implements

Runnable

{

// создаем объект класса MySprite

private MySprite bol;

// создаем объект класса LayerManager

private LayerManager lm;

// создаем бомбы

private MySprite bombal, bomba2, bombaB, bomba4;

// логическая переменная

boolean z;

public MyGameCanvas() throws lOException

{

// обращаемся к конструктору суперкласса Canvas

super(true);

// загружаем изображение мяча

linage bollmage = Image.createlmage («/bol.png»)

// инйциалтзируем объект bol

bol = new MySprite(bollmage, 23, 23);

// выбираем позицию в центре экрана

bol.setPosition(getWidth() /2, getHeight. () /2) ;

// загрузка изображения бомбы

Image bombalmage = Image.createlmage(«/bomba.png»);

// инициализируем первую бомбу

bombal = new MySprite(bombalmage, 23, 23);

// выбираем позицию для первой бомбы

bombal.setPosition(10, 10);

// инициализируем вторую бомбу

bomba2 = new MySprite(bombalmage, 23, 23);

// выбираем позицию для второй бомбы

bomba2 . setPosition( getwidth()-30, 10);

// инициализируем третью-бомбу

bоmbа3 = new MySprite(bombalmage, 23, 23);

// выбираем позицию для третьей бомбы

bоmbа3.setPosition(10, getHeight()-40);

// инициализируем четвертую бомбу

bomba4 = new MySprite(bombalmage, 23, 23);

// выбираем позицию для четвертой бомбы

bomba4.setPosition(getWidth()-30, getHeight 0-40);

// инициализируем менеджер уровней

lm = new LayerManager();

// добавляем мяч к уровню

lm.append(bol);

// добавляем бомбы к уровню

lm.append(bombal);

lm.append(bomba2);

lm.append(ЬотЬаЗ);

lm.append(bomba4); }

// обрабатываем столкновение

public void stolknovenie()

{

// столкновение с первой бомбой

if (bol. collidesWith (bombal, true))

{

bol.nextFrame();

bombal.nextFrame(); }

// столкновение со второй бомбой

if(bol.collidesWith(bomba2, true))

{

bol.prevFrame(); bomba2.prevFrame();

}

// столкновение с третьей бомбой

if (bol .collidesWith(bоmbа3 , true))

{

bol.setFrame (2) ;
vbomba3.setFrame(0);

}

// столкновение с четвертой бомбой

if(bol.collidesWith(bomba4, true))

{

int[] i = {2,3};

bol.setFrame(0);

bomba4 . setFrameSequence (i) ;

}
 }

public void start()

{

z = true;

// создаем и запускаем поток

 Thread t = new Thread(this);

t.start();

}

// останавливаем поток

public void stop()

{ z = false; }

public void run()

{

// получаем графический контекст

Graphics g = getGraphics(); while (z)

 {

// столкновение с препятствием

stolknovenie ();

// обрабатываем события с клавиш телефона

inputKey();

// рисуем графические элементы init(g);

// останавливаем цикл на 20 миллисекунд

 try { Thread.sleep(20);

}

catch (Java.lang.InterruptedException zxz) {};

}

}

private void inputKey()

{

//-определяем нажатую клавишу

int keyStates = getKeyStates();

// код обработки для левой нажатой клавиши

if ((keyStates & LEFT_PRESSED) != 0) bol.moveLeft();

// код обработки для правой нажатой клавиши

if ((keyStates & RIGHT_PRESSED) != 0) bol.moveRight();

// код обработки для клавиши вверх

if ((keyStates & UP_PRESSED) != 0) bol.moveUp();

// код обработки для клавиши вниз

if ({keyStates & DOWN_PRESSED) !=-0) bol.moveDown();

}

private void init(Graphics g)

 {

// желтый цвет фона

g.setColor(0xffff00);

// перерисовываем экран

g.fillRect(0, 0, getWidth(), getHeight());

// рисем уровень в точке 0,0

lm.paint(g, 0, 0);

// двойная буферизация

flushGraphics();

}

}

/**

файл MySprite.Java класс MySprite

*/
import javax.microedition.Icdui.*;

import javax.microedition.Icdui.game.*;

public class MySprite extends Sprite

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

oublic MySprite(Image image, int fw, int fh)

// обращаемся к конструктору суперкласса

super( image , fw, fh);

}
//метод для левой нажатой клавиши

public void moveLeft()

//передвигаем спрайт

move(-1,0);

//метод  для правой нажатой клавиши

publiс void moveRight()

//передвигаем спрайт

move(1,0);

}

// метод для клавиши вверх

 public void rnoveUp ()

// передвигаем спрайт

// метод для клавиши вниз

public void moveDown()

//передвигаем спрайт

 move(0,1);

}

}

В листинге 8-4 содержатся три класса MainGame, MyGameCanvas и My Sprite. Основной код обработки столкновений бомб и мяна находится в классе Мус игпйСа n vas - этому классу мы и уделим особое внимание при разборе - листинга.

В конструкторе класса MyGameCanvas происходит загрузка изображения мяча из файла ресурса bol.png, инициализация объекта bol, класса MySprite и устанавливается позиция прорисовки на экране объекта bol.

ImagebolImage = Image.createlmage(«/bol.png») ;

bol= new KySprioe(bollmage, 23, 23);

bol.setPosition(getWidth()/2 ,getHeight()/2 ) ;

Заметьте, что позиция вывода мяча на экран установлена в центре экрана, но эта позиция определена для левой верхней точки мяча, поэтому именно левый верхний угол изображения спрайта мяча будет находиться в центре экрана. Для того чтобы нарисовать сам спрайт в центре экрана, нужно переопределить опорную позицию мяча с помощью метода def ineRef erencePixel ().

Затем в конструкторе класса MyGameCanvas загружается изображение бомбы.

Image bombalmage=Image.createlmage(«/bomba.png»);

После этого происходит инициализация четырех объектов bombal, bomba2, bomba3 и bomba4 класса MySprite и устанавливается позиция для вывода всех четырех бомб на экран телефона.

bombal = new MySprite(bombalmage, 23, 23);

bombal.setPosition(10,10);

bomba2 = new MySprite(bombalmage, 23, 23);

bomba2.setPosition( getwidth()-30, 10);

bomba3 = new MySprite(bombalmage, 23, 23);

bonba3.setPosition(10, getHeight()-40);

bomba4 = new MySprite(bombalmage, 23, 23);.

bomba4.setPosition(getWidth()-30, getHeight()-40);

Все четыре бомбы рисуются в разных углах экрана слева направо и сверху вниз.

Произведя загрузку необходимых изображений и инициализируя все объекты класса MySprite, можно добавить их к уровню с помощью менеджера уровней.

lm.append(bol);

lm.append(bombal);

lm.append(bomba2);

lm.append(bomba3);

 lm. append (bomba4);

Наша задача в этом примере - это определение столкновения бомб и мячика, для этого создан метод stolknovenie (), где при помощи конструкции if/ else происходит обработка столкновения объектов bol и bombalbomba4. Сейчас было бы очень хорошо, если бы вы могли запустить программу из листинга 8.4 и попробовали осуществить столкновение мяча с четырьмя бомбами. Как мы договорились, при столкновении будет обсуждаться работа четырех разных методов.

В столкновении с первой бомбой, находящейся в левом верхнем углу экрана, используется метод next Frame (). Если вы переместите мячик по экрану, то при наезде на первую бомбу произойдет взрыв бомбы и мяча. То есть начнется перебор всех имеющихся фреймов обоих объектов в цикличном порядке. Как только вы уберете мячик с бомбы, взрыв обоих объектов прекратится, потому что закончится перебор фреймов изображений. А состояние бомбы и мяча будет соответствовать одному из фреймов всей анимационной последовательности, при этом возможности повлиять на остановку- перехода по фреймам в методе nextFrame () нет.

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

Третья бомба рисуется в нижнем углу экрана и для обработки столкновения мяча с бомбой используется метод setFrame (). Этот метод производит переход по заданным фреймам всей анимационной последовательности по номеру или индексу фрейма. В этом примере используется следующий код при столкновении мяча и третьей бомбы.

bol, setFrame (2);

bomba3.setFrame(0);

Когда вы передвинете мячик на третью бомбу, то увидите, что изображение мячика изменится, и будет соответствовать третьему фрейму всей анимационной последовательности мячика. Состояние бомбы останется неизменным, потому что используется индекс 0, а это первый фрейм бомбы.

Четвертая бомба при столкновении задействует метод setFrameSequenсе (), благодаря которому можно использовать фреймовые последовательности в виде массива индексов.

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


Глава 9. Мобильная мультимедиа-библиотека

  • В этой главе...
  • 9.1. Пакет javax.microedition.media
    • 9.1.1. Интерфейс Control
    • 9.1.2. Интерфейс Controllable
    • 9.1.3. Интерфейс Player
    • 9.1.4. Интерфейс PlayerListener
    • 9.1.5. Класс Manager
  • 9.2. Пакет javax.microedition.media.control
    • 9.2.1. Интерфейс ToneControl
    • 9.2.2. Интерфейс VolumeControl
  • 9.3. Воспроизведение wav-файлов
  • 9.4. Воспроизведение тональных звуков


В этой главе...

Воспроизведение звуков в играх создает более насыщенную- атмосферу. Хорошая звуковая дорожка к игре - это 30-40% успеха! Но, к сожалению, в мобильных играх, нет возможности воспроизведения мощной полноценной звуковой дорожки, как в компьютерных или приставочных играх, в виду ограничения системных ресурсов телефона. Поэтому, в основном, все звучание в играх сводится к воспроизведению так называемых тональных звуков. Каждый тональный звук соответствует определенной ноте, выстроив необходимую последовательность нот для воспроизведения можно получить определенную звуковую дорожку.

В профиле MIDP 1.0 возможность работы со звуком отсутствует, и все строится на использовании классов, предоставляемых производителями мобильных телефонов. В профиле MIDP 2.0 такая возможность имеется, поскольку появилась мобильная мультимедиа библиотека (MMAPI), разработаная экспертной группой, в состав которой входят известные компании:

  • Nokia (Specification Lead);
  • Aplix Corporation;
  • Beatnik. Inc.;
  • France Telecom;
  • Insignia Solutions;
  • Mitsubishi Electric Corp.;
  • Motorola;
  • Netdecisions Holdings United;
  • NTT DoCoMo, Inc.;
  • Openwave Systems Inc.;
  • PacketVideo Corporation;
  • Philips;
  • Siemens AG ICM MP TI;
  • Smart Fusion;
  • Sun Microsystems, Inc.;
  • Symbian Ltd;
  • Texas Instruments Inc.;
  • Vodafone;
  • Yamaha Corporation;
  • Zucotto Wireless.

На данный момент существуют две мобильные мультимедиа-библиотеки, различающиеся по своему назначению и спецификации, это:

  • Mobile Media API - предназначена для работы с устройствами имеющими боле мощные системные ресурсы. Это, как правило, карманные портативные устройства;
  • MIDP 2.0 Media API - эта библиотека направлена на поддержку мобильных устройств с ограниченными ресурсами.

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

  • Менеджер - это основной диспетчер, при помощи которого создаются все проигрыватели. Также менеджер имеет возможность в воспроизведении простых тональных звуков на телефоне. Менеджер в профиле MIDP 2.0 представлен классом Manager;
  • Проигрыватель - осуществляет непосредственное воспроизведение звуков и представлен интерфейсом Player

Bee взаимодействие построено на использовании нескольких интерфейсов и класса Manager, содержащихся в библиотеке MIDP 2.0 Media API, которая состоит из двух пакетов:

  • javax.microedition.media;
  • javax.microedition.media.control.

Эти два пакета содержат ряд интерфейсов и всего один класс Manager. Рассмотрим подробно оба пакета библиотеки MIDP 2.0 Media API, давая попутно краткую характеристику каждому интерфейсу, классу Manager и всем имеющимся методам. А потом, на основе полученного материала, создадим несколько примеров исходного кода, иллюстрирующих мoдель работы со звуком.


9.1. Пакет javax.microedition.media

Пакет javax.microedition.media необходим для работы со звуком и содержит четыре основных интерфейса и один класс, на базе которых и происходит воспроизведение звуков в телефоне.


9.1.1. Интерфейс Control

Интерфейс Control - это самый главный интерфейс, с его помощью осуществляется контроль над всеми имеющимися ресурсами, также от этого интерфейса наследуются еще два интерфейса ToneControl и VolumeControl.


9.1.2. Интерфейс Controllable

С помощью интерфейса Controllable можно получить управление над воспроизведением, посредством использования двух методов:

  • Control getControl (String controlType) - определяет тип управления;
  • Control[] getControls () - получает управление.


9.1.3. Интерфейс Player

Интерфейс Player наследуется от интерфейса Controllable и необходим для реализации процесса воспроизведения звуковых данных на основе формирования проигрывателей. Проигрыватели создаются методом createPlayer () класса Manager, например:

Player player1 = Manager.createPlayer();

После создания проигрывателя можно производить воспроизведения звука, для этого необходимо воспользоваться методами интерфейса Player.

Методы интерфейса Player

  • void addPlayerListener(PlayerListener playerListener)-осуществляет обработку событий от определенного проигрывателя;
  • void close () — закрывает проигрыватель;
  • void deallocate () - освобождает ресурс, занятый проигрывателем;
  • String getContentType () - получает тип звуковых данных воспроизводимых проигрывателем;
  • long getDuration () — получает размер звукового файла;
  • long getMediaTime () - получает время воспроизведения звуковых данных;
  • int getState()— определяет состояние проигрывателя;
  • void removePlayerListener(PlayerListener playerListener) — удаляет установленный обработчик событий;
  • void setLoopCount (int count) - устанавливает цикличное воспроизведение звуковых данных;
  • long setMediaTime(long now) - устанавливает время воспроизведения;
  • void start () - дает команду на воспроизведение;
  • void stop () - останавливает воспроизведение.

Большинство методов направленно на работу со звуковыми данными, позже в разделе 9.3 мы разберем подробнее работу с методами интерфейса Player.


9.1.4. Интерфейс PlayerListener

Интерфейс PlayerListener позволяет осуществлять обработку событий полученных от проигрывателя. Помните в главе 5 мы разбирали работу интерфейса CommandListener? Интерфейс PlayerListener функционирует почти по такой же схеме, но ориентирован на работу с проигрывателем. В составе интерфейса PlayerListener .имеется всего один метод:

  • void playerUpdate (Player player, String event, Object eventData) — обновляет состояние проигрывателя.

C помощью констант интерфейса Player в методе playerUpdate (), нужно задавать тип необходимых событий в параметрах eventData и event:

  • static String CLOSED - уведомляет о закрытии проигрывателя;
  • static String DEVICE_AVAILABLE - уведомляет о доступности проигрывателя;
  • static String DEVICE_UNAVAILABLE - уведомляет о недоступности проигрывателя;
  • static String DURATIONJJPDATED - обновляет состояние;
  • static String END_OF_MEDIA - уведомляет о конце воспроизведения данных проигрывателем;
  • static String ERROR - уведомляет об ошибке;
  • static String STARTED - уведомляет о начале работы проигрывателя;
  • static String STOPPED - уведомляет о конце работы проигрывателя;
  • static String VOLUME_CHANGED - уведомляет о выборе громкости для воспроизведения.


9.1.5. Класс Manager

Класс Manager создает проигрыватель для воспроизведения звуков, а также отслеживает доступные протоколы звуковых данных, с помощью нескольких методов.

  • static Player createPlayer(InputStream stream, String type) - создает проигрыватель для воспроизведения звуковых данных из потока;
  • static Player createPlayer(String locator) - создает проигрыватель для воспроизведения звуковых данных из определенного файла;
  • static String[] getSupportedProtocols(String content_type) - возвращает список доступных протоколов для мобильного устройства;
  • static void playTone(int note, int duration, int volume) -воспроизводит различные тональные звуки.


9.2. Пакет javax.microedition.media.control

Пакет javox.microedition.media.control небольшой по своему составу и производит контроль над процессами, связанными с воспроизведением и регулировкой звука. В разделе 9.4 этой главы очень подробно рассматривается схема контроля.


9.2.1. Интерфейс ToneControl

С помощью интерфейса ToneControl происходит настройка и построение блока тональных звуков для воспроизведения. Это достигается путем использования метода void setSequence (byte [ ] sequence), который устанавливает тональные звуки для воспроизведения и набора следующих констант:

  • static byte BLOCK_END - конец блока воспроизведения;
  • static byte BLOCK_START - стартовая позиция в блоке;
  • static byte C4 - нота До;
  • static byte PLAY_BLOCK - воспроизвести блок;
  • static byte REPEAT - повторить воспроизведение блока;
  • static byte SET_VOLUME - установить громкость;
  • static byte SILENCE - без звука;
  • static byte TEMPO — темп или скорость воспроизведения;
  • static byte VERSION - версия атрибута воспроизведения. С помощью перечисленных констант производится настройка блока тональных звуков для воспроизведения, о которых мы поговорим подробно в разделе 9.4.


9.2.2. Интерфейс VolumeControl

Интерфейс VolumeControl имеет методы, на основе которых можно реализовать управление громкостью воспроизведения:

  • int getLevel() - возвращает текущий уровень громкости;
  • boolean isMutedf) - определяет состояние сигнала;
  • int setLevel(int level) -устанавливает уровень громкости. Значение может находиться в пределах от 0 до 100;
  • void setMute (boolean mute) - устанавливает состояние сигнала.

Сейчас мы вкратце рассмотрели имеющиеся интерфейсы, классы, методы и константы двух пакетов javax.microedition.media и javax.microedition.media.control. Теперь давайте подытожим все полученную информацию и рассмотрим примеры, иллюстрирующие работу со звуком в мобильных телефонах.


9.3. Воспроизведение wav-файлов

Воспроизведение wav-фа.йлов в телефоне задача не сложная. Wav-файл должен быть размещен в каталоге создаваемого приложения. Если вы используете J2ME Wireless Toolkit 2.1, то расположите wav-файл в папке res. Впоследствии, после компиляции и установки программы, wav-файл будет находиться в JAR- архиве, и доступен для воспроизведения.

Для того чтобы воспроизвести необходимый wav-файл создается объект класса Inputstream для связывания потока данных с ресурсом, а именно wav-файлом,например:

Inputstream input =
getClassf).getResourceAsStream(«файл.wav»);

Затем создается проигрыватель:

Player player = Manager.createPlayer(input,«audio/X-wav»);

Проигрыватель формируется с помощью метода createPlayer() класса Manager. Количество создаваемых проигрывателей регламентируется только системными ресурсами телефона. После чего используется метод start() для воспроизведения wav-файла.

В листинге 9.1 вы найдете пример исходного кода, в котором происходит загрузка и воспроизведение wav-файла из JAR-архива. В примере используется класс Form, с помощью которого создается пустой экран, и добавляются две команды: выход из приложения и воспроизведение wav-файла. Основные действия разворачиваются в методе WavPlay (), где создается проигрыватель и воспроизводится wav-файл. Обратите также внимание на подключаемые пакеты.

/**

листинг 9.1.

класс WavMIDlet
воспроизводит wav-файл

*/

import javax.microedition.Icdui.*;

import javax.microedition.midlet.*;

import javax.microedition.media.*;

import javax.microedition.media.control.*;

import java.io.*;

public class WavMIDlet

extends MIDlet implements CommandListener

{

// команда выхода

private Command

exitMidlet = new Command("Выход",
Command.EXIT, 0);

// команда воспроизведения

private Command

pi = new Command("Играть", Command.OK, 1);

// объект mydisplay представляет экран телефона

private Display mydisplay;

public WavMIDlet()

{

mydisplay = Display.getDisplay(this);

}

public void startApp()

{

Form Is = new Form("Воспроизведение wav");

// добавляем команду выхода

ls.addCommand(exitMidlet);

// добавляем команду воспроизведения

ls.addCommand(pl);

ls.setCommandListener(this);

// отражаем текущий дисплей

mydisplay.setCurrent(Is);

}

private void WawPlay()

{

try {

// ищем ресурс с именем melod.wav

InputStream

input =getClass().getResourceAsStream("melod.wav");

// создаем проигрыватель

Player player = Manager.createPlayer(input,
"audio/X-wav");

// воспроизводим player.start();

}

 catch (lOException zxz) {} catch (MediaException zmz) {}

}

public void pauseApp() {}

public void destroyApp(boolean unconditional){}

public void commandAction(Command c, Displayable d)

{

if (c == exitMidlet)

 {

destroyApp(false); notifyDestroyed() ;

}

if (c = = pi) {

WawPlay();

}

}

 }


9.4. Воспроизведение тональных звуков

При создании звукового сопровождения к играм и приложениям в основном используются так называемые тональные звуки, генерируемые телефоном. Мобильные телефоны ограничены в системных ресурсах, поэтому воспроизведение wav, mp3 файлов не всегда возможно.

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

Перейдем к практике. Первым делом необходимо создать те самые семь нот. В классе ToneControl пакета javax.microedition.media.control.*, доступна константа С4, которая по своему звучанию соответствует ноте «До». Для того чтобы создать, например ноту Ре, можно воспользоваться следующей конструкцией кода:

byte Re = (byte)(ToneControl.C4+1);

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

Затем создается массив данных, можно назвать его секвенсором, в котором указывается последовательность нот. Синтаксис, используемый в секвенсоре, строго определен, и его необходимо правильно использовать. Например, имеется следующий массив данных, характеризующийся как секвенсор:

byte[] Nota = {...};

В этом массиве данных первой строкой кода должно идти указание версии используемого атрибута.

ToneControl.VERSION,1,

Затем задается скорость воспроизведения с помощью целочисленного значения, которое может варьироваться от 5 до 127. Например:

ToneControl.TEMPO,30,

Далее необходимо дать команду, указывающую начало блока последовательности нот для воспроизведения, например:

ToneControl.BLOCK_START, 0,

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

byte d = 4;

Re,d,Mi,d,Re,d,

Между воспроизведением нот можно использовать паузы для создания выразительной мелодии. Пауза задается с помощью константы SELENCE, например:

byte stop = ToneControl.SELENCE;

byte d = 4;

Тогда последовательность нот может быть следующей:

Re,d,stop,d,Mi,d,stop,d,stop,d,Re,d,

После того как вы задали всю последовательность нот, необходимо четко указать конец блока с помощью константы BLOCK_END следующим образом:

ToneControl.BLOCK_END, 0,

На каждую константу BLOCK_START, должна присутствовать константа BLOCK_END. Иначе возникнет ошибка при компиляции.

В конце нужно воспользоваться константой PLAY_BLOCK для воспроизведения блока последовательности нот. После этого созданный секвенсор можно использовать для воспроизведения проигрывателем тональных звуков. Посмотрите на листинг 9.2, где показана демонстрационная программа, воспроизводящая все семь нот одной октавы.

/ * *

листинг 9.2

класс TonMIDlet воспроизводит тональные звуки

*/

import javax.microedition.Icdui.*;

 import javax.microedition.midlet.*;

 import javax.microedition.media.*;

 import javax.microedition.media.control.*;

 import java.io.*;

public class TonMIDlet

extends MIDlet implements CommandListener

 // команда выхода

private Command

exitMidlet = new Command("Выход",Command.EXIT, 0);

// команда воспроизведения

private Command pi = new

Command("Играть", Command.OK, 1);

// объект mydisplay представляет экран телефона

private Display mydisplay;

public TonMIDlet()

{

mydisplay = Display.getDisplay(this);

}

public void startApp()

Form Is = new Form("Тональные звуки");

// добавляем команду выхода

ls.addCommand(exitMidlet);

// добавляем команду воспроизведения

ls.addCoiranand(pl);

ls.setCommandListener(this);

 // отражаем текущий дисплей

my.display. setCurrent (Is) ;

}

private void TonPlay() {

// нота До

byte Do = ToneControl.C4;,

// нота Ре

byte Re = (byte)(ToneControl.C4 + 1);

// нота  Ми

byte Mi = (byte)(ToneControl.C4 + 2) ;

// нота Фа

byte Fa = (byte)(ToneControl.C4 + 3);

// нота Соль

byte So = (byte)(ToneControl.C4 + 4);

// нота Ля

byte Lj = (byte)(ToneControl.C4 + 5);

// нота Си

byte Si = (byte)(ToneControl.C4 + 6);

// пауза

byte stop = ToneControl.SILENCE;

// скорость воспроизведения тональных звуков

byte speed = 30;

// продолжительность воспроизведения ноты

byte pr = 4;

// секвенсор

byte[] Nota = {

// атрибут, задающий номер версии

ToneControl.VERSION, 1,

// скорость воспроизведения

ToneControl.TEMPO, speed,

// начало блока

ToneControl.BLOCK_START, 0,

// последовательность нот для воспроизведения

Do,pr,stop,pr,Re,pr,stop,pr,Mi,pr,stop,pr,

Fa,pr,stop,pr,So,pr,stop,pr,Lj,pr,stop,pr,Si,pr,

// конец блока

ToneControl.BLOCK_END, 0,

// воспроизведение блока

ToneControl.PLAY_BLOCK, 0,

} ;

// воспроизводим тональные звуки из секвенсора

 try{

Player player =

Manager.createPlayer(Manager.TONE_DEVICE_LOCATOR);

player.realize();

 ToneControl toncontrl =
(ToneControl)player.getControl(«ToneControl»);

toncontrl.setSequence(Nota);

player.start();

}

catch (IOException zxz){}

catch (MediaException zmz){}

 }

public void pauseApp() {}

public void destroyApp(boolean unconditional){}

public void commandAction(Command c, Displayable d)

{

if (c = = exitMidlet)

{

destroyApp(false);

 notifyDestroyed();

}

if (c == pi)

{

TonPlay();

}

}

}

В основе программы из листинга 9.2 лежит модель, используемая в предыдущем разделе при .воспроизведении wav-файла. В классе TonMIDlet создается пустая форма классом Form и назначаются две команды: выход из программы и воспроизведение тональных звуков. При нажатии на кнопку Играть, задействуется метод TonPlay (), где создаются ноты, секвенсор, после чего происходит воспроизведение последовательности нот.


Приложение 1. Основы языка Java

  • В приложении ...
  • 1.1. Введение в программирование
  • 1.2. Объектно-ориентированное программирование
    • 1.2.1. Классы
    • 1.2.2. Методы
  • 1.3. Синтаксис и семантика языка Java 2 ME
    • 1.3.1. Комментарии
    • 1.3.2. Типы данных Java
    • 1.3.3. Операторы
    • 1.3.4. Метод main
    • 1.3.5. Закрытые и открытые члены классов
  • 1.4. Конструктор
  • 1.5. Объекты классов
  • 1.6. Условные операторы
  • 1.7. Управляющий оператор
  • 1.8. Циклы
    • 1.8.1. Оператор while
    • 1.8.2. Цикл do/while
    • 1.8.3. Цикл for
  • 1.9. Массивы
  • 1.10. Наследование
    • 1.10.1. Конструктор суперкласса
  • 1.11. Интерфейсы
  • 1.12. Пакеты


В приложении ...

Это приложение не претендует на роль полного руководства по языку Java (Ява), но данного материала будет достаточно для дальнейшего изучения книги. Предлагаемая к рассмотрению в этом разделе информация содержит основы языка Java и ориентирована на неподготовленного читателя. Также нужно иметь в виду, что обучение языку Java будет происходить в соответствии с контекстом книги, а именно, всей той части языка Java, необходимой для программирования мобильных устройств. То есть такие «продвинутые» темы как аплеты, библиотеки AWT и Swing в этом приложении не рассматриваются, поскольку не применяются в Java 2 Micro Edition.


1.1. Введение в программирование

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

Система программирования представляет собой огромную продуманную визуальную среду, где можно писать исходный код программы, переводить его в машинный код, тестировать, отлаживать и многое другое. Также существуют программы, которые позволяют производить вышеперечисленные действия при помощи командной строки. Язык Java предоставляет такую возможность, но в книге данная проблематика не освещается.

Вы, наверное, не раз слышали термин «программа написана под Windows или под Linux, Unix». Дело в том, что среды программирования при переводе языка программирования в машинный код могут быть двух видов — это компиляторы и интерпретаторы. Говоря про общий вид: компиляция или интерпретация программы задает способ дальнейшего выполнения программы. Программы написанные на языке Java всегда работают на основе интерпретации, тогда как программы написанные на C/C++ - компиляции. В чем разница этих двух способов? Компилятор после написания исходного кода в момент компиляции читает сразу весь исходный код программы и переводит в машинный код. После чего программа существует как одно целое и может выполняться только в той операционной системе, в которой она была написана. Поэтому программы, написанные под Windows, не могут функционировать в среде Linux и наоборот. Интерпретатор осуществляет пошаговое или построчное выполнение программы каждый раз, когда она выполняется. Во время интерпретации создается не выполняемый код, а виртуальный, который впоследствии выполняется виртуальной Java машиной. Поэтому на любой платформе — Windows или Linux, Java-программы могут одинаково выполняться при наличии в системе виртуальной Java машины, которая еще носит название Системы времени выполнения.

Все что сейчас от вас требуется - это изучение синтаксиса языка Java, для того чтобы писать и понимать исходные коды программ, написанные на этом языке. А так же освоить работу с одной из сред программирования, подробное описание которых вы найдете в главе 3. Это приложение содержит теоретический материал, раскрывающий особенности программирования на языке Java.


1.2. Объектно-ориентированное программирование

Java типиризированный, и по своей природе объектно-ориентированный язык программирования. Эти термины при детальном рассмотрении очень просты в понимании. Основных типов данных мы коснемся, когда будем обсуждать семантику языка, а сейчас сосредоточимся на объектно-ориентированной парадигме современного программирования.

Объектно-ориентированное программирование построено на объектах по аналогии с нашим миром. Если оглянуться вокруг себя, то обязательно можно найти что-то, что поможет более ярко разобраться в модели такого программирования. Например, я сейчас сижу за столом и печатаю эту главу на компьютере, который состоит из монитора, системного блока, клавиатуры, мыши и так далее. Все эти части являются объектами, из которых состоит компьютер. Зная это, очень легко сформулировать какую-то обобщенную модель работы всего компьютера. Если не разбираться в тонкостях программных и аппаратных свойств компьютера, то можно сказать, что объект Системный блок производит определенные действия, которые показывает объект Монитор. Объект Клавиатура в свою очередь может корректировать или вообще задавать действия для объекта Системный блок, а тот влияет на объект Монитор. Объект Колонки предназначен для воспроизведения звуковых данных с различных источников. Построенный процесс очень хорошо характеризует всю систему объектно-ориентированного программирования. Представьте себе некий мощный программный продукт, содержащий сотни тысяч строк кода. Если не использовать объектно-ориентированное программирование, то вся программа должна выполняться построчно, строка за строкой и в принципе каждая из последующих строк кода обязательно будет связана с предыдущей. Когда потребуется изменить этот программный код, скажем при необходимости улучшения каких-то элементов, то придется произвести большое количество работы с кодом. В объектно-ориентированном программировании все куда проще. Допустим, вас уже не устраивает пятнадцати дюймовый монитор. Вы можете спокойно его обменять, например на семнадцати или девятнадцати дюймовый монитор, конечно же, при наличии определенных материальных средств. Сам же процесс обмена не повлечет за собой огромных проблем. Ну, разве что драйвер придется сменить, да вытереть пыль из-под старого монитора. Объектно-ориентированное программирование очень легко и ясно отражает суть решаемой проблемы и что самое главное, дает возможность без ущерба для всей программы убирать старые и ненужные объекты заменяя их на новые, точней говоря, модернизировать без лишних затрат. Также общая читабельность всей программы становится намного проще. Существенно и то, что один и тот же код можно использовать в абсолютно разных программах.


1.2.1. Классы

Стержнем всех программ Java являются классы, на которых основывается объектно-ориентированное программирование. Вы по сути уже знаете, что такое классы, но пока об этом не догадываетесь. В предыдущем разделе мы говорили об объектах, ставя в пример устройство всего компьютера. Каждый объектов, из которых собран компьютер, является представителем своего класса. Например, класс Мониторов объединяет все мониторы вне зависимости от их типов, размеров и возможностей, а один какой-то конкретный монитор, стоящий на вашем столе и есть объект класса мониторов. Такой подход позволяет очень легко моделировать всевозможные процессы в программировании, облегчая решение поставленных задач. Например, имеется четыре объекта четырех разных классов: монитор, системный блок, клавиатура и колонки. Чтобы воспроизвести звуковой файл необходимо при помощи клавиатуры дать команду системному блоку, само же действие по даче команды вы будете наблюдать визуально на мониторе и, в итоге, колонки воспроизведут звуковой файл. То есть любой объект является частью определенного класса и содержит в себе все имеющиеся у этого класса средства и возможности. Объектов одного класса может быть столько, сколько это необходимо для решения поставленной задачи.


1.2.2. Методы

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

Каждый объект имеет свое назначение и призван решать определенный круг задач с помощью методов. Какой толк был бы, например, в объекте Клавиатура, если нельзя было бы нажимать на клавиши получая при этом возможность отдавать команды? Объект Клавиатура имеет некое количество клавиш, с помощью которых пользователь приобретает контроль над устройством ввода и может отдавать необходимые команды. Обработка таких команд в целом, происходит с помощью методов. Например, вы нажимаете клавишу Esc для отмены каких-либо действий и тем самым даете команду методу, закрепленному за этой клавишей который на программном уровне решает эту задачу. Сразу же возникает вопрос о количестве методов объекта Клавиатура, но здесь может быть различная реализация - как от определения методов для каждой из клавиш (что, вообще-то, неразумно), так и до создания одного метода который будет следить за общим состоянием клавиатуры. То есть, этот метод следит за тем, была ли нажата клавиша, а потом в зависимости от того какая из клавиш задействована, решает, что ему делать.

Итак, мы видим, что каждый из объектов может иметь в своем распоряжении набор методов для решения различных задач. А поскольку каждый объект является объектом определенного класса, то получается, что класс содержит набор методов, которыми и пользуются различные объекты одного класса. В языке Java все созданные вами методы должны принадлежать или являться частью какого-то конкретного класса.


1.3. Синтаксис и семантика языка Java 2 ME

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

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

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

Класс Телефон

 {

Метод Включить()

{

// операции по включению телефона

}

Метод Выключить()

{

// операции по выключению телефона

}

}

Таким вот образом может выглядеть класс Телефон. Заметьте, что фигурные скобки обозначают соответственно начало и конец тела класса, метода, либо всякой последовательности данных. То есть скобки указывают на принадлежность к методу или классу. На каждую открывающую скобку обязательно должна быть закрывающая скобка. Чтобы не запутаться их обычно ставят на одном уровне в коде. А теперь давайте запишем тот же самый класс только уже на языке Java.

class Telefon

{

void on()

{

// тело метода оn()

}

void off()

{

// тело метода off ()

}

}

Ключевое слово class в языке Java объявляет класс, далее идет название самого класса. В нашем случае это Telefon. Сразу пару слов касательно регистра записи. Почти во всех языках программирования важно сохранять запись названий в том регистре, в котором она была сделана. Если вы написали Telefon, то уже такое написание как telefon или TELefoN выдаст ошибку при компиляции. Как написали первоначально, так и надо писать дальше.

Зарезервированные или ключевые слова записываются в своем определенном регистре, и вы не можете их использовать, давая их названия методам, классам, объектам и так далее.

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

В теле класса Telefon имеются два метода: on () - включающий телефон и метод off () - выключающий телефон. Оба метода имеют свои тела и в них по идее должен быть какой-то программный код, описывающий необходимые действия обоих методов. Для нас сейчас не важно как происходит реализация этих методов, первостепенное - это синтаксис языка Java.

Оба метода имеют круглые скобки on (), внутри которых могут быть записаны параметры, например on (int time) или on (int time, int time1). С помощью параметров происходит своего рода связь методов с внешним миром. Говорят, что метод on (int time) принимает параметр time. Для чего это нужно? Например, вы хотите, чтобы телефон включился в определенное время. Тогда целочисленное значение в параметре time будет передано в тело метода и на основе полученных данных произойдет включение телефона. Если скобки пусты, то метод не принимает никаких параметров.


1.3.1. Комментарии

В классе Telefon в телах обоих методов имеется запись после двух слешей: //. Такая запись обозначает комментарии, которые будут игнорироваться компилятором, но нужны для читабельности кода. Чем больше информации вы закомментируете по ходу написания программы, тем больше у вас будет шансов вспомнить через год, что вы хотели сделать.

Комментарии в Java могут быть трех видов, это: //, /*...*/ и /**...*/. Комментарии, записанные с помощь оператора // должны располагаться в одной строке:

// Одна строка

!!! Ошибка! На вторую строку переносить нельзя!

// Первая строка

// Вторая строка

// ...

// Последняя строка

Комментарии, использующие оператор /*...*/ могут находится на нескольких строках. В начале вашего комментария поставьте /*, а в конце, когда закончите комментировать код, поставьте оператор * /.

Последний вид комментария /**...*/ используется при документировании кода и также может располагаться на любом количестве строк.


1.3.2. Типы данных Java

Чтобы задать произвольное значение, в Java существуют типы данных. Как уже говорилось, Java - язык типиризированный, поэтому каждое значение имеет свой тип. В классе Telefon мы создали два метода. Оба метода не имели параметров, но когда приводился пример метода on (int time) с параметром time, говорилось о передаче значения в метод. Данное значение указывало на время, с помощью которого якобы должен включиться телефон. Спецификатор int как раз и определяет тип значения time. В Java 2 ME шесть типов данных. Посмотрите на табл. 1.1.

Таблица 1.1.

Тип | Назначение | Размер в байтах
byte | маленькое целое | 1
short | короткое целое | 2
int | целое | 4
long | длинное целое | 8
char | символ | 2
boolean | логический тип |

Java 2 ME в отличие от Java 2 SE не поддерживает числа с дробной частью в связи с тем, что мобильные устройства имеют небольшие по объему ресурсы.

  • byte - маленькое цел счисленное значение от-128 до 128;
  • short - короткое целое значение в диапазоне от -32768 до 32767;
  • int- содержит любое целочисленное значение от -2147483648 до 2147483647;
  • long - очень большое целочисленное значение, от -922337203685475808 до 9223372036854775807;
  • char — это символьная константа в формате Unicode! Диапазон данного формата от 0 до 65536, что равно 256 символам. Любой символ этого типа должен записываться в одинарных кавычках: 'G';
  • boolean - логический тип, имеет всего два значения: false - ложь и true -истина. Этот тип часто используется в циклах о которых чуть позже. Смысл очень прост - если у вас в кармане есть деньги, предположительно это true, а если нет то false. Таким образом, если деньги имеются - идем в магазин за хлебом или пивом (нужное подчеркнуть), если нет денег -остаемся дома. То есть определяется логическая величина, способствующая выбору дальнейших действий вашей программы.

Чтобы объявить какое-то необходимое значение используется запись:

int time;

long BigTime;

char word;

Оператор точка с запятой необходим после таких записей в конце строки. Можно совместить несколько одинаковых по типу объявлений через запятую:

mt time, timel, time2;

Теперь давайте, усовершенствуем наш класс Telefon, добавив в него несколько значений. Методы on () и off () нам больше не нужны, добавим методы поинтересней.

class Telefon

{

//s- площадь дисплея

//w - высота дисплея

//h - ширина дисплея

int w, h, s;

//метод вычисляющий площадь дисплея

vord Area.()

{

S = w*h;

}

}

Итак, мы имеем три переменные S, w и h, отвечающие, соответственно, за площадь, высоту и ширину дисплея в пикселях. Метод Area () вычисляет площадь экрана телефона в пикселях. Операция бесполезная, но очень показательная и простая в понимании. Тело метода Area () обрело себя и имеет вид S = w*h. Мы просто перемножаем высоту на ширину и присваиваем или как еще говорят, сохраняем результат в переменной S. Сейчас мы подошли вплотную к операторам языка Java, с помощью которых можно совершать всевозможные операции.


1.3.3. Операторы

Операторы языка Java имеют различные назначения. Существуют арифметические операторы, операторы инкремента и декремента, логические операторы и операторы отношения.

Арифметические операторы очень просты и аналогичны операторам умножения «*», деления «/», сложения «+» и вычитания «-» используемые в математике. Существует оператор деления по модулю «%» и слегка запутанная на первый взгляд ситуация с оператором равно «=». Оператор равно в языках программирования называется оператором присваивания:

int х = 3

Здесь вы переменной х присваиваете значение 3. А оператор «равно» в языках программирования соответствует записи двух подряд операторов «равно»: <= = >. Рассмотрим на примере, что могут делать различные арифметические операторы.

int х, у, z; ;

х = 5;

У = 3 ;

Z = 0;

z = х + у;

В данном случае z будет иметь значение уже суммы х и у, то есть 8.

x = z*x;

Переменная х имела значение 5, но после такой записи предыдущее значение теряется и записывается произведение z *х (8*5), что равно 40. Теперь, если мы продолжим дальше наш код, то переменные будут иметь такой вид:

// х = 40;

 // У = 3 ;

// z = 8;

Это обязательно необходимо иметь в виду.

Что касается оператора деления, то поскольку Java 2 ME не поддерживает дробных чисел, то результат такого деления:

x = z/y;

что равносильно записи:

х = 8/3;

будет равен 2. Дробная часть просто отбрасывается, то же самое происходит при использовании оператор деления по модулю «%».

Операторы сложения и вычитания имеют те же назначения что и в математике. Отрицательные числа так же родственны.

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

int x = 5;

х++;

// Здесь х уже равен 6

Операция декремента уменьшает переменную на единицу.

int х = 5;

х -- ;

//х равен 4

Операции инкремента и декремента могут быть пост и префиксными:

int х = 5;

int у = 0;

y = х++;

8 последней строке кода сначала значение х присваивается у, это значение 5, и только потом переменная х увеличивается на еденицу. Получается что:

х = 6, у = 5

Префиксный инкремент имеет вид:

int х = 3;

int у = 0;

у = ++х;

И в этом случае, сначала переменная х увеличивается на один, а потом присваивает уже увеличенное значение у.

у = 4, х = 4

Операторы отношения позволяют проверить равенство обеих частей выражения. Имеется оператор равенства «= =», операторы меньше «<» и больше «>», меньше или равно «<=» и больше или равно «>=», а так же оператор отрицания «!=».

9 = = 10;

Это выражение не верно, девять не равно десяти, поэтому его значение этого выражения равно false.

9 != 10;

Здесь же, наоборот, оператор отрицания указывает на неравенство выражения, и значение будет равно true.

Операторы больше, меньше, больше или равно и меньше или равно аналогичны соответствующим операторам из математики.

Существует два логических оператора. Оператор «И», обозначающийся значками «&&» и оператор «ИЛИ», обозначенный в виде двух прямых слешей «||». Например, имеется выражение:

А*В && В*С;

В том случае, если только обе части выражения истинны, значение выражения считается истинным. Если одна из частей неверна, то значение всего выраже- , ния будет ложным.

В противовес оператору «&&» имеется оператор «I I », не напрасно имеющий название «ИЛИ».

А*В|| В*С;

Если любая из частей выражения истинна, то и все выражение считается истинным. Оба оператора можно комбинировать в одном выражении, например:

А*В || B*C && C*D ||В*А;

С помощью этого выражения я вас ввел, как мне кажется, в затруднение, неправда ли? Дело в том, что в Java, как и в математике существует приоритет или так называемая иерархия операторов, с помощью которой определяется какой из операторов главнее, а, следовательно, и проверяется первым. Рассмотрим с помощью списка приоритет всех операторов языка Java:

[] , . , () ,

! , ~, ++, - -, +(унарный), -(унарный), new,

*, /, % ,

+, -,

<< , >>, >>>,

<, <=, >, >=, = = , !=,

&,  ^,  | , &&, || , ?:,

= , +=, -=, *=, /=, %=, |=, ^=, <<=, >>=, >>>=.

Не со всеми операторами вы еще знакомы, поэтому пугаться не стоит. Ассоциативность операторов в списке следует слева на право и сверху вниз. То есть все, что находится левее и выше - старше по званию и главнее.


1.3.4. Метод main

Класс Telefon, который мы описывали в предыдущем разделе, имел один метод, с помощью которого вычислялась площадь дисплея. Созданная спецификация класса Telefon может быть описана как угодно. Можно добавить реагирующие на обработку событий с клавиатуры телефона и любые другие методы, которые вы сочтете нужными для описания класса Telefon. Таких, и подобных классов может быть любое количество. Каждый из классов принято хранить в своем отдельном файле с расширением *.java. Например, Telefon.java. Все методы находящиеся в классе Telefon, которые вы опишете для данного класса, обязаны производить определенные действия с объектом этого класса, иначе, зачем нужны эти методы. Реализация методов как уже говорилось, происходит непосредственно в создаваемом классе. Но возникает вопрос, где и как, происходит вызов необходимых по ситуации методов или создание объектов используемого класса. В языке Java для этих целей существует Memodmain (), который подобно строительной площадке собирает на своей платформе по частям объекты, методы, строя при этом функциональность всей программы.

public class RunTelefon

{

public static void main( String[] args)

{

// Работа программы

}

 }

Пока не обращайте внимания на ключевые слова public и static - о них чуть позже. Создав класс RunTelefon и определив в его теле метод main () мы теперь имеем возможность пользоваться классом Telefon и его не особо богатой функциональностью. Объединив эти два класса в один файл, либо записав каждый по отдельности, вы получите работоспособную программу. Класс Telefon содержит основные данные и методы, а класс RunTelefon берет на себя роль мотора. Внутри класса RunTelefon происходит создание объектов класса, в данном случае класса Telefon и вызовы соответствующих методов этого класса. Например:

class Telefon

{

//переменные

int w, h, s;

// метод

void Area()

{

S = w*h;

}

 }

class RunTelefon

 {

public static void main (String args[])

{

/* создание объектов и вызовы метода Area() */

}

}

Поскольку вы пока не умеете создавать объекты классов и вызывать методы, тело класса RunTelefon пустое. Прежде чем идти дальше, необходимо познакомиться с ключевыми словами public, private и protected, а так же научиться создавать конструкторы классов.


1.3.5. Закрытые и открытые члены классов

Ключевое слово public, объявленное перед методом main (), показывает на то, что метод main () считается открытым или в любом классе метод main () виден, и к нему можно обратиться. Ключевое слово public может назначаться не только методам, но и объектам класса, переменным, любым членам созданного класса. Все объявленные члены класса с ключевым словом public, будут доступны всем другим существующим в программе классам, поэтому стоит призадуматься, а хорошо ли это? Например, у вас есть какие-то данные, которые не должны быть доступны другим классам, что тогда? Для этого в языке Java существует еще пара ключевых слов: private и protected, благодаря которым вы защищаете свои члены классов от общего доступа.

По умолчанию, если вы не используете ключевые слова, Java назначает всем членам класса спецификатор public. Метод main () всегда должен вызываться с ключевым словом public, чтобы для всех классов программы метод main () был доступен. Как только программа начнет работать, первым делом она ищет метод main () и постепенно, шаг за шагом, а точнее, строка за строкой, выполняет все предписанные действия в методе main ().


1.4. Конструктор

Каждый класс обязан содержать конструктор. Конструктор - это тот же самый метод, но имеющий название класса, например:

class Telefon

{

Telefon();

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

int w, h, s;

// переменные

void Area();

// метод

}

Конструктор позволяет инициализировать создаваемые объекты данного класса с заданными значениями. Каждый класс имеет конструктор, и если вы явно не записали строку кода (как в нашем случае Telefon () , Java автоматически создаст его за вас, такой конструктор носит название конструктора по умолчанию.

Конструкторы в программировании очень полезны и ни одна профессиональная программа не обходится без конструкторов. Чтобы действительно ощутить мощь конструктора, надо создать конструктор с аргументами, благодаря которым можно инициализировать данные класса.

class Telefon

{

int w, h, s;

Telefon (int a, int b)

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

{

w = a;

h = b;

}

void Area()

// площадь телефона

{

S = W*h;

}

}

При создании объекта (об этом чуть позже), вы можете указать необходимые значения для параметров а и b, например: а = 70, b = 100. Эти заданные числа автоматически присвоятся переменным w и h при создании объекта класса Telefon. Тем самым произойдет инициализация объекта с необходимыми значениями.

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

Telefon (int a, intb);

 Telefon (char a, char b);

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


1.5. Объекты классов

Объекты представляют класс, наследуя от своего класса все возможности. Объявить объект очень просто, необходимо вначале указать класс, а потом объект этого класса. Например:

Telefon object;

Точно так же как создается переменная int а, создается и объект класса. Такая запись создаст пустой объект класса, инициализирующийся значением null. Конечно, это еще не полноценный объект, а всего лишь ссылка на данный класс. Чтобы создать полноценный класс, нужно воспользоваться ключевым словом new, с помощью которого происходит выделение области памяти для содержания создаваемого объекта.

Telefon object;

object = new Telefon);

или

Telefon object = new Telefonf);

Обе записи создания объекта класса Telefon одинаковы. Чаще всего используется вторая запись, но это можно оставить на усмотрение программиста. Сначала создается пустая ссылка object, а потом с помощью ключевого слова new выделяется память для объекта и он инициализируется конструктором класса Telefon (). Именно тут и необходим хорошо продуманный конструктор с параметрами, инициализирующий объект с заданными значениями.

Теперь давайте рассмотрим пример посложнее. Создадим класс с конструктором для инициализации высоты и ширины дисплея и в методе main () создадим объект класса Telefon, вычислив при этом площадь экрана абстрактного телефона.

class Telefon

{

int w, h, s;

// конструктор класса Telefon

 Telefon (int a, int b)

{

w = a;

h = b;

}

// метод, вычисляющий площадь экрана

void Area()

{

S = w*h;

}

}

// class RunTelefon может находится в файле

 RunTelefon.Java

class RunTelefon

 {

public static void main (String args[])

{

// создаем объект класса Telefon

Telefon object = new Telefon (70, 90);

// вычисляем площадь дисплея

object.Area();

}

 }

Разберем весь пример более подробно. Итак, мы создаем класс Telefon с тремя переменными: w, h и s, в которых впоследствии будут храниться, соответственно, ширина, высота и площадь дисплея телефона. Далее создаем конструктор класса Telefon для инициализации высоты и ширины дисплея. Метод Area () класса Telefon вычисляет площадь экрана, сохраняя полученный результат в переменной s. После этого идет класс RunTelefon с методом main (), являющийся входной точкой для всей программы. Как только написанное приложение начнет работать, программа найдет метод main () и начнет выполнять содержимое программы.

В первой строке кода метода main () происходит создание объекта класса Telefon со значениями ширины - 70 и высоты - 90 для экрана телефона. Вторая строка кода вызывает метод Area (), вычисляющий площадь дисплея. Метод Area () нельзя просто так вызвать в программе, он должен ссылаться на объект класса Telefon. Запись object.Area () как раз и указывает на то, что объект класса Telefon вызывает метод Area (). Если имеется несколько объектов класса Telefon, то есть несколько различных телефонов, тогда вызов метода Area () должен происходить для каждого из объектов класса Telefon, например:

object1.Area();

object2.Area();

objects.Area();

Для каждого из объектов класса Telefon будет вычисляться только своя площадь экрана. Давайте рассмотрим еще более сложную программу, создав несколько объектов класса Telefon, а заодно используем другую схему работы метода Area (), воспользовавшись ключевым словом return.

class Telefon

{

int w, h, s, n;

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

Telefon (int a, int b)

{

w = a;

h = b;

}

// вычисляет площадь дисплея int Area()

{

return w*h;

 }

}

// class RunTelefon может находится в.файле RunTelefon.java

class RunTelefon

{

public static void main (String[] args)

 {

// создадим объект Siemens

Telefon Siemens = new Telefon (101, 8.0);

// создадим объект nokia

Telefon nokia = new Telefon (128, 128);

// сохраним полученную площадь в s

s = Siemens.Area();

// сохраним полученную площадь в n

 n = nokia.Area();

}

}

В реализации класса Telefon изменился только метод Area (), использовалось ключевое слово return. С его помощью результат умножения высоты на ширину, то есть результат работы всего метода возвращается для дальнейшего использования в коде программы. А в рабочем цикле программы в методе main (), этот результат сохраняется в двух переменных s и N для каждого из объектов класса Telefon. В данном случае площадь экрана для объекта Siemens равна 101x80=8080, а для объекта nokia 128x128=16384 и оба результата хранятся в различных переменных.

У вас наверно сразу возникает вопрос, а как увидеть получившийся результат? Действительно, просчитать значение не составляет труда, но хотелось бы увидеть полученный результат на дисплее. Для этого в Java существует встроенный метод print In(). Чтобы увидеть на экране результат работы метода Area (), нужно добавить вызов метода print In ().

s = Siemens.Area();

System.out.println("Площадь экрана Siemens" + s) ;

n = nokia.Area()

System.out.println("Площадь экрана nokia" + n) ;

Метод print (), как уже говорилось, встроенный и принадлежит классу System, поэтому такая запись, out — это поток ввода, связывающий программу с консолью. Реально в программировании телефонов метод printIn () используется, как правило, в диагностических целях, но как логическое завершение примера подойдет. С помощью кавычек ограничивается количество выводимого на экран текста, это необходимое условие. Запись + s, применяет операцию конкатенации на основе оператора +, с помощью которого на экран выводится значение переменной s, то есть целочисленное значение равное площади экрана.

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


1.6. Условные операторы

Когда мы создавали и использовали класс RunTelefon, с методом main (), я говорил, что программа выполняет прописанный код строка за строкой и это действительно так. В небольших программах, таких, как мы создали, этого вполне достаточно, но в действительно огромных программах такой подход не логичен. Нельзя «прыгать» по программе, надо идти от строки к строке. Но если все же требуется перейти в программе к какому-то методу или месту программы, что тогда? Для этого в языке Java существуют условные операторы.

Рассмотрим ситуацию, которая более наглядно объяснит смысл операторов. Допустим, вы дома, у вас нет хлеба и надо сбегать в булочную за углом. Прежде чем идти в булочную вы обязательно проверите, есть ли у вас деньги на покупку хлеба и только потом отправитесь в магазин за хлебом. Здесь имеет место предусловие наличия денег, выполнение которого приводит вас либо к походу за хлебом, либо к соседу за деньгами. В том случае, если не рассматривать это предусловие, то вы бы вышли и пошли в магазин, а уже придя, стали бы искать по карманам. Вот для этого и существуют условные операторы. В языке Java имеется несколько условных операторов. Первый из них: if /else - представляющий собой такую сдвоенную конструкцию. Синтаксический шаблон условного оператора if /else выглядит следующим образом:

if (условие)

{

// действие №1

}

else

{

// действие №2

}

Переводя эту конструкцию на русский язык, можно сказать: если (if) некое условие верно, то перейти к действию №1, а иначе (else) выполнить действие №2. Такая сдвоенная конструкция if /else может быть не обязательна, иногда достаточно лишь записи оператора if. Можно использовать вложенные операторы if /else, например:

if (условие 1)

{

if (условие 2)

{

} }

Здесь проверяется первое условие и если оно верное, то происходит переход к следующему оператору if, если и это условие верное, то выполняются действия и во втором и в первом условном операторе. Если же условие во втором операторе if не верно, то выполняются действия только первого оператора if. Условные операторы в программировании на Java используются постоянно и важно понимать их общий принцип работы.


1.7. Управляющий оператор

В языке Java существует управляющий оператор switch, который можно в принципе отнести к условным операторам. Он тоже основан на неких условиях, но предоставляет многовариантное ветвление для выбора пути заданных действий. Посмотрите на синтаксический шаблон этого оператора:

switch (условие)

 {

case 1

// действие 1

break;

case 2:

// действие 2

break;

case 20:

// действие 20

break;

default:

//-действие по умолчанию break;

 }

Вся конструкция оператора switch основана на метках case, имеющих целочисленные значения. Когда условие, проверяющееся оператором switch совпадает с одним из значений метки case, то последующие за меткой действия будут выполнены. Если ни одно из условий не совпало с меткой case, то будут выполнены действия, следующие за меткой default. Оператор break, использующийся в конце всех действий для каждой метки очень важен. Когда условие совпадет с одной из меток и начнется выполнение указанных действий для этой метки, то выходной точкой служит оператор break. Если вы случайно забудете поставить оператор break, то ваша программа начнет выполнять следующую метку, сведя тем самым ваши усилия по выбору заданных действий на ноль. Никогда не забывайте ставить оператор break для каждой из меток!


1.8. Циклы

Вы задумывались когда-нибудь над тем, зачем вообще существуют программы? Если упростить и обобщить ответ на этот вопрос, то выяснится, что программы необходимы для автоматизации рабочего процесса, увеличения скорости выполняемой работы, избавления человека от тысяч монотонных действий и так далее. Сейчас, мы как раз и остановимся на повторяющихся друг за другом действиях.

Цикл - это последовательное выполнение повторяющихся действий на основе заданного предусловия. Например, нужно переставить сто ящиков из одного угла в другой. Если это каким-то образом записать на языке Java (к сожалению, переставить за вас ящики Java не сможет), то получится запись в сто строк наподобие этой:

1) взять ящик №1 и поставить другой угол;

2) взять ящик №2 и поставить другой угол;

3) взять ящик №3 и поставить другой угол;

...

100) взять ящик №100 и поставить другой угол;

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

Существует три оператора представляющих циклы в языке Java- это while, do/white и for. Каждый из операторов необходим в своей ситуации, но все же чаще всего используется оператор for. Рассмотрим по порядку каждый из операторов.


1.8.1. Оператор while

Синтаксическая запись оператора while выглядит следующим образом:

while (условие)

{

// действия

}

Также имеет место выполнение определенного предусловия, но в отличие от оператора if/else, данная конструкция построена на циклах проверки условия. Когда программа доходит до оператора while, если предложенное условие истинно, происходит выполнение всех действий в блоке из фигурных скобок {...}. После выполнения этих действий, снова происходит очередная проверка условий после оператора whilе и если условие опять истинно, происходит повторное выполнение действий в блоке. Действия в блоке выполняются до тех пор, пока условие не станет ложным, тогда происходит выход из цикла while. В основном все циклы управляются при помощи так называемых счетчиков. Рассмотрим не большой пример:

int i = 0;

while (i < 10)

{

// действия

i + +;

}

Сначала переменной i присваивается значение 0, далее происходит проверка условия i<10, если переменная i меньше цифры 10, выполняются все действия в блоке цикла. В конце блока переменная i увеличивается на 1и вновь проверяется условие в цикле. И так ровно десять, раз для нашего примера. Переменная i служит счетчиком для цикла while. Отсутствие операции по увеличению переменной i на единицу приведет к бесконечному циклу, поскольку 0 всегда будет меньше десяти. В циклах так же можно использовать оператор декремента, например:

int. i = 10;

while (i>0)

 {

// действия i --;

}

Те же действия, но уже в обратную сторону. Но все-таки чаще всего используется оператор декремента.

В цикле while имеется возможность использования булевых переменных, содержащих значения false или true. После оператора while происходит проверка предусловия, то можно воспользоваться булевой переменной, например:

boolean i = true,

while (i)

{

// действия

}

Переменная i истинна, ей присвоено значение true, поэтому происходит выполнение цикла whilе. Единственное о чем необходимо позаботиться - это о выходе из такого цикла, поскольку переменная i истинна, то цикл while будет выполняться бесконечно и такие циклы носят названия бесконечных циклов.

Напоследок хочу еще обратить ваше внимание на оператор равно ==. Если записать цикл таким образом:

int i = 0

while (i = = 5)

{

// действия

i + +;

}

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

int i =0

while (i = 5)

{

// действия

i++;

}

В предусловии происходит присвоение переменной i значения 5, а оттого, что это действие не запрещено, то произойдет выполнение блока цикла. В конце которого значение i увеличится на один, но в предусловии после оператора while, переменной i новь будет присвоено значение пять - это пример простого бесконечного цикла и как следствие, классическая ошибка, случающаяся с начинающими программистами.


1.8.2. Цикл do/while

Только что рассмотренный нами цикл while при определенных условиях может и не заработать. Например, если условие будет изначально ложно, то цикл не выполнится ни разу. Программа, дойдя до строки кода с оператором while, проверит условие и если оно будет равно false, проигнорирует весь цикл и перейдет к коду, следующему сразу за циклом while. Но иногда возникает необходимость в выполнении цикла по крайней мере один раз. Для этих целей в Java существует цикл do/while. Запись и создания цикла do/while осуществляется следующим образом:

do

{

// действия

}while (услрвие)

Между операторами do и while существует тело цикла, которое будет выполняться до тех пор, пока постусловие, следующее за оператором whilе, не будет ложно. Тело цикла выполнится) по меньшей мере, один раз, после чего будет произведена проверка условия. Цикл do/while используется не часто, но порой оказывается незаменим.


1.8.3. Цикл for

Это самый распространенный цикл, используемый в программировании, основанный на управлении счетчиком. Смысл работы цикла for схож с рассмотренными выше циклами while и do/while. Посмотрите, как выглядит цикл for:

for (int i = 0; i < 10; i++)

{

// действие

}

После ключевого слова for, следует условие выполнения цикла. Само же условие объединяет в себе три этапа по инициализации счетчика: i = 0 проверка условия i < 10 и увеличение переменной i на единицу. Когда программа доходит до цикла for, то происходит инициализация счетчика i = 0 и проверяется условие i < 10. Далее программа переходит в тело цикла. По окончанию всех действий в цикле for, происходит обращение к третьему этапу цикла: i++, увеличивая счетчик на единицу. После чего сразу же происходит переход ко второму этапу - проверке переменной i < 10 и повторный выход в тело цикла. Весь цикл продолжается до тех пор, пока условие i < 10 не станет ложным. Цикл for используется постоянно при инициализации массива данных, где без него очень сложно, а порой и не возможно обойтись.

Так же как и в цикле whilе возможно использование оператора декремента, например:

for (int i = 10; i > 0; i-)

{

//действие

}

Используя любую выбранную конструкцию цикла, вы получаете очень мощный инструмент программирования, избавляющий вас от написания большого количества строк кода.


1.9. Массивы

Очень часто в программировании встречается большое количество однотипных данных. Для того чтобы не объявлять, скажем, сто переменных, существуют массивы данных. Массив - это набор однотипных значений. В языке Java для создания массивов предусмотрена специальная запись:

int[]M;

С помощью такой записи создается пустая переменная, содержащая определенный массив данных. Объявление массива происходит так же как и объявление объекта класса. Необходимо воспользоваться ключевым словом new чтобы выделить память массиву и явно инициализировать его с количеством элементов. Например:

int[]M = new int[20];

В этой строке кода был создан целочисленный массив из двадцати элементов. К каждому из элементов массива можно обратиться при помощи индекса М [n], для сохранения либо изъятия значения заданного элемента.

М[0] = 3;

М[1] = 5;

М[2] = 20;

Индекс любого созданного массива всегда начинается с 0, об этом нужно помнить. Чтобы инициализировать массив данных, например из пятидесяти элементов, должно потребоваться пятьдесят строк кода, но в нашем распоряжении имеется цикл for, прекрасно справляющийся с этой задачей.

int[]М = new int[50];

for .(int i = 0; i<50; i++)

{

M[i]. = i;

}

В этом примере происходит инициализация каждого элемента массива от 0 до 49, соответственно, такими же значениями. Можно инициализировать массив другим способом, без ключевого слова new.

int[]M = (0, 1, 2, 3, 4}

В этом случае каждый элемент массива инициализируется пятью числами от 0 до 4. Все вышеперечисленные примеры создавали простой одномерный массив данных, но иногда приходится представлять данные в виде парных значений. Например, координаты по X и по Y в системе координат. Для этого в Java существуют многомерные массивы данных.

int stroka = 10;

int stolbec =10;

int[][]M = new[stroka][stolbec];

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

intn []M =

{

(5, 3, 8}, {7, 12, 16} , 49, 12, 14}

 }

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

int[][]M = new int[100][50];

for1(int i = 0; i < 100; i++)

for (int a = 0; a < 50; a++)

 M[i][a] =0;

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


1.10. Наследование

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

Наследование - это механизм, позволяющий наследовать от вышестоящего в иерархии класса все его возможности. Что значит класс, стоящий выше в иерархии? В языке Java существует термин суперкласс и подкласс. Например, имеется некий класс Siemens:

class Siemens

{
Int w, h;

int Area()

{

return w*h;

}

}

Чтобы создать подкласс класса Siemens, необходимо воспользоваться ключевым словом extends:

class SiemensMSS extends Siemens

{

// члены класса

}

Класс SiemensMSS является подклассом класса Siemens, в свою очередь класс Siemens является суперклассом для класса SiemensMSS. Класс SiemensMSS наследует все члены своего суперкласса Siemens и имеет возможность доступа к ним при одном условии: все члены суперкласса Siemens, к которым вы впоследствии захотите получить доступ, должны быть объявлены со спецификатором public. Поскольку мы не определяли вообще никакого спецификатора, а это по умолчанию равно ключевому слову public, то подкласс SiemensMSS, будет иметь доступ ко всем членам своего суперкласса Siemens. Вы можете воспользоваться методом Area () и переменными w и h. Вам не нужно переопределять переменные и метод суперкласса Siemens, но вы можете добавлять дополнительные переменные и методы для подкласса SiemensMS 5, реализующие свои специфические действия для этого подкласса.

Давайте рассмотрим небольшой пример по созданию суперкласса и подкласса. Как вы уже, наверное, догадались, я воспользовался маркой телефона Siemens М55 для названия подкласса. Чтобы не обижать других производителей телефонов, рассмотрим пример для Nokia.

// суперкласс Nokia class Nokia

{

// высота, ширина и площадь дисплея

int dh, dw, ds;

// метод, вычисляющий площадь дисплея

int Area()

{

return dw * dh;

}

 }

// подкласс Nokia5100

class Nokia310 extends Nokia

{

// высота, ширина и площадь всего телефона int th,dw, ds;

// метод, вычисляюшщий площадь телефона

 int tArea()

{

return tw * th;

}

{

//входная точка приложения

class RunNokia ;

{

public static void main (String args[])

{

// при создании объекта используется конструктор по умолчанию

Nokia3100 nokia3100 = new Nokia3100();

// задаем значения для переменных

 noki.a3100.dh = 128;

nokia3100.dw = 128;

nokia3100.th = 102;

nokia3100.tw = 43;

// вычисляем площадь дисплея

 ds = nokia.dArea();

}

// вычисляем полощадь телефона

dt = nokia.tArea();

}

{

}

Создав подкласс Nokia3100, вы получите доступ ко всем членам суперкласса Nokia, определенные как public. Используя оператор «.» (точка), вы открываете доступ к переменным и методам суперкласса. При создании объекта суперкласса, например Nokia nokiasuper = new Nokia (), объект созданного класса может пользоваться своими членами класса, но уже члены подкласса ему не доступны.

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

Суперкласс вправе иметь сколько угодно подклассов, например, в рассмотренном примере можно создать еще десяток-другой подклассов: Nokia5100, Nokia6600, Nokia2100 и так далее. Но каждый из подклассов может иметь только один суперкласс. Множественные наследования в языке Java не предусмотрены. Но каждый из подклассов может иметь свой подкласс, и такая цепочка наследования может длиться до разумной бесконечности.


1.10.1. Конструктор суперкласса

В рассмотренном примере по созданию суперкласса и подкласса Nokia, умышленно использовался конструктор по умолчанию. Ситуация с конструкторами суперклассов требует отдельного внимания.

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

// суперкласс Nokia

class Nokia

{

// конструктор суперкласса Nokia

// тело класса Nokia }

// подкласс NokiaSeries60 class NokiaSeries60

extends Nokia

 {

// конструктор подкласса NokiaSeries60

NokiaSeriesGO(int a, int b) ;

// тело подкласса NokiaSeries60

}

// подкласс Nokia6600 для суперкласса NokiaeSeries60

class Nokia6600

extends NokiaSeries60

{

// конструктор подкласса Nokia6600

Nokia6600 (short f, short b, short c)

{

super (a, b)

// тело конструктора

}

}

// подкласс Nokia6100 для суперкласса NokiaeSeries60

class Nokia6100 extends NokiaeSeries60

{

//конструктор подкласса Nokia6100

Nokia6100 (char a, char b)

{

super (a, b)

// тело конструктора

}

// тело подкласса Nokia6100

}

Если вы желаете воспользоваться конструктором ближайшего суперкласса, в конструкторе подкласса первым должно идти ключевое слово super с параметрами для необходимого конструктора суперкласса. Ключевое слово super имеет двойную смысловую нагрузку и может использоваться не только для вызова конструктора суперкласса. Второй вариант использования ключевого слова super, заключается в доступе к невидимому члену суперкласса. Сейчас мы коснулись так называемого вопроса видимости. Вы не задумывались над тем, что будет, если методы или переменные в суперклассе и подклассе будут совпадать по именам? Дело в том, что если подкласс будет иметь одинаковые названия любых членов класса, то он будет использовать только свои члены класса. Все данные суперкласса окажутся недоступными или невидимыми в силу совпадения названий. Для этих целей может быть использовано слoво super. Посмотрите на пример иллюстрирующий способ его использования:

// суперкласс Siemens

class Siemens

{

int a, b;

}

// подкласс SiemensMC62

 class SiemensMC62 extends Siemens

{

int a, b;

// конструктор подкласса SiemensMC62

SiemensMC62 (int c, int d)

{

super.a = с;

// для а в суперклассе

super.b = d;

// для b в суперклассе a = с;

// для а подкласса b = d;

// для b подкласса

}

}

Использование ключевого слова super очень похоже на обращение объекта класса к методам и переменным. Когда необходимо получить доступ к членам суперкласса, имеющим одинаковые названия, воспользуйтесь ключевым словом super или поступайте проще - давайте различные имена для членов суперкласса и подкласса.

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

Подводя итог темы наследования необходимо упомянуть о классе Object. В языке Java все классы наследуются от большого суперкласса Objec. Это происходит автоматически и беспокоится о явном наследовании при помощи ключевого слова extends не нужно.


1.11. Интерфейсы

В программировании мобильных телефонов на Java 2 ME очень часто используются интерфейсы. Интерфейс задает классу, что именно должен делать этот класс, но, не говоря каким образом должны быть реализованы Эти действия, то есть, это некая спецификация, в рамках которой происходит реализация необходимых действий. Создание интерфейса совершается при помощи ключевого слова interface, а для реализации каким-либо классом возможностей интерфейса используется ключевое слово implements. Чтобы более четко разобраться в работе с интерфейсами рассмотрим небольшой пример:

public interface Mylnterface

{

int Inkriment();

}

class MyOne implements Mylnterface

{

int a;

// реализация метода Inkriment() для класса MyOne

public int Inkriment()

{

a = 9++;

return a;

}

 }

class MyTwo implements Mylnterface

{

int a;

// реализация метода Inkriment() для класса

MyTwo public int Inkriment()

{

а = 2++;

return a; }

 }

Созданный интерфейс Mylnterfасе имеет один пустой метод Incriment (). Тело метода отсутствует, есть только его декларация, а класс МуОnе реализует данный интерфейс для своих нужд. В свою очередь класс MyTwo тоже реализует метод Incriment () в необходимой ему форме. Интерфейс задает, что именно надо сделать, а класс, реализующий данный интерфейс, решает, как ему это сделать. Все методы, заключенные в интерфейсе, обязательно должны быть созданы в классе, реализующим этот интерфейс. Интерфейсы не являются классами, поэтому создать интерфейс при помощи ключевого слова new невозможно, но создавать переменные интерфейса можно, в случае если они сохраняются на объекты класса. Любой интерфейс может наследовать другой интерфейс при помощи ключевого слова extends. Интерфейсы очень ярко отражает полифонизм языка Java.


1.12. Пакеты

При наличии большого количества своих классов, можно создавать пакеты, для этих классов, коллекционируя их. С помощью ключевого слова package можно создать пакет для класса. Для этого в самом начале файла, где вы пишете исходный код для класса, сделайте запись, например следующую, для созданного ранее в разделе 1.10.1 класса Nokia:

package Nokia;

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

import Nokia.*

Оператор звездочка в конце импорта класса Nokia обозначает доступ ко всем классам этого пакета. Но возможно обращение и к отдельному классу всего пакета, например:

import Nokia..NokiaeSeries60 .Nokia6600;

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

Кроме этого пакеты имеют еще одну ценную возможность - при создании своих классов существует вероятность того, что какой-нибудь программист, собирающий яблоки в Новой Зеландии возьмет и назовет свой созданный класс точно таким же именем. В этом случае возникает конфликт имен вызывающий исключительную ситуацию. Но если пользоваться возможностью создания пакетов, такая вероятность повторения снижается. Даже если названия созданных классов будут одинаковыми, содержаться они будут в разных пакетах. Конфликта не возникнет. Слышу провокационный вопрос: а если названия пакетов совпадут? Да вы правы, есть же сказка про Буратино от двух разных авторов... В таком случае можно воспользоваться рекомендуемой компанией Sun Microsystems, создавшей язык Java, схемой записи по зарезервированному домену в Интернете, например':

package ru.dmk;

Или как в случае упомянутой сказки о деревянном человечке:

package Buratino;

package Pinocchio;

И избежать тем самым конфликта имен. Такой способ записи по домену действительно работает и на этой схеме построены все пакеты в Java.

Язык Java имеет огромное количество предопределенных классов, существующих в виде библиотек. Все библиотеки разбиты на пакеты по своему назначению. Платформа Java 2 ME состоит из одиннадцати пакетов:

  • java.io;
  • java.lang;
  • java.util;
  • javax.microedition.lcdui;
  • javax.inicroedition.lcdui.game;
  • javax.microedition.io;
  • javax.microedition.inedia;
  • javax.microedition.media.control;
  • javax.microedition.pki;
  • javax.microedition.midlet;
  • javax.inicroedition.rms.

Каждый из пакетов содержит множество классов с различной областью применения. Имеются математические классы, классы, отвечающие за работу с сетью, классы ввода-вывода, классы утилит и так далее. Более подробно каждый из пакетов будет рассмотрен в главе 2. Для того чтобы воспользоваться имеющимися классами и методами, необходимо в начале исходного кода импортировать нужный для работы пакет:

import java.lang.*

Затем можно воспользоваться, к примеру методом abs (int а) .класса Math, возвращающим целочисленное значение переменой.

int а = 9;

int x = Math.abs(a);

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

В этом приложении мы рассмотрели язык программирования Java вкратце, но изученного материала будет достаточно для прочтения этой книги и освоения азов программирования мобильных телефонов на Java 2 Micro Edition.


Приложение 2. Справочник по Java 2 Micro Edition

  • В этом приложении...
  • 2.1. Пакет Java.lang
  • 2.2. Пакет Java.util
  • 2.3. Пакет java.io
  • 2.4. Пакет javax.microedition.io
  • 2.5. Пакет javax.microedition.lcdui
  • 2.6. Пакет javax.microedition.lcdui.game
  • 2.7. Пакет javax.microedition.media
  • 2.8. Пакет javax.microedition.media.control
  • 2.9. Пакет javax.microedition.midlet
  • 2.10. Пакет javax.microedition.pki
  • 2.11. Пакет javax.microedition.rms


В этом приложении...

В этом приложении содержится исчерпывающий справочный материал по всем пакетам, интерфейсам, классам, конструкторам классов и константам платформы Java 2 Micro Edition. Справочник выполнен на основе имеющейся документации к платформе Java 2 ME, находящейся на сайте компании Sun Microsystems, по адресу в Интернет: http://java.sun.com. Аналогичная документация также поставляется с платформой Java 2 ME, которую вы найдете на компакт-диске, приложенном к книге, в составе среды программирования SUN ONE Studio.4 Mobile Edition и J2ME Wireless Toolkit 2.1. Справочник рассматривает все пакеты, имеющиеся в составе платформы Java 2 ME. Каждый пакет содержит множество интерфейсов, классов, конструкторов и констант. Для всех имеющихся компонентов каждого пакета дается краткая характеристика, на основании которой вам будет очень легко сориентироваться в создании приложений для платформы Java 2 Micro Edition.


2.1. Пакет Java.lang

Содержит системные классы или основы языка Java.

2.1.1. Интерфейс Runnable

  • Использование интерфейса Runnable обеспечивает создание потока в программах.

Метод

  • void run () - запускает поток в приложении.

2.1.2. Класс Boolean

Объектно-ориентированный класс-оболочка или как еще говорят «обвертка» для типа Boolean. Конструктор

  • Boolean (boolean value) - создает объект класса Boolean.

Методы

  • boolean booleanValuet) - возвращает значение объекта класса Boolean;
  • boolean equals (Object obj)- возвращает значение true, если это объект класса Boolean;
  • int hashCode () - возвращает специальный код (хеш-код) объекта класса Boolean;
  • String toString () - возвращает объект класса String для булевой переменной. *

2.1.3. Класс Byte

Объектно-ориентированный класс оболочка, для простого типа Byte. Конструктор

  • Byte (byte value) - создает объект класса Byte.

Методы

  • byte byteValue() - возвращает значение объекта класса Byte;
  • boolean equals (Object obj )- возвращает значение в байтах для объекта класса Byte;
  • int hashCode () - возвращает специальный код (хеш-код) объекта . класса Byte;
  • static byte parseByte (String s)- возвращает значение в байтах для указанного объекта String;
  • static byte parseByte (String s, int radix) - возвращает значение в байтах для указанного объекта String на основе системы исчисления;
  • String toString () - возвращает объект класса String, представленный значением Byte.

Константы

  • static byte MAX_VALUE - максимальное значение в байтах;
  • static byte MIN_VALUE - минимальное значение в байтах.

2.1.4. Класс Character

Объектно-ориентированный класс-оболочка для простого типа Char. Конструктор

  • Character (char value) - создает объект класса Character.

Методы

  • char charValue() - возвращает значение объекта класса Character;
  • static int digit (char ch, int radix) — возвращает числовое значение на основе системы исчисления;
  • boolean equals (Object obj) - сравнивает объект;
  • int hashCode () - возвращает специальный код (хеш-код) объекта класса Character;
  • static boolean isDigitfchar ch) - узнает, является ли значение ch числовым значением;
  • Static boolean isLowerCase(char ch) — определяет, является ли символьное значение строчным;
  • static boolean isUpperCase (char ch) - определяет, является ли символьное значение заглавным;
  • static char toLowerCase (char ch) - переводит символ в нижний регистр;
  • String toString () - возвращает объект класса String, представленный значением Character;
  • static char toUpperCase(char ch) - переводит символ в верхний регистр.

Константы

  • static int MAX_RADIX - максимально доступное преобразование;
  • static char MAX_VALUE - максимальное значение;
  • static int MIN_RADIX - минимально доступное преобразование;
  • static char MIN_VALUE - минимальное значение.

2.1.5. Класс Class

Виртуальная Java машина создает объекты этого класса, которые представляют интерфейсы и классы языка Java. Методы

  • static Class forName (String с1assName)- возвращает объект Class по названию класса;
  • String getName ()-возвращает имя интерфейса, класса, массива классов, простых типов представляемых классом Class;
  • InputStream getResourceAsStream(String name) — берет искомый ресурс с заданным именем;
  • boolean isArray() - определяет, является ли объект массивом классов;
  • boolean isAssignableFrom(Class els) - определяет, является ли интерфейс или класс суперинтерфейсом или суперклассом;
  • boolean islnstance (Object obj) - определяет совместимость указанных объектов;
  • boolean islnterface () - определяет, каким типом интерфейса представлен данный класс;
  • Object newlnstance () - создает новый экземпляр класса;
  • String toString () - конвертирует объект к виду String.

2.1.6. Класс Integer

Объектно-ориентированный класс для простого типа int.

Конструктор

  • Integer (int value) - создает объект класса Integer.

Методы

  • byte byteValue () - возвращает значение в байтах;
  • boolean equals (Object obj) - сравнивает объекты;
  • int hashCode() - возвращает.специальный код (хеш-код) объекта класса Integer;
  • int intValue ()- возвращает значение числа как тип int;
  • long longValue () - возвращает значение числа как тип long;
  • static int parselnt (String s) — извлекает целое десятичное число из заданного объекта класса String; *
  • static int parselnt (String s, int radix) - извлекает целое десятичное число со знаком с использованием основания системы исчисления из заданного объекта класса String;
  • short shortValue() - возвращает значение числа как тип short;
  • static String toBinaryString(int i)-создает строковое представление целочисленного значения в виде целого числа без знака в двоичном представлении;
  • static String toHexString(int i) - создает строковое представление целочисленного значения в виде целого числа без знака в шестнадцатеричном представлении;
  • static String toDctalString(int i)- создает строковое представление целочисленного значения в виде целого числа без знака в восьмеричном представлении;
  • String toString() - возвращает объект класса String, представленный значением целого числа;
  • static String toString(int i) — возвращает заданный объект класса String как целое число;
  • static String toString(int i, int radix) — создает строковое представление целого числа на основании системы исчисления;
  • static Integer valueOf (String s) - возвращает новый объект класса Integer, инициализированный значением s;
  • static Integer valueOf (String s, int radix) -возвращает новый объект класса Integer, инициализированный значением s на основе системы исчисления.

Константы

  • static int MAX_VALUE - максимальное значение;
  • static int MIN_VALUE - минимальное значение.

2.1.7. Класс Long

Объектно-ориентированный класс-оболочка для простого типа long. Конструктор

  • Long (long value) - создает объект класса Long.

Методы

  • boolean equals (Object obj ) - сравнивает объекты;
  • int hashCode () - возвращает специальный код (хеш-код) объекта класса Long;
  • long longValue () - возвращает значение числа как тип long;
  • static long parseLong (String s) - извлекает большое целое десятичное число из заданного объекта класса String;
  • static long parseLongf String s, int radix) - извлекает большое целое десятичное число со знаком с использованием основания системы исчисления из заданного объекта класса String;
  • String toString() - возвращает объект класса String представленный значением большого целого числа;
  • static String toString (long i)- возвращает заданный объект класса String как целое большое число;
  • static String toString (long i, int radix) - создает строковое представление большого целого числа на основании системы исчисления.

Константы

  • static long MAX_VALUE - максимальное значение;
  • static long MIN_VALUE -минимальное значение.

2.1.8. Класс Math

Математический класс, содержащий несколько методов для различных математических операций. Очень сильно урезан в отличие от класса Math из Java 2 SE.

Методы

  • static int abs (int a) - возвращает абсолютное значение из параметра int а заданное целочисленным значением;
  • static long abs (long a) - возвращает абсолютное значение из параметра long а заданное большим целочисленным значением;
  • static int max (int a, int b)- возвращает одно большее из двух значений типа int;
  • static long max (long a, long b) - возвращает одно большее из двух значений типа long;
  • static int min(int a, int b)- возвращает одно меньшее из двух значений типа int;
  • static long min(long a, long b) - возвращает одно меньшее из двух значений типа long.

2.1.9. Класс Object

Суперкласс для всех классов Java. Все классы наследуются от класса Object и являются его подклассами

Методы

  • boolean equals (Object obj ) - сравнивает объекты;
  • Class getClass() - возвращает класс объекта;
  • int hashCode() - возвращает специальный код (хеш-код) для объекта;
  • void notify () - пробуждает отдельно взятый поток;
  • void notify-All () - пробуждает все имеющиеся потоки;
  • String toString () - возвращает строковое представление данного объекта;
  • void wait () - приостанавливает работу потока;
  • void wait (long timeout) - приостанавливает работу потока на время заданное в миллисекундах;
  • void wait (long timeout, int nanos) - приостанавливает работу потока на время заданное в миллисекундах, учитывая также дополнительное время заданное в наносекундах.

2.1.10. Класс Runtime

Класс времени исполнения приложения.

Методы

  • void exit (int status) - осуществляет выход из работающего приложения;
  • long f reeMemory () - возвращает количество доступной памяти в мобильном устройстве;
  • void gc () - производит сборку мусора;
  • static Runtime getRuntime ()- возвращает объект времени исполнения во время работы программы;
  • long totalMemory () -возвращает доступный объем памяти для виртуальной Java машины.

2.1.11. Класс Short

Объектно-ориентированный класс-оболочка для простого типа Short. Конструктор

  • Short (short value) — создает объект класса Short.

Методы

  • boolean equals (Object obj ) - сравнивает объекты;
  • int hashCode () - возвращает специальный код (хеш-код) объекта . класса Short;
  • static short parseShort (String s) - извлекает короткое целое десятичное число из заданного объекта класса String;
  • static short parseShort (String s, int radix) -извлекает короткое целое десятичное число с использованием основания системы исчисления из заданного объекта класса String;
  • short shortValue () - возвращает значение Переменной;
  • String toString () - возвращает объект класса String представляющий короткое целое значение.

Константы

  • static short MAX_VALUE - максимальное значение;
  • static short MIN_VALUE - минимальное значение.

2.1.12. Класс String

Создает символьные строки текста. Конструкторы

  • String() - создает пустой объект класса String, то есть объект не имеет определенной символьной последовательности;
  • String (byte [] bytes) - создает объект класса String из указанного массива байт в соответствующей кодировке поддерживаемой системой;
  • String (byte [] bytes, int off, int len.) - создает объект класса String из указанного массива байт в соответствующей кодировке поддерживаемой системой. Параметр off - это индекс первого байта, от которого происходит конвертация, и параметр len указывает на количество байт для конвертации;
  • String (byte [] bytes, int off, int len, String enc) -создает объект класса String из указанного массива байт в соответствующей кодировке поддерживаемой системой. Параметр off - это индекс первого байта, от которого происходит конвертация, параметр len указывает на количество байт для конвертации и параметр еnc на вид кодировки;
  • String (byte [] bytes, String enc) -создает объект класса String из массива байт в заданной кодировке указанной в параметре еnс;
  • String (char [ ] value) - создает строку текста из массива символов;
  • String (char [] value, int offset, int count) - создает строку текста из массива символов. Параметр offset - это начало массива и параметр count - длинна массива;
  • String (String value) - создает объект класса String со значением определенным в параметре value;
  • String (StringBuf f er buffer) - создает объект класса String со значением из параметра buffer, являющегося объектом класса StringBuffer.

Методы

  • char charAt(int index) - возвращает символ по заданному индексу в параметре index, отсчет идет от значения 0;
  • int compareTo (String anotherString) - сравнивает две строки на основании лексографии;
  • String concat (String str) - конкатенация двух строк;
  • boolean endsWith( String, suffix) - тестирует строку на окончание подстроки suffix;
  • boolean equals (Object anObject) - сравнивает строки;
  • byte[] getBytes() - конвертирует строку текста в массив байт в кодировке по умолчанию заданной системой устройства;
  • byte[] getBytes (String enc) - конвертирует строку текста в массив байт в кодировке указанной в параметре еnс;
  • void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) — производит копирование символов строки в массив символов;
  • int hashCode () - возвращает специальный код (хеш-код) для строки текста;
  • int indexOf (int ch) - возвращает положение первого символа в строке текста;
  • int indexOf(int ch, int fromlndex) - возвращает положение первого символа в строке текста и производит поиск по заданному индексу в параметре fromlndex;
  • int indexOf (String str) - возвращает положение первого символа в подстроке текста;
  • int indexOf (String str, int fromlndex) - возвращает положение первого символа в подстроке текста и производит поиск по заданному индексу в параметре fromlndex;
  • int lastlndexOf (int ch) - возвращает положение последнегосимвола в подстроке текста;
  • int lastlndexOf (int ch, int fromlndex) — возвращает положение последнего символа в лодстроке текста и производит поиск по заданному индексу в параметре fromlndex;
  • int length ()- возвращает длину определенной строки текста;
  • boolean . regionMatches (boolean ignoreCase, int toffset, String other, int oof f set, int len) - проверяет заданную область текста на совпадение;
  • String replace(char oldChar, char newChar) - производит замену строки текста на новую строку из параметра oldChar в параметр newChar;
  • boolean startsWith ('String prefix) - проверяет строку на совпадение с начальным указанием префикса;
  • boolean startsWith(String prefix, int toffset)-проверяет строку на совпадение с начальным указанием префикса и индекса;
  • String substring (int beginlndex) - возвращает новую строку текста, являющуюся подстрокой этого текста;
  • String substring(int beginlndex, int endlndex) -возвращает новую строку текста,, являющуюся подстрокой этого текста заданной начальным и конечным индексами;
  • char [ ] toCharArray () - конвертирует строку текста в массив символов;
  • String toLowerCase() - приводит строку текста к строчному написанию;
  • String toString ()-возвращает строковый объект;
  • String toUpperCase () - приводит строку текста к заглавному написанию;
  • String trim () - удаляет имеющиеся пробелы в начале и конце строки;
  • static String valueOf (boolean b) - возвращает строковое представление логической переменной;
  • static String valueOf (char с) - возвращает строковое представление переменной типа char;
  • static String valueOf (char [] data) - возвращает строковое представление массива значений типа char;
  • static String valueOf(char[} data, . int offset, int count) - возвращает строковое представление массива значений типа char с определенного начала по заданной длине;
  • static String valueOf (int i) - возвращает строковое представление переменной типа int;
  • static String1 valueOf(long 1)- возвращает строковое представление переменной типа long;
  • static String valueOf (Object obj ) - возвращает строковое представление объекта.

2.1.13. Класс StringBuffer

Класс StringBuffer может содержать строки символов любого размера.

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

  • stringBuffer () -создает пустой объект класса StringBuffer, то есть объект не имеет определенной символьной последовательности, с длинной не более шестнадцати символов;
  • StringBuffer (int length) - создает объект класса StringBuffer с заданной длинной;
  • StringBuffer (String str) - создает объект класса StringBuffer со значением из параметра str, являющегося объектом класса String.

Методы

  • StringBuffer append (boolean b) - добавляет в конец буфера логическую переменную в строковом представлении;
  • StringBuffer append (char с) - добавляет в конец буфера символ;
  • StringBuffer append (char [] str) - добавляет в конец буфера массив символов;
  • StringBuffer append(char[] str, int offset, int len) -добавляет в конец буфера массив символов по начальному индексу и длине массива символов;
  • StringBuffer аррепсЦ int i)-добавляет в конец буфера значение типа int в строковом представлении;
  • StringBuffer append (long 1) - добавляет в конец буфера значение типа long в строковом представлении;
  • StringBuffer append (Object obj) - добавляет в конец буфера объект в строковом представлении;
  • StringBuffer append(String str) -добавляет в конец буфера строку текста;
  • int capacity() - возвращает имеющеюся свободную емкость буфера;
  • char charAt(int index) - возвращает символ по заданному индексу в переменной index;
  • StringBuffer delete (int start, int end) - удаляет подстроку из строки по указанному начальному значению в параметре start и конечному в параметре end;
  • StringBuffer deleteCharAt (int index) - удаляет символ из строки по указанному индексу в параметре index;
  • void ensureCapacity(int. minimumCapacity) - задает минимальную емкость буфера;
  • void getChars(int srcBegin, int srcEnd, char[] dst,- int dstBegin) - копирует в символьный массив содержимое строкового буфера;
  • StringBuffer insert(int offset, boolean b)-вставляет в буфер строковое представление логической переменной из параметра boolean b;
  • StringBuffer insert(int offset, char с)- вставляет в буфер символ из параметра с;
  • StringBuffer insert(int offset, char[] str) - вставляет в буфер массив символов из параметра char [] str;
  • StringBuffer insert (int offset, int i) - вставляет в буфер строковое представление переменной типа int;
  • StringBuffer insert(int offset, long 1)- вставляет в буфер строковое представление переменной типа long;
  • StringBuffer insert(int offset, Object obj)- вставляет в буфер строковое представление объекта;
  • StringBuffer insert(int offset, String str) - вставляет в буфер строку текста;
  • int length() - определяет длину строки;
  • StringBuffer reverse () - производит замену буфера новой символьной последовательностью;
  • void setCharAt (int index, char ch) - устанавливает символ в буфер по заданному индексу;
  • void setLength(int newLength) - устанавливает новую длину для буфера;
  • String toStrihg() - преобразует содержимое буфера в строку.

2.1.14. Класс System

Содержит ряд системных методов.

Методы

  • static void arraycopy(Object src, int src_position. Object dst, int dst_position, int length) - копирует массив из указанного массива по заданной позиции;
  • static long currentTimeMillis () - возвращает время, измеряемое в миллисекундах;
  • static void exit (int status) - производит выход из программы;
  • static void gc () - совершает сборку мусора;
  • static String getProperty (String key) - возвращает приоритетное свойство по строковому ключу;
  • static int identityHashCode (Object x) - возвращает специальный код (хеш-код) объекта.

Константы

  • static PrintStream err - выходной поток, сообщающий об имеющихся ошибках;
  • static PrintStream out - выходной поток данных.

2.1.15. Класс Thread

Создает поток в работе приложения для виртуальной Java машины, мобильных телефонов. Доступна многопоточность.

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

  • Thread () - создает новый поток;
  • Thread (Runnable target) -1 создает новый поток с заданным объектом в параметре target, реализующем возможности интерфейса Runnable.

Методы

  • static int activeCount ()-возвращает количество задействованных потоков;
  • static Thread currentThread ()- возвращает выполняющийся в данный момент поток;
  • int getPriorfty () - узнает приоритет определенного потока;
  • boolean isAlive() - тестирует поток на работоспособность;
  • void (int) - ожидает окончание потока;
  • void setPriority (int newPriority) - устанавливает приоритет для потока;
  • static void sleep (long millis) - останавливает выполнение потока, на заданное количество времени, измеряемое в миллисекундах;
  • void start () - дает команду на выполнение потока посредством метода run () интерфейса Runnable;
  • String toString() - возвращает строковое представление потока;
  • static void yield () - регулирует вызовы последующих потоков низших по приоритету

Константы

  • static int MAX_PRIORITY - максимальный приоритет потока;
  • static int MIN_PRIORITY - минимальный приоритет потока;
  • static int NORM_PRIORITY - приоритет по умолчанию.

2.1.16. Класс Throwable

Суперкласс для всех классов, предназначенных для работы с ошибками и исключениями в языке программирования Java.

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

  • Throwable () - создает новый объект класса Throwable;
  • Throwable (String message) - создает новый объект класса Throwable с заданным сообщением об ошибках.

Методы

  • String getMessage() - возвращает сообщение об ошибке;
  • void printStackTrace () - отслеживает ошибки на выходном потоке;
  • String toString() - возвращает описание объекта класса Throwable.

2.1.17. Исключения

  • Exceptions - исключения для классов и подклассов;
  • ArithmeticException - арифметическое исключение;
  • ArraylndexOutOf BoundsException - исключение обрабатывающее неправильный индекс в массиве данных;
  • ArrayStoreException - исключение обрабатывающее неправильно заданный тип объекта в массиве объектов;
  • ClassCastExcept ion - неправильно указан подкласс объекта;
  • ClassNotFoundException - класс не найден;
  • IllegalAccessException - нет доступа к классу;
  • IllegalArgumentException — указан неправильный аргумент;
  • IllegalMonitorStateException - мониторинг объектов;
  • IllegalStateException - неправильно вызванный метод; .
  • IllegalThreadStateException - неправильные установки потока;
  • indexOutOf BoundsException - исключает неверный указанный индекс;
  • InstantiationExceptioh — исключает ситуацию в создании или вызове членов абстрактного класса;
  • interruptedException - исключает прерывание потока находящегося в состоянии ожидания:
  • NegativeArraySizeException - исключает ситуацию в создании большего размера массива данных, чем было указано при инициализации;
  • NumberFormatException - неправильное преобразование строки в целочисленный тип данных;
  • RuntimeException - суперкласс исключений времени исполнения виртуальной машины Java;
  • SecurityException - менеджер безопасности;
  • StringlndexOutOf BoundsException - выход индекса за приделы строки.

2.1.18. Ошибки

  • Error — обобщенная модель ошибок;
  • OutOfMemoryError - ошибки связанные с выходом за пределы памяти;
  • VirtualMachineError - ошибки времени исполнения.


2.2. Пакет java.util

В этом пакете содержатся классы стандартных утилит для создания Java 2 ME приложений. Пакет сильно урезан по сравнению со стандартным пакетом Java 2 SE.

2.2.1. Интерфейс Enumeration

Декларирует возможность доступа к элементам.

Методы

  • boolean hasMoreElements () - проверяет соответствующие перечисления на наличие элементов;
  • Object nextElement () - возвращает последующий элемент перечисления в том случае, если перечисления содержат более одного элемента.

2.2.2. Класс Calendar

Необходим для работы с датой и временем, выполняет функции обыкновенного календаря.

Конструктор

  • protected Calendar() - создает календарь. Язык и часовой пояс задаются по умолчанию.

Методы

  • boolean after (Object when) - сравнивает два объекта и возвращает значение true в том случае, если время представленное объектом when, находится после времени представленного другим сравниваемым объектом;
  • boolean before (Object when) - сравнивает два объекта и возвращает значение true в том случае, если время представленное объектом when, находится до времени представленного другим сравниваемым объектом;
  • boolean equals (Object obj ) - сравнивает объекты;
  • int get(int field) - получает значение определенного поля, например, время, день, месяц, год;
  • static Calendar getlnstance () - получает параметры часового пояса и языка по умолчанию;
  • static Calendar getlnstance(TimeZone zone) - получает параметры часового пояса и языка данного региона;
  • Date getTime () - получает время;
  • protected long getTimelnMillis () - получает время по Гринвичу, производя запись в виде миллисекунд;
  • TimeZone getTimeZone () - определяет часовой пояс региона;
  • void set (int field, int value) - задает определенному полю значение времени;
  • void setTime (Date date) - устанавливает необходимую дату;
  • protected void setTimelnMillis (long millis) —устанавливает время по Гринвичу, производя запись в виде миллисекунд;
  • void setTimeZone (TimeZone Value) - устанавливает часовой пояс региона.

Константы

  • stat ic int. AM — формат, отражающий запись времени до полудня;
  • static int AM_PM - формат, отражающий запись времени до полудня и после полудня;
  • static int APRIL - значение, указывающее месяц года Апрель;
  • static int AUGUST — значение, указывающее месяц года Август;
  • static int DATE - значение, указывающее день;
  • static int DAY_OF_MONTH - значение, указывающее день и месяц;
  • static int DAY_OF_WEEK - значение, указывающее день недели;
  • static int DECEMBER - значение, указывающее месяц года Декабрь;
  • static int FEBRUARY - значение, указывающее месяц года Февраль;
  • static int FRIDAY - значение, указывающее день недели пятницу;
  • static int HOUR - значение, указывающее время;
  • static int HOUR_OF_DAY - значение, указывающее время и день недели;
  • static int JANUARY - значение, указывающее месяц года Январь;
  • static int JULY-значение, указывающее месяц года Июль;
  • static int JUNE - значение, указывающее месяц года Июнь;
  • static int MARCH - значение, указывающее месяц года Март;
  • static int MAY — значение, указывающее месяц года Май;
  • static int MILLISECOND - формат записи времени в миллисекундах;
  • static int MINUTE - формат записи времени в минутах;
  • static int MONDAY - значение, указывающее день недели пятницу;
  • static int MONTH - месяц;
  • static int NOVEMBER - значение, указывающее месяц года Ноябрь;
  • static int OCTOBER - значение, указывающее месяц года Октябрь;
  • static int PM - формат, отображающий запись времени после полудня;
  • static int SATURDAY - значение, указывающее день недели суббота;
  • static int SECOND - устанавливает отображение времени в секундах;
  • static int SEPTEMBER - значение, указывающее месяц года Сентябрь;
  • static int SUNDAY - значение, указывающее день недели воскресенье;
  • static int THURSDAY - значение, указывающее день недели четверг;
  • static int TUESDAY - значение, указывающее день недели вторник;
  • static int WEDNESDAY - значение, указывающее день недели среда;
  • static int YEAR - значение, указывающее год.

2.2.3. Класс Date

Реализует возможность работы с датой.

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

  • Date () - создает объект класса Date;
  • Date (long date) - создает объект класса Date с форматом записи .00:00:00.

Методы

  • boolean equals (Object obj ) - сравнивает две даты;
  • long getTime () - получает время в миллисекундах;
  • int hashCode () - возвращает специальный код (хеш-код) объекта класса Date;
  • void setTimeflong time) - устанавливает время.

2.2.4. Класс Hashtable

Предоставляет возможность хранения объектов с доступом к ним по определенно заданному ключу.

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

  • Hashtable() - создает пустой объект класса Hashtable;
  • Hashtable (int initialCapacity) - создает объект класса Hashtable с заданной вместимостью.

Методы

  • void clear () -очищает объект класса Hashtable от набора имеющихся ключей;
  • boolean contains (Object value) - определяет наличие различных ключей;
  • boolean containsKey (Object key) — определяет наличие определенного ключа;
  • Enumeration elements () - возвращает последовательность имеющихся элементов;
  • Object get (Object key) - получает необходимый объект, используя при этом заданный для этого объекта ключ;
  • boolean isEmpty() - проверяет объект класса Hashtable на наличие ключей;
  • Enumeration keys () — возвращает последовательность доступных ключей;
  • Object put (Object key, Object value) - сохраняет объект и за-i данный для этого объекта ключ;
  • protected void rehash () — увеличивает вместимость объекта класса Hashtable;
  • Object remove (Object key) - удаляет указанный ключ;
  • G int size ()—определяет количество имеющихся ключей;
  • String toString() - возвращает строковое представление объекта класса Hashtable.

2.2.5. Класс Random

Генератор случайных чисел.

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

  • Random () - создает генератор случайных чисел;
  • Random (long seed) - создает объект класса Random, сгенерировав целое длинное число.

Методы

  • G protected int next (int bits) - генерирует следующее случайное число; .
  • G int next Int ()-генерирует целое случайное число из заданной последовательности;
  • long nextLong () - генерирует целое длинное случайное число из заданной последовательности;
  • void setSeeddong seed() - устанавливает заданное начальное число для последующей генерации случайных чисел.

2.2.6. Класс Stack

Реализует функциональность стека.

Конструктор

  • Stack () - создает пустой стек.

Методы

  • boolean empty ()- проверяет пустой созданный стек или нет;
  • Obj ect peek () - просмотр стека;
  • Object pop () - удаляет последний объект из стека;
  • Object push (Object item) - помещает объект в стек;
  • int search (Object о)- возвращает начальную позицию для первого объекта в стеке.

2.2.7. Класс Timer

Реализует возможность работы со временем по принципу таймера.

Конструктор

  • Timer () - создает таймер.

Методы

  • void cancel () - закрывает работу таймера;
  • void schedule (TimerTask task, Date time) — назначает задачу на заданное время;
  • void schedule(TimerTask task, Date firstTime, long period) - назначает задачу на заданное время, с ее последующим повторным выполнением. Частота повторений задается фиксированными промежутками времени;
  • void schedule (TimerTask task, long delay) - назначает выполнение задачи по прошествии заданного промежутка времени;
  • void schedule(TimerTask task, long delay, long period) — назначает выполнение задачи по прошествии заданного промежутка времени, с ее последующим повторным выполнением. Частота повторений задается фиксированными промежутками времени;
  • void scheduleAtFixedRate(TimerTask task, Date firstTime, long period) - назначает задачу на заданное время с ее последующим повторным выполнением. Частота повторений назначается относительно абсолютного времени;
  • void scheduleAtFixedRate(TimerTask task, long delay, long -period) - назначает выполнение задачи по прошествии заданного промежутка времени с ее последующим повторным выполнением; Частота повторений назначается относительно абсолютного времени.

2.2.8. Класс TimerTask

Планировщик задач.

Конструктор

  • protected TimerTask () - создает новую задачу.

Методы

  • boolean cancel () - отменяет выполнение задачи;
  • abstract void run() - определяет действие для выполнения планировщиком задач;
  • long- scheduledExecutionTime() - возвращает время выполнения задачи.

2.2.9. Класс TimeZone

Устанавливает и определяет часовой пояс.

Конструктор

  • TimeZone () - создает объект класса TimeZone.

Методы

  • static String [] getAvailablelDs ()- получает доступные идентификаторы часового пояса;
  • static TimeZone getDefault () - получает часовой пояс региона;
  • String getlD() - получает идентификатор часового пояса;
  • abstract int getRawOffset() - получает время по Гринвичу для часового пояса местонахождения;
  • static TimeZone getTimeZone (String ID) - получает часовой пояс;
  • abstract boolean useDaylightTime ()- необходим для определения использования часовым поясом перехода на летнее время.

2.2.10. Класс Vector

Создает массивы любого размера. Имеет возможность изменять размер заданного массива.

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

  • Vector () - создает пустой массив для содержания объектов;
  • Vector (int initialCapacity) - создает массив объектов с указанной размерностью;
  • Vector(int initialCapacity, int capacityIncrement)-создает массив объектов с указанной размерностью и заданным размером дополнений к этому массиву;

Методы

  • void addElement (Object obj ) - добавляет к массиву объектов ещё один объект;
  • int capacity () - узнает текущую вместимость заданного массива объектов;
  • boolean contains (Object elem) - определяет наличие указанного элемента в массиве объектов;
  • void copylnto (Object [] anArray) - копирует заданные элементы в массив объектов;
  • Object elementAt (int index) - возвращает искомый компонент по указанному индексу;
  • Enumeration elements () - возвращает число имеющихся элементов в массиве данных;
  • void ensureCapacity (int minCapacity) - увеличивает вместимость массива данных;
  • Object f irstElement () - возвращает самый первый элемент всего массива;
  • int indexOf (Object elem) - проверяет массив на присутствие объекта;
  • int indexOf (Object elem, int index) - проверяет массив на присутствие объекта по его индексу в массиве данных;
  • void insertElementAt (Object obj, int index) - вставляет объект в массив по заданному индексу;
  • boolean -isEmpty() - проверяет массив, не пустой ли он;
  • Object lastElement () - возвращает самый последний элемент всего массива данных;
  • int lastlndexOf (Object elem) — возвращает последний индекс данного элемента в массиве;
  • int lastlndexOf (Objevct elem, int index) - проверяет последнее присутствие объекта в массиве по его индексу;
  • void removeAllElements () - удаляет все элементы массива;
  • boolean removeElement (Object obj )-удаляет элемент массива;
  • void removeElementAt (int index) - удаляет элемент массива по индексу;
  • void setElementAt (Object obj, int index) — устанавливает элемент в массив по индексу;
  • void setSize(int newSize) - задает размер массива;
  • int size () - определяет размер массива;
  • String toString() - возвращает строковое представление массива данных;
  • void trimToSize () - уменьшает размерность массива.

Константы

  • protected int capacitylncrement - автоматическое увеличение массива на заданное число элементов, то есть шаг увеличения массива;
  • protected int elementCount - заданное число элементов массива;
  • protected Object [] elementDatа -массив данных, в котором сохранены элементы массива.

2.2.11. Исключения

  • EmptyStackException - указывает на пустой стек;
  • NoSuchElementException - указывает на отсутствие элементов в определенном перечислении.


2.3. Пакет Java.io

Классы этого пакета отвечают за работу с входными и выходными потоками данных.

2.3.1. Интерфейс Datalnput

Декларирует Методы для чтения простых типов во входном потоке данных.

Методы

  • boolean readBoolean () - читает входной байт данных и если значение этого байта отлчно от 0, то возвращает true, иначе возвращается значение f.alse;
  • byte readByte() — производит чтение и возврат одного входного байта;
  • char readChar () - производит чтение и возврат одного входного символа;
  • void readFully (byte [] b) - производит чтение входных байт, размещая их в массиве данных;
  • void readFully (byte [] b, int off, int len) -производит чтение указанных входных байт параметра len из параметра b;
  • int readlnt () - производит чтение и возврат входных байт типа int (четыре байта);
  • long readLong () - производит чтение и возврат входных байт типа long (восемь байт);
  • short readShort () - производит чтение и возврат входных байт типа short (два байта);
  • inf readUnsignedByte () - производит чтение и возврат одного входного байта в диапазоне от 0 до 256;
  • int readUnsignedShort () — производит чтение и возврат двух входных байт в диапазоне от 0 до 256;
  • String readUTF () - читает строку текста в формате UTF-8;
  • int skipBytes (int n) - переходит по входному потоку, минуя пропущенные байты.

2.3.2. Интерфейс DataOutput

Декларирует Методы для записи простых типов в выходной поток данных.

Методы

  • void write (byte [] b) - записывает в выходной поток массив байт;
  • void write (byte [] b, int off, int len) -производит запись определенных байт указанных в параметр len из параметра b выходного потока;
  • void write (int b) - производит запись в выходной поток восемь младших бит; .
  • void writeBoolean (boolean v) - записывает логическую переменную в выходной поток данных;
  • void writeByte (int v) - производит запись в выходной поток восемь младших бит;
  • void writeChar (int v) - производит запись в выходной поток данных значения типа char (один символ - это два байта);
  • void writeChars (String s) - производит запись в выходной поток данных строки текста;
  • void writelnt (int v) - производит запись в выходной поток данных значения типа int (четыре байта);
  • void writeLong (long v) — производит запись в выходной поток данных значения типа long (восемь байт);
  • void writeShort (int v) - производит запись в выходной поток данных значения типа short (два байта);
  • void writeUTF (String str) - записывает строку текста в выходной поток данных.

2.3.3. Класс ByteArraylnputStream

Совершает чтение входного потока байт из массива данных для дальнейшего размещения их в памяти.

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

  • ByteArraylnputStream (byte [ ] buf) - создает объект класса ByteArraylnputStream, параметр buf будет содержать буфер данных;
  • ByteArraylnputStream(byte[] buf, int offset, int length) - создает объект класса ByteArraylnputStream. Параметр buf будет содержать буфер данных, параметр offset задает смещение от первого байта, а параметр length определяет максимальное значения буфера.

Методы

  • int available ()-возвращает количество байт входного потока данных;
  • void close() - закрывает входной поток, попутно освобождая все захваченные ресурсы этим потоком;
  • void mark (int readAheadLimit) - устанавливает маркер в заданной позиции потока данных;
  • boolean markSupported() - проверяют объект класса ByteArraylnputStream на поддержку установки и сброса маркера;
  • int read () - производит чтение каждого последующего байта во входном потоке данных;
  • int read (byte [] b, int off, int len) - читает определенный байт, указанный в параметре len из параметра b входного потока данных;
  • void reset () - сбрасывает значение к установленному маркеру;
  • long skip (long n) - пропускает заданные байты входного потока.

Константы

  • protected byte [] buf - массив байт;
  • protected int count - последний индекс для чтения из входного потока;
  • protected int mark - позиция или маркер во входном потоке данных;
  • protected int pos - последующий индекс для чтения из входного потока.

2.3.4. Класс ByteArrayOutputStream

Производит запись потока байт из памяти в массив выходных данных.

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

  • ByteArrayOutputStream() - создает новый выходной поток для записи в массив байт;
  • ByteArrayOutputStream (int size) - создает новый выходной поток для записи в массив байт с заданным размером.

Методы

  • void close () - закрывает выходной поток, попутно освобождая все захваченные ресурсы этим потоком;
  • void reset () — сбрасывает в ноль счетчик выходных данных;
  • int size () - возвращает текущий размер буфера данных;
  • byte[] toByteArray () - создает массив байт;
  • String toString () -производит преобразование содержимого буфера в строку текста;
  • void write(byte[] b, int off, int leh) - записывает определенный байт, указанный в параметре len из параметра b в выходной лоток;
  • void write (int b) - записывает байт в выходной поток.

Константы

  • protected byte [ ] buf-заданный буфер данных;
  • protected int count - количество байт в буфере.

2.3.5. Класс DatalnputStream

Этот класс наследуется от интерфейса Datalnput, реализуя при этом все его Методы.

Конструктор

  • DatalnputStream (inputStream in) -создает новый входной поток данных.

Методы

  • int available ()-возвращает Доступное количество байт для чтения из входного потока;
  • void close () — закрывает входной поток;
  • void mark (int readlimit)-маркирует заданную позицию во входном потоке;
  • boolean markSupported () - проверяет объект класса DatalnputStream на поддержку установки и сброса маркера;
  • int read () - производит чтение каждого последующего байта во входном потоке данных;
  • int read (byte [] b) - производит чтение байт из массива во входном потоке данных;
  • int read(byte[] b, int off, int len) - читает определенный байт, указанный в параметре len из параметра b входного потока данных;
  • boolean readBoolean() - читает входной байт данных и если значение этого байта отлично от 0, то возвращает true, иначе возвращается значение false;
  • byte readByte() - производит чтение и возврат одного входного байта;
  • char readChar () - производит чтение и возврат одного входного символа;
  • void readFully (byte [ ] b) - производит чтение входных байт, размещая их в массиве данных;
  • void readFully (byte [] b, int off, int len)-производит чтение указанных входных байт параметра 1 en из параметра Ь;
  • int readlnt () - производит чтение и возврат входных байт типа int (четыре байта);
  • long readLong () - производит чтение и возврат входных байт типа long (восемь байт);
  • short readShort () - производит чтение и возврат входных байт типа short (два байта);
  • int readUnsignedShort () - производит чтение и возврат двух входных байт в диапазоне от 0 до 256; ,
  • String readUTF () - читает строку текста в формате UTF-8;
  • Static String readUTF (Datalnput in) - производит чтение из входного потока строки символов;
  • void reset () - сбрасывает позицию маркера;
  • long skip (long n) - пропускает заданные байты входного потока;
  • int. skipBytes (int n) - переходит по входному потоку, минуя пропущенные байты.

Константа

  • protected InputStream in - входной поток данных.

2.3.6. Класс DataOutputStream

Этот класс наследуется от интерфейса DataOutput, реализуя при этом все его Методы.

Конструктор

  • DataOutputStream(OutputStream out) - создает новый выходной поток данных.

Методы

  • voidclose() - закрывает выходной поток;
  • void flush() - производит сброс потока данных;
  • void write(byte[] b, int off, int len) - производит запись определенных байт указанных в параметре len из параметра b выходного потока;
  • void write (int b) - производит запись в выходной поток восемь младших бит;
  • void writeBoolean (boolean v) - записывает логическую переменную в выходной поток данных;
  • void writeByte (int v) - производит запись в выходной поток восемь младших бит;
  • void writeChar (int v) - производит запись в выходной поток данных значение типа char (один символ - это два байта);
  • void writeChars (String s) - производит запись в выходной поток данных строку текста;
  • void writelnt(int v) - производит запись в выходной поток данных значения типа int (четыре байта);
  • void writeLong (long v) - производит запись в выходной поток данных значения типа long (восемь байт);
  • void writeShort (int v) - производит запись в выходной поток данных значения типа short (два байта);
  • void writeUTF (String str) - записывает строку текста в выходной поток данных.

Константа

  • protected OutputStream out - выходной поток данных.

2.3.7. КлассInputStream

Абстрактный класс, предназначенный для работы с входным потоком байт.

Конструктор

  • InputStream() - Конструктор абстрактного класса InputStream.

Методы

  • int available () - возвращает доступное количество байт для чтения из входного потока;
  • void close () - закрывает входной поток;
  • void mark(int readlimit) - маркирует заданную позицию в входном потоке;
  • boolean markSupported () - проверяют объекты на поддержку установки и сброса маркера;
  • abstract read ()- производит чтение каждого последующего байта во входном потоке данных;
  • int read (byte [ ] b) - производит чтение байт из массива во входном потоке данных;
  • intread (byte [] b, int off, int len) - читает определенный байт, указанный в параметре len из параметра b входного потока данных;
  • void reset() - сбрасывает позицию маркера;
  • long skip (long n) - пропускает заданные байты входного потока.

2.3.8. Класс InputStreamReader

Наследуется от класса Reader, реализуя Методы для чтения символьных данных входного потока с перекодировкой.

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

  • InputStreamReader (InputStream is) — создает объект класса InputStreamReader, используя кодировку по умолчанию;
  • InputStreamReader(InputStream is String enc)-создает объект класса InputStreamReader, используя кодировку, заданную в параметре еnс.

Методы

  • void close() - закрывает поток;
  • void mark(int readAheadLimit) - маркирует позицию в потоке;
  • boolean markSupported() - определяет поддержку маркировки и сброса позиции в потоке;
  • int read () - производит чтение символа;
  • int read(char[] cbuf, int off., int len)- про изводит чтение символа в массив;
  • boolean ready () - определяет готовность потока на чтение данных из него;
  • void reset () - сбрасывает позицию маркера;
  • long skip (long n) - пропускает заданные символы.

2.3.9. Класс OutputStream

Абстрактный класс, предназначенный для работы с выходным потоком байт.

Конструктор

  • OutputStream () - Конструктор абстрактного класса OutputStream.

Методы

  • void close () - закрывает выходной поток;
  • void flush () - осуществляет сброс выходного потока;
  • void write (byte [] b) - записывает массив байт в выходной поток;
  • void writelbyte[] b, int off, int len) - производит запись определенных байт указанных в параметре len из параметра b выходного потока;
  • abstract void write (int b) - записывает определенный байт в выходной поток.

2.3.10. Класс OutputStreamWriter

Наследуется от класса Writer, реализуя Методы для записи символьных данных в выходной поток с перекодировкой. Конструкторы

  • OutputStreamWriter (OutputStream os) - создает объект OutputStreamWriter, используя кодировку по умолчанию;
  • OutputStreamWriter (OutputStream os, String enc) -создает объект OutputStreamWriter, используя кодировку, заданную в параметре еnс.

Методы

  • void close () - закрывает поток данных;
  • void flush () - сбрасывает поток данных;
  • void write (chart] cbuf, int off, int len) - производит запись определенных символов указанных в параметре len из параметра b выходного потока;
  • void write (int с) - записывает один символ;
  • void write (String str, int off, int len) - производит запись определенной части строки текста указанной в параметре len из параметра b выходного потока;

2.3.11. Класс PrintStream

Расширяет выходной поток способностью печати данных.

Конструктор

  • PrintStream (OutputStream out) - формирует объект класса Print -Stream, отвечающий за создание нового потока печати.

Методы

  • boolean checkError () - проверяет состояние потока;
  • void close() - закрывает поток данных;
  • void flush () - сбрасывает поток данных;
  • void print {boolean b) - производит печать логического значения;
  • void print (char с) - производит печать значения типа char;
  • void print (chart] s)-производит печать массива символов;
  • void print (int i) - производит печать значения типа int;
  • void print (long 1) - производит печать значения типа long;
  • void print (Object obj ) - производит печать объекта;
  • void print (String s) - производит печать строки текста;
  • void printlri() - производит печать, заканчивая переводом на новую строку;
  • void println (boolean x) - производит печать логического значения, заканчивая печать переводом на новую строку;
  • void println (char x) - производит печать значения типа char, заканчивая печать переводом на новую строку;
  • void println (char tx) - производит печать массива символов, заканчивая печать переводом на новую строку;
  • void println (int x) - производит печать значения типа int, заканчивая печать переводом на новую строку;
  • void println (long x) - производит печать значения типа long, заканчивая печать переводом на новую строку;
  • void println (Object x) - производит печать объекта, заканчивая печать переводом на новую строку;
  • void println (String x) - производит печать строки текста, заканчивая печать переводом на новую строку;
  • protected void setError() - приводит поток, содержащий некоторые ошибки к состоянию true;
  • void write(byte[]'buf, int off, int len) - производит запись определенных байт указанных в параметре len из параметра b потока печати;
  • void write (int b) - записывает байт в поток печати.

2.3.12. Класс Reader

Абстрактный класс, предназначенный для чтения символьных потоков данных.

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

  • protected Reader () - создает новый поток для чтения;
  • protected Reader (Object lock) - создает новый поток для чтения, синхронизирующийся с параметром lock.

Методы

  • abstract void close () - закрывает поток данных;
  • void mark (int readAheadLimit) - маркирует определенную позицию в потоке;
  • boolean markSupported() - проверяет поддержку маркировки и сброса позиции в потоке;
  • int read () - производит чтение символа;
  • int read (char[] cbuf) - производит чтение массива символов;
  • abstract int read(char[] cbuf, int off, int len) - Производит чтение в массив;
  • boolean ready() - определяет готовность потока для чтения данных;
  • void reset () - сбрасывает позицию маркера;
  • long skip (long n) - пропускает заданные символы.

Константа

  • protected Object lock - используется при синхронизации определенных действий в потоке.

2.3.13. Класс Writer

Абстрактный класс, предназначенный для записи символьных данных в выходной поток.

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

  • protected Writer () - создает новый символьный поток для записи данных;
  • protected Writer (Object lock) - создает новый символьный поток для записи данных»синхронизирующийся с параметром lock.

Методы

  • abstract void close () - закрывает поток данных;
  • abstract void flush() - сбрасывает поток данных;
  • void write (char [] cbuf) — производит запись в массив символов;
  • abstract void write(char[] cbuf, int off, int len)-совершает запись заданной части массива символов;
  • void write (int с) - записывает один единственный символ;
  • void write(String str) - записывает строку текста;
  • void write(String str, int off, int len) - совершает запись заданной части строки текста.

Константа

  • protected Object lock - используется при синхронизации определенных действий в потоке.

2.3.14. Исключения

  • EOFException - сигнализируете конце файла;
  • interruptedIOException - сигнализирует о прерванном действии по вводу-выводу;
  • IOException - указывает на исключение ввода вывода;
  • UnsupportedEncodingException - указывает на невозможность перекодировки;
  • UTFDataFormat Except ion - сигнализирует о прочтении строки формата UTF-8.


2.4. Пакет javax.microedition.io

Этот пакет обеспечивает мобильное устройство связью с сетью.

2.4.1. Интерфейс CommConnection

Находит последовательный порт.

Методы

  • int getBaudRate () - получает скорость передачи данных в бодах для связи;
  • int setBaudRate (int baudrate) - устанавливает скорость передачи данных в бодах для связи.

2.4.2. Интерфейс Connection

Общий тип всей связи с сетью.

Метод

  • void close () - закрывает имеющуюся связь с сетью.

2.4.3. Интерфейс ContentConnection

Определяет связь с потоком.

Методы

  • String getEncoding () - определяет кодировку потока;
  • long getLength () - возвращает продолжительность соединения; ,
  • String getType () - возвращает тип соединения.

2.4.4. Интерфейс Datagram

Общий интерфейс дейтограммы.

Методы

  • String getAddress () - получает адрес дейтограммы;
  • byte[] getData () - получает данные;
  • int getLength () - получает продолжительность соединения;
  • int getOffset() - получает смещение;
  • void reset () - производит сброс или обнуление указателей для чтения и записи;
  • void setAddress (Datagram reference) - устанавливает адрес дейтограммы, взятый с другой выбранной дейтограммы;
  • void setAddress (String addr) - устанавливает адрес дейтограммы;
  • void setData(byte[] buffer, int offset, int len) -устанавливает в буфере смещение и длину;
  • void setLength (int len) - устанавливает длину.

2.4.5. Интерфейс DatagramConnection

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

Методы

  • int getMaximumLength () - получает максимальную длину дейтограммы;
  • int getNominalLength () - получает номинальную длину дейтограммы;
  • Datagram newDatagram(byte[] buf, int size) - создает новый объект дейтограммы с указанным размером буфера;
  • Datagram newDatagram(byte [ ] buf, int size, String addr) -создает новый объект дейтограммы с указанным размером буфера и адресом ввода-вывода;
  • Datagram newDatagram(int size) - создает новый объект дейтограммы определенного размера;
  • Datagram newDatagram(int size, String addr) - создает новый объект дейтограммы определенного размера и с указанием адреса ввода-вывода;
  • void receive (Datagram dgram) — принимает дейтаграмму;
  • void send (Datagram dgram) - отсылает дейтаграмму.

2.4.6. Интерфейс HttpConnection

Декларирует Методы и Константы для протокола соединения HTTP.

Методы

  • long getDate() - возвращает данные;
  • String getFilef) - возвращает часть файла по адресу URL;
  • String getHeaderField(int n) - возвращает заголовок файла по индексу;
  • String getHeaderField(String name) -возвращает заголовок файла по названию;
  • long getHeaderFieldDate(String name, long def) -возвращает значение заданного поля.для даты;
  • int getHeaderFieldlnt(String name, int def)-возвращает значение заданного поля для номера;
  • String getHeaderFieldKey (int n) - получает файл заголовка по ключу;
  • String getHost() - возвращает информацию о соединении;
  • long getLastModified() - возвращает значение модифицированного заголовка;
  • int getPort () - возвращает номер порта соединения;
  • String getProtocol () - возвращает имя протокола;
  • String getQuery() - возвращает запрос на соединение;
  • String getRequestMethqcK ) - определяет текущий метод произведенного запроса;
  • String getRequestProperty (String key) - возвращает свойства запроса для соединения;
  • irit getResponseCode()- возвращает код состояния протокола HTTP;
  • String getResponseMessage () - возвращает сообщение о коде состояния протокола HTTP;
  • String getURL () - возвращает адрес соединения;
  • void setRequestMethodf String method) - задает метод для запроса адреса;
  • void setRequestProperty (String key, String value) -устанавливает свойства производимого запроса.

Константы

  • static String GET - метод соединения по протоколу HTTP;
  • static String HEAD- основной метод соединения по протоколу HTTP;
  • static int HTTP_ACCEPTED - запрос принят, но не был обработан;
  • static int HTTP_BAD_GATEWAY - недопустимый ответ от сервера;
  • static int HTTP_BAD_METHOD - не позволительный метод для запроса;
  • static int HTTP_BAD_REQUEST - запрос не был принят;
  • static int HTTP_CLIENT_TIMEOUT - запрос не произведен в момент ' связи с сервером;
  • static int HTTP_CONFLICT - запрос не закончен из-за конфликта;
  • static int HTTP_CREATED - запрос произведен;
  • static int HTTP_ENTITY_TOO_LARGE-отказ обработки запроса из-за большого размера;
  • static int HTTP_EXPECT_FAILED - запрос ожидания не выполнен;
  • static int HTTP_FORBIDDEN - запрос принят, но выполнен не будет;
  • static int HTTP_GATEWAY_TIMEOUT-сервер не получил своевременный ответ;
  • static int HTTP_GONE - затребованный ресурс не найден;
  • static int HTTP_INTERNAL_ERROR - неожиданная ошибка на сервере;
  • static int HTTP_LENGTH_REQUIRED - отказ от приема запроса.

2.4.7. Интерфейс HttpsConnection

Декларирует Методы и Константы для безопасного сетевого соединения.

Методы

  • int get Port ()- возвращает сетевой номер порта для соединения;
  • Securitylnfo getSecuritylnfo ()-получает информацию о безопасности связи.

2.4.8. Интерфейс InputConnection

Интерфейс для создания входной связи с сетью.

Методы

  • DatalnputStream openData!nputStream() - открывает и возвращает поток ввода данных для конкретного соединения;
  • InputStream openlnputstream ()- открывает ^возвращает входной поток для конкретного соединения.

2.4.9. Интерфейс OutputConnection

Интерфейс для создания выходной связи с сетью.

Методы

  • DataOutputStream openDataOutputStream() - открывает и возвращает поток вывода данных для конкретного соединения;
  • OutputStream open0utputstream() - открывает и возвращает выходной поток для конкретного соединения.

2.4.10. Интерфейс SecureConnection

Определяет безопасную связь с сетью.

Метод

  • Securitylnfo getSecuritylnfo ()-получает информацию о безопасности связи.

2.4.11. Интерфейс Securitylnfo

Имеет в своем составе методы для получения информации сетевой связи.

Методы

  • String getCipherSuite () - возвращает название используемого шифра связи;
  • String getProtocolName () - получает имя используемого протокола соединения;
  • String ge.tProtocolVersion () - получает версию используемого протокола;
  • Certificate getServerCertif icate () - осуществляет возврат сертификата безопасности соединения.

2.4.12. Интерфейс ServerSocketConnection

Реализует связь с сервером.

Методы

  • St-ring getLocalAddress () - получает локальный адрес связи с разъемом (socket);
  • int getLocal Port ()-получает локальный адрес связи с портом.

2.4.13. Интерфейс SocketConnection

Находит разъем (socket) для потока связи.

Методы

  • String getAddress () - получает адрес связи;
  • String getLocalAddress() - получает локальный адрес связи;
  • int getLocalPort () - получает локальный порт соединения;
  • int getPort() - получает порт соединения;
  • int getSocketOption (byte option) - получает необходимую опцию разъема для создания соединения;
  • void setSocketOption (byte option, int value) -устанавливает необходимую опцию разъема для создания соединения.

Константы

  • static byte DELAY - опция малого разъема (0);
  • static byte KEEPALIVE-опция поддержки особенностей разъема (2);
  • static byte LINGER - опция ждущего режима обработки вывода данных (1);
  • static byte RCVBUF - опция для определенного буфера получения (3);
  • static byte SNDBUF - опция для определенного буфера отправки (4).

2.4.14. Интерфейс StreamConnection

Этот интерфейс определяет связь с потоком и не имеет методов и констант.

2.4.15. Интерфейс StreamConnectionNotifier

Определяет возможность всей связи.

Метод

  • StreamConnection acceptAndOpen () - возвращает разъем сервера, с которым произошло соединение.

2.4.16. Интерфейс UDPDatagramConnecJion

Реализует связь с дейтограммой.

Методы

  • String getLocalAddress () - получает локальный адрес связи с дейтограммой;
  • int getLocalPort () - получает локальный порт связи с дейтаграммой.

2.4.17. Класс Connector

Класс для создания объектов связи.

Методы

  • static Connection open(String name) - создает и открывает соединение;
  • static Connection open(String name, int mode) - создает и открывает соединение по адресу и режиму соединения;
  • static Connection open(String name, int mode, boolean timeout s) - создает и открывает соединение по адресу, режиму соединения и исключения времени ожидания связи;
  • static DatalnputStream openDatalnputStream(String name) — -создает и открывает входной поток данных;
  • static DataOutputStream openDataOutputStream(String name) - создает и открывает выходной поток данных;
  • static InputStream open!nputStream(String name) -создает и открывает входной поток;
  • static OutputStream openOutputStream(String name)-создает и открывает выходной поток.

Константы

  • static int READ - режим доступа только для чтения данных;
  • static int READ_WRITE - режим доступа для чтения и записи данных;
  • static int WRITE - режим доступа только для записи данных;

2.4.18. Класс PushRegistry

Класс для поддержания списков связей.

Методы

  • static String getFilter(String connection) - получает заданный фильтр соединения;
  • static String getMIDlet(String connection) - получает заданный мидлет (MIDlet) для соединения;
  • static String[] listConnections(boolean available) -возвращает весь список подключений для комплекта мидлетов (MIDlet suite);
  • static long registerAlarm(String midlet, long time) -производит установку времени для запуска приложения;
  • static void registerConnection(String connection, String midlet, String filter) - производит установку времени для запуска соединения;
  • static boolean unregisterConnection(String connection) -удаляет регистрацию соединения.

2.4.19. Исключение

  • ConnectionNotFoundException - указывает на отсутствие связи.


2.5. Пакет javax.microedition.lcdui

Пакет классов пользовательского интерфейса (UI) для создания полей, форм, уведомлений, текста и так далее.

2.5.1. Интерфейс Choice

Содержит набор методов создающих возможность выбора заданных элементов

Методы

  • int append (String str.ingPart, Image imagePart) - добавляет элемент к набору элементов в конец всего имеющегося списка элементов;
  • void delete (int elementNum) - удаляет элемент по заданному номеру;
  • void deleteAll() - удаляет все элементы;
  • int getFitPolicy () - предоставляет предпочтительную экранную позицию;
  • Font getFont (int elementNum) - получает шрифт для элемента заданного по номеру;
  • Image getlmagetint elementNum) - получает изображение для элемента заданного по номеру;
  • int getSelectedFlags(boolean[] selectedArray_return) -производит запрос на состояние элементов массива;
  • int getSelectedlndex () - получает выбранный индекс элемента;
  • String getString (int elementNum) - получает строку текста по заданному номеру;
  • void insert(int elementNum, String stringPart, Image imagePart) - производит вставку элемента по заданному номеру в набор имеющихся элементов;
  • boolean .isSelected (int elementNum) - получает логическое значение, определяющее выбор того или иного элемента из набора элементов;
  • void set(int elementNum, String stringPart, Image image Part) - устанавливает новую строку текста с изображением по заданному номеру, заменяя предыдущую запись;
  • void setFitPolicy (int fitPolicy) - устанавливает предпочтительную экранную позицию;
  • void setFont(int elementNum, Font font) - устанавливает шрифт для заданного элемента;
  • void setSelectedFlags(boolean[] selectedArray)-устанавливает состояние элементов массива;
  • void setSelectedlndex(int elementNum, boolean selected) -устанавливает состояние элемента;
  • int size() - определяет количество элементов в наборе элементов.

Константы

  • static int EXCLUSIVE - эксклюзивный выбор;
  • static int IMPLICIT - неявный выбор;
  • static int MULTIPLE - множественный выбор;
  • static int POPUP - всплывающий вид выбора;
  • static int TEXT_WRAP_DEFAULT - текстовое сопровождение элемента будет находиться по умолчанию;
  • static int TEXT_WRAP_OFF - текстовое сопровождение элемента должно находится на одной строке;
  • static int TEXT_WRAP_ON - текстовое сопровождение элемента находится на любом количестве строк.

2.5.2. Интерфейс CommandListener

Реализует возможность обработчика событий.

Метод

  • void commandAct ion (Command c, Displayable d) -обработчик событий.

2.5.3. Интерфейс ItemCommandListener

Реализует возможность получения событий от объектов класса Item.

Метод

  • void commandAct ion (Command с, Item item) - обработчик событий.

2.5.4. Интерфейс ItemStateListener

Используется при получении событий о состоянии объектов класса Item устроенных в Form.

Метод

  • void itemStateChanged(item item) - определяет состояние объекта класса Item.

2.5.5. Класс Alert

Создает различные информационные сообщения.

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

  • Alert (String title) - создает пустое уведомление с заголовком;
  • Alert(String title, String alertText, Image alertlmage, AlertType alertType) - создает уведомление с заголовком, текстом, изображением и типом уведомления. :

Методы

  • void addCommand(Command cmd) - добавляет команду;
  • int getDefaultTimeout () - получает время для представления уведомления;
  • Image get Image () - получает изображение для экрана, представленного классом Alert;
  • Gauge getlndicator () —этот метод позволяет воспользоваться графическим измерителем класса Gauge;
  • String getstring()- получает текстовую строку;
  • int getTimeout () - получает заданное время для представления уведомления;
  • AlertType getType() - определяет тип используемого уведомления;
  • void removeCommand (Command cmd) - удаляет команду;
  • void setCommandLis'tener (CommandListener 1) - устанавливает обработчик событий;
  • void setlmage (Image img) — устанавливает изображение;
  • void setlndicator (Gauge indicator) - устанавливает индикатор измерителя для использования класса Gauge;
  • void setstring (String str) - устанавливает строку текста;
  • void setTimeout (int time) - устанавливает время;
  • void setType (AlertType type) - устанавливает тип уведомлений или информационных сообщений.

Константы

  • static Command DISMISS_COMMAND - команда отклонена;
  • static int FOREVER - определяет постоянный показ уведомления.

2.5.6. Класс AlertType

Отображает тип уведомления.

Конструктор

  • protected AlertType () - закрытый Конструктор подкласса.

Метод

  • boolean playSound (Display display) - воспроизводит звук. Константы ;
  • static AlertType ALARM - тревога;
  • static AlertType CONFIRMATION - подтверждение;
  • static AlertType ERROR - ошибка;
  • static AlertType INFO - информация;
  • static AlertType WARNING - предупреждение.

2.5.7. Класс Canvas

Абстрактный класс, обеспечивающий графическую прорисовку различных элементов на экране телефона.

Конструктор

  • protected Canvas () - создает новый объект класса Canvas.

Методы

  • int getGameAction (int keyCode) -связывает игровые действия с заданным ключевым кодом;
  • int getKeyCode (int gameAct ion) -получает ключевой код игровых действий;
  • String getKeyName (int keyCode) - получает ключевой код для клавиши;
  • boolean hasPointerEvents () - проверяет устройство на поддержку работы с указателем;
  • boolean hasPointerMotionEvents () - проверяет поддержку устройством перемещения указателя;
  • boolean hasRepeatEvents () - проверяет устройство на поддержку работы с повторными событиями; :
  • protected void hideNotify ()- выполняет запрос после удаления объекта класса Canvas с дисплея;
  • boolean isDoubleBuff ered()- осуществляет двойную буферизацию;
  • protected void keyPressed(int keyCode) - вызывается при нажатии клавиши;
  • protected void keyReleased (int keyCode) - вызывается при отпускании нажатой клавиши;
  • protected void keyRepeated(int keyCode) - повторное нажатие клавиши;
  • protected abstract void paint(Graphics g) - прорисовка или рендеринг графики на экране телефона;
  • protected void pointerDragged(int x, int у) -определяет перемещение курсора;
  • protected void pointerPressedfint x, int у) -определяет позицию курсора, в которой должно производится нажатие определенной клавиши;
  • protected void pointerReleased(int x, int у) -определяет позицию курсора в момент отпускания определенной клавиши;
  • void repaint () - повторяет прорисовку;
  • void repaint(int x, int у, int width, int height) —повторяет прорисовку заданной области;
  • void serviceRepaints () - повтор прорисовки дисплея;
  • void setFullScreenMode(boolean mode) - контроль над полноэкранным режимом отображения;
  • protected void showNotify() - выполняет запрос до вывода объекта класса Canvas на дисплей;
  • protected void sizeChanged(int w, int h) - изменяет размер.

Константы

  • static int DOWN - движение вниз;
  • static int FIRE - обычно используется в играх и реализует стрельбу из оружия;
  • static int GAME_A - игровая клавиша А;
  • static int GAME_B - игровая клавиша В;
  • static int GAME_C - игровая клавиша С;
  • static int GAME_D - игровая клавиша D;
  • static int KEY_NUM0 - клавиша 0;
  • static int KEY_NUM1-клавиша 1;
  • static int KEY_NUM2 - клавиша 2;
  • static int KEY_NUM3 - клавиша 3;
  • static int KEY_NUM4 - клавиша 4;
  • static int KEY_NUM5 - клавиша 5;
  • static int KEY_NUM6 - клавиша 6;
  • static int KEY_NUM7 - клавиша 7;
  • static int KEY_NUM8 - клавиша 8;
  • static int KEY_NUM9 - клавиша 9;
  • static int KEY_POUND - клавиша #;
  • static int KEY_STAR - клавиша *;
  • static int LEFT - движение влево;
  • static int RIGHT - движение вправо;
  • static int UP - движение вверх.

2.5.5. Класс ChoiceGroup

Встраиваемая группа выбираемых, элементов. Интегрируется в класс Form, наследуется от класса Item и реализует интерфейс Choice.

Конструктор

  • ChoiceGroup (String label, int choiceType) - создает пустой список элементов группы, определяя заголовок и тип группы элементов;
  • ChoiceGroup(String label, int choiceType, String[] string-Elements, Image [] imageElements) - создает группу элементов, определяя заголовок, тип группы элементов, текст и изображение для каждого элемента группы.

Методы

  • int append (String stringPart, Image imagePart) -добавляет элемент в группу;
  • void delete {int elementNum) - удаляет заданный элемент из группы;
  • void deleteAll() — удаляет все элементы;
  • int. getFitPolicy () - предоставляет предпочтительную экранную позицию;
  • Font getFont(int elementNum) - получает используемый шрифт элемента группы;
  • Image getlmage (int elementNum) - получает изображение для элемента группы;
  • int getSelectedFlags(boolean[]selectedArray_return) - возвращает значение Boolean для группы элементов;
  • int getSelectedlndex () - возвращает индекс выбранного элемента группы;
  • String getString (int elementNum) - получает строку текста по номеру;
  • void insert(int elementNum,String stringPart,Image imagePart) - вставляет элемент в группу;
  • boolean isSelected (int elementNum) - получает выбранную логическую величину;
  • void set(int elementNum, String stringPart, Image imagePart) - устанавливает текст и изображение в заданный элемент группы, при этом удаляя предыдущую запись;
  • void setFitPolicy (int fjtPolicy) - устанавливает предпочтительную экранную позицию;
  • void setFonttint elementNum, Font font) - устанавливает шрифт заданному элементу;
  • void setSelectedFlags(boolean[] selectedArray) — устанавливает состояние элементов группы;
  • void setSelected!ndex(int elementNum, boolean selected) -устанавливает особое состояние для элемента группы при использовании множественного типа;
  • int size () - возвращает количество используемых элементов группы.

2.5.9. Класс Command

Инкапсулирует командные действия, при этом не определят фактические действия на команды, а лишь содержит информацию.

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

  • Command(String label, int commandType, int priority) -создает команду для дальнейшей обработки. Команда содержит: название, тип и приоритет выполнения;
  • Command (String sho.rtLabel, String longLabel, int commandType, int priority) — создает команду для дальнейшей обработки. Команда содержит: короткое и длинное название, тип и приоритет выполнения.

Методы

  • int getCommandType () - получает тип используемой команды;
  • String getLabel() - получает метку или название команды;
  • String getLongLabel () — получает длинную метку или название команды;
  • int get Priority () - получает установленный приоритет команды.

Константы .

  • static int BACK - назад;
  • static Int CANCEL - отмена;
  • static int EXIT - выход;
  • static int HELP - помощь;
  • static int ITEM - новый экран, ассоциирующийся с экраном от которого происходит переход;
  • static int OK - хорошо;
  • static int SCREEN - новый экран;
  • static int STOP - стоп.

2.5.10. Класс Custom Item

Создает возможность в отображении новых графических элементов встроенных в класс Form.

Конструктор

  • protected Customltem( String label) - Конструктор абстрактного класса Customltem.

Методы

  • int getGameAction(int keyCode) - получает игровые действия по коду клавиши телефона;
  • protected int getlnteractionModes() - получает все доступные режимы взаимодействия;
  • protected abstract int getMinContentHeight() - получает минимальную высоту заданной области дисплея;
  • protected abstract int getMinContentWidth() -получает минимальную ширину заданной области дисплея;
  • protected abstract int getPrefContentHeight(int width) -получает предпочтительную высоту заданной области дисплея;
  • protected abstract int getPrefContentWidth(int height) -получает предпочтительную ширину заданной области дисплея;
  • protected void hideNotify () - уведомляет о недоступности;
  • protected void invalidate () - сигнализирует об изменении размера или местонахождения элемента;
  • protected void key Pressed (int keyCode)-обрабатывает нажатие клавиши;
  • protected void keyReleased(int keyCode) - обрабатывает отпускание клавиши;
  • protected void keyRepeated(int keyCode) - обрабатывает повторное нажатие клавиши;
  • protected abstract void paint(Graphics g, int w, int h) -рисует компоненты;
  • protected void pointerDragged(int x, int у) -осуществляет поддержку перьевого ввода;
  • protected void pointerPressed(int x, int у) - в месте установки указателя были произведены действия по нажатию определенной клавиши;
  • protected void pointeirReleased (int x, int у)-в месте установки указателя были произведены действия по отпусканию нажатой клавиши;
  • protected void repaint () - перерисовывает экран;
  • protected void repaint (int x, int y, int w, int h) -перерисовывает заданную область экрана;
  • protected void showNotify() - уведомление о возможности получения действий;
  • protected void sizeChanged (int w, int h) - изменяет размер.

Константы

  • protected static int KEY_PRESS - нажатие клавиши;
  • protected, static int KEY_RELEASE - отпускание клавиши;
  • protected static int KEY_RE'PEAT - повторное нажатие клавиши;
  • protected static int NONE - нет действий;
  • protected static int POINTER_DRAG - перетаскивание; .
  • protected static int POINTER_PRESS - указатель нажат;
  • protected static int POINTER_RELEASE - указатель отпущен;
  • protected static int TRAVERSE_HORIZONTAL - горизонтальный обход;
  • protected static int TRAVERSE_VERTICAL - вертикальный обход.

2.5.11. Класс DateField

Класс, представляющий работу с датой и временем. Интегрируется в класс Form, наследуется от класса Item.

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

  • DateField (String label, int mode) - создает объект класса DateField, с указанием метки и режима отображения объекта;
  • DateField(String label, int mode, TimeZone timeZone) -создает объект класса DateField, с указанием метки, режима отображения объекта и часового пояса.

Методы

  • Date getDate() - возвращает текущую дату;
  • void setDate(Date date) - устанавливает новую дату;
  • int getlnputMode () - получает установленные компоненты DATE, TIME или DATA_TIME;
  • void setlnputMode (int mode) - устанавливает компоненты DATE, TIME или DATE_TIME.

Константы

  • static int DATE - дата;
  • static int DATE_TIME - дата и время;
  • static int TIME - только время.

2.5.12. Класс Display

Менеджер дисплея определяющий, какой из объектов будет представлен на дисплее.

Методы

  • void callSerially(Runnable r) -производит запрос на вызов метода run () для объекта класса Runnable;
  • boolean f lashBacklight (int duration) - создает эффект подсветки;
  • int getBestlmageHeight (int imageType) - получает оптимальную высоту для изображения на экране;
  • int g-etBestlmageWidthfint imageType) - получает оптимальную ширину для изображения на экране;
  • int getBorderStyle (boolean highlighted) - штриховой стиль бордюра;
  • int getColor(int colorSpecif ier) - возвращает цвет;
  • Displayable getCurrent () - получает текущий объект Displayable для используемого мидлета;
  • static Display getDisplay(MIDletm) - получает -уникальный объект Display для используемого мидлета;
  • boolean isColor () - получает информацию о поддержке цвета в мобильном устройстве;
  • int numAlphaLevels () - получает количество альфа-прозрачных уровней;
  • int numColors () - получает количество цветов поддерживаемых мобильным устройством;
  • void setCurrent(Alert alert, Displayable nextDisplayable) - делает видимым на экране объект класса Alert;
  • void setCurrent(Displayable nextDisplayable) - делает видимым на экране последующий объект класса Displayable;
  • void setCurrentltemdtem item) - делает видимым на экране объект класса Item;
  • boolean vibrate (int duration) - запрос на поддержку вибрации.

Константы

  • static int ALERT - тип изображений для уведомлений;
  • static int CHOICE_GROUP_ELEMENT - тип изображения для класса ChoiceGroup;
  • static int COLOR_BACKGROUND - цветовой компонент, используется методом getColor ();
  • static int COLOR_BORDER - цветовой компонент, используется методом getColor();
  • static int COLOR_FOREGROUND - цветовой компонент, используется методом getColor ();
  • static int COLOR_HIGHLIGHTED_BACKGROUND - цветовой компонент, используется методом getColor ();
  • static int COLOR_HIGHLIGHTED_BORDER - цветовой компонент, используется методом .getColor ();
  • static int COLOR_HIGHLIGHTED_FOREGROUND - цветовой компонент, используется методом getColor ();
  • static int LIST_ELEMENT - тип изображения для класса List.

2.5.13. Класс Displayable

Абстрактный класс, содержит иерархию классов пользовательского интерфейса.

Методы

  • void addCommand (Command cmd) — добавляет команду;
  • int get Height () - получает высоту доступной области экрана в пикселях;
  • Ticker getTicker () - получает бегущую строку;
  • String getTitle() - получает заголовок;
  • int getWidth() - получает ширину доступной области экрана в пикселях;
  • boolean isShown() - проверяет видимость объекта на экране;
  • void removeCommand (Command cmd) - удаляет команду;
  • void setCommandListener (CommandListener 1) - устанавливает обработчик событий;
  • void setTicker (Ticker ticker) - устанавливает бегущую строку;
  • void setTitle (String s) - устанавливает заголовок;
  • protected void sizeChanged(int w, int h) - изменяет видимую область дисплея.

2.5.14. Класс Font

Класс шрифтов.

Методы

  • int charsWidth(char[] ch, int offset, int length) - применяется для правильного планирования использования шрифта на экране дисплея;
  • int charWidth (char ch) - получает ширину шрифта;
  • int getBaselinePosition () - вычисляет расстояние от верхней кромки текста до опорной позиции в пикселях;
  • static Font getDefaultFont () - получает системный шрифт, используемый устройством по умолчанию;
  • int getFace () - получает начертание шрифта используемого устройством по умолчанию;
  • static Font getFont(int f ontSpecif ier) - используется классом Customltem для получения специального шрифта;
  • static Font geltFont(int face., int style, int size) -получает шрифт с указанием начертания, стиля и размера;
  • int getHeight () - получает высоту щрифта;
  • int getSize() - получает размер шрифта;
  • int getStyle() - получает стиль шрифта;
  • boolean isBold() - возвращает значение true, если используется Bold;
  • boolean isltalic () - возвращает значение true, если используется Italic;
  • boolean isPlain() - возвращает значение true, если используется Plain;
  • boolean isUnderlined() -возвращает значение true, если используется Underlined;
  • int stringWidth (String str) - устанавливает строку текста;
  • int substringWidth(String str, int offset, int len) -устанавливает подстроку текста.

Константы

  • static int FACE_MONOSPACE - шрифт с небольшим интервалом;
  • static int FACE_PROPORTIANAL - пропорциональный шрифт;
  • static int FACE__SYSTEM - системный шрифт;
  • static int FONT_INPUT_TEXT - текст ввода;
  • static int FONT_STATIC_TEXT - заданный по умолчанию шрифт;
  • static int SIZE_LARGE - большой шрифт;
  • static int SI ZE_MEDIUM - средний шрифт;
  • static int SIZE_SMALL - маленький шрифт;
  • static int STYLE_BOLD - жирный шрифт;
  • static int STYLE_ITALIC - курсив;
  • static int STYLE_PLAIN - обычный шрифт;
  • static int STYLE.JJNDERLINED - подчеркнутый шрифт.

2.5.15. Класс Form

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

  • Form (String title) - создает новую пустую форму;
  • Form(String title, Item[] items) -создает новую форму с заданным заголовком и установленными компонентами класса Item.

Методы

  • int append (Image img) — добавляет в форму одно изображение;
  • int append (Item item) — этот метод добавляет любой из доступных компонентов класса Items созданную форму;
  • int append (String str) - добавляет в форму строку;
  • void delete (int itemNum) - удаляет компонент ссылающийся на itemNum;
  • void deleteAll() - удаляет все компоненты с имеющейся формы;
  • Item get (int itemNum) - получает позицию выбранного компонента;
  • int getHeight () — возвращает высоту экрана в пикселях доступную для встраиваемых компонентов;
  • int getWidth() - возвращает ширину экрана в пикселях доступную для встраиваемых компонентов;
  • void insert (int itemNum, Item item) - вставляет компонент в форму до определенного компонента;
  • void set(int itemNum, Item item) - устанавливает компонент, . ссылающийся на компонент itemNum, заменяя при этом предшествующий компонент;
  • void setltemStateListener(ItemStateListener iListener) - устанавливает переменную iListener для формы, заменяя при этом предыдущую переменную iListener;
  • int size ()-получает количество компонентов в форме.

2.5.16. Класс Gauge

Представляет графическое течение процесса, своего рода датчик или счетчик.

Конструктор

  • Gauge (String label, boolean intera'ctive, int maxValue, int initialValue) - создает графическое течение процесса с заданной меткой, режимом и максимальным и минимальным значением в работе.

Методы

  • void addCommand (Command cmd) - добавляет команду;
  • int getMaxValue () - получает значение максимального диапазона работы процесса;
  • int getValue ()-получает текущее значение в процессе работы;
  • boolean islnteractive () - определяет возможность изменения установленного счетчика;
  • void setDefaultCommand(Command cmd) - задает команду по умолчанию для компонентов Item;
  • void setltemCommandListener(ItemCommandListener 1) —устанавливает обработчик событий;
  • void setLabel (String label) - устанавливает метку для элемента;
  • void setLayout (int layout) - устанавливает директивы для элемента;
  • void setMaxValue (int maxValue) - устанавливает максимальное значение течение процесса;
  • void setPreferredSize(int width, int height) -задает ширину и высоту для графического представления всего течения процесса;
  • void setValuefint value) - устанавливает текущее значение процесса.

Константы

  • static int CONTINUOUS_IDLE - непрерывное и неактивное состояние с неопределенным диапазоном работы;
  • static int CONTINUOUS_RUNNING - непрерывное активное состояние с неопределенным диапазоном работы;
  • static int INCREMENTAL_IDLE - увеличивающееся и неактивное состояние с неопределенным диапазоном работы;
  • static int INCREMENTAL_UPDATING - увеличивающееся и постоянно модифицируемое состояние с неопределенным диапазоном работы;
  • static int INDEFINITE - максимальное значение с неопределенным диапазоном работы.

2.5.17. Класс Graphics

Предоставляет возможность рисования графических элементов на экране мобильного устройства.

Методы

  • void clipRect(int x, int у, int width, int height) -отсекает заданный прямоугольник;
  • void copyArea(int x_src, - int y_src, int width, int. . height, int x_dest, int y_dest, int anchor) - копирует прямоугольную область из установленных значений в параметрах x_src, y_src, width, height, в новую область x_dest, y_dest;
  • void drawArc(int x, int y, int width, int height, int startAngle, int аrсАngle) - рисует контур дуги в виде эллипса;
  • void drawChar(char character, int x, int y, int anchor) -рисует символ;
  • void drawChars(char[] data, int offset, int length, int x, int y, int anchor) - рисует массив символов;
  • void drawlmage (Image img, int x, int y, int anchor) -рисует изображение;
  • void drawLine (int xl, int yl, int x2 , int y2) -рисует линию из точки x1 и y1 до точки х2 и у2;
  • void drawRegion(Image src, int x_src, int y_src, int width, int height, int transform, int x_dest, int y_dest, int anchor) - копирует изображения в заданную область на экран телефона;
  • void drawRGB(int[] rgbData, int offset, int scanlength, int x, int y, int width, int height, boolean process-Alpha) - получает цвет в представлении ARGB и сохраняет в массиве данных;
  • void drawRoundRect(int x, int у, int width, int height, int arcWidth, int arcHeight) - рисует контур прямоугольника, используя закругленные углы;
  • void drawstring (String str, int x, int y, int anchor) -рисует строку текста с заданным цветом и размером шрифта;
  • void drawSubstring(String str, int offset, int len, int x, int y, int anchor) - рисует подстроку текста с заданным цветом и размером шрифта;
  • void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) - рисует заполненную цветом дугу;
  • void fillRect(int x, int y, int width, int height)-рисует заполненный цветом прямоугольник;
  • void fillRoundRect(int x, int y, int width, int height, int arcWidth, i-nt arcHeight) - рисует заполненный прямоугольник, используя закругленные углы;
  • void fillTriangle(int x1, int y1, int x2 , int y2 , int х3, int у3) - рисует заполненный цветом треугольник;
  • int getBlueCompone.nt () - получает синий компонент цвета;
  • int g_etClipHeight () - получает высоту для текущей области отсечения;
  • int getClipWidth () - получает ширину для текущей области отсечения;
  • int getClipX() - получает координату по оси X для текущей области отсечения;
  • int getClipY ()-получает координату по оси Y для текущей области отсечения;
  • int getColor() - получает текущий цвет;
  • int getDisplayColor (int color) - получает цвет для отображения;
  • Font getFont () - получает текущий шрифт;
  • int getGrayScale () - получает значение полутонов;
  • int getGreenComponent () - получает зеленный компонент цвета;
  • int getRedComponent () - получает красный компонент цвета;
  • int getStrokeStyle ()- получает используемый штриховой стиль;
  • int getTranslateX() - получает координату по оси X для перемещенного контекста;
  • int getTranslateY()- получает координату по оси У для перемещенного контекста;
  • void setCliptint x, int y, int width, int height) -устанавливает отсечение заданной области экрана;
  • void s.etColor (int RGB) - устанавливает цвет при помощи значения RGB;
  • void setColor( int red, int green, int blue) - назначает цвет при помощи трех цветовых компонентов red, green и blue;
  • void setF'ont (Font font) - устанавливает заданный шрифт;
  • void setGrayScale (int value) - задает значение полутонов;
  • void setStrokeStyle (int style) - задает штриховой стиль рисуемому контексту, используя Константы SOLID и DOTTED;
  • void translate (int x, int у) - перемещает систему координат в точку (х, у).

Константы

  • static int BASELINE - опорная линия привязки шрифта;
  • static int BOTTOM - нижняя линия привязки шрифта;
  • static int DOTTED - пунктирный стиль;
  • static int HCENTER - центральна линия привязки шрифта;
  • static int LEFT - левая сторона привязки шрифта;
  • static int RIGHT - правая сторона привязки шрифта;
  • static int SOLID - штриховой стиль;
  • static int TOP - верхняя линия привязки шрифта;
  • static int VCENTER - выравнивает по центру изображение.

2.5.18. Класс Image

Отвечает за загрузку и отображение любых видов графических изображений формата PNG.

Методы

  • static Image createlmage(byte[] imageData, int image-Offset, int imageLength) - загружает изображение, учитывая смещение и длину в байтах;
  • static Image createlmage (Image source) - загружает изображение из файла;
  • static. Image createlmage(Image image, int x, int y, int width, int height, int transform) - загружает изображение в заданное место, определенное координатами с возможностью трансформации изображения;
  • static Image createlmage (InputStream stream) —загружает изображение из потока;
  • static Image createlmage(int width, int height) -загружает изображение в заданные размеры;
  • static Image createlmage (String name) - загружает изображение из ресурса;
  • static Image createRGBImage(int[] rgb, int width, int height, boolean processAlpha) - загружает изображение, учитывая цветовую компоненту ARGB;
  • Graphics getGraphics ()- создает графический объект для представления изображения;
  • int getHeight () - получает высоту изображения;
  • void getRGB(int[] rgbData, int offset, int scanlength, int x, int y, int width, int height) - получает цвет в представлении ARGB и сохраняет в массиве данных;
  • int getWidth() - получает ширину изображения; .
  • boolean isMutable() - проверяет изображение.

2.5.19. Класс Imageltem

Контейнер для загружаемых в приложение сложных графических изображений

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

  • ImageItem(String label, Image img, int layout, String altText) - создает объект класса Imageltem с заданной меткой, изображением, размещением и дополнительной строкой текста;
  • Imageltem(String label, Image image, int layout, String altText, int appearanceMode) - создает объект класса ImageItem с заданной меткой, изображением, размещением, дополнительной строкой текста, и режимом представления.

Методы

  • String getAltText () - размещает текст;
  • int getAppearanceMode () - возвращает режим представления;
  • Image getlmage() - получает изображение;
  • int getLayout () - получает директивы для размещения изображений;
  • void set AltText (String text) -устанавливает дополнительный текст;
  • void setlmage (Image img) - устанавливает изображение;
  • void setLayout (int layout) - устанавливает директивы для размещения изображений'.

2.5.20. Класс Item

Суперкласс, содержащий ряд классов для их дальнейшей интеграции в класс Form.

Методы

  • void addCommand (Command cmd) - добавляет команду;
  • String getLabel() - получает метку объекта Item;
  • int getLayout () - использует директивы для размещения компонентов в форме;
  • int getMinimumHeight () - получает минимальную высоту;
  • int getMinimumWidth () - получает минимальную ширину;
  • int getPref erredHeight ()- получает предпочтительную высоту;
  • int getPreferre.dWidth() - получает предпочтительную ширину;
  • void notifyStateChanged() - компонент, содержащийся в форме. Уведомляет объект ItemStateListener о своем состоянии;
  • void removeCommand (Command cmd) - удаляет команду из компонента.
  • void setDefaultCommand (Command cmd) - встроенная команда по умолчанию для данного компонента;
  • void setltemCommandListener (ItemCommandListener 1) —устанавливает обработку событий для компонента;
  • void setLabel (String label) - устанавливает назначенную метлу для компонента;
  • void setLayout (int layout) - устанавливает рассмотренные выше директивы для форматирования компонента;
  • void setPref erredSize (int width, int height) -устанавливает оптимальную высоту и ширину компонента.

Константы

  • static int BUTTON - отображение элемента в виде кнопки;
  • static int HYPERLINK - отображение элемента в виде гиперссылки;
  • static int LAYOUT_2 - режим установки;
  • static int LAYOUT_BOTTOM - выравнивание по нижней стороне экрана;
  • static int LAYOUT_CENTER - выравнивание по центру экрана;
  • static int LAYOUT_DEFAULT - значение по умолчанию;
  • static int LAYOUT_EXPAND - увеличение ширины компонента;
  • static int LAYOUT_LEFT - выравнивание по левой стороне экрана;
  • static int LAYOUT_NEWLINE_AFTER - размещение на новой строке;
  • static int LAYOUT_NEWLINE_BEFORE - размещение в начале строки;
  • static int LAYOUT_RIGHT - выравнивание по правой стороне экрана:
  • static int LAYOUT_SHRINK - уменьшение компонента по ширине;
  • static int LAYOUT_TOP - выравнивание по верхней стороне экрана;
  • static int LAYOUT_VCENTER - выравнивание по центру экрана;
  • static int LAYOUT_VEXPAND - увеличение высоты для размещения компонента;
  • static int LAYOUT_VSHRINK - уменьшение высоты для размещения компонента;
  • static int PLAIN - установка режима появления первого плана для компонента.

2.5.21. Класс List

Создает список группы элементов.

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

  • List (String title, int listType) - формирует список с названием и типом созданного списка;
  • List(String title, int .listType, String[] stringElements, Image [] imageElements) - формирует список с названием, типом созданного списка, массивом строк и изображений для списка элементов.

Методы

  • int append(String stringPart, Image imagePart)-добавление списка элементов;
  • void delete (int elementNum) -удаление заданного элемента из списка;
  • void deleteAll() - удаление всех элементов из списка;
  • int getFitPolicy() - получает привилегированную позицию;
  • Font getFont(int elementNum) - получает шрифт для заданного элемента в списке;
  • Image getlmage(int elementNum) - получает изображение для заданного элемента в списке;
  • int getSelectedFlags(boolean[] selectedArray_return) -возвращает состояние всех элементов в виде массива данных;
  • int getSelectedIndex() - получает выбранный индекс элемента в списке;
  • String getString (int elementNum) - получает строку текста для выбранного элемента из списка;
  • void insert(int elementNum, String stringPart, Image image-Part ) - вставляет элемент в список до указанного номера элемента в списке.
  • boolean isSelected(int elementNum) - получает выбранный элемент из списка;
  • void removeCommand(Cqmmand cmd) - удаляет команду для списка;
  • void set(int elementNum, String stringPart, Image image-Part ) - вставляет новый элемент в список взамен предшествующего;
  • void setFitPolicy (int fitPolicy) - устанавливает привилегированную позицию;
  • void setFont(int elementNum, Font font) - устанавливает шрифт заданному элементу в списке;
  • void setSelectCommand(Command command) - этот метод предназначен для работы с типом IMPLICIT;
  • Void setSelqctedFiags(boolean[] selectedArray)-устанавливает состояние выбранных элементов;.
  • void setSelectedlndex(int elementNum, boolean selected) -устанавливает индекс выбранного элемента в списке;
  • void setTicker (Ticker ticker) - устанавливает бегущую строку;
  • void setTitle (String s) - добавляет название;
  • int size() -с помощью этого метода можно узнать количество элементов в списке.

Константа

  • static Command SELECT_COMMAND - команда по умолчанию для типа IMPLICIT.

2.5.22. Класс Screen

Суперкласс для всех высокоуровневых классов определяющих пользовательский интерфейс приложения.

2.5.23. Класс Spacer

Создает заданное пространство на экране.

Конструктор

  • Spacer (int minWidth, int minHeight) - создает пространство на экране с заданной шириной и высотой.

Методы

  • void addCommand( Command cmd) - добавляет команду;
  • void setDefaultCommand(Command cmd) - устанавливает команду по умолчанию;
  • void setLabel (String label) - устанавливает метку;
  • void setMinimumSize(int minWidth, int minHeight) -устанавливает минимальный размер для создаваемого пространства.

2.5.24. Класс String Item

Формирует текстовые строки.

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

  • Stringltem( String label, String text) - создает строку текста с заданной меткой;
  • Stfingltem(String label. String text, int appearanceMode) - создает строку текста с заданной меткой и режимом отображения.

Методы

  • int getAppearanceMode () - возвращает заданный способ отображения текста на экране;
  • Font getFont () - получает шрифт текста;
  • String getText () - получает текст для класса Stringitem;
  • void setFont(Font font) - устанавливает шрифт текста;
  • void setPreferredSize(int width, int height) - задает ширину и высоту текста;
  • void setText (String text) - устанавливает текст для класса Stringitem.

2.5.25. Класс TextBox

Организовывает редактируемый текстовый контейнер.

Конструктор

  • TextBox (String title, String text, int maxSize, ir.u constraints) - создает текстовый контейнер с заданным заголовком, строкой текста, максимальным размером символов и ограничением.

Методы

  • void .delete (int offset, int length) - удаляет все символы из созданного контейнера;
  • int getCaret Posit ion () - получает текущую позицию нахождения указателя на экране;
  • int getChars (char [ ] data) - копирует содержимое контейнера TextBox в массив данных;
  • int getConstraints () - получает текущие ограничения для контейнера;
  • int getMaxSize() - возвращает максимальное число символов, установленное для контейнера TextBox;
  • String getString () - получает строку текста из содержимого контейнера TextBox;
  • void insert(char[] data, int offset, int length, int position) - вставляет массив символов в TextBox;
  • void insert (String src, int position) - вставляет строку текста в TextBox;
  • void setChars (char [] data, int offset, int length) -прописывает в TextBox массив символов;
  • void setConstraints (int constraints) - устанавливает ограничения;
  • void setlnitiallnputMode (String characterSubset) -задает напоминание;
  • int setMaxSize (int maxSize) - устанавливает максимальный размер для TextBox;
  • void setString( String text) - прописывает в TextBox строку текста;
  • void setTicker (Ticker ticker) - устанавливает бегущую строку;
  • void setTitle (String s) - устанавливает заголовок;
  • int size () - определяет .размер TextBox.

2.5.26. Класс TextField

Создает редактируемый текстовый контейнер, который встраивается в класс Form.

Конструктор

  • TextField(String label, String text, int maxSize, int constraints) - создает текстовый контейнер с заданным заголовком, строкой текста, максимальным размером символов и ограничением, с последующей интеграцией в класс Form.

Методы

  • void delete (int offset, int length) — удаляет все символы из созданного контейнера;
  • int getCaretPosition () — получает текущую позицию нахождения указателя на экране;
  • int getChars (char [ ] data) — копирует содержимое контейнера TextField в массив данных;
  • int getConstraints () - получает текущие ограничения для контейнера;
  • int getMaxSize () - возвращает максимальное число символов, установленное для контейнера TextField;
  • String getString() - получает строку текста из содержимого контейнера TextField;
  • void insert(char[] data, int offset, int length, int position) - вставляет массив символов в TextField;
  • void insert (String src, int position) - вставляет строку текста в TextField;
  • void setChars(char[] data, int offset, int length)-прописывает в TextField массив символов;
  • void setConstraints (int constraints) - устанавливает ограничения;
  • void setlnitiallnputMode(String characterSubset) - задает напоминание;
  • int setMaxSize (int maxSize) - устанавливает максимальный размер для TextField;
  • void setString (String text) - прописывает в TextField строку текста;
  • int size () - определяет размер TextField.

Константы

  • static int ANY - определяет ввод любого текста;
  • static int CONSTRAINT_MASK - режим ограничения для маски;
  • static int DECIMAL - ввод дробных числовых значений;
  • static int EMAILADDR - используется при вводе электронного адреса;
  • static int INITIAL_CAPS_SENTENCE - начальный символ каждогo предложения будет печататься с заглавной буквы;
  • static int INITIAL_CAPS_WORD - начальный символ каждого слова будет печататься с заглавной буквы;
  • static int NON_PREDICTIVE - значение слов, не используемое в словаре, найдено не будет;
  • static int NUMERIC - для ввода только целочисленных значений;
  • static int PASSWORD - для ввода пароля;
  • static int PHONENUMBER - для ввода телефонного номера;
  • static int UNEDITABLE - редактирование не доступно;
  • static int URL - для ввода адреса сайта.

2.5.27. Класс Ticker

Создает на экране бегущую строку текста.

Конструктор

  • Ticker (String str) - формирует бегущую строку текста.

Методы

  • String getString() - получает строку текста, заданную для объекта класса Ticker;
  • void setString (String str) — устанавливает строку текста для отображения ее на экране с помощью объекта класса Ticker, заменяя ее новой строкой.


2.6. Пакет javax.microedition.lcdui.game

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

2.6.1. Класс GameCanvas

Абстрактный класс, содержащий основные элементы игрового интерфейса.

Конструктор

  • protected GameCanvas (boolean suppressKeyEvents) - Конструктор абстрактного класса GameCanvas.

Методы

  • void f lushGraphics () - копирует изображение из внеэкранного буфера на экран;
  • void flushGraphics(int x, int y, int width, int height) -копирует изображение из внеэкранного буфера на экран в заданный по размеру прямоугольник;
  • protected Graphics getGraphics () - получает графические элементы для представления их в последствии классом GameCanvas;
  • int getKeyStates () — определяет, какая из клавиш нажата;
  • void paint (Graphics g) - рисует графические элементы, представленные классом GameCanvas.

Константы

  • static int DOWN_PRESSED - движение вниз;
  • static int FIRE_PRESSED - реализует стрельбу из оружия;
  • static int GAME_A_PRESSED - игровая клавиша А;
  • static int GAME_B_PRESSED - игровая клавиша В;
  • static int GAME_C_PRESSED - игровая клавиша С;
  • static int GAME_D_PRESSED - игровая клавиша D;
  • static int LEFT_PRESSED - движение влево;
  • static int RIGHT_PRESSED - движение вправо;
  • static int UP_PRESSED - движение вверх.

2.5.2. Класс Layer

Абстрактный класс, отвечающий за уровни представляемые в игре

Методы

  • int getHeight () - получает высоту экрана;
  • int getWidth () - получает ширину экрана;
  • int getX () - получает горизонтальную координату уровня;
  • int getY () - получает вертикальную координату уровня;
  • boolean isVisible() - получает видимость данного уровня;
  • void move (int dx, int. dy) - перемещает уровень на dx и dy координаты;
  • abstract void paint (Graphics g) - рисует уровень;
  • void setPosition (int x, int у) - устанавливает уровень в позицию, обозначенную в координатах х и у;
  • void setVisible (boolean visible) - устанавливает видимость данного уровня.

2.6.3. Класс LayerManager

Менеджер имеющихся в игре уровней.

Конструктор

  • LayerManager () - создает менеджер уровней.

Методы

  • void append (Layer 1) - добавляет уровень в менеджер уровней;
  • Layer getLayerAt (int index) - получает уровень с заданным индексом;
  • int getSize() - получает общее количество уровней;
  • void insert (Layer I, int index) - подключает новый уровень в заданный индекс;
  • void paint (Graphics g, int x, int у) - представляет текущий менеджер уровней в заданных координатах;
  • void remove (Layer 1) - удаляет уровень из менеджера уровней;
  • void setViewWindow(int x, int у, int width, int height) -устанавливает область на экране для отображения уровня.

2.6.4. Класс Sprite

Создает спрайт, представляющий изображение или анимационные фреймы.

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

  • Sprite (Image image) - создает не анимированный спрайт;
  • Sprite (Image image, int . f rameWidth, int. frameHeight) - создает спрайт представленный анимационными фреймами;
  • Sprite (Sprite s) - создает спрайт из другого спрайта.

Методы

  • boolean collidesWith(Sprite s, boolean pixelLevel) - onpeделяет столкновение между спрайтами;
  • boolean coll.idesWitn(T'iledLayer t, boolean pixelLevel) -определяет столкновение между спрайтом и препятствием нарисованным при помощи класса TiledLayer;
  • public void defineReferencePixel(int x, int у) -изменяет опорную позицию спрайта, перенося ее в точку с координатами х и у;
  • int getFrame() - получает текущий фрейм;
  • int getFrameSequenceLength() - получает количество элементов в анимационных фреймах;
  • int getRawFrameCount () - получает количество Не использованных фреймов;
  • int getRef PixelX () - получает координату по оси X для спрайта;
  • int getRef PixelY ()-получает координату По оси Y для спрайта;
  • void next Frame () - осуществляет переход на следующий фрейм;
  • void paint {Graphics g) - рисует спрайт;
  • void prevFrame () - осуществляет переход на предыдущий фрейм;
  • void setFrame(int sequencelndex) - устанавливает заданный фрейм;
  • void setFrameSequence (int [] sequence) -устанавливает определенную фреймовую последовательность;
  • void setlmage(Image img, int - frameWidth, -int frame-Height ) - изменяет изображение спрайта на новое изображение;
  • void setRef PixelPosition (int x, int у) - устанавливает координаты по осям X и Y для спрайта;
  • void setTransform(int transform)- производит трансформацию спрайта.

Константы

  • static int TRANS_MIRROR - отраженный по вертикали;
  • static int TRANS_MIRROR_ROT180 - отраженный по вертикали со сдвигом на 180° по часовой стрелке;
  • static int TRANS__MIRROR_ROT270 - отраженный по вертикали со сдвигом на 270° по часовой стрелке;
  • static int TRANS__MIRROR_ROT90 - отраженный но вертикали со сдвигом на 90° по часовой стрелке;
  • static int TRANS_NONE - без трансформации;
  • static int TRANS_ROT180 - сдвинут почасовой стрелке на 180°;
  • static int TRANS_ROT270 - сдвинут по часовой стрелке на 270°;
  • static int TRANS_ROT90 - сдвинут по часовой стрелке на 90°.

2.6.5. Класс Tiled Layer

Осуществляет создание фоновых изображений.

Конструктор

  • TiledLayer(int columns, int rows, Image image, int tileWidth, int tileHeight) — создает фоновое изображение с заданным количеством столбцов, строк, исходным изображением и шириной и высотой одной ячейки рисунка.

Методы

  • int createAnimatedTile(int staticTilelndex) - создает анимационный фон и возвращает следующий индекс ячейки;
  • void fillCells(int col, int row, int numCols, int numRows , int tilelndex) — заполняет ячейки;
  • int getAnimatedTile(int animatedTilelndex) - получает индекс анимационной последовательности;
  • int getCell(int col, int row) - получает ячейку;
  • int getCellHeight () - получает высоту ячейки в пикселях;
  • int getCellWidth () - получает ширину ячейки в пикселях;
  • int getColumns () - получает количество колонок, на которое разбито изображение фона;
  • int getRows () - получает количество строк, на которое разбито изображение фона;
  • void paint (Graphics g) -рисует фон;
  • void setAnimatedTile(int animatedTilelndex, int staticTilelndex) - устанавливает анимационную последовательность;
  • void setCell(int col, int row, int tilelndex) - рисует заданную ячейку;
  • void setStaticTileSet(Image image, int tileWidth, int tileHeight) -заменяет набор ячеек.


2.7. Пакет javax.microedition.media

Пакет добавлен в профиль МШР 2.0 и дает возможность в создании звукового сопровождения в приложении.

2.7.1. Интерфейс Control

Осуществляет контроль над процессами.

2. 7.2. Интерфейс Controllable

Осуществляет контроль над объектами.

Методы

  • Control getControl (String controlType) - получает объект, осуществляющий управление;
  • Control [] getControls() - получает совокупность объектов осуществляющих управление.

2.7.3. Интерфейс Player

Реализует контроль над воспроизведением.

Методы

  • void addPlayerListener(PlayerListener playerListener) -осуществляет обработку событий от определенного проигрывателя;
  • void close () - закрывает проигрыватель;
  • void deallocate () - освобождает ресурс, занятый проигрывателем;
  • String getContentType()- получает тип аудио данных, воспроизводимых проигрывателем;
  • long getDuration () - получает размер аудио файла;
  • long getMediaTime () - получает время воспроизведения аудио данных;
  • int getstate() - определяет состояние проигрывателя;
  • void prefetch () - захватывает ресурсы для последующего воспроизведения данных;
  • void realize () - создает проигрыватель без захвата ресурсов;
  • void removePlayerListener(PlayerListener playerListener) - удаляет установленный обработчик событий;
  • void setLoopCount (int count) - устанавливает цикличное воспроизведение аудио данных;
  • long setMediaTime (long now) - устанавливает время воспроизведения;
  • void start () - дает команду на воспроизведение;
  • void stop () - останавливает воспроизведение.

Константы

  • static int CLOSED - закрывает проигрыватель;
  • static int PREFETCHED - захватывает ресурсы для воспроизведения;
  • static int REALIZED - приобретает информацию для воспроизведения;
  • static int STARTED - воспроизведение запущенно;
  • static long TIME_UNKNOWN - неизвестное время установки;
  • static int UNREALIZED - не произошло захвата ресурсов и информации для воспроизведения.

2.7.4. Интерфейс PlayerListener

Получает асинхронные события проигрывателя.

Методы

  • void playerUpdate(Player player, String event, Object eventData) - обновляет состояние проигрывателя.

Константы

  • static String CLOSED - уведомляет о закрытии проигрывателя;
  • static String DEVICE_AVAILABLE - уведомляет о доступности проигрывателя;
  • static String DEVICE_UNAVAILABLE - уведомляет о недоступности проигрывателя;
  • static String DURATION_UPDATED - обновляет состояние;
  • static String END_OF_MEDIA - уведомляет о конце воспроизведения данных проигрывателем;
  • static String ERROR - уведомляет об ошибке;
  • static String STARTED - уведомляет о начале работы проигрывателя;
  • static String STOPPED — уведомляет о конце работы проигрывателя;
  • static String VOLUME_CHANGED - уведомляет о выборе громкости для воспроизведения.

2.7.5. Класс Manager

Менеджер системных ресурсов.

Методы

  • static Player createPlayer(InputStream stream, String type ) - создает проигрыватель для воспроизведения аудио данных из потока;
  • static Player createPlayer(String locator) - создает проигрыватель для воспроизведения аудио данных из определенного файла;
  • static String[]getSupportedContentTypes(String protocol) - возвращает список доступных контекстных типов для протоколов;
  • static String[] getSupportedProtocols(String content_type) - возвращает список доступных протоколов для контекстных типов;
  • static void playTone(int note, int duration, int volume) -воспроизводит различные тональные звуки.

Константа

  • static String TONE_DEVICE_LOCATOR - необходимая для последовательного воспроизведения тонов устройства.

2.7.6. Исключения

  • MediaException - исключает ошибки в работе методов этого пакета.


2.8. Пакет javax.microedition.media.control

Осуществляет контроль над процессами.

2.8.1. Интерфейс ToneControl

Производит воспроизведение тональных звуков на устройстве.

Метод

  • void setSequence (byte [] sequence) - устанавливает тональные звуки.

Константы

  • static byte BLOCK_END - конец блока воспроизведения;
  • static byte BLOCK_START - стартовая позиция в блоке;
  • static byte C4-нота До;
  • static byte PLAY_BLOCK - воспроизвести блок;
  • static byte REPEAT - повторить воспроизведение блока;
  • static byte RESOLUTION - событие;
  • static byte SET_VOLUME - установить громкость;
  • static byte SILENCE - без звука;
  • static byte TEMP() - темп или скорость воспроизведения;
  • static byte VERSION — версия атрибута воспроизведения.

2.8.2. Интерфейс VolumeControl

Регулирует громкость воспроизведения.

Методы

  • int getLevel () — возвращает текущий уровень громкости;
  • boolean isMuted() - определяет состояние сигнала;
  • int setLevel(int level) - устанавливает уровень громкости. Значение может находиться в приделах от 0 до 100;
  • void setMute (boolean, mute) - устанавливает состояние сигнала.


2.9. Пакет javax.microedition.midlet

С помощью этого пакета происходит связь между приложением и мобильным информационным профилем устройства (MIDP).

2.9.1. Класс MIDIet

Основной класс мйдлета должен наследовать класс MIDlet для управления работой приложения.

Конструктор

  • protected MIDIet () - закрытый Конструктор.

Методы

  • int checkPermission (String permission) - получить статус;
  • protected abstract void destroyApp (boolean unconditional )- заканчивает работу программы;
  • String getAppProperty (String key) - получает свойства программного обеспечения;
  • void notifyDestroyed() - уведомляет программное обеспечение о конце работы;
  • void notifyPaused() — уведомляет программное обеспечение о паузе в работе;
  • protected abstract void pauseApp () - переходит в состояние паузы;
  • boolean platformRequest (String URL) - дескриптор устройства получает URL;
  • void resumeReguest () - переход в активное состояние;
  • protected abstract void startApp() - входная точка программы, осуществляет старт приложения.

2.9.2. Исключение

  • MIDletStateChangeException - исключает неправильную работу с классом MIDlet.


2.10. Пакет javax.microedition.pki

Сертифицирует информацию для безопасной связи.

2.10.1. Интерфейс Certificate

Общий сертификат связи.

Методы

  • String getlssuer() - получает используемый сертификат;
  • long gefeNotAf ter () - получает момент времени после которого сертификат использовать нельзя;
  • long getNotBe f ore ()- получает момент времени, до которого сертификат использовать нельзя;
  • String getSerialNumber () - получает серийный номер сертификата;
  • String getSigAlgName () - получает имя используемого алгоритма записи данного сертификата;
  • String getSubject() - получает название субъекта сертификата; "
  • String getType() - получает тип сертификата;
  • String getVersion() - получает версию сертификата.

2.10.2. Исключение

  • Certif icateExceptio - обобщенный вид ошибок, возникший при использовании данного сертификата.


2.11. Пакет javax.microedition.rms

Осуществляет хранение, удаление, добавление записей в системную память устройства.

2.11.1. Интерфейс RecordComparator

Осуществляет сортировку записей.

Метод

  • int compare (byte [] reel, byte[] rec2 )-сортирует записи.

Константы

  • static int EQUIVALENT - две записи одинаковы;
  • static int FOLLOWS - первая запись больше второй записи;
  • static int PRECEDES - вторая запись больше чем первая.

2.11.2. Интерфейс RecordEnumeration

Реализует двунаправленный список записи.

Методы

  • void destroy () - освобождает захваченные ресурсы;
  • boolean hasNextElement () - возвращает значение true, если имеются последующие записи;
  • boolean hasPreviousElement () - возвращает значение true, если имеются предшествующие записи;
  • boolean isKeptUpdated () - возвращает значение true в том случае. если сохраняются изменения в записи;
  • void keepUpdated (boolean keepUpdated) - устанавливает, возможно ли сохранение индексов записей при изменении, удалении или добавлении записей;
  • byte [ ] nextRecord () - возвращает копию следующей записи в списке:
  • int nextRecordld () — возвращает идентификатор следующей записи в списке;
  • int numRecords () - возвращает число доступных записей;
  • byte[] previousRecord() - возвращает копию предыдущей записи в списке;
  • int previousRecord() - возвращает идентификатор предыдущей записи в списке;
  • void rebuild() -делает запрос для обновления списка доступных записей;
  • void reset () - сбрасывает индекс записи к первоначальному значению.

2.11.3. Интерфейс Record Filter

Определяет совпадения записей.

Метод

  • boolean matches (byte [] candidate) - возвращает значение true, если кандидат соответствует заданному критерию.

2.11.4. Интерфейс RecordListener

Производит обработку событий связанных с изменением, добавлением и удалением записей.

Методы

  • void recordAdded(RecordStore recordStore, int recordld) -вызывается после добавления записи;
  • void recordChanged(RecordStore recordStore, int recordld) - вызывай после изменения записи;
  • void recordDeleted(RecordStore recordStore, int recordld) — вызван после удаления записи.

2.11.5. Класс RecordStore

Производит запись данных.

Методы

  • int addRecord(byte[] data, int offset, int numBytes) -добавляет новую запись в память мобильного устройства;
  • void addRecordListener(RecordListener listener)-добавляет обработчик событий;
  • void closeRecorclStore () - закрывает запись;
  • void deleteRecord(int recordld) -удаляет запись по идентификатору;
  • static void deleteRecordStore(String recordStoreName) -удаляет запись по имени;
  • long getLastModif ied () - возвращает последнее время изменения записи;
  • String getName () - получает имя записи;
  • int getNextRecordlD() - получает идентификатор последующей записи;
  • int getNumRecords () - получает количество доступных записей;
  • byte[] getRecord (int recordld) - возвращает копию записи;
  • int getRecord(int recordld, byte[] buffer, int offset) -возвращает данные записи;
  • int getRecordSize (int recordld) - получает размер заданной записи;
  • int getsize() - получает размер всех записей;
  • int getSizeAvailable() - получает количество доступной памяти для записи;
  • int getVersion() - получает версию записи:
  • static String [] listRecordStores ()-возвращает список записей;
  • static RecordStore openRecordStore(String recordStoreName, boolean create if Necessary)- открывает память для записи;
  • static RecordStore openRecordStore(String recordStoreName, boolean createlfNecessary, int authmode, boolean writable) - открывает память для записи;
  • static RecordStore openRecordStore(String recordStoreName, String vendorName, String suiteName) - открывает память для записи;
  • void removeRecordListener(RecordListener listener) -удаляет обработчик событий;
  • void setMode(int authmode, boolean writable) - изменят режим доступа;
  • void setRecord(int recordld, byte[] newData, int offset, int numBytes) - вводит данные в запись.

Константы

  • static int AUTHMODE_ANY - позволяет осуществить доступ для любого комплекта мидлетов;
  • static int AUTHMODE_PRIVATE - позволяет осуществить доступ только из данной программы.


Введение

  • Предисловие
  • Что вы должны знать
  • Какое программное обеспечение используется
  • О чем эта книга


Предисловие

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

Обилие разнообразных моделей телефонов создает на этом рынке большую конкуренцию. Множество производителей стараются включить в телефоны как можно больше различных функций. Присутствием в телефоне адресной книги, органайзера, будильника и даже счетчика калорий уже никого не удивишь, и в какой-то момент времени возник вопрос, а чем же еще можно оборудовать телефон? Самым идеальным решением этого вопроса могла стать возможность загрузки в телефон программ сторонних производителей. Не секрет, что основная масса телефонов работает на основе прошивки, поэтому загрузка программ в телефон не возможна. Чтобы такая возможность появилась, производителям надо было бы решить ряд сложных вопросов. Во-первых - это язык программирования, на котором будут писаться программы для телефонов и, соответственно,, поддержка этого языка самим телефоном. Второе - это аппаратная архитектура мобильных телефонов, которая сильно ограничена в своих системных ресурсах, а это процессор, память, графический интерфейс. Улучшение архитектуры неизменно ведет к увеличению стоимости телефона, поэтому идеальной в этом случае стала платформа Java 2 Micro Edition, созданная компанией Sun Microsystems.

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

Но и в этой сфере не обошлось без накладок. Появление большого количества производителей мобильных устройств в какой-то мере сопутствовало хаосу в стандартах, используемых при программировании телефонов. Каждая компания видела, да и, пожалуй, видит, свои пути развития в стандартизации своего программного обеспечения. Поэтому на рынке сейчас имеется масса инструментальных средств чут£ ли не для каждой из моделей мобильных телефонов. В этом направлении, как мне кажется, сильно преуспела финская компания Nokia, являющаяся законодателем мод, а может и лидером в производстве телефонов. Платформа Java 2 ME призвана обеспечить определенный стандарт в этой области. Каждый из телефонов, имеющий поддержку Java, в теории может иметь совместимость с любым программным обеспечением, созданным на Java 2 ME. Вы спросите, почему в теории?

Дело в том, что каждый из производителей телефонов имеет свои устоявшиеся характеристики по аппаратной части мобильного устройства. В большей степени это относится к дисплею телефона, модели графического интерфейса и отсутствию либо наличию различных комбинаций клавиш телефона. То есть любой программный код, написанный на Java 2 ME, обязан работать на любом телефоне с поддержкой Java. Но в виду всевозможных различий между марками, а иногда даже моделями телефонов от одного производителя, результаты могут быть несколько иными, рассмотрим пример с дисплеем. Телефоны Siemens с цветными дисплеями в своей массе имеют разрешение 101x80, тогда как у телефонов Nokia в большинстве доступно разрешение 128x128 пикселей и при этом каждая из марок телефонов имеет свои различия в графическом отображении некоторых элементов пользовательского интерфейса. Поэтому при программировании приложений, этот фактор придется иметь в виду. Как программист вы должны отвечать за совместимость написанной программы с различными моделями телефонов, что, безусловно, увеличит ваши трудности в создании хорошего приложения.

Поговорив о капле дегтя в большой цистерне меда, перейдем к меду. Несомненно, Java 2 ME - это стандарт, обеспечивающий совместимость программного обеспечения с любой маркой телефона. Стремительное развитие технологий мобильных устройств обязано подразумевать определенный эталон в данном направлении. Немалое количество сторонних разработчиков при строгой стандартизации заинтересовано в развитии рынка программного обеспечения телефонов. В наше время телефон имеет почти каждый человек, в отличие, скажем от портативных компьютеров на основе операционных систем Palm и Pocket PC. Поэтому рынок мобильных устройств по своим масштабам считается наиболее перспективным, а платформа Java 2 ME, является стандартом в создании программ для телефонов.

Язык программирования Java 2 ME сам по себе не сложен^ а обилие готовых библиотек позволяет писать Java приложения за короткий промежуток времени. И что самое главное, наборы инструментальных средств программирования поставляемые компанией Sun Microsystems и производителями телефонов абсолютно бесплатны! Множество энтузиастов со всего мира в кратчайшие сроки создают как платные, так и бесплатные программы и игры на Java 2 ME. Задача этой книги - дать исчерпывающую информацию по программированию мобильных телефонов, поддерживающих платформу Java 2 ME.


Что вы должны знать

Для того чтобы научиться программировать мобильные телефоны на Java 2 ME, вам необходимо знать только русский язык. Если вы новичок в программировании и не знакомы ни с одним языком программирования, то в приложении 1 содержится полная информация непосредственно по языку программирования Java. Изучив приложение 1, вы сможете научиться программированию телефонов на Java 2 ME и приступить к прочтению этой книги. Те читатели, которые уже знакомы с основами Java, могут сразу приступайте к прочтению книги с первой главы.

Все главы книги написаны в доступной форме и рассчитаны на широкий круг читателей. Множество примеров с подробными комментариями призваны улучшить понимание общей концепции платформы Java 2 ME.


Какое программное обеспечение используется

Естественно, что вся работа по созданию программ для мобильных телефонов происходит на компьютере и наличие мобильного телефона совсем не требуется. В качестве операционной системы используется Windows XP корпорации Microsoft. Большинство программного обеспечения ориентировано именно на эту операционную систему.


О чем эта книга

Книга предназначена для самостоятельного изучения как языка программирования Java, так и для программирования приложений для мобильных телефонов. Подробно рассматриваются все имеющиеся пакеты библиотек Java 2 ME, разбираются классы, методы и интерфейсы, раскрывается механизм работы программ на Java 2 ME. Прочтение всей книги лучше осуществлять в хронологическом порядке, главу за главой. В приложении 2 содержится справочник, дающий исчерпывающую информацию по всем интерфейсам, классам, методам и константам платформы Java 2 Micro Edition.

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

Во второй главе изучаются основы платформы Java 2ME. Рассматриваются профили MIDP 1.0 и MIDP 2.0, являющиеся спецификацией, предъявляемой к аппаратной части телефона. Разбираются все имеющиеся в Java 2 ME классы, и прослеживается общая линия наследования классов и интерфейсов.

В третьей главе объясняется установка, настройка и работа интегрированных сред программирования. Будет изучено два инструментария: Sun ONE Studio 4 Mobile Edition и J2ME Wireless Toolkit 2.1. Особое внимание уделяется компоновке и компиляции исходного кода.

Четвертая глава повествует об имеющихся наборах инструментальных средств программирования (SDK), предоставляемых производителями телефонов. Анализируются инструментарии компаний Nokia, Siemens, Sony Ericsson, Motorola и Samsung. Все программные средства чаще всего поставляются в виде телефонных эмуляторов. Интегрируя эти наборы SDK в среды программирования, рассмотренные в главе 3, таким образом вы сможете тестировать созданные программы на телефонах различных моделей.

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

Шестая глава полностью посвящена имеющимся в Java 2 ME классам пользовательского интерфейса. Использование этих классов в приложении помогает создать красочный и логически понятный интерфейс программы.

В седьмой главе раскрываются секреты программирования графики. На практике объясняется механизм рисования графики и создание создания игрового цикла для профиля MIDP 1.0. Затрагиваются некоторые вопросы, связанные с передвижением и столкновением объектов в играх для мобильных телефонов.

Восьмая глава освещает темы, связанные с техникой программирования игр для профиля MIDP 2.0. Будут проанализированы все имеющиеся игровые классы, вопросы связанные с анимацией, столкновением и перемещением объектов по экрану телефона.

Девятая глава содержит подробное описание мультимедийной библиотеки, при помощи которой возможно осуществляется воспроизведение звуков на телефонах.

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

Приложение 2 выполнено в виде справочника по всем основным интерфейсам, классам, методам и константам платформы Java 2 ME. Вся справочная информация разбита на соответствующие разделы и выстроена по алфавиту, что поможет читателю быстро найти подробную информацию о том или ином компоненте платформы Java 2 ME.