Двойная буферизация
Листинг 6.9. Двойная буферизация использует два графических контекста. Единственный способ получить второй графический контекст в МЮР - через класс Image
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import Java.io.lOException;
Демонстрирует двойную буферизацию графического контекста
для отображения в Canvas.
public class DoubleBufferDerao extends Canvas
implements CommandListener
{
// Константа, которая представляет белый цвет.
private static final int WHITE = OxFF « 16 I OxFF « 8 | OxFF;
private static Command back = new Command("Back", Command.BACK, 1);
GraphicsDemo gDemo = GraphicsDemo.getlnstance();
private Display display = Display.getDisplay(gDemo);
// Объект изображения, используемый для получения
// внеэкранного объекта Graphics, private Iraage offscreen;
// Переменная, используемая для определения того, осуществляет
// ли реализация автоматическую двойную буферизацию.
// Сохраняет значение true, если реализация автоматически
// осуществляет двойную буферизацию, иначе становится
false. private boolean autoDoubleBuffered = true;
/**
Конструктор No-arg.
* /
public DoubleBufferDemo()
super();
addCoramand(back);
setCommandListener(this);
display.setCurrent(this);
if ( ! isDoubleBufferedO )
{
// Если реализация не использует двойную буферизацию
// автоматически, извлеките Image для того, чтобы мы могли
// получить из него внеэкранный Graphics. Этот Image изменяемый!
// Его размерами являются высота и ширина данного Canvas.
offscreen = Image.createlmage(getWidth (),
getHeight () ) ;
autoDoubleBuffered = false;
}
)
protected void paintdipRect (Graphics g)
int clipX = g.getClipX() ;
ir.t clipY = g.getClipY() ;
int clipH = g.getClipHeight();
int clipW = g.getClipWidth();
int color = g.getColor ();
g.setColor (WHITE);
g.fillRect(clipX, clipY, clipW, clipH);
g,setColor(color);
}
public void paint(Graphics g)
}
Graphics originalG = null;
int width = getWidthf);
int height = getHeight ();
if (!autoDoubleBuffered)
}
// Сохраняем первоначальный графический контекст и получаем
// новый внеэкранный Graphics из утилиты Image.
originalG = g;
g = offscreen.getGraphics ();
// Очищаем отсекаемый прямоугольник с помощью нового объекта
// Graphics. Таким образом, мы используем двойную буферизацию
// для очистки Canvas, следовательно, избегая мерцания.
// Очистка Canvas является рисованием, как и все другие
// операции по рисованию. paintdipRect (g) ;
}
else
{
// Очищаем Canvas с первоначальной графикой, поскольку
// реализация не выполняет двойной буферизации автоматически.
paintdipRect (g) ;
}
for (int x = 0, у = 0; (x < width /2);
x = x + 2)
{
g.drawRect(x, y, (width - x) - x, (height - y) - y) ;
у +1; у +1 ;
}
// При рисовании изображения содержимое внеэкранного
// контекста Graphics изображения на самом деле копируется
// в контекст Graphics устройства. if (!autoDoubleBuffered)
{
originalG.drawlmage(offscreen, 0, 0,
Graphics.TOP | Graphics.LEFT);
{{
public void commandAction(Command c, Displayable d)
}
if (c == back)
GraphicsDemo.getInstance().display!);
}
}
}
Конструктор содержит первый код, связанный с двойной буферизацией. Нижеприведенный оператор, взятый из безаргументного конструктора DoubleBufferDemo, определяет, поддерживает ли реализация автоматическую двойную буферизацию.
if (!isDoubleEuffered())
{
offscreen = Image.createlmage(getWidth(), getHeight());
autoDoubleBuffered = false;
}
Если реализация не поддерживает двойную буферизацию, приложению не нужно выполнять ее. Метод Canvas.IsDoubleBuffered() сообщает вам, не выполняет ли реализация двойную буферизацию неявно. Обратите внимание на конструкцию объекта Image. Этот вызов Image, create Image () создает изменяемый объект Image. Приложение нуждается в изменяемом Image, потому что оно выполняет рисование в контексте Graphics объекта Image, являющемся нужным вам внеэкранным буфером. Это единственный способ получения дополнительного Graphics в MIDP.
Метод paint () содержит остальной код двойной буферизации. Если автоматическая двойная буферизация не осуществляется, приложение должно выполнить ее. Это требует второго графического контекста. Следующий фрагмент метода paint () демонстрирует эту идиому
public void paint(Graphics g)
if (!autoDoubleBuffered)
originalG = g;
g = offscreen.getGraphics();
else
{
paintClipRect(g);
}
. . .
}
Временная переменная хранит ссылку на первоначальный объект Graphics, который представляет графический контекст устройства. Новый графический контекст получается через объект Image, созданный ранее. Этот Graphics связан с Image. Последовательность событий представлена схематично на рисунке 6.11.
Теперь метод paint (Graphics g) выполняет свои операции по рисованию во внеэкранном контексте Graphics. При выполнении он копирует содержимое внеэкранного Graphics в первоначальный контекст Graphics, что в результате формирует изображение на дисплее. Операция копирования совершается с помощью вызова метода Graphics.drawlmage(). Этот метод говорит по сути: «Копируй содержимое графического контекста этого аргумента изображения в меня».
Механизм двойной буферизации в MIDP отличается от двойной буферизации Swing. В Swing вы можете выполнять двойную буферизацию операций по рисованию в любом Component, не только в объектах Canvas. Приложения Swing вызывают Java. awt. Component .getGraphics () для получения внеэкранного графического контекста. Приложение может рисовать в этом контексте. Оно затем связывает этот внеэкранный графический контекст с самим устройством.