я подготовил код, который будет
Для своего первого примера я подготовил код, который будет работать на платформе Java 1.1. Хотя виртуальные машины JVM 1.2 достаточно распространены, не все могут размещать программы на этой платформе. К сожалению, провайдеры не сильно спешат обновлять виртуальные машины на своих серверах. Как следствие, приходится разрабатывать сервлеты, работающие на платформе Java 1.1. Это не сильно затруднят задачу; тем не менее, есть некоторые сложности, связанные с формированием изображений, которые мы обсудим ниже.
Будем строить круговую диаграмму (pie chart), которую мы, для полноты картины, раскрасим и подпишем. На диаграмме будут изображены напитки, употребляемые разработчиками программного обеспечения. Посмотрим, как можно это сделать.
Для операций ввода/вывода изображений в Java 1.1 Sun предлагает библиотеку Jimi. Sun приобрел ее у небольшой компании. Перед тем, как начать распространять эту библиотеку, компания Sun перенесла классы в пакет com.sun, а в остальном ничего не изменила.
Следующие шаги необходимо проделать для формирования PNG изображения с использованием Jimi.
- Создать окно приложения(Frame для получения изображения.
- Использую AWT изображение, создать реализацию класса Graphics.
- Нарисовать картинку с помощью объекта Graphics.
- Создать объект JimiWriter на основе потока данных, передаваемых клиенту.
- Преобразовать изображение в соответствующий формат и отправить его клиенту.
Для формирования и модификации изображений на платформе Java 1.1 необходимо использовать активную AWT компоненту. Как правило, сервлет не должен создавать AWT компоненты, которые обычно используются в приложениях с графическим интерфейсом пользователя. В этом случае, вам нужен графический (AWT) объект для того, что бы получить объект класса Graphics, с помощью которого можно рисовать новые картинки. Придется смириться с маленьким окошком на консоли Веб сервера. Если вам известны способы создания изображения в Java 1.1 без использования AWT компонент, пожалуйста, сообщите мне. Один из возможных вариантов, загрузить с диска сервера заранее подготовленный шаблон, например методом java.awt.Toolkit.createImage(). После того, как вы создали AWT изображение, вы можете получить реализацию класса Graphics и использовать ее для рисования. Имея в своем распоряжении объект Graphics, вы можете закрыть ненужное окно на консоли сервера. Я оставлю этот эксперимент заинтересованным читателям.
Напомню, что для связи с классом, рисующим круговую диаграмму, сервлет использует интерфейс ImageProducer. Поэтому наш класс JIMIProducer должен реализовывать этот интерфейс. Прежде всего, создадим AWT окно, AWT изображения и, наконец, объект Graphics:
Frame f = new Frame();
f.setVisible(true; image = f.createImage(ImageWidth, ImageHeight); graphics = image.getGraphics(); f.setVisible(false);
Ключевой метод класса JIMIProducer - drawSlice. Получая на входе метку и величину сегмента в градусах, этот метод рисует сегмент диаграммы, раскрашивает его и подписывает. Далее, я расскажу подробней, как это происходит.
Будем заполнять "внутренности" диаграммы по часовой стрелке, начиная с положения "три часа", то есть первую линию проведем из центра к окружности ограничивающей диаграмму в положении часовой стрелки в три часа дня (или ночи, как вам больше нравиться). Отступим по часовой стрелке необходимое количество градусов и нарисуем вторую линию, ограничивающую сегмент диаграммы. И так далее. Приведенный ниже код получает на входе величину сегмента в градусах и рисует границу этого сегмента. Он вызывается последовательно для всех сегментов, при этом предполагается, что в сумме угловые величины составят 360 градусов.
//************************************************* // Преобразуем угол в радианы // 1 градус = pi/180 радиан //************************************************* doubletheta = degrees * (3.14/180); currentTheta += theta;
//************************************************* // Переводим в декартовы координаты // x = r cos @ // y = r sin @ //************************************************* double x = Radius * Math.cos(currentTheta);
double y = Radius * Math.sin(currentTheta);
Point mark2 = newPoint(center); mark2.translate((int)x,(int)y); graphics.drawLine (center.x, center.y, mark2.x, mark2.y);
Затем, нужно раскрасить сегменты диаграммы. Для этого можно воспользоваться очень полезным методом fillArc():
graphics.setColor(colors[colorIndex++]); graphics.fillArc(Inset, Inset, PieWidth, PieHeight, -1 * lastAngle, -1 * degrees);
Последняя задача метода drawSlice() нарисовать метки сегментов. Расположение надписи рассчитывается, основываясь на метрике используемого шрифта. Окончательный вариант диаграммы можно посмотреть на рисунке.
![](javaservlet_01.gif)
Рис. 1. Окончательный вариант круговой диаграммы. (Не все броузеры показывают файлы формата PNG, поэтому здесь мы поставили GIF файл.)