До СЃРёС… РїРѕСЂ РјС‹ создавали приложения (applications), работающие самостоятельно (standalone) РІ JVM РїРѕРґ управлением графической оболочки операционной системы. Рти приложения имели собственное РѕРєРЅРѕ верхнего СѓСЂРѕРІРЅСЏ типа Frame, зарегистрированное РІ РѕРєРѕРЅРЅРѕРј менеджере (window manager) графической оболочки.
РљСЂРѕРјРµ приложений язык Java позволяет создавать апплеты (applets). Рто программы, работающие РІ среде РґСЂСѓРіРѕР№ программы — браузера. Апплеты РЅРµ нуждаются РІ РѕРєРЅРµ верхнего СѓСЂРѕРІРЅСЏ — таким РѕРєРЅРѕРј служит РѕРєРЅРѕ браузера. Апплеты РЅРµ запускаются СЃ помощью JVM — РёС… загружает браузер, который сам запускает JVM для выполнения апплета. Рти особенности отражаются РЅР° написании программы апплета.
С точки зрения графической библиотеки AWT, апплет — это всякое расширение класса Applet, который, в свою очередь, расширяет класс Panel. Таким образом, апплет — это панель специального вида, контейнер для размещения компонентов с дополнительными свойствами и методами. Менеджером размещения компонентов по умолчанию, как и в классе Panel, служит FlowLayout. Класс Applet находится в пакете j ava. applet, в котором кроме него есть только три интерфейса, реализованные в браузере. Надо заметить, что не все браузеры реализуют эти интерфейсы полностью.
В графической библиотеке Swing всякий апплет расширяет класс JApplet, расширяющий класс Applet. Главные дополнения Swing к свойствам апплета AWT заключаются в возможности добавления системы меню методом setJMenuBar(JMenuBar) и в наличии множества панелей, как в классе JFrame. На панели, получаемой методом getContentPane (), по умолчанию установлен менеджер размещения BorderLayout.
Еще одна особенность апплета, вытекающая из того, что он не запускается машиной JVM, заключается в том, что отпадает необходимость в методе main (), его нет в апплетах.
В апплетах редко встречается конструктор. Дело в том, что при запуске апплета создается его контекст. Во время выполнения конструктора контекст еще не сформирован полностью, поэтому не все начальные значения удается определить в конструкторе.
Начальные действия, обычно выполняемые РІ конструкторе Рё методе main (), РІ апплете записываются РІ метод init () класса Applet. Ртот метод автоматически запускается исполняющей системой Java браузера сразу же после загрузки апплета. Р’РѕС‚ как РѕРЅ выглядит РІ РёСЃС…РѕРґРЅРѕРј РєРѕРґРµ класса Applet:
public void init(){}
Негусто! Метод init () не имеет аргументов, не возвращает значения и должен переопределяться в каждом апплете — подклассе класса Applet.
Обратные действия — завершение работы, освобождение ресурсов — записываются при необходимости в метод destroy(), тоже выполняющийся автоматически при выгрузке апплета. В классе Applet есть пустая реализация этого метода.
Кроме методов init () и destroy() в классе Applet присутствуют еще два пустых метода, выполняющихся автоматически. Браузер должен обращаться к методу start () при каждом появлении апплета на экране и обращаться к методу stop(), когда апплет уходит с экрана. В методе stop () можно определить действия, приостанавливающие работу апплета, в методе start () — возобновляющие ее. Надо сразу же заметить, что не все браузеры обращаются к этим методам как должно. Работу указанных методов можно пояснить простым житейским примером.
Приехав весной на дачный участок, вы прокладываете водопроводные трубы, прикручиваете краны, протягиваете шланги — выполняете метод init () для своей оросительной системы. После этого, приходя летом на участок, вы включаете краны — запускаете метод start (), а уходя, выключаете их — выполняете метод stop (). Наконец, осенью вы разбираете оросительную систему, отвинчиваете краны, просушиваете и укладываете водопроводные трубы — выполняете метод destroy().
Все эти методы в апплете необязательны. В листинге 18.1 записан простейший апплет библиотеки AWT, выполняющий вечную программу HelloWorld.
Листинг 18.1. Апплет HelloWorld
import java.awt.*; import java.applet.*;
public class HelloWorld extends Applet{ public void paint(Graphics g){
g.drawString("Hello, XXI century World!", 10, 30);
}
}
Рта программа записывается РІ файл HelloWorldjava Рё компилируется как обычно:
javac HelloWorld.java
Компилятор создает файл HelloWorld.class, но воспользоваться для его выполнения интерпретатором j ava теперь нельзя — нет метода main (). Вместо интерпретации надо дать указание браузеру для запуска апплета.
Все указания браузеру даются пометками, тегами (tags), на языке HTML (HyperText Markup Language). В частности, указание на запуск апплета дается в теге
Листинг 18.2. Файл HTML ДЛЯ загрузки апплета HelloWorld
Ниже выполняется апплет.<Ьг>
Ртот текст заносится РІ файл СЃ расширением html или htm, например HelloWorld.html. РРјСЏ файла произвольно, никак РЅРµ связано СЃ апплетом или классом апплета.
РћР±Р° файла — HelloWorld.html Рё HelloWorld.class — помещаются РІ РѕРґРёРЅ каталог РЅР° сервере, Рё файл HelloWorld.html загружается РІ браузер, который может находиться РІ любом месте Рнтернета. Браузер, просматривая HTML-файл, выполнит тег
Рис. 18.1. Апплет HelloWorld в окне Internet Explorer |
В этом простом примере можно заметить еще две особенности апплетов. Во-первых, размер апплета задается не в нем, а в теге
Во-вторых, как видно на рис. 18.1, у апплета серый фон. Такой фон был в первых браузерах, и апплет не выделялся из текста в окне браузера. Теперь в браузерах принят белый фон, который можно установить обычным для компонентов методом
setBackground(Color.white ), обратившись к нему в методе init ( ).
Р’ состав JDK любой версии РІС…РѕРґРёС‚ программа appletviewer. Рто простейший браузер, предназначенный для запуска апплетов РІ целях отладки. Если РїРѕРґ СЂСѓРєРѕР№ нет полноцен-
ного обозревателя, можно воспользоваться им. Программа appletviewer запускается из командной строки:
appletviewer HelloWorld.html
На рис. 18.2 appletviewer показывает апплет HelloWorld.
Рис. 18.2. Апплет HelloWorld в окне программы appletviewer |
Приведем пример невидимого апплета. В нижней строке браузера — строке состояния (status bar) — отражаются сведения о загрузке файлов. Апплет может записать в нее любую строку str методом showStatus(String str). В листинге 18.3 приведен апплет, записывающий в строку состояния браузера "бегущую строку", а в листинге 18.4 — соответствующий HTML-файл.
Листинг 18.3. Бегущая строка в строке состояния браузера
// Файл RunningString.j ava import java.awt.*; import java.applet.*;
public class RunningString extends Applet{ private boolean go;
public void start(){ go = true;
sendMessage("Рта строка выводится апплетом");
}
public void sendMessage(String s){
String s1 = s + " ";
while (go){
showStatus(s); try{
Thread.sleep(200);
}catch(Exception e){} s = s1.substring(1) + s.charAt(0);
s1 =s;
}
public void stop(){ go = false;
}
}
Листинг 18.4. Файл RunningString.html
Здесь работает апплет.<ы>
К сожалению, нет строгого стандарта на выполнение апплетов, и браузеры могут запускать их по-разному. Программа appletviewer способна показать апплет не так, как браузеры. Приходится проверять апплеты на всех имеющихся в распоряжении браузерах, добиваясь одинакового выполнения.
Приведем более сложный пример. Апплет ShowWindow создает окно SomeWindow типа Frame, в котором расположено поле ввода типа TextField. В него вводится текст, и после нажатия клавиши
Листинг 18.5. Апплет, создающий окно
// Файл ShowWindow.j ava import java.awt.*; import java.awt.event.*; import java.applet.*;
public class ShowWindow extends Applet{ private SomeWindow sw = new SomeWindow(); private TextField tf = new TextField(30); private Button b = new Button("Скрыть");
public void init(){
add(tf); add(b); sw.pack(); b.addActionListener(new ActShow()); sw.tf.addActionListener(new ActShow());
}
public void start(){ sw.setVisible(true); } public void stop(){ sw.setVisible(false); } public void destroy(){ sw.dispose(); sw = tf = b = null; }
public class ActShow implements ActionListener{ public void actionPerformed(ActionEvent ae){ if (ae.getSource() == sw.tf) tf.setText(sw.tf.getText()); else if (b.getActionCommand() == "Показать"){ sw.setVisible(true); b.setLabel("Скрыть");
}else{
sw.setVisible(false) ; b.setLabel("Показать");
}
}
}
}
class SomeWindow extends Frame{
public TextField tf = new TextField(50);
SomeWindow(){
super(" РћРєРЅРѕ РІРІРѕРґР°");
add(new LaЬel(,,Введите, пожалуйста, свое имя"), "North"); add(tf, "Center");
}
}
Листинг 18.6. Файл ShowWindow.html
Здесь появится Ваше имя.<Ьг>
_|Рї|С…] | |
<J_ | Введите, пожалуйста, свое имя |
Done 1 1 Р™ | |Рван Петрович |
Warning; Applet Window |
Рис. 18.3. Апплет, создающий окно
Замечание по отладке
Браузеры помещают загруженные апплеты в свой кэш, поэтому после нажатия кнопки Refresh или Reload запускается старая копия апплета из кэша. Для загрузки новой копии надо при щелчке по кнопке Refresh в Internet Explorer (IE) держать нажатой клавишу
Упражнения
1. Создайте апплет — "записную книжку", как в главе 15.
2. Создайте апплет — "рисовалку" по схеме главы 15.
3. Запрограммируйте игру в "крестики-нолики" в виде апплета.
Передача параметров в апплет
При запуске приложения интерпретатором j ava из командной строки в него можно передать параметры в виде аргумента метода main(String[] args). В апплеты тоже можно передавать параметры, но другим путем.
Передача параметров в апплет производится с помощью тегов , располагаемых между открывающим тегом в HTML-файле. В тегах указывается название параметра name и его значение value.
Передадим, например, в наш апплет HelloWorld параметры шрифта. В листинге 18.7 показан измененный файл HelloWorld.html.
Листинг 18.7. Параметры для передачи в апплет
Ниже выполняется апплет.<ы>
В апплете для приема каждого параметра надо воспользоваться методом getParameter (String name) класса Applet, возвращающим строку типа String. В качестве аргумента этого метода задается значение параметра name в виде строки, причем здесь не различается регистр букв, а метод возвращает значение параметра value тоже в виде строки.
Замечание по отладке
Операторы System.out.println(), обычно записываемые в апплет для отладки, выводят указанные в них аргументы в специальное окно браузера Java Console. Сначала надо установить возможность показа этого окна. В Internet Explorer это делается установкой флажка Java Console enabled после выбора команды Tools | Internet Options | Advanced. После перезапуска IE в меню View появляется команда Java Console.
В листинге 18.8 показан переработанный апплет HelloWorld. В нем назначен белый фон, а шрифт устанавливается с параметрами, извлеченными из HTML-файла.
Листинг 18.8. Апплет, принимающий параметры
import java.awt.*; import java.applet.*;
public class HelloWorld extends Applet{ public void init(){
setBackground(Color.white);
String font = "Serif";
int style = Font.PLAIN, size = 10;
font = getParameter("fontName");
style = Integer.parseInt(getParameter("fontStyle")); size = Integer.parseInt(getParameter("fontSize")); setFont(new Font(font, style, size));
} public void paint(Graphics g){
g.drawString("Hello, XXI century World!", 10, 30);
}
}
Совет
Надеясь на то, что параметры будут заданы в HTML-файле, все-таки задайте начальные значения переменным в апплете, как это сделано в листинге 18.8.
На рис. 18.4 показан работающий апплет.
Рис. 18.4. Апплет с измененным шрифтом |
Правила хорошего тона рекомендуют описать параметры, передаваемые апплету, в виде массива, каждый элемент которого — массив из трех строк, соответствующий одному параметру. Данная структура представляется в виде "имя", "тип", "описание". Для нашего примера можно написать:
String[][] pinfo = {
{"fontName", "String", "font name"},
{"fontStyle", "int", "font style"},
{"fontSize", "int", "font size"}
};
Затем переопределяется метод getParameterInfo (), возвращающий указанный массив. Рто пустой метод класса Applet. Любой объект, желающий узнать, что передать апплету, может вызвать этот метод. Для нашего примера переопределение выглядит так:
public String[][] getParameterInfo(){ return pinfo;
}
Кроме того, правила хорошего тона предписывают переопределить метод getAppletInfo (), возвращающий строку, в которой записано имя автора, версия апплета и прочие сведения об апплете, которые вы хотите предоставить всем желающим. Например:
public String getAppletInfo(){
return "MyApplet v.1.5 P.S.Ivanov";
}
Несколько параметров имеют специальное значение. Они передаются не апплету, а браузеру и учитываются им при запуске JVM. Во-первых, параметром java_arguments можно передать аргументы запуска JVM, например,
Во-вторых, можно указать браузеру, чтобы он для выполнения апплета запустил отдельный экземпляр JVM, дав параметру separate_jvm значение true (по умолчанию
false):
В-третьих, параметром java_version можно указать версию JRE, необходимую для выполнения апплета, например,
Рта версия будет загружена РІ браузер, если ее там еще нет.
Р’-четвертых, если загрузка апплета задерживается, браузер показывает РІ области экрана, предназначенной для апплета, стандартное РѕРєРЅРѕ-заставку СЃ логотипом Lava, стандартным текстом Рё индикатором выполнения загрузки апплета, РЅР° жаргоне называемом "градусником". Рти стандартные значения можно заменить СЃ помощью параметров, как показывает следующий пример:
Посмотрим теперь, какие еще атрибуты можно задать в теге
Атрибуты тега
Перечислим все атрибуты тега
Обязательные атрибуты:
□ code — URL-адрес файла с классом апплета или архивного файла;
□ width и height — ширина и высота апплета в пикселах.
Необязательные атрибуты:
□ codebase — URL-адрес каталога, в котором расположен файл класса апплета. Если этот атрибут отсутствует, браузер будет искать файл в том же каталоге, в котором лежит соответствующий HTML-файл;
□ archive — файлы всех классов, составляющих апплет, могут быть упакованы архиватором ZIP или специальным архиватором JAR, который мы опишем в главе 25, в один или несколько архивных файлов. Атрибут задает URL-адреса этих файлов через запятую;
в–Ў align — выравнивание апплета РІ РѕРєРЅРµ браузера. Ртот атрибут имеет РѕРґРЅРѕ РёР· следующих значений: absbottom, absmiddle, baseline, bottom, center, left, middle, right,
TEXTTOP, TOP;
□ hspace и vspace — горизонтальные и вертикальные поля, отделяющие апплет от других объектов в окне браузера в пикселах;
в–Ў download — РїРѕСЂСЏРґРѕРє загрузки изображений апплетом. Рмена изображений перечисляются через запятую РІ РїРѕСЂСЏРґРєРµ загрузки;
□ name — имя апплета. Атрибут нужен, если загружаются несколько апплетов с одинаковыми значениями code и codebase;
□ style — информация о стиле CSS (Cascading Style Sheet, каскадная таблица стилей);
□ title — текст, отображаемый в процессе выполнения апплета;
□ alt — текст, выводимый вместо апплета, если браузер не может загрузить его;
в–Ў mayscript — РЅРµ имеет значения. Рто слово указывает РЅР° то, что апплет будет обращаться Рє тексту JavaScript.
Между тегами можно написать текст, который будет выведен, если браузер не сможет понять тег
codebase = "" width = "300" height = "200" align = "TOP" vspace = "5" hspace = "5" mayscript alt = "If you have a java-enabled browser, you would see an applet here.">
If your browser recognized the applet tag, you would see an applet here.
Совет
Обязательно упаковывайте РІСЃРµ классы апплета РІ zip- Рё jar-архивы Рё указывайте РёС… РІ параметре archive РІ HTML-файле. Рто значительно СѓСЃРєРѕСЂРёС‚ загрузку апплета.
Следует еще сказать, что, начиная с версии 4.0, в языке HTML есть тег
Мы уже упоминали, что при загрузке апплета браузер создает контекст, в котором собирает все сведения, необходимые для выполнения апплета. Некоторые сведения из контекста можно передать в апплет.
Сведения об окружении апплета
Метод getcodeBase () возвращает URL-адрес каталога, в котором лежит файл класса апплета.
Метод getDocumentBase () возвращает URL-адрес каталога, в котором лежит HTML-файл, вызвавший апплет.
Браузер реализует интерфейс Appletcontext, находящийся в пакете java.applet. Апплет может получить ссылку на этот интерфейс методом getAppletContext ( ).
С помощью методов getApplet(String name) и getApplets() интерфейса AppletContext можно получить ссылку на указанный аргументом name апплет или на все апплеты, загруженные в браузер.
Метод showDocument (URL address) загружает в браузер HTML-файл с адреса address.
Метод showDocument (URL address, String target) загружает файл РІРѕ фрейм, указанный вторым аргументом target. Ртот аргумент может принимать следующие значения:
□ _self — то же окно и тот же фрейм, в котором работает апплет;
□ _parent — родительский фрейм апплета;
□ _top — фрейм верхнего уровня окна апплета;
□ _blank — новое окно верхнего уровня;
□ name — фрейм или окно с именем name. Если оно не существует, то будет создано.
Упражнение
4. Напишите апплет, собирающий все сведения о своем контексте.
Рзображение Рё Р·РІСѓРє РІ апплетах
Рзображение РІ Java — это объект класса Image, представляющий прямоугольный массив пикселов. Его РјРѕРіСѓС‚ показать РЅР° экране логические методы drawimage () класса
Graphics.
Мы рассмотрим их подробно в главе 20, а пока нам понадобятся два логических метода:
drawImage(Image img, int x, int y, ImageObserver obs); drawImage(Image img, int x, int y, int width, int height,
ImageObserver obs);
Методы начинают рисовать изображение, не дожидаясь окончания загрузки изображения img. Более того, загрузка не начнется, пока не вызван метод drawimage (). Методы возвращают false, пока загрузка не закончится.
Аргументы (x, y) задают координаты левого верхнего угла изображения img; width и height — ширину и высоту изображения на экране; obs — ссылку на объект, реализующий интерфейс ImageObserver, следящий за процессом загрузки изображения. Последнему аргументу можно дать значение this.
Первый метод задает на экране такие же размеры изображения, как и у объекта класса Image, без изменений. Получить эти размеры можно методами getWidth(), getHeight() класса Image.
Рнтерфейс ImageObserver, реализованный классом Component, Р° значит, Рё классом Applet, описывает только РѕРґРёРЅ логический метод imageUpdate (), выполняющийся РїСЂРё каждом изменении изображения. Рменно этот метод побуждает перерисовывать компонент РЅР° экране РїСЂРё каждом его изменении. Посмотрим, как его можно использовать РІ процессе загрузки файлов РёР· Рнтернета.
Слежение за процессом загрузки
Если РІС‹ хотя Р±С‹ раз видели, как изображение загружается РёР· Рнтернета, то заметили, что РѕРЅРѕ появляется РЅР° экране РїРѕ частям РїРѕ мере загрузки. Рто РїСЂРѕРёСЃС…РѕРґРёС‚ РІ том случае, РєРѕРіРґР° системное свойство awt. image. incrementalDraw имеет значение true.
При поступлении каждой порции изображения браузер вызывает логический метод imageUpdate () интерфейса ImageObserver. Аргументы этого метода содержат информацию о процессе загрузки изображения img. Рассмотрим их:
imageUpdate(Image img, int status, int x, int y, int width, int height);
Аргумент status хранит информацию о загрузке в виде одного целого числа, которое можно сравнить со следующими константами интерфейса ImageObserver:
□ width — ширина уже загруженной части изображения известна и может быть получена из аргумента width;
□ height — высота уже загруженной части изображения известна и может быть получена из аргумента height;
□ properties — свойства изображения уже известны, их можно получить методом
getProperties () класса Image;
□ somebits — получены пикселы, достаточные для рисования масштабированной версии изображения; аргументы x, y, width, height определены;
□ framebits — получен следующий кадр изображения, содержащего несколько кадров; аргументы x, y, width, height не определены;
□ allbits — все изображение получено, аргументы x, y, width, height не содержат информации;
□ error — загрузка прекращена, рисование прервано, определен бит abort;
□ abort — загрузка прервана, рисование приостановлено до прихода следующей порции изображения.
Вы можете переопределить этот метод в своем апплете и использовать его аргументы для слежения за процессом загрузки и выяснения момента полной загрузки.
Другой способ отследить окончание загрузки — воспользоваться методами класса MediaTracker. Они позволяют проверить, не окончена ли загрузка, или приостановить работу апплета до окончания загрузки. Один экземпляр класса MediaTracker может следить за загрузкой нескольких зарегистрированных в нем изображений.
Класс MediaTracker
Сначала конструктором MediaTracker(Component comp) создается объект класса для указанного аргументом компонента. Аргумент конструктора чаще всего this.
Затем методом addImage(Image img, int id) регистрируется изображение img под порядковым номером id. Несколько изображений можно зарегистрировать под одним номером.
После этого логическими методами checkID(int id), checkID(int id, boolean load) и checkAll () проверяется, загружено ли изображение с порядковым номером id или все зарегистрированные изображения. Методы возвращают true, если изображение уже загружено, false — в противном случае. Если аргумент load равен true, то производится загрузка всех еще не загруженных изображений.
Методы statusID(int id), statusID(int id, boolean load) и statusAll() возвращают целое число, которое можно сравнить со статическими константами complete, aborted, errored.
Наконец, методы waitForiD(int id) и waitForAll() ожидают окончания загрузки изображения.
В главе 20 в листинге 20.5 мы применим эти методы для ожидания загрузки изображения.
Рзображение, находящееся РІ объекте класса Image, можно создать непосредственно РїРѕ пикселам или получить РёР· графического файла, типа GIF или JPEG, РѕРґРЅРёРј РёР· РґРІСѓС… методов класса Applet:
□ getimage(url address) — задается URL-адрес графического файла;
□ getImage(URL address, String fileName) — задается адрес каталога address и имя графического файла filename.
Аналогично, звуковой файл в апплетах представляется в виде объекта, реализующего интерфейс AudioClip, и может быть получен из файла типа AU, AIFF, WAVE или MIDI одним из трех методов класса Applet с такими же аргументами:
getAudioClip(URL address);
getAudioClip(URL address, String fileName); newAudioClip(URL address);
Последний метод — статический, его можно использовать не только в апплетах, но и в приложениях.
Рнтерфейс AudioClip РёР· пакета java.applet очень РїСЂРѕСЃС‚. Р’ нем всего три метода без аргументов. Метод play() проигрывает мелодию РѕРґРёРЅ раз. Метод loop() бесконечно повторяет мелодию. Метод stop() прекращает проигрывание.
Ртот интерфейс реализуется браузером. Конечно, перед проигрыванием звуковых файлов браузер должен быть связан СЃРѕ Р·РІСѓРєРѕРІРѕР№ системой компьютера.
В листинге 18.9 приведен простой пример загрузки изображения и звука из файлов, находящихся в том же каталоге, что и HTML-файл. На рис. 18.5 показано, как выглядит изображение, увеличенное в два раза.
Листинг 18.9. Звук и изображение в апплете
import java.applet.*; import java.awt.*; import java.awt.image.*;
public class SimpleAudioImage extends Applet{ private Image img;
private AudioClip ac;
public void init(){
img = getImage(getDocumentBase(), Mjavalogo52x88.gifM); ac = getAudioClip(getDocumentBase(), "yesterday.au");
}
public void start(){ ac.loop(); }
public void paint(Graphics g){
int w = img.getWidth(this), h = img.getHeight(this); g.drawimage(img, 0, 0, 2 * w, 2 * h, this);
}
public void stop(){ ac.stop(); }
}
Рис. 18.5. Вывод изображения |
Перед выводом на экран изображение можно преобразовать, но об этом мы поговорим
в главе 20.
Упражнения
5. Напишите апплет, показывающий несколько изображений, меняющихся при нажатии кнопки.
6. Напишите аналогичный апплет, в котором изображения меняются каждые 3 секунды.
Защита от апплета
Как РІРёРґРЅРѕ РёР· предыдущего текста, апплету РІ браузере позволено очень немного. Рто РЅРµ случайно. Апплет, появившийся РІ браузере откуда-то РёР· Рнтернета, способен натворить РјРЅРѕРіРѕ бед. РћРЅ может быть вызван РёР· файла СЃ увлекательным текстом, невидимо обыскать файловую систему Рё похитить секретные сведения, или, напротив, открыть РѕРєРЅРѕ, неотличимое РѕС‚ РѕРєРЅР°, РІ которое РІС‹ вводите пароль, Рё перехватить его.
Поэтому браузер сообщает при загрузке апплета: "Applet started...", а в строке состояния окна, открытого апплетом, появляется надпись: "Warning: Applet Window".
Но это не единственная защита от апплета.
Браузер может вообще отказаться от загрузки апплетов. В Firefox это делается с помощью кнопки Disable в окне, вызываемом командой Tools | Add-ons, в Internet Explorer — в окне после выбора команды Tools | Internet Options | Security. В таком случае говорить в этой книге больше не о чем.
Если браузер загружает апплет, то создает ему ограничения, так называемую песочницу (sandbox), в которой "резвится" апплет, но выйти из которой не может. Каждый браузер создает свои ограничения, но обычно они заключаются в том, что апплет:
□ не может обращаться к файловой системе машины, на которой он выполняется, даже для чтения файлов или просмотра каталогов;
□ может связаться по сети только с тем сайтом, с которого он был загружен;
□ не может прочитать системные свойства, как это делает, например, приложение в листинге 6.4;
□ не может печатать на принтере, подключенном к тому компьютеру, на котором он выполняется;
□ не может воспользоваться буфером обмена (clipboard);
□ не может запустить приложение методом exec ();
□ не может использовать "родные" методы или загрузить библиотеку методом load ();
□ не может остановить JVM методом exit ();
□ не может создавать классы в пакетах java.*, а классы пакетов sun.* не может даже загружать.
Браузеры способны усилить или ослабить эти ограничения, например разрешить локальным апплетам, загруженным с той же машины, где они выполняются, доступ к файловой системе. Наименьшие ограничения имеют доверенные (trusted) апплеты, снабженные электронной подписью с помощью классов из пакетов java.security.*.
РџСЂРё создании приложения, загружающего апплеты, необходимо обеспечить средства проверки апплета Рё задать ограничения. РС… предоставляет класс SecurityManager. Ркземпляр этого класса или его наследника устанавливается РІ JVM РїСЂРё запуске виртуальной машины статическим методом
setSecurityManager(SecurityManager sm);
класса System. Обычные приложения не могут использовать данный метод.
Каждый браузер расширяет класс SecurityManager по-своему, устанавливая те или иные ограничения. Единственный экземпляр этого класса создается при запуске JVM в браузере и не может быть изменен.
Апплеты в библиотеке Swing
Как уже говорилось ранее, апплеты, созданные средствами графической библиотеки Swing, расширяют класс JApplet, непосредственно расширяющий класс Applet. Основные расширения заключаются в возможности добавить систему меню и в наличии множества панелей подобно классу JFrame. Впрочем, в апплетах Swing чаще всего окно создают в отдельном классе. В листинге 18.10 показан шаблон создания апплета.
Листинг 18.10. Шаблон апплета, использующего Swing
import java.awt.*; import java.awt.event.*; import javax.swing.*;
public class SwingAppletTemplate extends JApplet{
public void init(){
Container c = getContentPane();
c.setLayout(new XxxLayout()); // По умолчанию BorderLayout c.add(new MainFrame()); // Главное окно апплета
}
public void start(){
}
public void stop(){
}
public void destroy(){
}
}
class MainFrame extends JFrame{
// Главное окно, показываемое в апплете
}
Апплет JApplet
Как сказано ранее, апплеты, созданные средствами библиотеки Swing, расширяют класс JApplet, являющийся непосредственным расширением класса Applet. Поэтому, подобно любому апплету, они наследуют четверку методов: init(), start(), stop(), destroy(). Как всякое окно верхнего уровня библиотеки Swing, апплеты Swing содержат всего один компонент — корневую панель класса JRootPane. Поэтому к апплетам относится все сказанное ранее о размещении компонентов в окне верхнего уровня JFrame. В частности, панелью содержимого по умолчанию управляет менеджер размещения
BorderLayout.
Если в браузере, выполняющем апплет, имеется библиотека Swing, то апплет класса JApplet можно вызвать тегом
Для подключения модуля Java Plug-in старых версий вместо тега
Для того чтобы получить преобразованный файл, достаточно набрать командную строку
java -jar htmlconverter.jar dummy.html
Версиям Java JRE, начиная с JDK 1.4, для запуска апплета не нужен тег
В документации Java SE, в каталоге $JAVA_HOME/docs/technotes/guides/plugin/, есть руководство разработчика, подробно объясняющее правила работы с Java Plug-in.
Упражнение
7. Перепишите апплеты предыдущих упражнений для библиотеки Swing.
Заключение
Апплеты были первоначальным практическим применением Java. Р—Р° первые РґРІР° РіРѕРґР° существования Java были написаны тысячи очень интересных Рё красивых апплетов, ожививших WWW. Масса апплетов разбросана РїРѕ Рнтернету, хорошие примеры апплетов собраны РІ JDK РІ каталоге demo/applets.
В JDK вошел целый пакет j ava. applet, в который корпорация Sun собиралась заносить классы, развивающие и улучшающие апплеты.
С увеличением скорости и улучшением качества компьютерных сетей значение апплетов сильно упало. Теперь вся обработка данных, прежде выполняемая апплетами, переносится на сервер, браузер только загружает и показывает результаты этой обработки, становится "тонким клиентом".
РЎ РґСЂСѓРіРѕР№ стороны, появилось РјРЅРѕРіРѕ специализированных программ, РІ том числе написанных РЅР° Java, загружающих информацию РёР· Рнтернета. Такая возможность есть сейчас Сѓ всех музыкальных Рё видеопроигрывателей.
Более того, апплеты широко применяются в сотовых телефонах и других мобильных устройствах, поэтому рано говорить о том, что они устарели и выходят из употребления.
Тем не менее компания Oracle больше не развивает пакет java.applet. В нем так и остался один класс и три интерфейса.
Как альтернатива апплетам с 2007 года развивается технология JavaFX, позволяющая легко создавать анимацию, различные звуковые и видеоэффекты, то, что сейчас называют Rich Internet Applications. Ознакомиться с JavaFX можно на сайте http:// .
Вопросы для самопроверки
1. Что такое апплет?
2. Чем апплет отличается от приложения?
3. Можно ли написать программу, которую смогут выполнять и интерпретатор, и браузер, т. е. одновременно апплет и приложение?
4. Можно ли написать конструктор в апплете?
5. Будет ли выполняться конструктор в апплете?
6. Как передать параметры в апплет?
7. Может ли апплет читать файлы на машине браузера?
8. Может ли апплет читать файлы на машине, с которой он загружен?
9. Может ли апплет передавать данные по сети?
ГЛАВА 19