Электронная библиотека книг Александра Фролова и Григория Фролова.
 
Библиотека
Братьев
Фроловых
Электронная библиотека книг Александра Фролова и Григория Фролова.
Библиотека системного программиста
Программирование на JAVA
ПК. Шаг за шагом
Другие книги
Восстановление данных
Антивирусная защита
Статьи для
программистов
Пользователю компьютера
[Назад]

Библиотека примеров приложений Java

Оглавление
Растровые изображения в аплете

Растровые изображения в автономном приложении
Класс MediaTracker
Класс ImageObserver
Создание изображений
Фильтр RGBImageFilter
Фильтр CropImageFilter
Полупрозрачные изображения
Класс PixelGrabber
Внеэкранное изображение

Назад Вперед

9.4. Класс ImageObserver

Пример показывает применение класса ImageObserver для отслеживания процесса загрузки изображения. Аплет дорисовывает изображение по мере поступления его очередного фрагмента.

Исходный текст примера

Архив проекта для Java WorkShop 2.0

Демонстрация
(ваш браузер должен уметь работать с аплетами Java JDK 1.1)

Немного теории

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

Чтобы использовать этот интерфейс, приложение должно определить метод imageUpdate:

public abstract boolean
  imageUpdate(Image img, int infoflags,
  int x, int y, int width, int height);

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

g.drawImage(Img, x, y, 
  width, height, this);

Здесь предполагается, что метод imageUpdate определен в главном класса аплета и поэтому в качестве ссылки на интерфейс ImageObserver мы передали значение this.

В процессе загрузки изображения, инициированной вызовом метода drawImage, будет многократно вызываться метод imageUpdate. Через параметр infoflags ему будут передаваться флаги, сигнализирующие о текущем состоянии процесса загрузки:

Флаг Описание
WIDTH Изображение загружено настолько, что стала доступна его ширина. Значение ширины изображения можно получить из параметра width метода imageUpdate
HEIGHT Аналогично предыдущему, но для высоты изображения. Высоту изображения можно получить из параметра height метода imageUpdate
PROPERTIES Стали доступны свойства изображения, которые можно получить методом getProperty класса Image
SOMEBITS Стали доступны биты изображения для рисования в масштабе. Через параметры x, y, height и width передаются координаты и размеры прямоугольной области, которая ограничивает загруженную часть изображения
FRAMEBITS Загружен очередной фрейм изображения, состоящего из нескольких фреймов. Параметры x, y, height и width следует игнорировать
ALLBITS Изображение загружено полностью. Параметры x, y, height и width следует игнорировать
ERROR При загрузке произошла ошибка
ABORT Загрузка изображения была прервана или отменена

Как видите, информация, передаваемая методу imageUpdate в параметрах x, y, width и height зависит от значения флага infoflags.

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

Если вам нужно только дождаться завершения процесса загрузки, достаточно использовать флаг ALLBITS. Для проверки ошибок воспользуйтесь флагами ERROR и ABORT.

Описание примера

Пример аплета демонстрирует использование класса ImageObserver для отслеживания процесса загрузки растрового изображения.

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

pic1.gif (12591 bytes)

Рис. 1. Изображение загружено лишь наполовину

pic2.gif (24131 bytes)

Рис. 2. Изображение загружено полностью

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

Обратимся к исходному тексту.

Главный класс аплета

Главный класс аплета IObserverDemo не имеет никаких особенностей:

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

public class IObserverDemo extends Applet
{
  . . .
}

В нем мы определили несколько полей.

Поле bImagesLoaded используется для хранения признака полного завершения загрузки изображения:

boolean bImagesLoaded = false;

В поле img хранится ссылка на загружаемое изображение:

Image img;

Следующие поля предназначены для хранения значений соответствующих параметров метода imageUpdate:

int curX = 0;
int curY = 0;
int curWidth = 0;
int curHeight = 0;

В приложении они не используются и предусмотрены только для примера.

Метод init

Метод init вызывается при инициализации аплета:

public void init()
{
  img = getImage(getDocumentBase(), 
    "img1.jpg");
}

В его задачу входит инициирование процесса загрузки изображения методом getImage.

Метод imageUpdate

Этот метод определен следующим образом:

public boolean imageUpdate(Image img, 
  int bFlags,
  int x, int y, int width, int height)
{
  . . .
}

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

bImagesLoaded = ((bFlags & ALLBITS) != 0);

if(bImagesLoaded)
  repaint();

Если завершился, в параметре bFlags установлен флаг ALLBITS. В этом случае метод imageUpdate перерисовывает окно аплета.

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

if((bFlags & SOMEBITS) != 0)
{
  curX = x;
  curY = y;
  curWidth = width;
  curHeight = height;
      
  repaint();
}

Дополнительно мы сохраняем координаты уже загруженного фрагмента изображения.

Значение, возвращаемое методом imageUpdate, зависит от того, завершился ли полностью процесс загрузки изображения или нет:

return !bImagesLoaded;
Метод update

Так как в процессе загрузки изображения окно нашего аплета многократно перерисовывается, следует предусмотреть меры для исключения мерцания. Мы переопределили метод update:

public void update(Graphics g)
{
  paint(g);
}

Версия этого метода из базового класса также вызывает метод paint, однако перед этим она стирает окно аплета. Исключив стирание, мы избавляемся от мерцания.

Метод paint

Этот метод просто рисует изображение в левом верхнем углу аплета:

public void paint(Graphics g)
{
  g.drawImage(img, 0, 0, this);
}

Обращаем ваше внимание на последний параметр метода. Мы передаем значение указателя на интерфейс ImageObserver как this. В результате в процессе загрузки будет получать управление метод imageUpdate, определенный в главном классе аплета как часть этого интерфейса.


Назад Вперед

[Назад]


Создание интернет-магазинов: http://www.shop2you.ru/ © Александр Фролов, Григорий Фролов, 1991-2016