Программирование мобильных телефонов на Java

         

определенный для классов пользовательского интерфейса.



В 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, то можете пользоваться всеми имеющимися компонентами вне зависимости от принадлежности к одному из профилей.

Класс 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.

Методы класса 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°, указывая в направлений новых компонентов, выпадающих из зоны видимости. Такой механизм реализован в любом телефоне вне зависимости от производителя. Можно добавлять любое количество компонентов в форму, но очевидно, что необходимо задуматься и о дизайне пользовательского интерфейса и не валить все «в кучу». Наилучшим решением будет продуманная структура переходов с экрана на экран.

Класс 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 содержится ряд подклассов, обеспечивающих создание интуитивно понятного пользовательского интерфейса. Давайте рассмотрим эти подклассы.

Класс 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. В ваших программах это могут быть любые другие события, необходимые для решения конкретных задач.

Класс 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. С помощью джойстика или клавиш перемещения, можно установить необходимые параметры для обоих элементов.

Класс 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

Класс 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

Класс 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

Класс 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 показан эмулятор с изображением на экране фотографии.

Класс 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 и используйте его по назначению.

Класс 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, вы можете выбрать необходимый тип уведомлений или информационных сообщений, формируя органичные, удобные приложения, предусматривающие любые варианты развития событий.

Методы класса 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

Класс 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 пикселей.

Методы класса 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 более внимательно.

Класс Ticker



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

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

public  Ticker(String  str);


Параметры конструктора класса Ticker:
 str - строка текста появляющаяся в виде бегущей строки.
Создавая объекта класса Ticker с помощью рассмотренного конструктора, вы задаете значение для параметра str и эта строка текста будет циклично прокручиваться в программе.


Рис. 6.12. Объект класса Ticker создает в верхней части экрана бегущую строку

Методы класса 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 добавляется в форму, организовывая тем самым бегущую строку в верхней части экрана телефона.

Класс Image



При рассмотрении класса ImageItem мы уже использовали объекты класса Image, но тогда был рассмотрен только один метод и способ работы с классом Image. В этом разделе вы более подробно познакомитесь с этим классом. Класс Image необходим для загрузки и хранения изображений в формате PNG. Чаще всего загружаемые изображения находятся в рабочем каталоге приложения. Но могут находиться и где угодно, надо только правильно указать путь местонахождения для загрузки. При упаковке приложения в JAR-файл, все имеющиеся изображения автоматически копируются в архив, и при работе программы на телефоне, загрузка уже осуществляется из JAR-файла. Загружаемые изображения могут использоваться во время работы с классами Alert, Choice, ChoiceGroup, Form, ImageItem и Graphics. Качество воспроизведения изображения на экране всецело зависит от возможностей используемого телефона. Если изображение больше фактического размера дисплея, то сервис телефона организует прокрутку изображения и если это не входит в ваши планы, то следует придерживаться минимальных размеров ширины и высоты при создании изображений.

Методы класса 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 показан эмулятор телефона, воссоздающий загруженное изображение, посмотрите, насколько больше экран телефона и как разместилось меньшее по размеру изображение на дисплее.

Класс 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, с помощью классов низкоуровневого интерфейса.