7.4. Работа с графикой
Вывод графики осуществляется с помощью объектов типа java.awt.Graphics. Для них определен ряд методов, описанных в следующей далее таблице.
Подразумевается, что w - ширина области или фигуры, h - высота; x,y - координаты левого верхнего угла области. Для фигуры x,y - координаты левого верхнего угла прямоугольника, в который вписана фигура.
Таблица
7.2.
Параметры вывода графики |
Color getColor() |
Узнать текущий цвет рисования. |
setColor(Color c) |
Задать текущий цвет рисования. |
Font getFont() |
Узнать текущий шрифт для вывода текстовой информации. |
setFont(Font f) |
Установить текущий шрифт для вывода текстовой информации. Экземпляр шрифта создается с помощью конструктора Font("имяШрифта",стильШрифта,размерШрифта ) |
FontMetrics getFontMetrics() |
Узнать параметры текущего шрифта |
FontMetrics getFontMetrics(Font f) |
Узнать параметры для произвольного шрифта f
|
setXORMode(Color c1) |
Установка режима рисования XOR ("исключающее или") для цвета c1. При этом вывод точки цвета color дает цвет, равный побитовому значению color ^ c1 (то есть color XOR c1) для числовой RGB-кодировки цвета. Повторный вывод графического изображения на то же место приводит к восстановлению первоначального изображения в области вывода. |
setPaintMode() |
Возврат в обычный режим из режима рисования XOR. |
translate(x0,y0) |
Сдвиг начала координат графического контекста в точку x0,y0. Все координаты, указанные при выводе графических примитивов, отсчитываются относительно этого начала координат. |
Рисование контурных фигур |
drawLine(x1,y1,x2,y2) |
Вывод линии из точки с координатами x1,y1 в точку x2,y2
|
drawRect(x,y,w,h) |
Вывод прямоугольника. |
drawRoundRect(x,y,w,h,arcWidth,arcHeight) |
Вывод скругленного прямоугольника. |
draw3DRect(x,y,w,h,isRaised) |
Вывод "объемного" прямоугольника. Если переменная isRaised ==true, он "выпуклый" ( raised ), иначе - "вдавленный". |
drawPolygon(Polygon p) ; drawPolygon(int[] xPoints, int[] yPoints, int nPoints)
|
Вывод многоугольника по массиву точек, nPoints – число точек. |
drawPolyline(int[] xPoints,int[] yPoints, int nPoints) |
Вывод незамкнутой ломаной линии по массиву точек, nPoints – число точек. |
drawOval(x,y,w,h) |
Вывод эллипса. |
drawArc(x,y,w,h,startAngle,arcAngle) |
Вывод дуги эллипса. Начальный угол startAngle и угол, задающий угловой размер дуги arcAngle, задаются в градусах. |
drawImage(Image img,int x,int y, ImageObserver observer) и другие перегруженные варианты метода |
Вывод изображения. |
Рисование заполненных фигур |
clearRect(x,y,w,h) |
Очистка прямоугольника (заполнение текущим цветом) |
fillRect(x,y,w,h) |
Вывод прямоугольника, заполненного текущим цветом. |
fillRoundRect(x,y,w,h,arcWidth,arcHeight) |
Вывод скругленного прямоугольника, заполненного текущим цветом. |
fill3DRect(x,y,w,h, isRaised) |
Вывод "объемного" прямоугольника, заполненного текущим цветом. Если переменная isRaised ==true, он "выпуклый" (raised), иначе - "вдавленный". |
fillPolygon(Polygon p) fillPolygon(int[] xPoints, int[] yPoints, int nPoints)
|
Вывод многоугольника, заполненного текущим цветом. |
fillOval(x,y,w,h) |
Вывод эллипса, заполненного текущим цветом. |
fillArc(x,y,w,h,startAngle,arcAngle) |
Вывод сектора эллипса, заполненной текущим цветом. Заполняется сектор, ограниченный отрезками из центра эллипса в концы дуги, и самой дугой. |
copyArea(x,y,w,h,dx,dy) |
Копирование области на новое место, сдвинутое от старого на dx,dy
|
Вывод текстовой информации |
drawString(s,x,y) |
Вывод строки s |
drawChars(char[] data,int offset,int length,int x,int y) |
Вывод массива символов |
drawBytes(byte[] data,int offset,int length,int x,int y) |
Вывод символов, представленных как последовательность байт |
Управление областью вывода |
setClip(x,y,w,h) setClip(Shape clip)
|
Установка новых границ области вывода. Вне этой области при выводе графических примитивов они усекаются (не выводятся). |
clipRect(x,y,w,h) |
Сужение области вывода. |
Rectangle getClipBounds() Rectangle getClipBounds(Rectangle r)
|
Возвращает параметры прямоугольника, в который вписана область вывода. |
Graphics create() |
g1=g.create() - создание копии графического объекта g
|
dispose() |
Деструктор - уничтожение графического объекта с одновременным высвобождением ресурсов (без ожидания, когда это сделает сборщик мусора). |
Пример метода, работающего с графикой.
java.awt.Graphics g,g1;
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
java.awt.Graphics g,g1;
g=jPanel1.getGraphics();
int x1=20,x2=120,y1=20,y2=120;
int x3=20,y3=20,w3=60,h3=80;
int x4=30,y4=60,w4=30,h4=40;
int x0=10,y0=10,w0=10,h0=10;
int w1=80,h1=120;
g.setClip(0,0,60,80);//границы области вывода
g.drawLine(x1,y1,x2,y2);//линия
g.drawOval(x3,y3,w3,h3);//эллипс
g.clipRect(x4,y4,20,20);//сужение области вывода
g.clearRect(x4,y4,w4,h4);//очистка прямоугольника
g.setClip(0,0,200,280); //новые границы области вывода
g.copyArea(x1,y1,w1,h1,60,0);
g.draw3DRect(10,20,w1,h1,false);
g.drawPolygon(new java.awt.Polygon(new int[]{10,10,20,40},
new int[]{10,20,30,60},4) );
}
В случае попытки такого использования возникает проблема: при перерисовке графического контекста все выведенное изображение исчезает. А перерисовка вызывается автоматически при изменении размера окна приложения, а также его восстановлении после минимизации или перекрытия другим окном.
Для того, чтобы результаты вывода не пропадали, в классе приложения требуется переопределить метод paint, вызываемый при отрисовке. Код этого метода может выглядеть так:
public void paint(java.awt.Graphics g){
super.paint(g);
g=jPanel1.getGraphics();
... – команды графического вывода
}
Правда, при изменении размера окна приложения этот код не сработает, и для панели надо будет назначить обработчик
private void jPanel1ComponentResized (java.awt.event.ComponentEvent evt) {
... – команды графического вывода
}
То, что для изменения размера компонента следует писать отдельный обработчик, вполне разумно – ведь при восстановлении окна требуется только воссоздать изображение прежнего размера. А при изменении размера может потребоваться масштабирование выводимых элементов. Поэтому алгоритмы вывода графики в этих случаях заметно отличаются.
В случае отрисовки из обработчика какого-либо события изменения графического контекста не происходит до окончания обработчика. Это принципиальная особенность работы по идеологии обработчиков событий – пока не кончится один обработчик, следующий не начинается. Для досрочной отрисовки непосредственно во время выполнения обработчика события служит вызов метода update(Graphics g). Пример:
for(int i=0;i<=100;i++){
FiguresUtil.moveFigureBy(figure,dx,dy);
update(g);
};
При работе со статическими изображениями изложенных алгоритмов вполне достаточно. Однако при использовании движущихся элементов во многих графических системах возникает мельтешение, связанное с постоянными перерисовками. В этих случаях обычно применяют идеологию двойной буферизации: отрисовку элементов по невидимому буферному изображению, а затем показ этого изображения в качестве видимого. А то изображение, которое было видимо, при этом становится невидимым буфером.