6. Взаимодействие с аплетами Java

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

Еще одна интересная возможность взаимодействия сценариев JavaScript с объектами документа HTML, которую мы рассмотрим в нашей книге, это связь сценариев и аплетов Java. Оказывается, из сценариев JavaScript вы можете обращаться к полям и методам аплетов Java.

Языку программирования Java мы посвятили 30 и 32 тома “Библиотеки системного программиста”, которые называются, соответственно, “Microsoft Visual J++. Создание приложений. Часть 1” и “Microsoft Visual J++. Создание приложений. Часть 2”. Перед тем как читать главу нашей книги “Взаимодействие с аплетами Java” мы рекомендуем вам ознакомиться с этими томами.

Встраивание аплета Java в документ HTML

Для того чтобы встроить аплет в документ HTML, вы должны воспользоваться оператором <APPLET>, например:

<APPLET
    CODE=MyApplet.class
    NAME="MyApplet"
    ID=MyApplet
    WIDTH=320
    HEIGHT=240>
</APPLET>

Перечислим допустимые параметры оператора <APPLET>:

Параметр Описание
ALIGN Выравнивание окна аплета относительно окружающего его текста. Возможны следующие значения:
LEFT выравнивание влево относительно окружающего текста;
CENTER центрирование;
RIGHT выравнивание вправо относительно окружающего текста;
TOP выравнивание по верхней границе;
MIDDLE центрирование по вертикали;
BOTTOM выравнивание по нижней границе
ALT С помощью этого параметра можно задать текст, который будет отображаться в окне аплета в том случае, если браузер не может работать с аплетами Java
CODE Имя двоичного файла, содержащего код аплета. По умолчанию путь к этому файлу указывается относительно каталога с файлом HTML, куда встроен аплет. Такое поведение может быть изменено параметром CODEBASE
CODEBASE Базовый адрес URL аплета, то есть путь к каталогу, содержащему аплет
HEIGHT Начальная ширина окна аплета в пикселах
WIDTH Начальная высота окна аплета в пикселах
HSPACE Зазор слева и справа от окна аплета
VSPACE Зазор сверху и снизу от окна аплета
NAME Имя аплета. Оно может быть использовано другими аплетами, расположенными в одном и том же документе HTML, а также сценариями JavaScript
TITLE Строка заголовка

Дополнительно между операторами <APPLET> и </APPLET> вы можете задать параметры аплета. Для этого используется оператор <PARAM>.

Пользуясь операторами <PARAM>, расположенными в документе HTML сразу после оператора <APPLET>, можно передать аплету произвольное количество параметров, например, в виде текстовых строк:

<APPLET
CODE=MyApplet.class
    NAME="MyApplet"
    ID=MyApplet
    WIDTH=320
    HEIGHT=240>
    <PARAM NAME=ParamName1 VALUE="Param Value 1">
    <PARAM NAME=ParamName2 VALUE="Param Value 2">
    <PARAM NAME=ParamName3 VALUE="Param Value 3">
    <PARAM NAME=ParamName4 VALUE="Param Value 4">
     . . .
</APPLET>

Здесь через параметр NAME оператора <PARAM> передается имя параметра аплета, а через параметр VALUE - значение соответствующего параметра.

Вызов методов аплета Java из сценария JavaScript

Сценарий JavaScript может получить доступ к полям и методам аплетов, расположенных в документе HTML, адресуясь к аплетам как к элементам массива document.applets. Например, для доступа к первому аплету вы можете использовать строку document.applets[0]. Однако удобнее указывать имя аплета, заданное в параметре NAME оператора <APPLET>, например document.MyApplet.

В качестве примера покажем, как можно вызывать из сценария JavaScript методы аплета Rectangles, описанного нами в упомянутом выше 32 томе “Библиотеки системного программиста”. Этот аплет рисует в своем окне прямоугольники случайного размера, закрашенные случайным цветом.

Мы создали документ HTML, разместив в нем аплет Rectangles и форму с кнопками Start Animation и Stop Animation (рис. 6.1).

Рис. 6.1. Аплет Rectangles управляется кнопками с помощью сценария JavaScript

Сразу после загрузки документа в окне аплета запускается процесс анимации. Если нажать кнопку Stop Animation, рисование новых прямоугольников будет приостановлено. С помощью кнопки Start Animation можно возобновить процесс рисования.

Заметим, что если поместить курсор мыши в область окна аплета, анимация будет остановлена, а когда курсор мыши покинет пределы окна аплета - снова запущена. Однако такое поведение определяется самим аплетом и не имеет отношения к нашему сценарию JavaScript.

Исходный текст документа HTML, содержащий аплет и форму с кнопками, представлен в листинге 6.1.

Листинг 6.1. Файл chapter6/Rectangles/Rectangles.html

<HTML>
  <HEAD>
    <TITLE>Rectangles</TITLE>
  </HEAD>
  <BODY>
    <HR>
    <APPLET
      CODE=Rectangles.class
      NAME="Rectangles"
      ID=Rectangles
      WIDTH=320
      HEIGHT=240 >
    </APPLET>
    <HR>
    <FORM>
      <INPUT TYPE="button" VALUE="Start Animation" onClick="document.Rectangles.start()">
      <INPUT TYPE="button" VALUE="Stop Animation" onClick="document.Rectangles.stop()">
    </FORM>
    <A HREF="Rectangles.java">The source.</a>
  </BODY>
</HTML>

Здесь параметр NAME оператора <APPLET> задает имя аплета как Rectangles.

Когда пользователь нажимает на кнопку Start Animation, управление получает обработчик события onClick, определенный следующим образом:

onClick="document.Rectangles.start()"

Этот обработчик вызывает метод start, определенный в аплете Rectangles. Этот метод запускает анимацию в окне аплета, если она была остановлена.

Аналогично, обработчик события onClick кнопки Stop Animation вызывает метод stop, также определенный в аплете Rectangles и предназначенный для остановки анимации:

onClick="document.Rectangles.stop()"

Исходный текст аплета Rectangles мы воспроизвели в листинге 6.2. Подробное описание этого аплета вы найдете в разделе “Приложение Rectangles” первой главы 32 тома “Библиотеки системного программиста”.

Листинг 6.2. Файл chapter6/Rectangles/Rectangles.java

// =========================================================
// Рисование прямоугольников в отдельной задаче
//
// (C) Фролов А.В, 1997, 1998
//
// E-mail: frolov@glas.apc.org
// WWW:    http://www.glasnet.ru/~frolov
//            или
//         http://www.dials.ccas.ru/frolov
// =========================================================
import java.applet.*;
import java.awt.*;
import java.util.*;

public class Rectangles extends Applet implements Runnable
{
  // Ссылка на задачу рисования прямоугольников
  Thread m_Rectangles = null;

  // -------------------------------------------------------
  // getAppletInfo
  // Метод, возвращающей строку информации об аплете
  // -------------------------------------------------------
  public String getAppletInfo()
  {
    return "Name: Rectangles\r\n" +
      "Author: Alexandr Frolov\r\n" +
      "E-mail: frolov@glas.apc.org" +
      "WWW:    http://www.glasnet.ru/~frolov" +
      "Created with Microsoft Visual J++ Version 1.0";
  }

  // -------------------------------------------------------
  // paint
  // Метод paint, выполняющий рисование в окне аплета
  // -------------------------------------------------------
  public void paint(Graphics g)
  {
    // Определяем текущие размеры окна аплета
    Dimension dimAppWndDimension = size();
    
    // Выбираем в контекст отображения желтый цвет
    g.setColor(Color.yellow);
    
    // Закрашиваем внутреннюю область окна аплета
    g.fillRect(0, 0, 
      dimAppWndDimension.width  - 1, 
      dimAppWndDimension.height - 1);

    // Выбираем в контекст отображения черный цвет
    g.setColor(Color.black);

    // Рисуем рамку вокруг окна аплета
    g.drawRect(0, 0, 
      dimAppWndDimension.width  - 1, 
      dimAppWndDimension.height - 1);
  }

  // -------------------------------------------------------
  // start
  // Метод вызывается при первом отображении окна аплета
  // -------------------------------------------------------
  public void start()
  {
    if (m_Rectangles == null)
    {
      m_Rectangles = new Thread(this);
      m_Rectangles.start();
    }
  }
  
  // -------------------------------------------------------
  // stop
  // Метод вызывается, когда окно аплета исчезает с экрана
  // -------------------------------------------------------
  public void stop()
  {
    if (m_Rectangles != null)
    {
      m_Rectangles.stop();
      m_Rectangles = null;
    }
  }

  // -------------------------------------------------------
  // run
  // Метод, который работает в рамках отдельной задачи
  // Он рисует в окне аплета прямоугольники случайного
  // цвета, размера и расположения
  // -------------------------------------------------------
  public void run()
  {
    // Получаем контекст отображения для окна аплета
    Graphics g = getGraphics();

    // Определяем текущие размеры окна аплета
    Dimension dimAppWndDimension = size();

    while (true)
    {
      int x, y, width, height;
      int rColor, gColor, bColor;
      
      // Выбираем случайным образом размеры
      // и расположение рисуемого прямоугольника
      x = (int)(dimAppWndDimension.width * Math.random());
      y = (int)(dimAppWndDimension.height * Math.random());
      width = (int)(dimAppWndDimension.width * 
              Math.random()) / 2;
      height = (int)(dimAppWndDimension.height * 
              Math.random()) / 2;
      
      // Выбираем случайный цвет для рисования 
      // прямоугольника
      rColor = (int)(255 * Math.random());
      gColor = (int)(255 * Math.random());
      bColor = (int)(255 * Math.random());

      // Устанавливаем выбранный цвет в контексте 
      // отображения
      g.setColor(new Color(rColor, gColor, bColor));

      // Рисуем прямоугольник
      g.fillRect(x, y, width, height);

      // Выполняем задержку на 50 миллисекунд
      try
      {
        Thread.sleep(50);
      }
      catch (InterruptedException e)
      {
        stop();
      }
    }
  }

  // -------------------------------------------------------
  // mouseEnter
  // Метод вызывается, когда курсор мыши оказывается над
  // окном аплета
  // -------------------------------------------------------
  public boolean mouseEnter(Event evt, int x, int y)
  {
    if (m_Rectangles != null)
    {
      // Когда курсор мыши оказывается над поверхностью
      // окна аплета, временно приостанавливаем
      // задачу рисования прямоугольников
      m_Rectangles.suspend();
    }
    return true;
  }

  // -------------------------------------------------------
  // mouseExit
  // Метод вызывается, когда курсор мыши покидает
  // окно аплета
  // -------------------------------------------------------
  public boolean mouseExit(Event evt, int x, int y)
  {
    if (m_Rectangles != null)
    {
      // Когда курсор мыши покидает окно аплета,
      // возобновляем работу задачи рисования 
      // прямоугольников
      m_Rectangles.resume();
    }
    return true;
  }
}

Доступ к полям аплета Java из сценария JavaScript

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

Заметим, что сценарию JavaScript доступны только те поля и методы аплета, определенные как public.

На рис. 6.2 показан внешний вид документа HTML, в котором расположен один аплет и форма с одним многострочным текстовым полем и одной кнопкой.

Рис. 6.2. Сценарий JavaScript вызывает получает информацию от аплета

В окне аплета, расположенном в верхней части документа, находится поле редактирования текста и кнопка с надписью “Получить строку”. Если набрать в поле редактирования любую текстовую строку и нажать эту кнопку, то введенная строка будет отображена в нижней части аплета после символа >. Такой аплет мы описали в 30 томе “Библиотеки системного программиста” в разделе “Приложение TxtField” пятой главы.

Если нажать кнопку “Get applet info and text”, то сценарий JavaScript извлечет из аплета введенную текстовую строку (она хранится в поле с именем str), а также получит описание аплета, вызвав метод getAppletInfo, определенный в нашем аплете.

Введенная строка и информация об аплете будет затем отображена сценарием в многострочном поле редактирования, как это показано на рис. 6.2.

Таким образом, наш сценарий обращается к полю и методу, определенным в аплете.

Исходный текст документа HTML вы найдете в листинге 6.3.

Листинг 6.3. Файл chapter6/TxtField/TxtField.html

<HTML>
  <HEAD>
    <TITLE>Get text</TITLE>
    <SCRIPT LANGUAGE="JavaScript">
    <!--

    function getTextFromApplet()
    {
      var szMsg="null";
      GetForm.Comment.value = document.applets[0].str + 
      "\n" + "---------------------------\n" +
      document.applets[0].getAppletInfo();
    }

    // -->
    </SCRIPT>
  </HEAD>
  <BODY>
    <HR>
    <APPLET
      CODE=TxtField.class
      NAME="TxtField"
      ID=TxtField
      WIDTH=320
      HEIGHT=140>
    </APPLET>
    <HR>
    <FORM NAME="GetForm">
      <P><TEXTAREA NAME="Comment"
        ROWS="7" COLS="45">
      </TEXTAREA>
      <P>
      <INPUT TYPE="button" VALUE="Get applet info and text" onClick="getTextFromApplet();">
    </FORM>
    <A HREF="TxtField.java">The source.</a>
  </BODY>
</HTML>

Для кнопки, расположенной в форме с именем GetForm, мы определили обработчик события onClick:

onClick="getTextFromApplet();"

Этот обработчик вызывает функцию getTextFromApplet, выполняющую взаимодействие с аплетом.

Функция getTextFromApplet обращается к аплету как к самому первому элементу массива document.applets[0]:

GetForm.Comment.value = document.applets[0].str + 
  "\n" + "---------------------------\n" +
  document.applets[0].getAppletInfo();

Здесь мы записываем в свойство value многострочного поля GetForm.Comment значение переменной str, к которому добавлен разделитель из символов “-“ и строка описания аплета, полученная от метода getAppletInfo.

Исходный текст аплета приведен в листинге 6.4.

Листинг 6.4. Файл chapter6/TxtField/TxtField.java

// =========================================================
// Однострочное текстовое поле класса TextField
//
// (C) Фролов А.В, 1997, 1998
//
// E-mail: frolov@glas.apc.org
// WWW:    http://www.glasnet.ru/~frolov
//            или
//         http://www.dials.ccas.ru/frolov
// =========================================================
import java.applet.*;
import java.awt.*;

public class TxtField extends Applet
{
  // Создаем ссылку на объекты типа TextField
  TextField txt;

  // Создаем ссылку на объекты типа Button
  Button btnGetText;

  // Строка для хранения введенных данных
  public String str;

  // -------------------------------------------------------
  // getAppletInfo
  // Метод, возвращающей строку информации об аплете
  // -------------------------------------------------------
  public String getAppletInfo()
  {
    return "Name: TxtField\r\n" +
      "Author: Alexandr Frolov\r\n" +
      "E-mail: frolov@glas.apc.org\r\n" +
      "WWW:    http://www.glasnet.ru/~frolov\r\n" +
      "Created with Microsoft Visual J++ Version 1.0";
  }

  // -------------------------------------------------------
  // init
  // Метод, получающий управление при инициализации аплета
  // -------------------------------------------------------
  public void init()
  {
    // Создаем редактируемое однострочное текстовое поле
    txt = new TextField("Введите строку текста", 35);

    // Создаем кнопку, с помощью которой можно получить
    // содержимое текстового поля
    btnGetText = new Button("Получить строку");

    // Добавляем текстовое поле в окно аплете
    add(txt);
    
    // Добавляем кнопку в окно аплете
    add(btnGetText);

    // Получаем и сохраняем текущий текст,
    // установленный в поле
    str = txt.getText();

    // Устанавливаем цвет фона
    setBackground(Color.yellow);
  }

  // -------------------------------------------------------
  // action
  // Метод вызывается, когда пользователь выполняет
  // действие над компонентами
  // -------------------------------------------------------
  public boolean action(Event evt, Object obj)
  {
    // Ссылка на кнопку, от которой пришло сообщение
    Button btn;

    // Проверяем, что событие вызвано кнопкой, а не
    // другим компонентом
    if(evt.target instanceof Button)
    {
      // Получам ссылку на кнопку, вызвавшую событие
      btn = (Button)evt.target;

      // Проверяем ссылку на кнопку
      if(evt.target.equals(btnGetText))
      {
        // Получаем и сохраняем текущий текст,
        // установленный в поле
        str = txt.getText();

        // Перерисовываем окно аплета
        repaint();
      }

      // Если событие возникло от неизвестной кнопки,
      // мы его не обрабатываем
      else
      {
        return false;
      }

      // Возвращаем признак того, что мы обработали событие
      return true;
    }

    // Если событие вызвано не кнопкой, 
    // мы его не обрабатываем
    return false;
  }
      
  // -------------------------------------------------------
  // paint
  // Метод paint, выполняющий рисование в окне аплета
  // -------------------------------------------------------
  public void paint(Graphics g)
  {
    // Определяем текущие размеры окна аплета
    Dimension dimAppWndDimension = size();
    
    // Выбираем в контекст отображения черный цвет
    g.setColor(Color.black);

    // Рисуем рамку вокруг окна аплета
    g.drawRect(0, 0, 
      dimAppWndDimension.width  - 1, 
      dimAppWndDimension.height - 1);

    // Рисуем строку, полученную из текстового поля
    g.drawString("> " + str, 10, 100);
  }
}

Этот текст воспроизведен нами с небольшими изменениями из 30 тома “Библиотеки системного программиста”. Изменения заключаются в том, что мы добавили к определению поля str ключевое слово public:

public String str;

Это необходимо для того чтобы поле str было доступно из сценария JavaScript.

Динамическая загрузка аплетов Java

Еще одна полезная возможность, которая появляется у вас при использовании сценариев JavaScript, - это динамическая перезагрузка аплетов Java в документах HTML, созданных с использованием фреймов.

Идея динамической загрузки аплетов заключается в том, что сценарий JavaScript динамически создает документ HTML, в котором находится оператор <APPLET>. Передавая аплету в этом документе различные значения параметров с помощью оператора <PARAM>, сценарий JavaScript может управлять его работой.

На рис. 6.3 мы показали документ HTML, состоящий из двух фреймов.

Рис. 6.3. Строка в окне аплета и ее шрифтовое оформление зависят от положения переключателей в левом фрейме

В левом фрейме находится форма с переключателями и кнопкой, а правой - аплет Java. Если включить один из переключателей с названиями шрифтов, а затем нажать кнопку, то в окне аплета появится название шрифта. Это название будет оформлено с применением шрифта, выбранного вами в левом фрейме.

Займемся описанием исходных текстов нашего документа HTML.

В файле Index.html (листинг 6.6) находится описание фреймов.

Листинг 6.6. Файл chapter6/FrameLoad/Index.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
  <HEAD>
    <TITLE>Динамическая загрузка аплетов</TITLE>
  </HEAD>
  <FRAMESET COLS="180,*" FRAMEborder=0>
    <FRAME SCROLLING="auto" NAME="toc" SRC="toc.html">
    <FRAME SCROLLING="auto" NAME="mainpage" SRC="main.html">
    <NOFRAME>
      <BODY BGCOLOR="#FFFFFF">
      </BODY>
    </NOFRAME>
  </FRAMESET>
</HTML>

Левый фрейм называется toc, а правый - mainpage.

Исходный текст документа для фрейма toc мы привели в листинге 6.6.

Листинг 6.6. Файл chapter6/FrameLoad/toc.html

<HTML>
  <BODY BGCOLOR="#B0FFD8">
    <SCRIPT LANGUAGE="JavaScript">
    <!--
      var szFont="Arial";

      function chkRadio(form,value)
      {
        szFont = value;
      }
    // -->
    </SCRIPT>

    <FORM>
      <B>Font:</B><BR>
      <INPUT TYPE="radio" NAME="font" VALUE="Arial" CHECKED 
         onClick="if(this.checked) {chkRadio(this.form,this.value);}"> Arial<BR>

      <INPUT TYPE="radio" NAME="font" VALUE="Courier" 
         onClick="if(this.checked) {chkRadio(this.form,this.value);}"> Courier<BR>

      <INPUT TYPE="radio" NAME="font" VALUE="TimesRoman" 
         onClick="if(this.checked) {chkRadio(this.form,this.value);}"> TimesRoman<BR>

      <INPUT TYPE="radio" NAME="font" VALUE="Helvetica" 
         onClick="if(this.checked) {chkRadio(this.form,this.value);}"> Helvetica<BR>
      <P>
      <INPUT TYPE=button VALUE="Show Applet" 
         onClick="parent['mainpage'].location='main.html';"> 
    </FORM>
  </BODY>
</HTML>

Для работы с переключателями типа radio мы использовали уже знакомую вам методику. Обработчик события onClick проверяет, находится ли переключатель во включенном состоянии. Если это так, обработчик вызывает функцию chkRadio, передавая ей ссылку на форму и значение свойства value, соответствующее включенному переключателю.

Функция chkRadio сохраняет это значение в переменной szFont:

function chkRadio(form,value)
{
  szFont = value;
}

Каждый из переключателей имеет значение параметра VALUE, соответствующее названию одного из шрифтов, доступных аплетам Java. Поэтому переменная szFont хранит название шрифта, выбранного пользователем в левом фрейме.

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

onClick="parent['mainpage'].location='main.html';"

Он устанавливает свойство location фрейма mainpage (то есть правого фрейма), присваивая ему адрес документа main.html. Исходный текст этого документа приведен в листинге 6.7.

Листинг 6.7. Файл chapter6/FrameLoad/main.html

<HTML>
  <BODY BGCOLOR="#FFFFFF">
    <SCRIPT LANGUAGE="JavaScript">
    <!--
      var szFont = parent.toc.szFont;

      document.write("<APPLET CODE=TextOut.class ID=TextOut WIDTH=300 HEIGHT=140 >");
      document.write("<param name=Str1 value='" + szFont + "'>");
      document.write("<param name=Font1 value='" + szFont + "'>");
      document.write("<param name=Type1 value='Plain'>");
      document.write("</APPLET>");
    // -->
    </SCRIPT>
  </BODY>
</HTML>

Тело документа main.html содержит только сценарий JavaScript. Этот сценарий динамически создает строки оператора <APPLET> с параметрами Str1, Font1 и Type1.

Параметр Str1 задает текст, отображаемый в окне аплета. Наш сценарий использует для этого параметра название шрифта, выбранного пользователем в левом фрейме:

var szFont = parent.toc.szFont;

Параметр Font1 задает шрифт для текста, отображаемого в окне аплета. Этот параметр также задается с использованием названия шрифта, выбранного в левом фрейме:

document.write("<param name=Font1 value='" + szFont + "'>");

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

Исходный текст аплета Java, использованного в нашем примере, приведен в листинге 6.8. Это упрощенный вариант алпета, описанного нами в 30 томе “Библиотеки системного программиста” в разделе “Приложение TextOut третьей главы.

Листинг 6.8. Файл chapter6/FrameLoad/TextOut.java

// =========================================================
// Установка различных шрифтов.
// Демонстрация способов передачи параметров в аплет
//
// (C) Фролов А.В, 1997, 1998
//
// E-mail: frolov@glas.apc.org
// WWW:    http://www.glasnet.ru/~frolov
//            или
//         http://www.dials.ccas.ru/frolov
// =========================================================

import java.applet.*;
import java.awt.*;

public class TextOut extends Applet
{
  // -------------------------------------------------------
  // Поля класса.
  // Создаются автоматически для всех параметров аплета
  // -------------------------------------------------------
  private String m_Str1 = "Hello 1";
  private String m_Font1 = "Arial";
  private String m_Type1 = "Bold";

  // -------------------------------------------------------
  // Имена параметров
  // -------------------------------------------------------
  private final String PARAM_Str1 = "Str1";
  private final String PARAM_Font1 = "Font1";
  private final String PARAM_Type1 = "Type1";

  // -------------------------------------------------------
  // getAppletInfo
  // Метод, возвращающей строку информации об аплете
  // -------------------------------------------------------
  public String getAppletInfo()
  {
    return "Name: TextOut\r\n" +
      "Author: Alexandr Frolov\r\n" +
      "E-mail: frolov@glas.apc.org" +
      "WWW:    http://www.glasnet.ru/~frolov" +
      "Created with Microsoft Visual J++ Version 1.0";
  }

  // -------------------------------------------------------
  // getParameterInfo
  // Метод, возвращающий описание параметров
  // -------------------------------------------------------
  public String[][] getParameterInfo()
  {
    String[][] info =
    {
      { PARAM_Str1, "String", "Text string to write" },
      { PARAM_Font1, "String", "Text font" },
      { PARAM_Type1, "String", "Font type" },
    };
    return info;    
  }

  // -------------------------------------------------------
  // init
  // Вызывается во время инициализации аплета
  // -------------------------------------------------------
  public void init()
  {
    // Рабочая переменная для получения параметров
    String param;

    // Получение параметров и сохранение
    // их значений в полях класса

    // Строки, которые будут выведены в окно аплета
    param = getParameter(PARAM_Str1);
    if (param != null)
      m_Str1 = param;


    // Шрифты для отображения строк
    param = getParameter(PARAM_Font1);
    if (param != null)
      m_Font1 = param;

    // Начертание шрифтов
    param = getParameter(PARAM_Type1);
    if (param != null)
      m_Type1 = param;
  }

  // -------------------------------------------------------
  // paint
  // Метод paint, выполняющий рисование в окне аплета
  // -------------------------------------------------------
  public void paint(Graphics g)
  {
    // Начальная координата для вывода по вертикали
    int yStart   = 20;

    // Текущая координата для вывода строки
    int yCurrent = 20;

    // Определяем текущие размеры окна аплета
    Dimension dimAppWndDimension = size();
    
    // Выбираем в контекст отображения желтый цвет
    g.setColor(Color.yellow);
    
    // Закрашиваем внутреннюю область окна аплета
    g.fillRect(0, 0, 
      dimAppWndDimension.width  - 1, 
      dimAppWndDimension.height - 1);

    // Выбираем в контекст отображения черный цвет
    g.setColor(Color.black);

    // Рисуем рамку вокруг окна аплета
    g.drawRect(0, 0, 
      dimAppWndDimension.width  - 1, 
      dimAppWndDimension.height - 1);

    // Получаем стиль шрифта и выбираем шрифт
    // в соответствии с этим стилем
    if(m_Type1.equals("Bold"))
      g.setFont(new Font(m_Font1, Font.BOLD, 25));

    else if(m_Type1.equals("Italic"))
      g.setFont(new Font(m_Font1, Font.ITALIC, 25));

    else if(m_Type1.equals("Plain"))
      g.setFont(new Font(m_Font1, Font.PLAIN, 25));

    // Отступ для первой строки
    yCurrent += yStart;

    // Рисуем первую строку
    g.drawString(m_Str1, 10, yCurrent);
  }
}