Понятие апплета
Содержание
1 Введение
2 Запуск потоков в апплетах
3 Классы Applet, Image и MediaTracker
Введение
В первом упоминании Java-технологии, наиболее перспективными выглядели, так называемые, апплеты (небольшие программы, исполняемые внутри броузера, и позволяющие сделать web-страницы более интерактивными). Вспомним Internet 1995 года, когда большинство web-страниц было статичными, а динамическое содержимое состояло из Perl-скриптов, исполняемых посредством CGI (Common Gateway Interface) интерфейса. Особо большого пространства для фантазии при проектировании сайтов не было, отсутствовала анимированная графика, а также какое-либо взаимодействие между пользователями. Такое взаимодействие требует для отправки информации web-серверу использование цикла запроса-ответа иного рода. В то же время, компания Netscape захватила рынок броузеров и первой получила лицензию на использование продукции Java для броузера Netscape Navigator. После этого компания Microsoft также подписала контракт и включила в Internet Explorer свою версию виртуальной машины для поддержки выполнения Java-программ.
Спустя несколько лет мир снова взглянул на апплеты, как на программы, встраиваемые в броузер. Разработчики снова стали использовать решения, базирующиеся на апплетах, так как Java Plug-in от Sun позволяет обновлять старую версию виртуальной машины, встроенную в Internet Explorer, до последней – Java Runtime Environment (JRE) – посредством Технологии Get Java.
Однако чем же все-таки является апплет? С технической стороны, апплетом может служить любой класс, расширяемый от класса Applet пакета java.applet. Это фактическое определение, однако не исчерпывающее. Если у вас имеется данный подкласс, вы можете добавить его к web-странице, разместив между тегами <APPLET> - </APPLET>. После этого броузер будет загружать класс апплета и отображать его в назначенном пространстве.
Кроме этого у вас в распоряжении имеются методы init, start, stop и destroy. При рисовании и отображении областей применяется метод paint, так как Applet является подклассом java.awt.Component. Эти пять ключевых методов работают следующим образом:
init – вызывается при загрузке броузером основного класса Applet. Обычно у апплетов нет конструктора. Вместо этого используется код их единовременной инициализации.
start – вызывается в начале выполнения апплета при посещении пользователем страницы.
stop – вызывается для остановки выполнения аплета, когда пользователь покидает страницу, содержащую данный апплет.
destroy – вызывается в случае, если броузер должен завершить работу апплета. При этом ресурсы можно восстановить, однако у вас не будет над ними контроля.
paint – вызывается, когда броузер определяет, что область отображения апплета является неверной.
В качестве примера рассмотрим апплет, который при вызове каждого из пяти методов выводит информацию в консоль. Метод paint используется также для отображения сообщения на экране. При каждом вызове метода paint число увеличивается. При этом напрашивается вопрос о том, где же можно найти сообщения, записываемые в консоль. Ответ зависит от используемого броузера, а иногда и от его версии. В IE 6.0 Java Console находится в меню Tools. В рабочем цикле Microsoft и IE6 консоль расположен в меню View. А в броузерах Mozilla и Netscape 7.0, Java Console находится в меню Web Development (вложено в меню Tools).
Код апплета выглядит следующим образом:
import java.awt.*;
import java.applet.*;
public class FirstApplet extends Applet {
public void init() {
System.out.println("In init()");
}
public void start() {
System.out.println("In start()");
}
public void stop() {
System.out.println("In stop()");
}
public void destroy() {
System.out.println("In destroy()");
}
public synchronized void paint(Graphics g) {
System.out.println("In paint()");
g.drawString("Painting...", 50, 50);
}
}
Скомпилируйте апплет так же, как и любой другой исходный файл:
javac FirstApplet.java
Если в файле не будет ошибок, будет создан класс FirstApplet.class.
Загрузка апплетов несколько отличается от загрузки автономных программ. Вместо обеспечения основного метода, исполняемого один раз при загрузке файла, загрузка апплета требует наличия HTML-файла. Именно в нем размещается тег <APPLET>. Вот как выглядит определение тега:
<APPLET // Обязательные CODE = appletClass or OBJECT = serializedApplet HEIGHT = pixels WIDTH = pixels // Необязательные CODEBASE = codebaseURL ARCHIVE = archiveList ALT = alternateText NAME = instanceName ALIGN = alignment HSPACE = pixels VSPACE = pixels > <PARAM NAME = attribute1 VALUE = value1> <PARAM NAME = attribute2 VALUE = value2> ... Alternate HTML </APPLET>
Для апплета, файл-загрузчик должен выглядеть так, как представлено ниже, и располагаться в той же директории, что и файл .class:
<APPLET code=FirstApplet height=200 width=200> </APPLET>
Атрибут code указывает имя загружаемого класса. Значение атрибутов width и height очевидно – при их помощи выставляется желаемый размер отображения апплета. Если файл класса апплета использует базовую директорию отличную от директории файла-загрузчика HTML, вам потребуется задать CODEBASE, позволяющий указать броузеру расположение базовой директории.
Поместите данный тег в любой HTML-файл и загрузите его в броузере.
Далее представлен пример метода, содержащего несколько локальных внутренних классов:
ПРИМЕЧАНИЕ: При использовании виртуальной машины Microsoft, Java консоль может отобразить ошибку NoClassDefFoundError. Если у вас не установлен Java Plug-in, то запуск апплета при помощи виртуальной машины Microsoft будет невозможным, так как с момента ее выпуска формат файла .class изменился. Для того чтобы сделать файл .class совместимым с более старыми версиями Microsoft VM, нельзя использовать программные средства новее версии 1.1.4, а компилировать следует при помощи опции –target следующим образом:
javac -target 1.1 FirstApplet.java
Подобной проблемы не возникнет, если у вас был установлен Java Plug-in. В этом случае вам потребуется просто скомпилировать исходный код и загрузить HTML-файл в своем броузере.
Запуск потоков в апплетах
Используя потоки в апплетах, необходимо учитывать несколько важных концепций:
Создавая апплет, вы расширяете класс Applet. Поэтому, для того чтобы использовать потоки, необходимо реализовать интерфейс Runnable или определить поток как внутренний класс Thread.
public class Example extends Applet implements Runnable
В методе start апплета создайте новый объект Thread (хотя объект thread также содержит метод start, он не совпадает с соответствующим методом апплета).
Из-за того, что реализуется интерфейс Runnable, вам необходимо обеспечить для класса метод run. Данный метод вызывается при запуске потока объектом thread для выполнения предназначенных ему операций.
Следующий апплет демонстрирует скроллинг текста, который «проходит» по своему собственному потоку, что позволяет вносить новый текст в текстовое поле во время его прокрутки. Если бы прокручивающийся текст не находился в отдельном потоке, то этот текст так бы загрузил ЦПУ, что вводить текст в поле было бы невозможным.
import java.applet.*;
import java.awt.*;
public class ExampleThreads extends Applet implements Runnable {
String text = "An example of text scrolling in its own thread.";
TextField field;
Thread thread;
boolean running;
public void init() {
// открыть init
Font fnt = new Font("Monospaced", Font.BOLD, 26);
setFont(fnt);
FontMetrics fm = getFontMetrics(fnt);
int spaceWidth = fm.charWidth(' ');
int panelWidth = getSize().width;
int numSpaces = panelWidth / spaceWidth + 1;
// Добавить необходимые пробелы в текст
for (int i = 0; i < numSpaces; ++i) {
text = text + ' ';
}
field = new TextField("Type Here");
add(field);
}
// закрыть init
public void start() {
if (thread == null) {
thread = new Thread(this);
running = true;
thread.start();
}
}
public void run() {
while (running) {
text = text.substring(1, text.length()) + text.charAt(0);
repaint();
try {
Thread.sleep(100);
}
catch (InterruptedException e) {
}
}
}
public void stop() {
if (thread != null) {
running = false;
thread = null;
}
}
public void paint(Graphics g) {
g.drawString(text, 0, 150);
}
}
Создайте HTML-страницу, как показано далее, после чего запустите ее в программе для просмотра апплетов или в броузере.
<html> <head> <title>Test Program</title> </head> <body> <applet code="ExampleThreads.class" width="400" height="200"> </applet> </body> </html>
При запуске приложение должно выглядеть следующим образом:
Классы Applet, Image и MediaTracker
В представленной ранее статье описано, как посредством HTML-страницы передавать в апплет некоторую информацию, такую как местоположение файла класса, а также высота и размеры самого апплета. Кроме передачи информации о самом апплете и его исходном файле, можно также передавать необязательные параметры, используя для этой цели теги PARAM и метод getParameter класса Applet.
Например, вы хотите, чтобы в апплете отображалась графические или какие-либо другие объекты. Для того чтобы в апплете можно было использовать изображения, необходимо сначала связать каждое из них с абстрактным классом Image. Затем, путем передачи параметров через HTML-файл, можно задать информацию о количестве изображений и их именах.
Например, если вам необходимо отобразить в апплете четыре изображения, можно начать со строки:
Image images = new Image[4];
У класса Image также есть методы getWidth и getHeight, которые возвращают значение размеров изображений в пикселях.
Тег PARAM имеет следующий синтаксис:
<PARAM NAME = attribute1 VALUE = value1>
При помощи тега PARAM можно указывать апплету количество используемых изображений:
<PARAM NAME = number VALUE=4>
При помощи тегов PARAM укажем в HTML-файле имена файлов с изображениями:
<PARAM NAME = image1 VALUE=seahorse.jpg> <PARAM NAME = image2 VALUE=rockfish.jpg> <PARAM NAME = image3 VALUE=tubesnout.jpg> <PARAM NAME = image4 VALUE=seabass.jpg>
Укажите апплету извлечь данные параметры при помощи метода getParameter. Строка String, передаваемая в метод getParameter, возвращает в HTML-тег значение названного параметра.
Например:
getParameter("image1");
возвращает строку seahorse.jpg.
Для того чтобы узнать местонахождение встраиваемых ресурсов апплета вызовите метод getCodeBase, который возвратит их URL-адрес. Метода getImage позволяет извлечь объект изображения для выведения его на экран:
getImage(getCodeBase(), "CoLogo.jpg");
Осуществлять более сложные операции (такие как переключение между изображениями) можно при помощи класса MediaTracker, позволяющего управлять загружаемыми изображениями и отображать их статус. Класс MediaTracker является классом утилиты, используемым для отслеживания статуса многочисленных медиа-объектов.
Чтобы сконструировать объект MediaTracker, вызовите конструктор MediaTracker и передайте ему Component, который выполняет прорисовку изображений.
Например:
ImagePanel p = new ImagePanel();
MediaTracker tracker = new MediaTracker(p);
Если вы уже создали объект MediaTracker, задайте ему изображение, вызвав для этого метод addImage (Image image, int ID). Кроме того, каждому изображению может быть назначен уникальный идентификатор. Данный идентификатор контролирует порядок приоритетов, в котором выбираются изображения. С его помощью можно также идентифицировать уникальные наборы независимых изображений. Чем больше значение ID, тем выше приоритет загрузки изображений.
Например:
tracker.addImage(image, IMAGE_ID);
Для того чтобы определить, загружено ли изображение и готово ли оно к прорисовке, вызовите один из нижеперечисленных методов:
checkAll – проверяет, закончилась ли загрузка всех изображений, отслеживаемых данным объектом media tracker.
checkAll(boolean load) – проверяет, закончилась ли загрузка всех изображений, отслеживаемых данным объектом media tracker.
checkID(int id) – проверяет, закончилась ли загрузка всех изображений, отслеживаемых данным объектом media tracker, и помеченных специальным идентификатором.
statusAll(boolean load) – вычисляет и возвращает побитовый оператор включающего ИЛИ статуса всех media-объектов, отслеживаемых данным объектом media tracker.
waitForAll() – начинает загрузку всех картинок, отслеживаемых данным media tracker.
waitForAll(long ms) – начинает загрузку всех изображений, отслеживаемых данным объектом media tracker.
Наример:
int status = tracker.statusALL();
if (status & MediaTracker.COMPLETE);
System.out.println("Images have been loaded");
В классе MediaTracker есть также другие методы и константы, полезные при работе с изображениями.