Historia wymaga pasterzy, nie rzeźników.

width, h = d.height;
mImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
// Obtain the Graphics2D for the offscreen image.
Graphics2D g2 = mImage.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
// Load an image from a file.

page 165
Java 2D Graphics
try {
String filename = "Raphael.jpg";
InputStream in = getClass().getResourceAsStream(filename);
JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(in);
BufferedImage image = decoder.decodeAsBufferedImage();
in.close();
// Draw the loaded image on the offscreen image.
g2.drawImage(image, 0, 0, w, h, null);
}
catch (Exception e) { System.out.print(e); }
// Draw some concentric ellipses.
g2.setStroke(new BasicStroke(2));
Color[] colors = { Color.red, Color.blue, Color.green };
for (int i = -32; i < 40; i += 8) {
g2.setPaint(colors[Math.abs(i) % 3]);
g2.drawOval(i, i, w - i * 2, h - i * 2);
}
}
}
The main() method sets up a frame window to contain the example. All of the action is in the paint() and createOffscreenImage() methods. All paint() has to do is create the offscreen image, if necessary, and render it to the screen. The createOffscreenImage() method first creates a new offscreen image that will fit inside the ImageDuplicity component. Then it loads another image from a file and renders the loaded image on the offscreen image, scaling it to fit. Finally, createOffscreenImage() draws some colored concentric ellipses on the offscreen image. Figure 15.10 shows what this looks like.
9.5 Double Buffering
One important application of offscreen images is double buffering. This is a technique that eliminates flicker in animated graphics. Double buffering gets its name from the fact that there are two graphics areas (buffers) involved—the onscreen buffer and the offscreen image. Animation is just the process of showing one frame after another. Without double buffering, you simply clear the drawing area and draw the new frame. Repeated clearing and redrawing produces flicker, as shown in the next example, Annoyance. This class simply renders a filled rectangle at the coordinates of the last mouse motion event. When you move the mouse around in the window, you'll notice the flicker.
import java.awt.*;
import java.awt.event.*;

public class Annoyance
extends ApplicationFrame
implements MouseMotionListener {
public static void main(String[] args) {
new Annoyance();
}

private int mX, mY;
public Annoyance() {
super("Annoyance v1.0");
addMouseMotionListener(this);
setVisible(true);
}

public void mouseMoved(MouseEvent me) {
mX = (int)me.getPoint().getX();
mY = (int)me.getPoint().getY();

page 166
Java 2D Graphics
repaint();
}

public void mouseDragged(MouseEvent me) { mouseMoved(me); }

public void paint(Graphics g) {
int s = 100;
g.setColor(Color.blue);
g.fillRect(mX - s / 2, mY - s / 2, s, s);
}
}
Double buffering eliminates the flicker from this example. Basically, I'll render the rectangle into an offscreen image and then transfer the image to the screen. This erases the old picture and draws the new one in one step. The new paint() method looks like this:
public void paint(Graphics g) {
// Clear the offscreen image.
Dimension d = getSize();
checkOffscreenImage();
Graphics offG = mImage.getGraphics();
offG.setColor(getBackground());
offG.fillRect(0, 0, d.width, d.height);
// Draw into the offscreen image.
paintOffscreen(mImage.getGraphics());
// Put the offscreen image on the screen.
g.drawImage(mImage, 0, 0, null);
}
Note that we have to clear the offscreen image first. Normally, a drawing surface is cleared in Component's update() method. However, since our real drawing happens offscreen, we have to manually clear the offscreen image.
But update() is still clearing the onscreen drawing surface. Since our offscreen image will completely replace the onscreen drawing surface, we don't want update() to clear the onscreen drawing surface every time the image is rendered. Our new class, therefore, overrides update() so that all it does is call paint().
import java.awt.*;
import java.awt.event.*;
public class SmoothMove
extends ApplicationFrame
implements MouseMotionListener {
public static void main(String[] args) {
new SmoothMove();
}

private int mX, mY;
private Image mImage;

public SmoothMove() {
super("SmoothMove v1.0");
addMouseMotionListener(this);
setVisible(true);
}

Podstrony