Interface devant être implantée par une classe d'affichage : Afficheur.java

import java.awt.*;

/**
 * L'interface <code>Afficheur</code> specifie les methodes a implanter
 * pour developper une classe utilisable en tant qu'objet <code>Afficheur</code>
 * gere au sein d'un {@link ApplicationCanvas ApplicationCanvas}.
 * 
 * @author Nicolas Janey
 * @author nicolas.janey@univ-fcomte.fr
 * @version 1.0, 12/11/08
 */


public interface Afficheur {
  
/**
 * Methode d'affichage executee en boucle infinie pour realiser l'affichage d'une image.
 * 
 * @param g l'objet <code>Graphics</code> d'affichage.
 * @param numeroImage le nombre de fois ou cette methode a deja ete appelee.
 * @param tx la largeur (en pixels) de la zone de dessin.
 * @param ty la hauteur (en pixels) de la zone de dessin.
 */

  public void paint(Graphics g,int numeroImage,int tx,int ty);
}

Classe de gestion d'une fenêtre : ApplicationFrame.java

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

/**
 * La classe <code>ApplicationFrame</code> implante la <code>Frame</code> principale
 * d'une application d'affichage d'un {@link ApplicationCanvas ApplicationCanvas}
 * munie d'un {@link Afficheur Afficheur}.
 *
 * @author Nicolas Janey
 * @author nicolas.janey@univ-fcomte.fr
 * @version 1.0, 12/01/06
 */


public class ApplicationFrame extends Frame 
                              implements WindowListener,
                                         ActionListener,
                                         ItemListener {

/**
 * {@link ApplicationCanvas ApplicationCanvas} affiche dans la <code>Frame</code>.
 */

  private ApplicationCanvas ac;

/**
 * Barre de menus de la <code>Frame</code>.
 */

  private MenuBar mb = new MenuBar();

/**
 * Menu de la barre de menus de la <code>Frame</code>.
 */

  private Menu m1 = new Menu("Fichier");

/**
 * Menu de la barre de menus de la <code>Frame</code>.
 */

  private Menu m2 = new Menu("Affichage");

/**
 * Item de menu du menu de la barre de menus de la <code>Frame</code>.
 */

  private MenuItem mq = new MenuItem("Quitter");

/**
 * Vector {@link Afficheur Afficheur} de la <code>Frame</code>.
 */

  private Vector vaff;

/**
 * Vector d'items de menu de la <code>Frame</code>.
 */

  private Vector vcmi;
  
/**
 * La tache de fond de la <code>Frame</code>.
 */

  private ThreadTacheDeFond ttdf;

/**
 * Item de menu de controle de l'animation de la <code>Frame</code>.
 */

  private CheckboxMenuItem anim = new CheckboxMenuItem("Animation",false);
  
/**
 * Constructeur pour une <code>ApplicationFrame</code>
 * non munie d'un {@link Afficheur Afficheur}.
 *
 */

  public ApplicationFrame(String s) {
    super();
    ac = new ApplicationCanvas(null);
    setTitle(s);
    addWindowListener(this);
    setMenuBar(mb);
    mb.add(m1);
    m1.add(mq);
    mq.addActionListener(this);
    mb.add(m2);
    m2.add(anim);
    anim.setEnabled(false);
    anim.addItemListener(this);
    add(ac);
    vcmi = new Vector();
    vaff = new Vector();
  }

/**
 * Constructeur pour une <code>ApplicationFrame</code>
 * munie d'un {@link Afficheur Afficheur}.
 *
 * @param afficheur l'objet {@link Afficheur Afficheur} d'initialisation.
 * 
 */

  public ApplicationFrame(String s,Afficheur afficheur) {
    super();
    ac = new ApplicationCanvas(afficheur);
    setTitle(s);
    addWindowListener(this);
    setMenuBar(mb);
    mb.add(m1);
    m1.add(mq);
    mq.addActionListener(this);
    mb.add(m2);
    m2.add(anim);
    anim.setEnabled(false);
    anim.addItemListener(this);
    add(ac);
    vcmi = new Vector();
    vaff = new Vector();
  }

/**
 * Ajoute un afficheur a une <code>ApplicationFrame</code>
 * et ajuste le menu "Affichage" en consequence.
 *
 * @param s la chaine de caracteres associee a l'{@link Afficheur Afficheur}
 *   dans le menu "Affichage".
 * @param afficheur l'objet {@link Afficheur Afficheur}.
 * 
 */

  public void add(String s,Afficheur afficheur) {
    ac.set(afficheur);
    CheckboxMenuItem cmi = new CheckboxMenuItem(s);
    cmi.addItemListener(this);
    cmi.setState(true);
    if ( vcmi.size() == 0 )
      m2.addSeparator();
    m2.add(cmi);
    vaff.add(afficheur);
    vcmi.add(cmi);
    ajusteStates(cmi);
  }

/**
 * Ajuste l'etat des <code>CheckboxMenuItem</code> de la <code>Frame</code>.
 *
 * @param cmi la <code>CheckboxMenuItem</code> mise a actif.
 *   Les autres sont mis a faux.
 * 
 */

  private void ajusteStates(CheckboxMenuItem cmi) { 
    cmi.setState(true);
    for ( int i = 0 ; i < vcmi.size() ; i++ ) {
      CheckboxMenuItem cbmi =(CheckboxMenuItem) vcmi.elementAt(i);
      if ( cmi != cbmi )
        cbmi.setState(false); }
  }

/**
 * Ajuste l'{@link Afficheur Afficheur} correspondant au choix
 * d'un <code>CheckboxMenuItem</code> de la <code>Frame</code>.
 *
 * @param cmi la <code>CheckboxMenuItem</code> selectionnee.
 * 
 */

  private void ajusteAfficheur(CheckboxMenuItem cmi) {  
    for ( int i = 0 ; i < vcmi.size() ; i++ ) {
      CheckboxMenuItem cbmi =(CheckboxMenuItem) vcmi.elementAt(i);
      if ( cmi == cbmi ) {
        Afficheur aff =(Afficheur) vaff.elementAt(i);
        ac.set(aff); } }
  }

/**
 * Affecte le {@link ThreadTacheDeFond ThreadTacheDeFond} de gestion
 * de tache de fond.
 *
 * @param ttdf le {@link ThreadTacheDeFond ThreadTacheDeFond} affecte.
 * 
 */

  public void setAnimator(ThreadTacheDeFond ttdf) {
    this.ttdf = ttdf;
    anim.setEnabled(true);
  }

/**
 * Active/desactive l'animation geree par le {@link ThreadTacheDeFond ThreadTacheDeFond}
 * de gestion de tache de fond.
 *
 * @param animated le booleen reglant le nouvel etat.
 * 
 */

  public void setAnimated(boolean animated) {
    if ( ttdf != null )
      ttdf.setAnimated(animated);
  }
  
/**
 * "Termine" le programme.
 *
 * 
 */

  public void quitter() {
    System.exit(0);
  }
  
/**
 * Retourne le {@link ApplicationCanvas ApplicationCanvas} associe a this.
 *
 * @return le {@link ApplicationCanvas ApplicationCanvas} associe a this.
 * 
 */

  public ApplicationCanvas getCanvas() {
    return(ac);
  }
  
  public void actionPerformed(ActionEvent e) {
    if ( e.getSource() == mq ) {
      quitter(); }
  }
  
  public void windowActivated(WindowEvent e) {
  }
  
  public void windowClosed(WindowEvent e) {
  }
  
  public void windowClosing(WindowEvent e) {
    quitter();
  }
  
  public void windowDeactivated(WindowEvent e) {
  }
  
  public void windowDeiconified(WindowEvent e) {
  }
  
  public void windowIconified(WindowEvent e) {
  }
  
  public void windowOpened(WindowEvent e) {
  }

  public void itemStateChanged(ItemEvent e) {
    CheckboxMenuItem cmi =(CheckboxMenuItem) e.getSource();
    if ( cmi == anim ) {
      setAnimated(anim.getState());
      return; }
    ajusteStates(cmi);
    ajusteAfficheur(cmi);
  }
}

Classe de gestion d'un Canvas d'affichage : ApplicationCanvas.java

import java.lang.*;
import java.awt.*;
import java.awt.event.*;

/**
 * La classe <code>ApplicationCanvas</code> implante un <code>Canvas</code> de dessin
 * faisant appel a la methode paint d'une classe implantant {@link Afficheur Afficheur}.
 *
 * @author Nicolas Janey
 * @author nicolas.janey@univ-fcomte.fr
 * @version 1.0, 16/11/08
 */


public class ApplicationCanvas extends Canvas {

/**
 * {@link Afficheur Afficheur} gere par le <code>Canvas</code>.
 */

  private Afficheur afficheur;

/**
 * Nombre d'images deja affichees.
 */

  private static int image = 0;

/**
 * Constructeur pour un <code>ApplicationCanvas</code>
 * muni de son {@link Afficheur Afficheur}.
 *
 * @param afficheur l'objet {@link Afficheur Afficheur} d'initialisation.
 * 
 */

  public ApplicationCanvas(Afficheur afficheur) {
    super();
    this.afficheur = afficheur;
  }

/**
 * Affecte un {@link Afficheur Afficheur} a un <code>ApplicationCanvas</code>.
 *
 * @param afficheur l'objet {@link Afficheur Afficheur} effecte.
 * 
 */

  public void set(Afficheur afficheur) {
    this.afficheur = afficheur;
    repaint();
  }

/**
 * Methode d'affichage.
 *
 * @param g l'objet <code>Graphics</code> d'affichage gere par le canvas.
 * 
 */

  public void paint(Graphics g) {
    image++;
    if ( afficheur != null )
      afficheur.paint(g,image,getWidth(),getHeight());
  }
}

Classe de gestion d'un Thread "tâche de fond" : ThreadTacheDeFond.java

import java.awt.*;

/**
 * La classe <code>ThreadTacheDeFond</code> implante un <code>Thread</code>
 * permettant de gerer le rafraichissement d'un <code>Canvas</code>
 * a interval regulier d'une duree arbitraire.
 *
 * @author Nicolas Janey
 * @author nicolas.janey@univ-fcomte.fr
 * @version 1.0, 16/11/08
 */


public class ThreadTacheDeFond extends Thread {
  
/**
 * Le <code>Canvas</code> a rafraichir regulierement.
 */

  private Canvas c;
  
/**
 * Le booleen indiquant si l'animation est en cours.
 */

  private boolean animated;
  
/**
 * La temporisation entre chaque demande de rafraichissement.
 */

  private int temporisation;
  
/**
 * Le booleen controlant l'exécution du <code>Thread</code>.
 */

  private boolean ok = true ; 

/**
 * Constructeur pour un <code>ThreadTacheDeFond</code> muni d'une certaine temporisation
 * et d'un certain <code>Canvas</code>.
 * 
 */

  public ThreadTacheDeFond(int temporisation,Canvas c) {
    this.c = c;
    this.temporisation = temporisation;
    ok = true;
    animated = false;
  }

/**
 * Methode d'execution.
 * 
 */

  public void run() {
    while ( ok ) {
      if ( animated )
        c.repaint();
      try {
        sleep(temporisation); }
      catch(Exception e) { } }
  }

/**
 * "Termine" le fonctionnement de this.
 * 
 */

  public void arret() {
    ok = false ;
  }

/**
 * Active/desactive l'animation geree par this.
 * 
 */

  public void setAnimated(boolean animated) {
    this.animated = animated ;
  }
}

RETOUR