TP sur les visiteurs

Exercice 1

Commencez par terminer le tp précédent sur le pattern commande.

Exercice 2

On veut ajouter un certain nombre de fonctionnalités au programme de dessin, mais sans rajouter trop de méthodes aux classes qui forment le dessin lui-même. Par exemple, on a défini un format très simple de sauvegarde des dessins :

Chaque forme est listée sur une ligne, avec son type et les coordonnées des composants. Pour un cercle : son centre puis son rayon ; pour un segment, les coordonnées de ses deux extrémités, le tout séparés par des espaces.
        cercle 30.0 10.2 5.0
        segment 5.0 0.0 10.0 20.0
        segment 0 0 100 100
    
Le chargement ne pose pas de problème majeur. Mais pour la sauvegarde, on a besoin de savoir à quel type de forme on a affaire pour pouvoir accéder à ses données. Pour cela, on va définir un visiteur :
        public interface FormeVisiteur {
            void visitCercle(Cercle c);
            void visitSegment(Cercle s);
        }
    
Et ajouter à chaque forme la méthode accept(FormeVisiteur v) qui lui correspond.

Question 1

On va ajouter les deux classes suivantes à votre code OuvrirAction et SauverAction.

De plus, dans SimpleDrawAppli, nous ajoutons les deux méthodes suivantes :


        public void ouvrirFichier() {
            try {
                JFileChooser fileChooser = new JFileChooser();
                int res = fileChooser.showOpenDialog(frame);
                if (res == JFileChooser.APPROVE_OPTION) {
                    File file = fileChooser.getSelectedFile();
                    // Pour pouvoir utiliser la classe Files, et ses méthodes simplifiées:
                    Path path = file.toPath();
                    List lignes = Files.readAllLines(path, Charset.forName("utf-8"));
                    // ... votre code
    
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    
        public void sauverFichier() {
            try {
                JFileChooser fileChooser = new JFileChooser();
                int res = fileChooser.showSaveDialog(frame);
                if (res == JFileChooser.APPROVE_OPTION) {
                    File file = fileChooser.getSelectedFile();
                    // Pour pouvoir utiliser la classe Files, et ses méthodes simplifiées:
                    Path path = file.toPath();
                    // L'objet pour pouvoir écrire nos données...
                    Writer w = Files.newBufferedWriter(path, Charset.forName("utf-8"));
                    // ... votre code
                    w.close();
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }    
    
ça n'est probablement pas le meilleur endroit, mais je vous laisse améliorer la structure du code après coup.

En utilisant le pattern Visiteur pour la méthode sauverFichier, complétez le code des deux méthodes.

Exercice 2

On ajoute un nouveau type de formes, le groupe (pattern composite). Un groupe est une forme qui contient d'autres formes. Pour déplacer un groupe, on déplacera toutes les formes de ce groupe.

Question 1

Une fois la classe Groupe créée, vous êtes amenés à modifier le visiteur. Faites-le partout où c'est nécessaire.

Dans un premier temps, on supposera que quand on sauvegarde un groupe, on ne sauve que les formes qu'il contient, pas le groupement lui-même. Vous pourrez ensuite réfléchir à une modification du format de fichier pour gérer correctement les groupes

Question 2

Pour créer des groupes: ajouter à votre vue la notion de selection. Une sélection est un ensemble de formes. Ajoutez un outil "selectionneur", ou, si vous préférez, modifiez l'outil de déplacement pour que :

Ajoutez un bouton "normal" à la barre des boutons, qui exécutera une commande créerGroupeCommande. Cette commande :

Question 3

Que se passe-t-il dans votre programme si on a sélectionné certaines formes, qu'on les a supprimées, et qu'on groupe ?