ROBOWEB : Документация : Документация по JAVA , описание JAVA , примеры JAVA , программирование на JAVA , JAVA аплеты , исходники , исходные тексты , source , make программ на JAVA , библиотека классов JAVA , Java WorkShop , Java Studio , компоненты JAVA , свойства события методы JAVA , сокет , передача данных , потоковые сокеты , доступ к файлам , датаграммные сокеты , растровое изображение , видео , звуковые файлы , sun взлом защита скачать бесплатно новые свежие архив секреты недокументированные способы русский перевод компьютер zip каталог add url forum форум чат chat программист программер хакер xakep hack баги компилить сорцы научиться урок обучение домашняя страница home page разработка создание применение примеры способы портал документ знания
Разработка сайтов, web дизайн - Центр Русского Дизайна HOD.RU
FLASH
3D Studio MAX
DreamWeawer FAQ
Изучение HTML
META тэги
CSS
Руководство по стилям
Спецификация WML (WAP)
Язык DHTML
Спецификация XML
Руководство по Java
Документация по JavaScript
Язык HOD Text Processor
Интерфейс CGI
Документация по Perl 5
Perl FAQ
Документация по PHP
PHP/FI 2.0
Документация по SQL
Базы данных
Доступ к БД

Рейтинг@Mail.ru Rambler's Top100

Веб дизайнеру
Каталог сайтов Axes.ru


Аплет CDRotation

 

В этом разделе мы расскажем об аплете CDRotation, в окне которого вращается компакт-диск.

В левом верхнем углу каждого кадра отображается его порядковый номер. Этот номер не нарисован в файлах кадров, а надписывается приложением после рисования очередного кадра. Такое невозможно, если располагать в документе HTML файл AVI или многосекционный файл GIF.

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

Главный файл исходных текстов приложения CDRotation представлен в листинге 1.

Листинг 1. Файл CDRotation.java

import java.applet.*;
import java.awt.*;
public class CDRotation extends Applet
  implements Runnable
{
  Thread m_CDRotation = null;
  private Graphics m_Graphics;
  private Image m_Images[];
  private int m_nCurrImage;
  private int m_nImgWidth  = 0;
  private int m_nImgHeight = 0;
  private boolean m_fAllLoaded = false;
  private final int NUM_IMAGES = 11;
  public String getAppletInfo()
  {
    return "Name: CDRotation";
  }
  private void displayImage(Graphics g)
  {
    if (!m_fAllLoaded)
      return;
    g.drawImage(m_Images[m_nCurrImage],
       (size().width - m_nImgWidth)   / 2,
       (size().height - m_nImgHeight) / 2,
        null);
    g.drawString(
      (new Integer(m_nCurrImage)).toString(),
      (size().width - m_nImgWidth)  /2,
     ((size().height - m_nImgHeight)/2)+
     10);
  }
  public void paint(Graphics g)
  {
    Dimension dimAppWndDimension = size();
    g.setColor(Color.white);
    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_fAllLoaded)
    {
      displayImage(g);
    }		
    else
      g.drawString("Please, wait...",
        10, dimAppWndDimension.height / 2);
  }
  public void start()
  {
    if (m_CDRotation == null)
    {
      m_CDRotation = new Thread(this);
      m_CDRotation.start();
    }
  }	
  public void stop()
  {
    if (m_CDRotation != null)
    {
      m_CDRotation.stop();
      m_CDRotation = null;
    }
  }
  public void run()
  {
    m_nCurrImage = 0;
    if (!m_fAllLoaded)
    {
      repaint();
      m_Graphics = getGraphics();
      m_Images   = new Image[NUM_IMAGES];
      MediaTracker tracker =
         new MediaTracker(this);
      String strImage;
      for (int i = 0; i < NUM_IMAGES; i++)
      {
        strImage = "images/cdimg0" +
          ((i < 10) ? "0" : "") + i + ".gif";
        m_Images[i] = getImage(
          getDocumentBase(), strImage);
        tracker.addImage(m_Images[i], 0);
      }
      try
      {
	tracker.waitForAll();
	m_fAllLoaded = !tracker.isErrorAny();
      }
      catch (InterruptedException e)
      {
      }	
      if (!m_fAllLoaded)
      {
        stop();
        m_Graphics.drawString(
          "Load error", 10,
           size().height / 2);			
        return;
      }
      m_nImgWidth  =
        m_Images[0].getWidth(this);
      m_nImgHeight =
         m_Images[0].getHeight(this);
    }	
    repaint();
    while (true)
    {
      try
      {
        displayImage(m_Graphics);
	m_nCurrImage++;
	if(m_nCurrImage == NUM_IMAGES)
	m_nCurrImage = 0;
        Thread.sleep(30);
      }
      catch (InterruptedException e)
      {
	stop();
      }
    }
  }
}

Листинг 2 содержит исходный текст документа HTML, созданного для аплета CDRotation.

Листинг 2. Файл CDRotation.tmp.html

<applet name="CDRotation"
  code="CDRotation"
  codebase=
"file:/e:/sun/articles/vol13/src/CDRotation"
  width="500"
  height="600"
  align="Top"
  alt="If you had a java-enabled browser,
 you would see an applet here.">
</applet>

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

Рассмотрим наиболее важные методы нашего аплета.

Метод start

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

if (m_CDRotation == null)
{
  m_CDRotation = new Thread(this);
  m_CDRotation.start();
}

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

Метод stop

Метод stop останавливает работу потока, когда окно аплета исчезает с экрана:

if(m_CDRotation != null)
{
  m_CDRotation.stop();
  m_CDRotation = null;
}

Для остановки вызывается метод stop.

Метод paint

Сразу после получения управления, метод paint закрашивает окно аплета белым цветом и рисует вокруг него черную рамку.

Затем метод проверяет содержимое флага m_fAllLoaded. Этот флаг установлен в значение true, когда все кадры видеофильма загружены и сброшен в значение false, когда загрузка кадров еще не завершена. Последняя ситуация возникает всегда при первом вызове метода paint.

Если все изображения загружены, метод paint вызывает метод displayImage, определенный в нашем приложении:

if(m_fAllLoaded)
{
  displayImage(g);
}

Этот метод, о котором мы еще расскажем подробнее, отображает в окне аплета текущий кадр видеофильма.

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

else
  g.drawString("Please, wait...",
    10, dimAppWndDimension.height / 2);

Метод run

Метод run работает в рамках отдельного потока. Он занимается последовательным рисованием кадров нашего видеофильма.

Прежде всего метод run записывает нулевое значение в поле m_nCurrImage, хранящее номер текущего отображаемого кадра:

m_nCurrImage = 0;

Далее выполняется проверка, загружены ли все кадры видеофильма, для чего анализируется содержимое флага m_fAllLoaded.

Если изображения не загружены (а в самом начале так оно и есть) метод run перерисовывает окно аплета и получает контекст отображения для этого окна. Затем создается массив объектов Image для хранения кадров видеофильма:

m_Images   = new Image[NUM_IMAGES];

Метод run создает также объект класса MediaTracker для ожидания загрузки всех кадров видеофильма:

MediaTracker tracker =
  new MediaTracker(this);

Далее метод run в цикле загружает изображения и добавляет их в объект класса MediaTracker для того чтобы можно было дождаться загрузки всех кадров:

for (int i = 0; i < NUM_IMAGES; i++)
{
  strImage = "images/cdimg0" +
   ((i < 10) ? "0" : "") + i + ".gif";
  m_Images[i] = getImage(
    getDocumentBase(), strImage);
  tracker.addImage(m_Images[i], 0);
}

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

Имена файлов, составляющих отдельные кадры, начинаются с префикса cdimg0, вслед за которым идет номер кадра (00, 01, 02, и так далее), и расширение имени .gif.

Ожидание загрузки кадров выполняется с помощью метода waitForAll, о котором мы вам уже рассказывали:

try
{
  tracker.waitForAll();
  m_fAllLoaded = !tracker.isErrorAny();
}
catch (InterruptedException e)
{
}

После окончания ожидания флаг завершения загрузки устанавливается только в том случае, если метод isErrorAny вернул значение false, то есть если не было никаких ошибок.

Если же произошла ошибка, в окне аплета отображается соответствующее сообщение, после чего работа метода run (и, следовательно, работа созданного для него потока) заканчивается:

if(!m_fAllLoaded)
{
  stop();
  m_Graphics.drawString(
    "Load error",
    10, size().height / 2);
  return;
}

В случае удачной загрузки всех кадров метод run получает ширину и высоту первого кадра видеофильма и сохраняет эти значения в переменных m_nImgWidth и m_nImgHeight:

m_nImgWidth  =
  m_Images[0].getWidth(this);
m_nImgHeight =
  m_Images[0].getHeight(this);

Далее окно аплета перерисовывается:

repaint();

При этом метод paint отображает в окне аплета первый кадр видеофильма.

На следующем этапе работы метода run запускается цикл отображения кадров фильма:

while (true)
{
  try
  {
    displayImage(m_Graphics);
    m_nCurrImage++;
    if(m_nCurrImage == NUM_IMAGES)
      m_nCurrImage = 0;
    Thread.sleep(30);
  }
  catch (InterruptedException e)
  {
    stop();
  }
}

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

Между отображением кадров выполняется задержка величиной 30 миллисекунд.

Метод displayImage

Метод displayImage вызывается из двух мест - из метода paint при перерисовке окна аплета и из метода run (периодически).

Если кадры видеофильма не загружены, содержимое флага m_fAllLoaded равно false и метод displayImage просто возвращает управление, ничего не делая:

if(!m_fAllLoaded)
  return;

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

g.drawImage(m_Images[m_nCurrImage],
  (size().width - m_nImgWidth)   / 2,
  (size().height - m_nImgHeight) / 2,
   null);

После того как кадр нарисован, мы надписываем на нем его порядковый номер, вызывая для этого метод drawString:

g.drawString((new Integer(
  m_nCurrImage)).toString(),
  (size().width - m_nImgWidth)   / 2,
  ((size().height - m_nImgHeight) / 2) + 10);




Содержание