Cours:Système d'éclairage - MVC

De troyesGEII
Aller à : navigation, rechercher


Système d'éclairage MVC

Introduction

L'objectif est d'écrire une interface graphique au système d'éclairage déjà programmé en Processing, et ceci en utilisant une forme de programmation nommée MVC "Modèle-Vue-Contrôleur":

  • le modèle est tout simplement constitué des classes de notre système d'éclairage: Lampe, Commutateur et Bouton. Lorsqu'un changement se produit dans une classe du modèle, cette classe notifie à la vue ce qu'il vient de se produire.
  • la vue est une ensemble de classes (par exemple, graphiques) qui représentent l'état des classes du modèle. Par exemple, il faudra une classe LampeGraphique qui, lorsqu'elle est notifiée, représente le nouvel état de la classe Lampe.
  • le contrôleur qui sert à faire communiquer de la vue vers le modèle. Dans notre application, le contrôleur servira à appuyer sur le Bouton du modèle lorsque l'on clique sur le bouton de l'interface graphique (la vue).


le Modèle

les classes du modèle

Il s'agit du coeur de l'application: dans notre cas, il s'agit des classes du système d'éclairage.

Ces classes seront à écrire dans un package de nom modele.

Nous aurons donc à réécrire trois classes:

  • la classe Lampe:
    • 2 attributs: puissance et estAllume
    • 1 constructeur avec en paramètre la puissance
    • 2 méthodes: allumer() et eteindre().
  • la classe Commutateur
    • 2 attributs:
      • etat qui représente l'état du commutateur
      • lampes , un tableau de 3 cases de type Lampe (la lampe de 50W est dans la case numéro 0).
    • un constructeur avec en paramètre un tableau de 3 Lampe.
    • une méthode augmenterPuissance().
  • la classe Bouton
    • 1 attribut: c de type Commutateur.
    • 1 méthode appuyer().

la notification à la vue

Pour qu'une classe puisse notifier à une autre un changement, elle doit:

  • hériter de la classe Observable (java.util.Observable)
  • notifier le changement par:
   setChanged();
   notifyObservers(...);

Dans la version la plus simple de notre application, la classe Lampe devra hériter de la classe Observable et notifier qu'elle change d'état (cad, dans allumer() et dans eteindre()) par:

   setChanged();
   notifyObservers(estAllume);


la Vue

Elle est constituée d'une FaceAvant sur laquelle 3 objets LampeGraphique et un JButton seront placés.

Ces deux classes FaceAvant et LampeGraphique seront placées dans un package de nom vue.


la classe LampeGraphique

Pour des raisons de simplicité de programmation, cette classe héritera de la classe Java JButton (qui correspond normalement à un bouton d'interface graphique).

Chaque objet de type LampeGraphique observera en permanence un objet de type Lampe: il devra s'allumer (resp. s'éteindre) lorsque la lampe s'allumera (resp. s'éteindra).

Pour ce faire, il devra implémenter l'interface java Observer qui permet de devenir un observateur d'un objet de type Observable (la Lampe). Cette interface (promesse de méthode) promettant une méthode update(), il faudra donc l'écrire dans LampeGraphique.


    public class LampeGraphique extends JButton implements Observer {
    
           public LampeGraphique(String nomLampe) {
                  // positionner nomLampe dans le JButton
                  super(nomLampe);
                  ...
           }
    
           public void allumer() {
                  // positionner couleur de fonds à blanc et couleur de texte à noir: voir setBackground(...) et setForeground(...)
                  ...
           }
    
           public void eteindre() {
                  // positionner couleur de fonds à noir et couleur de texte à blanc
                  ...
           }
    
           public void update(Observable arg0, Object arg1) {
                  // arg0 est la lampe qui a émis le message arg1 (arg1 = état de la lampe, booléen)
                  // algo: si arg1 vrai, allumer LampeGraphique, sinon l'éteindre
                  if (((boolean)arg1)==true) allumer();
                     else eteindre();
           }
    }

la classe FaceAvant

  • Cette classe héritera de la classe java JFrame, ce qui lui permettra d'être une fenêtre graphique sur l'écran. Elle aura un constructeur recevant un tableau de 3 LampeGraphique et un objet de type Controleur (Rappel: ce contrôleur servira lorsque l'on cliquera sur le bouton graphique).
  • elle sera constituée de:
    • un panel (JPanel) de 3 objets de type LampeGraphique. Ce panel sera placé en haut de la fenêtre graphique.
    • un bouton graphique (JButton, en bas de la fenêtre) qui permettra d'appuyer sur l'objet Bouton du modèle.

Le code cette classe ressemblera donc à ce qui suit:


    public class FaceAvant extends JFrame {

           JButton bouton;

	   public FaceAvant(LampeGraphique[] lg, Controleur controleur) {
	
                // récupère une référence sur l'intérieur de la fenêtre
		Container c = this.getContentPane();

                // création d'un nouveau panel
		JPanel p = new JPanel();

                // placement des 3 LampeGraphique dans ce panel
		p.add(lg[0], BorderLayout.WEST);
		p.add(lg[1], BorderLayout.CENTER);
		p.add(lg[2], BorderLayout.EAST);

                // le panel est place en haut de la fenêtre
		c.add(p, BorderLayout.NORTH);

                // création du bouton
                bouton=new JButton("bouton");

                // le bouton est place en bas de la fenêtre
		c.add(bouton, BorderLayout.SOUTH);

                // connexion du bouton avec son controleur
		bouton.addActionListener(controleur);

                // qq bricoles sur la fenêtre
		setLocationRelativeTo(null);                   // au centre de l'écran
		setDefaultCloseOperation(EXIT_ON_CLOSE);       // fermer la fenêtre permet de quitter l'application
		pack();                                        // création de la fenêtre à la bonne taille 
		setVisible(true);                              // la fenêtre est visible
	   }

}


le Contrôleur

Cette classe Controleur est chargée de gérer les clics souris sur le bouton de l'interface graphique (la vue).

Cette classe sera à écrire dans un package de nom controleur.

Ce contrôleur, devant réaliser une action sur le Bouton du modèle (action appuyer()), doit donc posséder un attribut de type Bouton qui sera initialisé par le constructeur Controleur.

Cette classe Controleur devra implémenter l'interface ActionListener (écouteur d'action), qui promet une méthode ActionPerformed appelée automatiquement lorsqu'un clic sur le bouton se produit.

public class Controleur implements ActionListener {

	private Bouton b;

	public Controleur(Bouton b) {
		....
	}

	public void actionPerformed(ActionEvent arg0) {
		b.appuyer();
	}

}


la classe de test TestGUI

Elle est chargée de la création des différents objets et de leur association:

  • pour le modèle:
    • création de tl: un tableau de trois Lampe.
    • création d'un commutateur associé à tl.
    • création d'un bouton associé au commutateur.


  • pour le contrôleur:
    • création d'un contrôleur associé au bouton du modèle.


  • pour la vue:
    • création de tlg: un tableau de trois LampeGraphique
    • sur chacune des lampes du tableau de Lampe, rajout de l'objet observateur correspondant LampeGraphique en utilisant la méthode addObserver():
for (int i=0;i<tl.length;i++) {
    tl[i].addObserver(tlg[i]);
    }
  • création de la FaceAvant, ce qui crée la fenêtre sur l'ecran.
new FaceAvant(tlg, controleur);


Travail à faire

  • Ecrire et faire fonctionner cette application.
  • Modifier LampeGraphique et Lampe pour que LampeGraphique puisse construire nomLampe de manière autonome.
  • Afficher au milieu de la fenêtre la puissance actuelle d'éclairage, suivant les lampes allumées.
  • Modifier LampeGraphique pour que certaines instances de cette classe aient un fonctionnement inversé par rapport à la lampe qu'elles sont chargées d'observer.


Ressources : pour aller plus loin

Design Pattern MVC

GUI en Java