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 ;
}
}