Design Patterns and Video Games

AWT GUI Facade (3): Display an image

The facade seen in the previous post has only an interface with its methods. It is also possible to enrich a facade with additional interfaces, connected to each other by various means. To illustrate it, I propose to add image management. This addition also makes it possible to present another design pattern: the Factory Method Pattern.

This post is part of the AWT GUI Facade series.

In graphic libraries, it is generally not possible to directly access the raw data of an image, it is always necessary to go through an identifier or a class to apply some processing. Knowing this, a relevant approach is to encapsulate what makes it possible to process the image in a dedicated class, for example:

Compared to the previous post, the following methods have been added to the GUIFacade interface:

Other methods dedicated to the creation and processing of images can be imagined, these are only examples among others.

The Image interface is used to represent access to an image managed by the graphics library. Methods can be proposed to work with an image. In our example, the getWidth() and getHeight() methods return the width and height of the image. Other methods can be imagined, such as a draw() method that would draw the image, instead of the one within the GUIFacade interface.

For the implementation of the facade, we still use the AWT library. For the Image interface implementation, an AWTImage class is proposed:

public class AWTImage implements Image {

    private BufferedImage image;

    @Override
    public int getWidth() {
        if (image == null) {
            throw new RuntimeException("The image was not loaded");
        }
        return image.getWidth();
    }

    @Override
    public int getHeight() {
        if (image == null) {
            throw new RuntimeException("The image was not loaded");
        }
        return image.getHeight();
    }

    void loadImage(String fileName) {
        try {
            image = ImageIO.read(this.getClass().getClassLoader().getResource(fileName));
        } catch (IOException ex) {
            throw new RuntimeException("Error when reading "+fileName);
        }
    }

    void draw(Graphics graphics,int x,int y) {
        graphics.drawImage(image, x, y, null);
    }
}

The AWTImage class holds an image reference to a java.awt.image.BufferedImage. getWidth() and getHeight() methods return the width and height of the image. The other two methods are not part of the facade, and are invisible to its users. They are used by the AWTGUIFacade class to load the image (loadImage() method) and display it in a java.awt.Graphics (draw() method):

public class AWTGUIFacade implements GUIFacade {

    ...

    @Override
    public Image createImage(String fileName) {
        AWTImage image = new AWTImage();
        image.loadImage(fileName);
        return image;
    }   

    @Override
    public void drawImage(Image image, int x, int y) {
        if (!(image instanceof AWTImage))
            throw new IllegalArgumentException("Invalid image type");
        AWTImage awtImage = (AWTImage) image;
        awtImage.draw(graphics,x,y);
    }   

}

This new version of the facade can be used in the following way to display a window with an image:

public static void run(GUIFacade gui) {
    Image titleImage = gui.createImage("title.png");
    gui.createWindow("AWT Graphic User Interface Facade",
        titleImage.getWidth(),titleImage.getHeight());
    while(!gui.isClosingRequested()) {
        if (gui.beginPaint()) {
            gui.drawImage(titleImage,0,0);
            gui.endPaint();
        }
    }      
    gui.dispose();
}

The image is created from the file "title.png" (1. 2), a window of the size of the image is also created (l.3), and as long as the game is not finished (l. 5), the drawing is started (1. 6), the picture is displayed (1. 7) and the drawing is ended (1. 8).

The code of this post can be downloaded here:

awtfacade03.zip

To compile: javac com/learngameprog/awtfacade03/Main.java
To run: java com.learngameprog.awtfacade03.Main

Contents - Next: draw with tiles