Search code examples
javaswinggraphics2d

Understanding Swing code from "Filthy Rich Clients"


Below is the code from "Filthy Rich Clients" by Romain Guy and Chet Haase

private class ImageViewer extends JComponent {
    private BufferedImage image, landscape;

    private ImageViewer() {
        try {
            image = ImageIO.read(new File("picture.png"));
            landscape = ImageIO.read(new File("landscape.jpg"));
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    @Override
    protected void paintComponent(Graphics g) {
        BufferedImage temp = new BufferedImage(getWidth(), getHeight(),
            BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2 = temp.createGraphics();

        if (shadow.isSelected()) {
            int x = (getWidth() - image.getWidth()) / 2;
            int y = (getHeight() - image.getHeight()) / 2;
            g2.drawImage(image, x + 4, y + 10, null);

            Composite oldComposite = g2.getComposite();
            g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_IN, 0.75f));
            g2.setColor(Color.BLACK);
            g2.fillRect(0, 0, getWidth(), getHeight());
            g2.setComposite(oldComposite);
            g2.drawImage(image, x, y, null);
        } else {
            int x = (getWidth() - image.getWidth()) / 2;
            int y = (getHeight() - image.getHeight()) / 2;
            g2.drawImage(image, x, y, null);

            Composite oldComposite = g2.getComposite();
            g2.setComposite(AlphaComposite.SrcIn);
            x = (getWidth() - landscape.getWidth()) / 2;
            y = (getHeight() - landscape.getHeight()) / 2;
            g2.drawImage(landscape, x, y, null);
            g2.setComposite(oldComposite);
        }

        g2.dispose();
        g.drawImage(temp, 0, 0, null);
    }
}

It is a part of the code to obtain the following output with different states when checkbox is checked:- enter image description here

What i dont understand is

1)what is the line

BufferedImage temp = new BufferedImage(getWidth(), getHeight(),
        BufferedImage.TYPE_INT_ARGB);

doing there because if I write only the following code and run nothing is obtained in the output.

BufferedImage temp = new BufferedImage(getWidth(), getHeight(),
        BufferedImage.TYPE_INT_ARGB);
    Graphics2D g2 = temp.createGraphics();

    if (jcb.isSelected()) {
        int x = (getWidth() - image.getWidth()) / 2;
        int y = (getHeight() - image.getHeight()) / 2;
        g2.drawImage(image, x + 4, y + 10, null);
           }

2)What is the need to obtain g2 after creating the 'temp' bufferedImage? Can't I do it directly like

Graphics2D g2=(Graphics2D)g.create();

3)What is practical difference between TYPE_INT_RGB and TYPE_INT_ARGB.?


Solution

  • This is double buffering: http://docs.oracle.com/javase/tutorial/extra/fullscreen/doublebuf.html

    You first draw on an off-screen image, which in this case is backed by a BufferedImage object referenced in the variable temp; then you do whatever to the off-screen image; finally, you print the result on the component, via g.drawImage(temp, ...). This is not to have the user see glitches or artifacts due to the image being constructed directly on the screen.