Электронная библиотека книг Александра Фролова и Григория Фролова.
Shop2You.ru Создайте свой интернет-магазин
Библиотека
Братьев
Фроловых

Microsoft Visual J++. Создание приложений и аплетов на языке Java. Часть 2

© Александр Фролов, Григорий Фролов
Том 32, М.: Диалог-МИФИ, 1997, 288 стр.

[Назад] [Содеожание] [Дальше]

Приложение Scroller

Приложения, рассмотренные выше, демонстрируют различные методы реализации мультизадачности в Java, но едва ли вы найдете для них применение (разве лишь гипнотизирование пользователей). Ниже мы приведем исходные тексты приложения Scroller, которое имеет некоторую практическую ценность.

В своем окне приложение Scroller показывает строки текста, медленно всплывающие вверх (рис. 1.4). Вы можете использовать этот аплет для размещения рекламной информации на своем сервере. Всплывающий текст (как и всякое движение на сранице сервера Web) будет привлекать внимание пользователя.

Рис. 1.4. Окно аплета Scroller

Строки (в количестве 6 штук) можно задавать в параметрах аплета, редактируя текст документа HTML, содержащего этот аплет. Первая строка выделяется красным цветом.

Исходные тексты приложения

Исходный текст приложения Scroller представлен в листинге 1.7.

Листинг 1.7. Файл Scroller\Scroller.java


// =========================================================
// Просмотр текста в режиме динамической свертки 
// по вертикали
//
// (C) Фролов А.В, 1997
//
// 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 Scroller extends Applet implements Runnable
{
  // Ссылка на задачу, выполняющую свертку
  Thread m_Scroller = null;

  // Отображаемые строки
  private String m_String1 = "Мы представляем наши новые книги";
  private String m_String2 = 
    "Том 29. Сервер Web своими руками";
  private String m_String3 = 
    "Том 30. Microsoft Visual J++. Создание приложений на языке Java. Часть 1";
  private String m_String4 = 
    "Том 31. Разработка приложений для Internet с Visual C++ и MFC";
  private String m_String5 = 
    "Том 32. Microsoft Visual J++. Создание приложений на языке Java. Часть 2";
  private String m_String6 = "";

  // Имена параметров
  private final String PARAM_String1 = "String1";
  private final String PARAM_String2 = "String2";
  private final String PARAM_String3 = "String3";
  private final String PARAM_String4 = "String4";
  private final String PARAM_String5 = "String5";
  private final String PARAM_String6 = "String6";

  // -------------------------------------------------------
  // getAppletInfo
  // Метод, возвращающей строку информации об аплете
  // -------------------------------------------------------
  public String getAppletInfo()
  {
    return "Name: Scroller\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_String1, "String", "Parameter description" },
      { PARAM_String2, "String", "Parameter description" },
      { PARAM_String3, "String", "Parameter description" },
      { PARAM_String4, "String", "Parameter description" },
      { PARAM_String5, "String", "Parameter description" },
      { PARAM_String6, "String", "Parameter description" },
    };
    return info;		
  }

  // -------------------------------------------------------
  // init
  // Метод, получающий управление при инициализации аплета
  // -------------------------------------------------------
  public void init()
  {
    // Рабочая строка
    String param;

    // Получение параметров
    param = getParameter(PARAM_String1);
    if (param != null)
      m_String1 = param;

    param = getParameter(PARAM_String2);
    if (param != null)
      m_String2 = param;

    param = getParameter(PARAM_String3);
    if (param != null)
      m_String3 = param;

    param = getParameter(PARAM_String4);
    if (param != null)
      m_String4 = param;

    param = getParameter(PARAM_String5);
    if (param != null)
      m_String5 = param;

    param = getParameter(PARAM_String6);
    if (param != null)
      m_String6 = param;
  }

  // -------------------------------------------------------
  // paint
  // Метод paint, выполняющий рисование в окне аплета
  // -------------------------------------------------------
  public void paint(Graphics g)
  {
    // Определяем текущие размеры окна аплета
    Dimension dimAppWndDimension = size();

    // Определяем текущие размеры окна аплета
    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_Scroller == null)
    {
      m_Scroller = new Thread(this);
      m_Scroller.start();
    }
  }
	
  // -------------------------------------------------------
  // stop
  // Метод вызывается, когда окно аплета исчезает с экрана
  // -------------------------------------------------------
  public void stop()
  {
    if (m_Scroller != null)
    {
      m_Scroller.stop();
      m_Scroller = null;
    }
  }

  // -------------------------------------------------------
  // run
  // Метод, который работает в рамках отдельной задачи
  // Он выполняет динамическую свертку строк текста 
  // -------------------------------------------------------
  public void run()
  {
    // Счетчик сдвинутых строк
    int ShiftsCounter = 0;

    // Размер сдвига по вертикали
    int yShift;
    
    // Высота символов текста
    int yChar;

    // Номер текущей рисуемой строки
    int CurrentStr = 0;
    
    // Массив сдвигаемых строк
    String s[] = new String[6];

    // Инициализация массива строк
    s[0] = m_String1;
    s[1] = m_String2;
    s[2] = m_String3;
    s[3] = m_String4;
    s[4] = m_String5;
    s[5] = m_String6;

    // Получаем контекст отображения
    Graphics g = getGraphics();
    Dimension dimAppWndDimension = size();

    // Определяем метрики текущего шрифта
    FontMetrics fm = g.getFontMetrics();

    // Сохраняем полную высоту символов шрифта
    yChar = fm.getHeight();

    // Бесконечный цикл сдвига строк
    while (true)
    {
      try
      {
        // Увеличиваем содержимое счетчика сдвигов        
        ShiftsCounter++;

        // Если сдвинута полная строка, рисуем
        // следующую строку в нижней части окна
        if(ShiftsCounter == yChar + 5)
        {
          // Сбрасываем счетчик сдвигов
          ShiftsCounter = 0;
          
          // Первую строку отображаем красным цветом,
          // остальные - черным
          if(CurrentStr == 0)
            g.setColor(Color.red);
          else
            g.setColor(Color.black);

          // Рисуем строку
          g.drawString(s[CurrentStr], 
            10, dimAppWndDimension.height - 10);
          
          // Увеличиваем счетчик строк
          CurrentStr++;

          // Если уже нарисовали шесть строк, сбрасываем
          // счетчик строк
          if(CurrentStr > 5)
            CurrentStr = 0;
        }

        // Устанавливаем шаг сдвига равным одному пикселу
        yShift = 1;

        // Выполняем свертку 
        g.copyArea(0, yShift + 1, 
          dimAppWndDimension.width  - 1, 
          dimAppWndDimension.height - 1,
          0, -yShift);

        // Закрашиваем область ввода желтым цветом
        g.setColor(Color.yellow);

        g.fillRect(1, dimAppWndDimension.height 
          - yShift - 1, 
          dimAppWndDimension.width  - 2, 
          dimAppWndDimension.height - 1);
        
        // Выполняем задержку в 50 миллисекунд
        Thread.sleep(50);
      }
      catch (InterruptedException e)
      {
        stop();
      }
    }
  }
}

В листинге 1.8 вы найдете исходный текст документа HTML, который был создан для аплета Scroller.

Листинг 1.8. Файл Scroller\Scroller.html


<html>
<head>
<title>Scroller</title>
</head>
<body>
<hr>
<applet
    code=Scroller.class
    id=Scroller
    width=400
    height=240 >
    <param name=String1 value="Мы представляем наши новые книги:">
    <param name=String2 value="Том 29. Сервер Web своими руками">
    <param name=String3 value="Том 30. Microsoft Visual J++. Создание приложений на языке Java. Часть 1">
    <param name=String4 value="Том 31. Разработка приложений для Internet с Visual C++ и MFC">
    <param name=String5 value="Том 32. Microsoft Visual J++. Создание приложений на языке Java. Часть 2">
    <param name=String6 value="">
</applet>
<hr>
<a href="Scroller.java">The source.</a>
</body>
</html>

Описание исходных текстов

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

Основной класс аплета реализует интерфейс Runnable, поэтому для задачи рисования и сдвига строк текста мы не создаем свой класс на базе класса Thread.

Поля класса Scroller

В поле m_Scroller записывается ссылка на задачу рисования и сдвига строк текста.

Шесть полей типа String с именами от m_String1 до m_String6 предназначены для хранения сдвигаемых строк текста.

Поля с именами от PARAM_String1 до PARAM_String6 хранят имена параметров аплета.

Метод init

Единственная задача метода init нашего приложения - получение параметров аплета и запись их в соотвестствующие поля класса. Эта задача решается с помощью метода getParameter, при этом строка param типа String используется как рабочая:


String param;
param = getParameter(PARAM_String1);
if (param != null)
  m_String1 = param;

Аналогичным образом метод получает значения всех шести параметров.

Метод paint

Метод paint подготавливает окно аплета для рисования - закрашивает его в желтый цвет и рисует вокруг окна черную рамку.

Метод start

Метод start основного класса аплета вызывается, когда пользователь отображает страницу сервера Web с аплетом. Наша реализация этого метода создает новую задачу и сохраняет ссылку на нее в поле m_Scroller.

Метод stop

Метод stop основного класса останавливает работу задачи, когда пользователь покидает страницу сервера Web с аплетом, вызывая для этого метод stop.

Метод run

Внутри метода run мы определили массив строк, проинициализировав его значениями, полученными из параметров аплета:


String s[] = new String[6];
s[0] = m_String1;
s[1] = m_String2;
s[2] = m_String3;
s[3] = m_String4;
s[4] = m_String5;
s[5] = m_String6;

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

Так как для рисования строк текста нужно знать контекст отображения, мы получаем его при помощи метода getGraphics:


Graphics g = getGraphics();

Мы также определяем размеры окна аплета, знание которых необходимо для организации сдвига содержимого окна:


Dimension dimAppWndDimension = size();

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


FontMetrics fm = g.getFontMetrics();
yChar = fm.getHeight();

В рамках бесконечного цикла мы подсчитываем количество сдвигов (в счетчике ShiftsCounter), а также сдвинутые строки (в счетчике CurrentStr). Заметим, что для обеспечения плавности сдвига мы перемещаем строки по одному пикселу. Когда величина сдвига достигает высоты символов yChar плюс 5, метод run рисует новую строку.

Перед рисованием строки мы выбираем в контекст отображения красный или черный цвет, в зависимости от номера строки:


if(CurrentStr == 0)
  g.setColor(Color.red);
else
  g.setColor(Color.black);

Вы можете выделять нужные вам строки любым другим способом, например, наклоном или жирным шрифтом.

Для рисования строки мы вызываем метод drawString:


g.drawString(s[CurrentStr], 
  10, dimAppWndDimension.height - 10);

Строка будет нарисована на десять пикселов выше нижней границы окна аплета.

После рисования строки мы проверяем, последняя она, или нет:


CurrentStr++;
if(CurrentStr > 5)
  CurrentStr = 0;

Если строка последняя, мы сбрасываем счетчик текущей строки, после чего перебор строк начнется с самого начала.

Для выполнения свертки мы вызываем метод copyArea, знакомый вам по 30 тому “Библиотеки системного программиста”:


yShift = 1;
g.copyArea(0, yShift + 1, 
  dimAppWndDimension.width  - 1, 
  dimAppWndDimension.height - 1,
  0, -yShift);

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

После сдвига освободившаяся область закрашивается желтым цветом:


g.setColor(Color.yellow);
g.fillRect(1, dimAppWndDimension.height - yShift - 1, 
  dimAppWndDimension.width  - 2, 
  dimAppWndDimension.height - 1);

Далее выполняется задержка на 50 миллисекунд, после чего работа бесконечного цикла возобновляется с самого начала:


Thread.sleep(50);
[Назад] [Содеожание] [Дальше]