Методические указания. Апплет должен быть создан на основе шаблонов, содержащихся в Приложении 4(или при помощи системы Java Applet Wizard).

Объявление элементов класса апплета.

В классе апплета объявим следующие элементы:

int yHeight; // высота символов шрифта, выбранного по умолчанию

Dimension appSize; // текущий размер окна апплета

Инициализация апплета (метод init()).

При инициализации апплета в методе init() получим высоту символов шрифта для вывода текста в окно.

Для того, чтобы получить информацию о контексте окна апплета вне метода paint(), необходимо получить контекст отображения (методу paint() этот контекст передается через параметр). Получим этот контекст g класса Graphics методом апплета getGraphics() (cм. приложение LinesDraw).

Затем получим объект fm класса FontMetrics, который содержит метрики текущего шрифта, методом g.getFontMetrics() (приложение FontsList).

Сохраним высоту символов, выдаваемую методом fm.getHeight(), в переменной yHeight. Эта величина нужна для определения шага свертки.

Перерисовка окна апплета (метод paint()).

Для перерисовки изображения в окне используется метод paint(), которому передается объект g типа Graphics (g - контекст отображения для окна). Методами этого класса пользуются для вывода графической информации в окно апплета.

В данном апплете этот метод используется для определения текущего размера appSize окна и для закраски фона окна и рисовании рамки окна (см. приложение LinesDraw).

Обработка нажатия клавиши (метод keyDown()).

Переопределим в классе апплета метод-обработчик нажатия клавиши клавиатуры keyDown(). В этом методе будем выводить строку информации о нажатой клавише в верхней части окна. Сначала сформируем объект s класса String, равный

"Character "+(char)key+" -> Key "+key+" -> Modifiers "+evt.modifiers

затем получим методом getGraphics() контекст окна g класса Graphics и выведем в окно строку s в точке с координатами (10, yHeight) методом g.drawString().

Метод keyDown() должен возвратить true, так как обработка завершена.

Обработка отпускания клавиши (метод keyUp()).

Переопределим в классе апплета метод-обработчик отпускания клавиши клавиатуры keyUp().

Получим методом getGraphics() контекст окна g класса Graphics и с помощью метода g.copyArea() скопируем часть экрана, ограниченную прямоугольником с началом в точке (0, 1), шириной appSize.width-1 и высотой appSize.height-yHeight-5, в область с началом в точке (0, yHeight+1).

Затем методом g.setColor() выберем цвет фона Color.yellow и методом g.fillRect() закрасим область вывода очередной строки - прямоугольник с началом в точке (1, 1), шириной appSize.width-2 и высотой yHeight+1.

Метод keyUp() должен возвратить true, так как обработка завершена.

 

Задания к лабораторной работе

Задание 1.Создать апплеты FontsList, LinesDraw, KeyCodes и объяснить их работу. Апплеты должны иметь возможность работать как независимые приложения.

Задание 2. Дать ответы на контрольные вопросы.

Контрольные вопросы

1. Над объектом какого типа выполняются все графические операции?

2. Почему рекомендуется использовать ограниченный набор цветов?

3. Почему рекомендуется использовать ограниченный набор шрифтов?

4. Как получить метрики шрифтов?

5. Когда возникают события?

6. Какой метод какого класса получает управление при возникновении события? Что передается ему в качестве параметра?

7. Какие методы отвечают за обработку простых событий от мыши?

8. Какое значение (true или false) должен вернуть метод-обработчик для того, чтобы событие считалось обработанным и не передавалось на дальнейшую обработку методу суперкласса?

9. Какие методы отвечают за обработку простых событий от клавиатуры?

10. Для чего нужен фокус ввода?

 

ЛАБОРАТОРНАЯ РАБОТА № 4

КОМПОНЕНТЫ И ИСПОЛЬЗОВАНИЕ ЭЛЕМЕНТОВ УПРАВЛЕНИЯ

(4 часа)

МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ЛАБОРАТОРНОЙ РАБОТЕ

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

1. Компоненты GUI

Графическое окружение языка Java основано на классе Component. Всякий графический вывод на экран связан (прямо или косвенно) с компонентом. Например, в силу того, что апплеты фактически являются потомками класса Component, имеется возможность рисовать прямо в апплете, не прибегая для этого к специальным методам.

Класс Component содержит очень много методов для обеспечения работы с компонентом GUI.

Некоторые методы класса Component:

· getParent - Получает объект-предок компонента

· isShowing - Проверяет, является ли компонент видимым

· isEnabled - Проверяет, является ли компонент разрешенным

· location - Возвращает текущее положение компонента

· size - Возвращает текущий размер компонента

· bounds - Возвращает текущие границы компонента

· enable - Разрешает компонент

· disable - Запрещает компонент

· show - Отображает компонент

· hide - Скрывает компонент

· getForeground - Получает текущий цвет переднего плана

· setForeground - Устанавливает текущий цвет переднего плана

· getBackground - Получает текущий цвет фона

· setBackground - Устанавливает текущий цвет фона

· getFont - Получает текущий шрифт

· setFont - Устанавливает текущий шрифт

· move - Перемещает компонент в новое положение (в системе координат предка)

· resize - Изменяет ширину и высоту компонента

· reshape - Изменяет форму компонента (положение, высоту и ширину)

· prefferedSize - Возвращает предпочтительный размер компонента

· minimumSize - Возвращает минимальный размер компонента

· getGraphics - Получает графический контекст компонента

· getFontMetrics - Получает типографские параметры текущего шрифта

· paint - Отвечает за рисование компонента

· update - Отвечает за обновление компонента, вызывается методом repaint()

· paintAll - Отвечает за рисование компонента и его подкомпонентов

· repaint - Вызывает перерисовку компонента. Этот метод вызывает метод update()

· print - Отвечает за печать компонента

· imageUpdate - Отвечает за перерисовку компонента при изменении выводимого в компоненте изображения типа Image

· createImage - Создает изображение

· prepareImage - Подготавливает изображение типа Image для визуализации

· checkImage - Возвращает состояние создания экранного представления изображения

· inside - Проверяет, находится ли заданная точка «внутри» компонента

· locate - Возвращает компонент, содержащий заданную точку

· deliverEvent - Доставляет событие компоненту

· postEvent - Пересылает событие компоненту, в результате чего вызывается метод handleEvent()

· handleEvent - Отвечает за обработку события. Если метод возвращает false, то событие передается предку компонента

· mouseDown, mouseDrag, mouseUp, mouseMove, mouseEnter, mouseExit - Отвечают за обработку соответствующих событий мыши

· keyUp, keyDown - Отвечают за обработку соответствующих событий клавиатуры

· action - вызывается в том случае, если в компоненте происходит некоторое действие

· gotFocus - Указывает на то, что компонент получил фокус ввода

· lostFocus - Указывает на то, что компонент потерял фокус ввода

· requestFocus - Запрашивает фокус ввод

· nextFocus - Передает фокус следующему компоненту

Этими методами могут пользоваться все наследуемые от класса Component классы GUI - все элементы управления и класс контейнеров. Эти компоненты GUI имеют следующие деревья наследования:

Object ® Component ® Button

Object ® Component ® CheckBox

Object ® Component ® Choice

Object ® Component ® List

Object ® Component ® Scrollbar

Object ® Component ® Label

Object ® Component ® Canvas

Object ® Component ® TextComponent

Object ® Component ® TextComponent ® TextField

Object ® Component ® TextComponent ® TextArea

Object ® Component ® Container

Для того чтобы нарисовать изображение, вывести некоторый текст или разместить элемент пользовательского интерфейса на экране, должен использоваться контейнер класса Container или его подкласса. Контейнеры- это объекты, которые содержат компоненты. А компоненты - это объекты, которые попадают под класс Component: кнопки, полосы прокрутки, другие элементы управления. Контейнеры сами являются подклассами Component, что подразумевает возможность их вложения или размещения внутри друг друга.

Так, например, класс Applet является подклассом Panel, который в свою очередь является подклассом Container, а тот - подклассом Component. Поэтому все апплеты умеют вводить и отображать компоненты. Нужно просто создать компонент и ввести его в апплет.

2. Устройства или элементы управления

Рассмотрим такие компоненты, как элементы управления. При их помощи можно создавать программы, обладающие развитым пользовательским интерфейсом. Язык Java содержит все стандартные элементы управления, которые можно обнаружить в современных компьютерных операционных системах.Элементы управления сначала создаются, затем добавляются в контейнер (объект класса Container) его методом add().

2.1 Кнопки

Кнопки (класс Button) - это устройства, которые дают возможность нажимать на них, чтобы проинициализировать некоторое действие.

Для создания кнопок необходимо в методе класса Container (или его подкласса) просто создать экземпляр объекта Button, дать ему имя и добавить его в контейнер:

Button myButtom=new Button("Click me!");

add(myButton);

или еще проще:

add(new Button("Click me!"));

Следует обратить внимание на то, что при создании кнопки не передаются координаты X, Y ее положения. Это происходит потому, что элементы управления, как и все устройства, размещаются на экране в соответствии с правилами, определяемыми менеджерами компоновки(размещения): при этом координаты не используются. Подробно менеджеры размещения будут рассматриваться в следующей главе.

Создать кнопку можно с заданной меткой (строкой), а можно и без нее. Для этого предназначены соответствующие конструкторы Button() и Button(String label). Для изменения и получения метки кнопки существуют методы setLabel() и getLabel() соответственно.

Обработка событий от кнопки (и от других компонент)

Для обработки событий, создаваемых кнопками, и другими компонентами, можно переопределить метод handleEvent() контейнера, содержащего эти компоненты. Однако существует более простой способ, основанный на переопределении метода action(), который получает управление, когда пользователь совершает какое-либо действие с компонентом (нажатие на кнопку мышью; завершение ввода строки в текстовом поле - нажатие клавиши «Enter»; выбор элемента из списка - двойной щелчок мышью; изменение состояния переключателя щелком мыши или клавишей пробела; выбор элемента из меню выбора - одинарный щелчок мышью).

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

События в методе action() обрабатываются следующим образом. Прежде всего необходимо проверить, объект какого типа создал событие. Это делается при помощи операции instanceof. Рассмотрим пример для обработки событий от кнопок (щелчок мышью на кнопке), предполагая, что контейнер включает в себя кнопки btn1, btn2 и btn3:

public boolean action(Event evt, Object obj)

{

// обработка событий от кнопок

if(evt.target instanceof Button) // объект является кнопкой?

{// получаем ссылку на кнопку, вызвавшую событие

Button btn=(Button)evt.target;

// получаем метку кнопки

String lbl=btn.getLabel();

// проверка, от какой именно кнопки пришло событие

if(btn.equals(btn1)) // от кнопки с номером 1?

{ // обработка события от кнопки 1

................................ }

else if(btn.equals(btn2)) // от кнопки с номером 2?

{ // обработка события от кнопки 2

................................ }

else if(btn.equals(btn3)) // от кнопки с номером 3?

{ // обработка события от кнопки 3

................................ }

else

{ // если событие вызвано кнопкой,

// обработчик которой не

// предусмотрен в данном методе

return false; }

// если событие обработано, иначе return false

return true; }

// аналогичный процесс обработки событий ACTION_EVENT

// от других компонент

if(evt.target instanceof КлассЭлементаGUI)

{ // получаем ссылку на компонент, вызвавший событие

КлассЭлементаGUI element=

(КлассЭлементаGUI)evt.target;

// проверка, от какого именно компонента этого класса

// пришло событие и обработка этого события от

// конкретного компонента

.............................................

return true; // если событие обработано, иначе return false

}

// необработанные события передаем на дальнейшую обработку

return false; }

Нужно отметить, что не все действия пользователя обрабатываются методом action(), например, события линейки прокрутки можно обработать только методом handleEvent(). Методом action() обрабатываются только те события, для которых элемент id объекта evt класса Event равен ACTION_EVENT (см. предыдущую главу). Другие события обрабатываются более универсальным методом handleEvent().

Рекомендация. Если контейнер содержит элементы управления, события от которых не обрабатываются методом action(), то рекомендуется обработку всех событий от всех компонентов производить в методе handleEvent(), чтобы не делить процесс обработки на части, а обрабатывать события централизовано. Процесс обработки событий в методе handleEvent() аналогичен процессу обработки в методе action():

public boolean handleEvent(Event evt)

{ switch(evt.id)

{ default:// передача сообщения на обработку

// методу базового класса

return super.handleEvent(evt);

case Event.ACTION_EVENT:

// обработка событий от кнопок

// объект является кнопкой?

if(evt.target instanceof Button)

{// ссылка на кнопку, вызвавшую событие

Button btn=(Button)evt.target;

// получаем метку кнопки

String lbl=btn.getLabel();

if(btn.equals(btn1)) // событие от кнопки 1?

{// обработка события

.................... }

else if(btn.equals(btn2))

{ // обработка события

.................... }

else if(btn.equals(btn3))

{ // обработка события

.................... }

else return false;

// если событие обработано, иначе return false

return true; }

// аналогичный процесс обработки событий

// Event.ACTION_EVENT от других компонент

if(evt.target instanceof КлассЭлементаGUI)

{ // ссылка на компонент, вызвавший событие

КлассЭлементаGUI element=

(КлассЭлементаGUI)evt.target;

// проверка, от какого именно компонента этого

// класса пришло событие и обработка этого

// события от конкретного компонента

.............................................

// если событие обработано, иначе return false

return true; }

break; }

return true; }

2.2 Флажки (или переключатели)

Язык Java поддерживает два типа флажков-переключателей (класс Checkbox): исключающие и неисключающие.

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

Исключающие флажки (переключатели с зависимой фиксацией) позволяют одновременно выбрать только один элемент в группе флажков. Если выбирается другой элемент в группе, то выбор предыдущего флажка отменяется, а новый выбор выделяется. Для создания такой группы флажков сначала создается объект класса CheckboxGroup, а затем создаются объекты класса Checkboх, входящие в эту группу, для чего используется конструктор Checkbox(String label, CheckboxGroup group, boolean state).

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

// создание одного независимого флажка и добавление его в контейнер

add(new Checkbox("It is checkbox"));

// создание группы флажков

CheckboxGroup gr=new CheckboxGroup();

// создание флажков группы gr и добавление их в контейнер

Checkboх first, second, third;

// флажок сброшен

first=new Checkbox("1st checkbox from group",gr,false);

add(first);

// флажок установлен

second=new Checkbox("2nd checkbox from group",gr,true);

add(second);

// флажок сброшен

third=new Checkbox("3rd checkbox from group",gr,false);

add(third);

Класс CheckboxGroup содержит методы для определения текущего выбора и установки нового выбора для флажков группы. Метод getCurrent() возвращает ссылку на выбранный флажок группы, а метод setCurrent() переносит выбор на задаваемый флажок группы.

При помощи методов класса getLabel() и getState() класса Checkbox можно получить метку флажка и текущее состояние переключателя, а при помощи методов setLabel() и setState() изменить метку флажка установить состояние флажка.

Для проверки того, какой группе флажков принадлежит флажок, класса Checkbox содержит метод getCheckboxGroup(), а для того, чтобы поместить ранее созданный независимый флажок в группу, или для изменения группы, в которую теперь будет входить флажок, используется метод setCheckboxGroup().