Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Использование JDK (Java Developer’s Kit). 2 страница




}

//-------------------------------------------------------------------------

public void destroy()

{

// Сделать: Добавьте сюда код завершения работы апплета

}

//--------------------------------------------------------------------------

public void paint(Graphics g)

{

g.drawString("Created with Microsoft Visual J++ Version 1.1", 10, 20);

}

//--------------------------------------------------------------------------

public void start()

{

// Сделать: Добавьте сюда код, который должен

// работать при запуске апплета

}

//--------------------------------------------------------------------------

public void stop()

{

// Сделать: Добавьте сюда код, который должен

// работать при остановке апплета

}

// Сделать: Добавьте сюда код, необходимый для работы

// создаваемого специализированного апплета

}

Листинг HTML-файла:

<html>

<head>

<title>AppletWithParam</title>

</head>

<body>

<hr>

<applet

code=AppletWithParam.class

name= AppletWithParam

width=320

height=240 >

<param name=String_1 value="First string">

<param name=String_2 value="Second string">

</applet>

<hr>

<a href=" AppletWithParam.java">The source.</a>

</body>

</html>

Дополним созданный шаблон апплета. Сначала в HTML-файле изменим значения параметров апплета:

<param name=String_1 value="New first string">

<param name=String_2 value="New second string">

А затем выведем в методе paint() строки, получаемые апплетом в виде параметров:

public void paint(Graphics g)

{

g.drawString(m_String_1, 10, 20);

g.drawString(m_String_2, 10, 50);

}

3.3 URL-адреса, загрузка и вывод графических изображений

Создадим апплет ParamUrlImage (пример 5), в котором через параметр аплета передается имя gif-файла, содержимое которого затем выводится в окне апплета. При создании шаблона апплета (тексты шаблонов содержатся в Приложении 2) следует задать имя параметра FileName, а значение по умолчанию - “sample.gif”. В каталог, где содержится файл исходного текста, следует поместить файл с изображением sample.gif

Загрузить изображение можно при помощи URL-адреса на файл с изображением. URL, или Uniform Resource Locators (“унифицированная ссылка на ресурс”), - полный адрес объекта в сети WWW.

В Java есть отдельный класс для обработки URL-адресов - java.net.URL. Самый простой способ создания объекта URL состоит в использовании конструктора URL(String add), передавая ему обычный WWW-адрес, например

URL addUrl=new URL("http://www.vvsu.ru/");

Нужно отметить, что фрагмент кода, где происходит реализация класса URL, может сгенерировать исключение MalformedURLException, если вдруг объект не может по какой-либо причине быть создан (например, если передаваемая конструктору строка не является URL-адресом). Компилятор требует обработать возможность возникновения исключительной ситуации при помощи блоков try-catch, например:

try

{ URL addUrl=new URL("http://www.vvsu.ru/");

}

catch(MalformedURLException e)

{ // код здесь выполняется, если строка URL неправильна

}

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

Класс URL содержит конструктор, которому передается абсолютный базовый URL и строка, содержащая путь к объекту относительно этого базового указателя. Создать URL на файлы своего сервера (или своего локального компьютера) можно при помощи именно этого конструктора. Для получения URL на каталог, содержащий класс работающего апплета, используется метод getCodeBase() класса Applet. Так имя загружаемого графического файла содержится в переменной m_FileName класса, то для загрузки графического изображения можно использовать следующий фрагмент, помещаемый в метод init() класса ParamUrlImage:

try

{ Im=getImage(new URL(getCodeBase(),m_FileName));

}

catch(MalformedURLException e)

{ // код здесь выполняется, если строка URL неправильна

Im=createImage(0,0); // создание пустого изображения

}

Предварительно необходимо в классе апплета ParamUrlImage определить переменную Im:

Image Im;

и импортировать в файл класса ParamUrlImage пакет java.net:

import java.net.*;

Класс Image определяет простое двумерное графическое изображение. Для загрузки изображения из файла используется метод getImage(), принимающий URL это файла. Этот метод может импортировать изображения любого графического формата, поддерживаемого WWW-броузером (чаще всего используются форматы GIF и JPEG).

Для вывода изображения в окно необходимо в методе paint() апплета ParamUrlImage вызвать метод drawImage() класса Graphics, передавая ему изображение, координаты расположения изображения и ссылку текущий объект класса ParamUrlImage:

public void paint(Graphics g)

{ g.drawImage(Im,0,0,this);

}

3.4 Двойная буферизация графического изображения

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

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

Создадим шаблон апплета QuickPicture (пример 6) на основе шаблонов из Приложения 1 (или при помощи системы Java Applet Wizard). В каталог, где содержится файл исходного текста, следует поместить файл с изображением sample.gif.

В классе апплета объявить переменные:

Image pic; // изображение из файла

boolean picLoaded=false; // было ли полностью загружено изображение

В методе init() класса апплета загрузить графическое изображение pic из файла, затем создать пустое изображение offScreenImage -нечто вроде виртуального экрана в памяти, получить графический контекст этого “экрана”, в который затем вывести изображение pic:

try

{ pic=getImage(new java.net.URL(getCodeBase(),"sample.gif"));

}

catch(java.net.MalformedURLException e)

{ // код здесь выполняется, если строка URL неправильна

pic=createImage(0,0); // создание пустого изображения

}

// создание виртуального экрана

Image offScreenImage=createImage(size().width,size().height);

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

Graphics offScreenGraphics= offScreenImage.getGraphics();

// вывод изображения на виртуальный экран

offScreenGraphics.drawImage(pic,0,0,this);

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

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

Переопределим в классе апплета метод imageUpdate():

public boolean imageUpdate(Image img,int infoflags,int x,int y,int w,int h)

{ if(infoflags==ALLBITS)

{ // изображение загружено полностью

picLoaded=true;

repaint();// перерисовать окно апплета

// больше метод imageUpdate не вызывать

return false;

}

return true; // изображение загружено в память не полностью

}

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

Переменная picLoaded используется в методе paint(). Когда она принимает значение true, то изображение pic (загруженное уже полностью), выводится в окно апплета:

public void paint (Graphics g)

{ if(picLoaded)

{ // четвертым параметром передается null,

// он не позволяет функции drawImage() вызывать

// метод imageUpdate() в процессе вывода

g.drawImage(pic,0,0,null);

// сообщение в панель состояния

showStatus("Done");

}

else

{ // сообщение в панель состояния

showStatus("Loading image");

}

}

Так как изображение теперь находится в памяти, оно тотчас появляется в окне апплета.

4. События и их обработка

Для того, чтобы взаимодействовать с пользователем в реальном масштабе времени и отслеживать изменения в оболочке времени выполнения Java, апплеты используют понятие событие (event). Событие - это информация, сгенерированная в ответ на некоторые действия пользователя (перемещение мыши, нажатие клавиши мыши или клавиши на клавиатуре). События также могут быть сгенерированы в ответ на изменение среды - к примеру, когда окно апплета заслоняется другим окном. Оболочка времени выполнения следит за происходящими событиями и передает информацию о событии особому методу, называемому обработчиком событий (event handler).

4.1 Обработчики событий от мыши и клавиатуры

Многие обычно используемые обработчики событий определены для класса Applet и по умолчанию не делают ничего - чтобы их использовать, надо переопределить метод суперкласса апплетов в классе создаваемого апплета, например:

public boolean mouseMove(Event evt,int x,int y)

{ // здесь можно разместить код, выполняющийся

// если мышь перемещается

return true; // событие обработано

}

Метод mouseMove() вызывается всякий раз при перемещении мыши. После обработки события метод возвращает true.

Перечислим часто используемые обработчики событий:

· boolean mouseDown(Event evt, int x, int y) - нажата кнопка мыши, параметры x и у указывают расположение мыши.

· boolean mouseUp(Event evt, int x, int y) - кнопка мыши отпущена.

· boolean mouseMove(Event evt, int x, int y) - перемещение мыши.

· boolean mouseDrag(Event evt, int x, int y) - перемещение мыши с нажатой кнопкой.

· boolean mouseEnter(Event evt, int x, int y) - перемещение мыши на окно апплета.

· boolean mouseExit(Event evt, int x, int y) - мышь покинула окно апплета.

· boolean keyDown(Event evt, int key) - нажата клавиша перемещения курсора или функциональная клавиша. Параметр key указывает эту клавишу.

· boolean keyUp(Event evt, int key) - клавиша перемещения курсора или функциональная клавиша отпущена.

Переопределяя эти методы в подклассе класса Applet, можно обрабатывать различные действия пользователя.

Обработчикам событий клавиатуры передается в качестве одного из параметров идентификатор клавиши. Идентификатор клавиши - это целое число, которое соответствует нажатой клавише. Обычные клавиши символов имеют значения, соответствующие их ASCII-кодам. Кроме того, Java поддерживает множество специальных клавиш (UP, DOWN, LEFT, RIGHT, PGUP, PGDOWN, HOME, END, F1 - F12). Эти специальные клавиши фактически определены как статические целые переменные (константы) класса Event. Следующий фрагмент иллюстрирует проверку нажатия клавиш управления курсором:

public boolean keyDown(Event evt, ink key)

{ switch(key)

{ case Event.UP:......; break;

case Event.DOWN:......; break;

case Event.LEFT:......; break;

case Event.RIGHT:......; break;

default: break;

}

return true;

}

4.2 Обработка событий

Рассмотрим, что происходит при возникновении события в окне апплета. При этом создается объект класса Event, в котором сохраняется информация для идентификации события и который передается затем методу handleEvent(). Этот метод проверяет тип события и вызывает соответствующий обработчик, передавая ему относящиеся к событию параметры. Например, при перемещении мыши возникает событие типа MOUSE_MOVE, которое и передается методу handleEvent(). Последний вызывает соответствующий этому событию метод mouseMove(), передавая ему положение мыши.

Класс Event содержит переменные, в которых хранится информация о событии. Перечислим переменные, описывающие событие:

· Object target - компонент (объект), в котором произошло событие

· int id - тип события, одна из констант, определенная в классе Event.

· int key - идентификатор клавиши

· int modifiers - состояние маски наложения клавиш

· long when - время, в которое произошло событие.

· int x - коодината x события

· int y - коодината y события

· int clickCount - равна 1 или 2 в зависимости от того был сделан одинарный или двойной щелчок.

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

public boolean handleEvent(Event evt)

{ switch(evt.id)

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

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

return super.handleEvent(evt);

case Event.MOUSE_MOVE:....; break;

case Event.MOUSE_DRAG:....; break;

case Event.MOUSE_UP:....; break;

case Event.MOUSE_DOWN:....; break;

}

return true;

}

События можно генерировать прямо в программе. Для этого нужно просто создать новый экземпляр класса Event, используя один из конструкторов, и послать его соответствующему объекту (можно даже самому себе):

// создание сообщения текущему объекту класса (самому себе)

Event Evt=new Event(this, // пункт назначения

System.currentTimeMillis(), // время события

MOUSE_MOVE, // тип события

new_x,new_y, // координаты x и y события

0,0); // идентификатор клавиши и модификаторы

4.3 Апплет, обрабатывающий события

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

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

В каталог, где содержится файл исходного текста, следует поместить файл с изображением arrow.gif

Для хранения состояния класса MouseEvent объявить в классе переменные:

private int m_x=0, m_y=0; // текущее положения курсора

private boolean follow=true; // режим отслеживания включен/выключен

Image imageCur; // переменная для граф. изображения

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

try

{ imageCur=getImage(new java.net.URL(getCodeBase(),"arrow.gif"));

}

catch(java.net.MalformedURLException e)

{ // код здесь выполняется, если строка URL неправильна

imCur=createImage(0,0); // создание пустого изображения

}

Для прорисовки изображения апплета вызывается метод paint(), его следует переопределить в классе MouseEvent следующим образом:

public void paint(Graphics g)

{ // рамка вокруг окна апплета

Dimension size=size(); // размер компонента (окна апплета)

g.drawRect(0,0,size.width-1,size.height-1);

// прорисовка изображения

g.drawImage(imageCur,m_x,m_y,this)

}

За обработку такого события, как перемещение мыши, отвечает метод mouseMove(). В этом методе необходимо сохранить текущие координаты мыши и перерисовать окно апплета:

public boolean mouseMove(Event evt, int x, int y)

{ if(follow) // если режим отслеживания

{ m_x=x; m_y=y; // сохранение координат

repaint(); // перерисовка окна

}

return true;

}

Режим слежения за курсором включается и выключается при нажатии, поэтому следует изменить метод mouseDown() следующим образом:

public boolean mouseDown(Event evt, int x, int y)

{ follow=!follow;

return true;

}

4.4 Устранение мерцания при выводе, двойная буферизация

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

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

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

Модифицируем апплет MouseEvent (пример 8), так чтобы эффект мерцания был устранен. В апплете нужно определить ссылки на виртуальный экран и его контекст отображения:

// изображение (виртуальный экран)

private Image OffScreenImage;

// контекст отображения (интерфейс) изображения

private Graphics OffscreenGraphics;

Для создания объектов этих типов добавим следующий фрагмент в метод init() после кода загрузки картинки из файла arrow.gif:

// пустое изображение (виртуальный экран)

OffScreenImage=createImage(size().width,size().height);

// получение контекста отображения для OffScreenImage

OffscreenGraphics=OffScreenImage.getGraphics();

В этом фрагменте создается пустое изображение размером с окно апплета (виртуальный экран). Объект OffscreenGraphics - это контекст для вывода в OffScreenImage. Апплет будет при помощи этого контекста рисовать на виртуальном экране с такой скоростью, с какой только сможет. Метод модификации update(), переопределяемый в апплете выводит изображение на объект Graphics с такой скоростью, с какой только сможет:

public void update(Graphics g)

{ // перерисовать виртуальный экран,

// то есть изображение OffScreenImage

paint(OffscreenGraphics);

// вывести изображение OffScreenImage в окно

g.drawImage(OffScreenImage,0,0,this);

}

Переопределим также и метод paint(), теперь он может, используя передаваемый ему контекст, выводить изображение на виртуальный экран при вызове его из метода update(), когда сам апплет требует перерисовки методом repaint(), так и при вызове его системой тогда, когда для окна требуется перерисовка в связи с его перекрытиями другими окнами:

public void paint(Graphics g)

{

g.setColor(Color.gray);

g.fillRect(0,0,size().width-1,size().height-1);

g.setColor(Color.black);

g.drawRect(0,0,size().width-1,size().height-1);

g.drawImage(imageCur,m_x,m_y,this);

}

5. Апплеты двойного назначения

Апплеты двойного назначения - это программа, которая может работать и под управлением WWW-навигатора, и автономно, как самостоятельное приложение. Создать апплеты двойного назначения, объединяющие функциональные возможности апплета и приложения в одном программном коде, достаточно легко. Следует лишь ввести оба метода main() и init() в одну и ту же программу, при этом выполняя в методе main() некоторые специфические действия.

Прежде всего в методе main() необходимо создать рамку окна, в котором будет отображаться вся графика (для создания рамки используется подкласс класса Frame, в котором как минимум переопределен метод-обработчик событий). Затем создать экземпляр класса апплета и связать его рамкой (фреймом). С помощью экземпляра апплета можно вызвать методы init() и start(), запуская апплет в методе main() так, как обычно это делает WWW-навигатор.

Нужно напомнить, что приложения не принимают параметры через HTML-файл, как это делает апплет. И следовательно, придется передавать приложению все параметры в одной командной строке, как это обычно делается с аргументами стандартной командой строки. Т.е. передача параметров такому апплету двойного назначения должна дублироваться при помощи командной строки и при помощи тега <PARAM> HTML-файла.

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

Создадим апплет двойного назначения Combi (пример 9) при помощи системы Java Applet Wizard. Для подготовки шаблона апплета двойного назначения в первой диалоговой панели нужно установить переключатель “As on applet and as on application”.

Рассмотрим тексты файлов, созданные системой Java Applet Wizard. Тексты подобных шаблонных файлов содержатся в Приложении 4 и их можно в дальнейшем использовать в качестве шаблонов апплета двойного назначения.

Пример 9. Файлa, созданный Java Applet Wizard

Листинг Java-файла первичного класса:

//*************************************************************

// Combi.java: Applet

//

//*************************************************************

import java.applet.*;

import java.awt.*;

import CombiFrame; // импорт класса рамки (фрейма)

public class Combi extends Applet

{

// ПОДДЕРЖКА РАБОТЫ ПРОГРАММЫ КАК ПРИЛОЖЕНИЯ:

// Признак режима работы программы:

// true - работа в качестве приложения

// false - работа в качестве апплета

//--------------------------------------------------------

private boolean m_fStandAlone = false;

// ПОДДЕРЖКА РАБОТЫ ПРОГРАММЫ КАК ПРИЛОЖЕНИЯ:

// Метод main() - точка входа в случае работы программы как

// приложения. Если программа загружается при помощи

// документа HTML, то этот метод игнорируется

//--------------------------------------------------------

public static void main(String args[])

{ // Здесь можно обработать аргументы

// командной строки, если они есть

// Создать рамку (фрейм) для апплета. Класс CombiFrame

// наследуется от класса Frame, в нем как минимум

// переопределяется метод завершение работы приложения

//------------------------------------------------

CombiFrame frame = new CombiFrame("Combi");

// До изменения размеров фрейма отобразить его.

// Это необходимо для того, чтобы метод insert()

// выдавал правильные значения

//------------------------------------------------

frame.show(); frame.hide();

frame.resize(frame.insets().left + frame.insets().right + 320,

frame.insets().top + frame.insets().bottom + 240);

// Создание объекта апплета, связывание апплета и фрейма

//------------------------------------------------

Combi applet_Combi = new Combi();

frame.add("Center", applet_Combi);

// Установление признака режима работы - приложение

//------------------------------------------------

applet_Combi.m_fStandAlone = true;

// Вызов методов ааплета для его запуска

//------------------------------------------------

applet_Combi.init();

applet_Combi.start();

// Отображение окна фрейма

//------------------------------------------------

frame.show();

}

//--------------------------------------------------------

public Combi()

{

// Сделать: Добавьте сюда код конструктора

}

//--------------------------------------------------------

public String getAppletInfo()

{

return "Name: Combi\r\n" +

"";

}

//--------------------------------------------------------

public void init()

{ //------------------------------------------------

resize(320, 240);

// Сделать: Добавьте сюда код инициализации

}

//--------------------------------------------------------

public void destroy()

{

// Сделать: Добавьте сюда код завершения работы апплета

}

//--------------------------------------------------------

public void paint(Graphics g)

{

g.drawString("Created with Microsoft Visual J++ Version 1.1",10, 20);

}

//--------------------------------------------------------

public void start()

{

// Сделать: Добавьте сюда код, который должен

// работать при запуске апплета

}

//--------------------------------------------------------

public void stop()

{

// Сделать: Добавьте сюда код, который должен

// работать при остановке апплета

}

// Сделать: Добавьте сюда код, необходимый для работы

// создаваемого специализированного апплета

}

Листинг Java-файла класса фрейма для апплета:




Поделиться с друзьями:


Дата добавления: 2014-11-20; Просмотров: 458; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.203 сек.