| Форум| Гостевая| Ссылки| Программы| Исходные тексты| Наши партнеры|
   
| Главная| Рассылки| Услуги| Библиотека| Новости| Авторам| Программистам| Студентам|
delphi c++ assembler
 

Оглавление

Растровые изображения
Загрузка и рисование
Класс Image
Ожидание загрузки
Видео
Аплет CDRotation

    Аплет CDRotation

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

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

    pic01.gif (3268 bytes)

    Рис. 1. Изображение вращающегося компакт-диска в окне аплета CDRotation

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

    Главный файл исходных текстов приложения 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);


Java | Продукты и решения | Технологии | Сервис и обучение
О компании | Партнеры | Новости | Поиск
Sun Microsystems Inc. Corporate Information Our partners News and Events Search on site Java Computing Products and Solutions Technologies and Researches Education and Service Content
Используются технологии uCoz

Rambler's Top100 Rambler's Top100

©  Adept Design Studio

Используются технологии uCoz