Главная » Java, Web » Двойная буферизация image

0

Объекты image могут храниться в памяти компьютера. Эти изображения, если они не записаны в буфер экрана, не видимы пользователю. Изображения, хранимые в памяти компьютера, могут быть очень быстро скопированы в буфер экрана и стать видимыми. Именно такая техника используется при рисовании компонентов swing, которые предоставляют дополнительные возможности при работе с графикой. Картинка создается шаг за шагом, образуя изображение в памяти компьютера. Этот процесс может занять некоторое время. Если бы процесс рисования происходил в буфере экрана, пользователь смог бы заметить мерцание картинки. Удобнее заменить существующую картинку уже созданной новой картинкой и не рисовать ее в процессе отображения на экран. Замена одного изображения другим готовым изображением происходит мгновенно. Пользователь не заметит мерцания, вызванного тем, что картинка создается в процессе ее отображения. При этом изображение, особенно при использовани анимации, становится гладким.

Техника предварительного создания изображения в памяти компьютера и дальнейшее ее отображение на экран после того, как картинка уже создана, называется двойной буферизацией. Также используется термин кадровая буферизация. Видеокарта, переходя от буфера одного кадра к буферу другого кадра, отображает любой кадр практически мгновенно. Каждый кадровый буфер используется для отображения нового изображения на экране компьютера. Копирование памяти не требуется. Однако в Java при технике двойной буферизации копирование памяти необходимо. Конечно, можно отказаться от использования двойной буферизации, но при этом на экране будет заметно мерцание.

В качестве иллюстрации рассмотрим два примера. Файл DB.java (листинг 1.31) описывает перетаскиваемый красный квадрат с использованием техники двойной буферизации. не используется в файле NonDB.java (листинг 1.30). Второй апплет при перетаскивании квадрата будет мерцать. Чтобы сделать эффект мерцания более заметным, фон содержит множество серых горизонтальных линий, это увеличивает время прорисовывания, делает мерцание сильно заметным.

Листинг 1.30. Файл NonDB.java

двойная буферизация отсутствует

impo гt j ava.awt.*; impo rt j ava.awt.event.*; import javax.swing. *; public class NonDB extends JApplet { public void init() { setContentPane(new Display());

getRootPane().setDoubleBuffered(false); }

class Display extends JPanel implements MouseListener, MouseMotionListener { int xl, yl; boolean dragging; int offsetX, offsetY; Display () { xl = 10; yl = 10;

setBackground(Color.white); addMouseListener(this) ; addMouseMotionListener(this); setDoubleBuffered(false);

public void paintcomponent(Graphics g) { int width = getSize().width; // ширина компонента int height = getSize().height; // высота компонента g.setColor(Color.white); g. fillRect(0,0,width,height); g.setColor(Color.gray);

for (int i = 3; i < width; i += 2) // вертикальные линии g.drawLine(i,0,i,height);

for (int j = 3; j < height; j += 2) // горизонтальные линии g.drawLine(0,j,width, j); g.setColor(Color.red) ;

g.fillRect(xl, yl, 50, 50); // красный квадрат

g.setColor(Color.black);

g.drawRect(0, 0, width — 1, height — 1);

g.drawRect(1, 1, width — 3, height — 3);

}

public void mousePressed(MouseEvent evt) {

if (dragging) return; int x = evt. getX () ; int у = evt.getY() ;

if (x >= xl && x < xl+50 && у >= yl && у < yl+50) { dragging = true; offsetX = x — xl;

offsetY = у — yl; }

}

public void mouseReleased(MouseEvent evt) { dragging = false;

if (xl + 50 < 3 || xl > getSize().width – 3

II yl + 50 < 3 || yl > getSize().height – 3) { xl = 10; yl = 10;

repaint(); }

}

public void mouseDragged(MouseEvent evt) {

if (dragging == false)

return;

int x = evt. getX () ; // положение мыши int у = evt.getY();

xl = x — offsetX; // перемещение квадрата yl = у — offsetY;

repaint(); }

public void mouseMoved(MouseEvent evt) { } public void mouseClicked(MouseEvent evt) { } public void mouseEntered(MouseEvent evt) { }

public void mouseExited(MouseEvent evt) { } }

Листинг 1,31. Файл DB.java

используется двойная буферизация

impo гt j ava.awt.*; impo rt j ava.awt.event.*; import javax.swing. *; public class DB extends JApplet { public void init() {

setContentPane(new Display()); }

class Display extends JPanel implements MouseListener, MouseMotionListener { int xl, yl; boolean dragging; int offsetX, offsetY; Display () { xl = 10; yl = 10;

setBackground(Color.white); addMouseListener(this) ; addMouseMotionListener(this);

}

public void paintComponent(Graphics g) { int width = getSize().width; int height = getSize().height; super.paintComponent(g); g.setColor(Color.gray) ; for (int i = 3; i < width; i += 2) g.drawLine(i,0,i,height);

for (int j = 3; j < height; j += 2) g.drawLine(0,j,width,j); g.setColor(Color.red); g.fillRect(xl, yl, 50, 50); g.setColor(Color.black); g.drawRect(0, 0, width — 1, height — 1); g.drawRect(1, 1, width — 3, height — 3);

public void mousePressed(MouseEvent evt) {

if (dragging) return;

int x = evt.getX(); int у = evt.getY() ; if (x >= xl && x < xl+50 && у >= yl && у < yl+50) { dragging = true; offsetX = x — xl;

offsetY = у — yl; }

}

public void mouseReleased(MouseEvent evt) { dragging = false;

if (xl + 50 < 3 || xl > getSize().width – 3

II yl + 50 < 3 || yl > getSize().height – 3) { xl = 10; yl = 10;

repaint(); }

}

public void mouseDragged(MouseEvent evt) {

if (dragging == false)

return;

int x = evt. getX () ; int у = evt.getY(); xl = x — offsetX; yl = у — offsetY;

repaint(); }

public void mouseMoved(MouseEvent evt) { } public void mouseClicked(MouseEvent evt) { } public void mouseEntered(MouseEvent evt) { }

public void mouseExited(MouseEvent evt) { } }

}

Бывает полезно создание собственного невидимого изображения. Это можно сделать при помощи метода createimage (). Этот метод определен в классе component. Поэтому его можно использовать практически в любом месте апплета:

Image offScreenlmage = createimage(width, height);

Класс image содержит метод getGraphics (), этот метод возвращает объект

Graphics:

Graphics offscreenGraphics = offScreenlmage.getGraphics();

Теперь можно использовать рисование. Все рисование будет осуществлено

на скрытом рисунке:

offscreenGraphics.drawRect(10,10, 50,100) ;

После того как картинка нарисована, ее можно скопировать в другой графический контекст при помощи метода drawimage ():

g.drawimage(offScreenlmage,0,0,null)

Скрытые изображения можно использовать для решения задачи восстановления изображений после того, как область апплета была невидимой.

Источник: Будилов В. А. Интернет-программирование на Java. — СПб.: БХВ-Петербург, 2003. — 704 е.: ил.

По теме:

  • Комментарии