Назад
Вперед
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 - полностью.
Рис. 1. Изображение загружено лишь наполовину
Рис. 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,
определенный в главном классе аплета как часть
этого интерфейса.
Назад Вперед |