Programmation orientée objet en Java

MVC : programmer son IHM

Patrick Bellot

Télécom ParisTech
E-mail : bellot@telecom-paristech.fr
Tél : 06 63 33 22 57

Licence des droits d'usage

Par le téléchargement ou la consultation de ce document, l'utilisateur accepte la licence d'utilisation qui y est attachée, telle que détaillée dans les dispositions suivantes, et s'engage à la respecter intégralement.

La licence des droits d'usage de ce document confère à l'utilisateur un droit d'usage sur le document consulté ou téléchargé, totalement ou en partie, dans les conditions définies ci-après, et à l'exclusion de toute utilisation commerciale.

Le droit d'usage défini par la licence autorise un usage dans un cadre académique, par un utilisateur donnant des cours dans un établissement d'enseignement secondaire ou supérieur et à l'exclusion expresse des formations commerciales et notamment de formation continue. Ce droit comprend :

Aucune modification du document dans son contenu, sa forme ou sa présentation n'est autorisée.

Les mentions relatives à la source du document et/ou à son auteur doivent être conservées dans leur intégralité.

Le droit d'usage défini par la licence est personnel, non exclusif et non transmissible.

Tout autre usage que ceux prévus par la licence est soumis à autorisation préalable et expresse de l'auteur : bellot@telecom-paristech.fr.

La notion de modèle






Introduction à MVC

La notion de Modèle

Dessiner dans les JPanel

Le modèle MVC


MVC (Modèle - Vue - Contrôleur) est un patron de conception (design pattern) utilisé pour programmer des interfaces utilisateur.

Notre modèle

Notre modèle devra contenir tout ce qui est nécessaire pour déterminer l'état de l'interface et les données de l'application :

Un segment


Google : JAVA SE7 Line2D

Le segment

Un Segment est un Line2D.Float étendu par une couleur (extension modulaire).

package model;

import java.awt.* ;
import java.awt.geom.* ;

public class Segment extends Line2D.Float 
{
   private Color color ;

   public Segment(float x1, float y1, 
                  float x2, float y2, Color color)
   {
      super(x1,y1,x2,y2) ;

      this.color = color ;
   }

}

Le modèle

Le Modèle contient ce qui avait été énuméré :

package model;

import java.awt.* ;
import java.util.* ;

public class DrawingAppModel 
{
   private final ArrayList<Segment> editedSegments  = new ArrayList<Segment>(128) ;
   private       Color              currentColor    = new Color(0,0,0) ;
   private       Segment            currentSegment  = null ;
   private       Segment            selectedSegment = null ;
   private       boolean            modified        = false ;
	
   // getters et setters	
   ...
   ...
   ...	
}

Où mettre le modèle ?

Le modèle va être mis en attribut de la fenêtre principale. La fenêtre principale est accessible à tous les composants.
Code à rajouter dans DrawingApp :
        import model.* ; // rajouter en début de fichier

	
	// rajouter dans la classe DrawingApp

	private DrawingAppModel drawingAppModel = new DrawingAppModel() ;

	public DrawingAppModel getDrawingAppModel() 
	{
		return drawingAppModel;
	}

	public void setDrawingAppModel(DrawingAppModel drawingAppModel) 
	{
		this.drawingAppModel = drawingAppModel;
	}

Dans Eclipse, il suffit de déclarer le nouvel attribut puis de demander à Eclipse de générer les getters et les setters.

Dessin dans les JPanel


Lorsque l'on passe une fenêtre devant un composant, un événement est généré. Cet événement est traité par la Event Dispatch Thread qui demandera au composant de se redessiner sur l'écran. Voir plus loin.

Dessin dans les JPanel


Redéfinir la méthode paintComponent pour un JPanel permet de transformer le panneau en zone de dessin.

Google : JAVA SE7 Graphics

Dessin dans les JPanel

ColorIndicator

A rajouter dans la classe ColorIndicator :

@Override
protected final void paintComponent(Graphics g)
{
   // Paint the background
   super.paintComponent(g) ;
		
   // Get widget dimension
   int w = getWidth() ;
   int h = getHeight() ;
		
   // Draw a rectangle
   g.setColor(drawingApp.getDrawingAppModel().getCurrentColor()) ;
   g.fillRoundRect(4, 4, w-8, h-8, 15, 15) ;

   // Draw a border
   g.setColor(Color.BLACK); 
   g.drawRoundRect(4, 4, w-8, h-8, 15, 15) ;
}

Exemple

Drawing Panel

public class DrawingPanel extends JPanel
{
   private final DrawingApp drawingApp ;
	
   public DrawingPanel(DrawingApp drawingApp)
   {
      this.drawingApp = drawingApp ;
		
      setBackground(Color.WHITE) ;
		
      setPreferredSize(new Dimension(256,256)) ;
   }
	
   @Override
   protected void paintComponent(Graphics g)
   {
      // Paint the background
      super.paintComponent(g) ;
		
      // Ask the model to draw the segments
      drawingApp.getDrawingAppModel().paintSegments(g) ;
   }

}

En vertu de principe de délégation, on ne va pas accéder aux données du DrawingAppModel pour peindre les segments. On va demander au DrawingAppModel de dessiner ce qu'il contient.

Graphics2D


Google : JAVA SE7 Graphics2D

Dessiner un segment

Un segment se dessine tout seul dans un Graphics. A mettre dans la classe Segment:
private final static float[] dash = { 4.0f } ;
   
private final static BasicStroke usualStroke  ;
private final static BasicStroke largeStroke ;
private final static BasicStroke dashStroke  ;
   
static { // Static initialization of drawing modes
   usualStroke  = new BasicStroke() ;
   largeStroke  = new BasicStroke(3.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER) ;
   dashStroke   = new BasicStroke(1.0f, BasicStroke.CAP_ROUND,
                                  BasicStroke.JOIN_MITER, 10.0f, dash, 0.0f) ;	   
}
   
public final void paint(Graphics g, boolean selected, boolean current)
{
   Graphics2D g2 = (Graphics2D)g ;
		
   g2.setColor(color) ;
	   
   if (current) {   
      g2.setStroke(dashStroke) ;  // Dashed lines mode
      g2.draw(this) ;
      g2.setStroke(usualStroke) ; // Normal mode
   } else if (selected) {
      g2.setStroke(largeStroke) ; // Large lines mode
      g2.draw(this) ;
      g2.setStroke(usualStroke) ; // Normal mode
   } else {
      g2.draw(this) ; 
   }
}

In the model

Le DrawingAppModel demande à chacun des segments de se dessiner.

public class DrawingAppModel
{
   private final ArrayList<Segment> editedSegments  = new ArrayList<Segment>(128) ;
   private       Color              currentColor    = Color.WHITE ;
   private       Segment            currentSegment  = null ;
   private       Segment            selectedSegment = null ;
   private       boolean            modified        = false ;
	
   public final void paintSegments(Graphics g)
   {
      for (Segment s : editedSegments)
         s.paint(g,false,false) ;
		
      if (selectedSegment != null)
         selectedSegment.paint(g,true,false) ;
		
      if (currentSegment != null)
         currentSegment.paint(g,false,true) ;
   }	

   ...
}

MVC






Continuer avec MVC

Observer-Observable

Retour sur MVC

Dans le patron de conception MVC, la vue est une représentation graphique du modèle.

Observer - Observable

Observer - Observable

Observer - Observable

Observer - Observable

Observer - Observable

Observer - Observable

L'Observer

Propagation du message

Propagation du message

Propagation du message

Observer - Observable

Fin




Programmation orientée objet en Java


Des questions ?


Télécom ParisTech