Façade Bibliothèque Graphique AWT (3): Afficher une image

La façade vue dans l’article précédent ne comporte qu’une interface avec ses méthodes. Il est également possible d’enrichir une façade avec des interfaces supplémentaires, connectées entre elles par divers moyens. Pour l’illustrer, je vous propose d’ajouter la gestion des images. Cet ajout permet par ailleurs de présenter un autre patron de conception: le patron Fabrique (Factory Method Pattern).

Au sein des bibliothèques graphiques, il n’est généralement pas possible d’accéder directement aux données brutes d’une image, il faut toujours passer par un identifiant ou une classe pour appliquer un traitement particulier. Sachant cela, une approche pertinente consiste à encapsuler ce qui permet de traiter l’image dans une classe dédiée, par exemple:

Par rapport à l’article précédent, les méthodes suivantes ont été ajoutées à l’interface GUIFacade:

  • La méthode createImage() permet de créer une Image à partir du nom d’un fichier. Ce faisant, nous sommes en train d’utiliser le patron Fabrique, qui permet d’abstraire la création d’objets, et dont le processus de création dépend d’un jeu d’héritage. Dans le cas présent, l’utilisateur de la méthode createImage() ne sait pas quelle implantation de l’interface Image va être utilisée. Ce choix dépend de la classe qui implante l’interface GUIFacade, dont les détails ne sont pas nécessairement connus de l’utilisateur, puisque c’est une façade.
    Une fois de plus, l’idée est de libérer l’utilisateur de spécificités particulières, et le laisser se concentrer sur le problème qu’il a à traiter, dans notre cas le rendu d’un jeu 2D en tuiles.
  • La méthode drawImage() permet de dessiner une image aux coordonnées (x,y).

D’autres méthodes dédiées à la création et au traitement des images peuvent être imaginées, celles-ci ne sont des exemples parmi d’autres.

L’interface Image permet de représenter l’accès à une image gérée par la bibliothèque graphique. Des méthodes qui ne concernent que l’image gérée peuvent être proposées pour rendre la façade agréable. Dans notre exemple, les méthodes getWidth() et getHeight() renvoient la largeur et la hauteur de l’image. D’autres méthodes peuvent être imaginées, comme une méthode draw() qui permettrait de dessiner l’image, à la place de celle au sein de l’interface GUIFacade.

Pour l’implantation de la façade, nous restons sur la bibliothèque AWT. Pour l’interface Image, une classe AWTImage est proposée:

public class AWTImage implements Image {

    private BufferedImage image;

    @Override
    public int getWidth() {
        if (image == null) {
            throw new RuntimeException("L'image n'a pas été chargée");
        }
        return image.getWidth();
    }

    @Override
    public int getHeight() {
        if (image == null) {
            throw new RuntimeException("L'image n'a pas été chargée");
        }
        return image.getHeight();
    }
    
    void loadImage(String fileName) {
        try {
            image = ImageIO.read(this.getClass().getClassLoader().getResource(fileName));
        } catch (IOException ex) {
            throw new RuntimeException("Erreur lors de la lecture de "+fileName);
        }
    }
    
    void draw(Graphics graphics,int x,int y) {
        graphics.drawImage(image, x, y, null);
    }
}

La classe AWTImage encapsule une référence image vers une java.awt.image.BufferedImage. Les deux méthodes getWidth() et getHeight() de la façade retournent la largeur et la hauteur de cette image. Les deux autres méthodes ne font pas parties de la façade, et sont invisibles pour ses utilisateurs. Elles sont utilisées par la classe AWTGUIFacade pour charger l’image (méthode loadImage()) et l’afficher dans un java.awt.Graphics (méthode draw()):

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("Type d'image invalide");
        AWTImage awtImage = (AWTImage) image;
        awtImage.draw(graphics,x,y);
    }   

}

Cette nouvelle version de la façade peut être utilisée de la manière suivante pour afficher une fenêtre avec une image:

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

L’image est créée à partir du fichier “title.png” (l. 2), une fenêtre de la taille de l’image est également créée (l. 3), et tant que le jeu n’est pas terminé (l. 5), le dessin est démarré (l. 6), l’image affichée (l. 7) et le dessine terminé (l. 8).

Le code de cet article peut être téléchargé ici.
Pour compiler, saisissez: javac fr/phtools/awtfacade03/Main.java
Pour lancer, saisissez: java fr.phtools.awtfacade03.Main

Ce contenu a été publié dans Tutoriel, avec comme mot(s)-clé(s) , , , . Vous pouvez le mettre en favoris avec ce permalien.

Laisser un commentaire