Перейти на главную   
  helloworld.ru - документация и книги по программированию  
helloworld.ru - документация и книги по программированию
    главная     хостинг    
Поиск по сайту:  
Смотрите также
Языки программирования
C#
MS Visual C++
Borland C++
C++ Builder
Visual Basic
Quick Basic
Turbo Pascal
Delphi
JavaScript
Java
PHP
Perl
Assembler
AutoLisp
Fortran
Python
1C

Интернет-технологии
HTML
VRML
HTTP
CGI
FTP
Proxy
DNS
протоколы TCP/IP
Apache

Web-дизайн
HTML
Дизайн
VRML
PhotoShop
Cookie
CGI
SSI
CSS
ASP
PHP
Perl

Программирование игр
DirectDraw
DirectSound
Direct3D
OpenGL
3D-графика
Графика под DOS

Алгоритмы
Численные методы
Обработка данных

Сис. программирование
Драйверы

Базы данных
MySQL
SQL

Другое

Хостинг


Друзья
demaker.ru
Реклама

Лучший хостинг. Аренда серверов




helloworld.ru

Оглавление

Растровые изображения
Загрузка и рисование
Класс 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);
Назад Вперед












helloworld.ru © 2001-2021
Все права защищены