C. Recanati
InHM Java
Master M1, 2008

TP n° 4

Exercice 1  Sorties mises en tampon (= « bufferisées ») vers un fichier.
1) Ecrire un programme qui calcule les 200 premiers nombres premiers et les stocke dans un tableau, considéré ici comme tampon (ou, pour utiliser le terme anglais, considéré ici comme buffer).
2) Ecrire ensuite les nombres trouvés dans le fichier intitulé « premiers.bin » d’un répertoire « DonnesUtilisables », en faisant les tests nécessaires pour vérifier que « DonnesUtilisables » correspond bien à un nom de répertoire (et créer ce répertoire s’il n’existe pas).
3) Créer un flot de sortie des données du tableau tampon vers le fichier « premiers.bin », et écrire les nombres premiers (du tableau) dans ce fichier à l’aide de la méthode writeLong().  Fermer ensuite le flot et en imprimer la taille. Le résultat obtenu vous semble-t-il raisonnable ? (rappel : vous devez avoir écrit 200 valeurs de type long de 8 octets chacune).

Exercice n°2  (reprise de l’exercice 2 du TP n°1). Le but de cet exercice est de créer une application qui mémorise un ensemble de points tirés aléatoirement et les affiche selon différents modes dans une fenêtre (sous forme de petits ronds, de petites croix, ou comme un polygone).

Un point sera une instance de la classe java.awt.Point. L’ensemble de points sera mémorisé dans un vecteur ensPts de la classe principale. Un champ mode (entier) indiquera le mode d’affichage des points. Il y aura trois modes d’affichage différents, définis par des constantes nommées : 
- rond  : les points  seront dessinés comme de petits ovales; 
- croix  : les points seront  dessinés sous forme de croix ;
- poly  : le polygone joignant les points sera dessiné ;

1) Ecrire une interface définissant les constantes pour le mode d’affichage dans un fichier séparé. Se servir de cette interface dans l’application pour initialiser le champ mode à rond.
2) Ecrire une méthode initAleatoire prenant trois paramètres: nb, le nombre de points que l’on souhaite stocker, et la largeur et la hauteur du cadre qui englobera les points. Cette méthode crée nb Points dont les coordonnées positives se situent dans le  cadre indiqué, et les stocke dans le vecteur ensPts de la classe principale.
  Pour le tirage aléatoire des points, on trouvera dans la classe Math la méthode random() qui retourne un double compris entre 0.0 et 1.0. et la méthode round(double a) qui retourne l’entier long le plus proche de a.

3) Ecrire une sous-classe Dessin de JFrame qui possède les constructeurs suivants :
a)	un constructeur à deux arguments permettant de définir le titre de la fenêtre et le mode d’affichage graphique. Vous supposerez d’abord que l'entier mode passé en paramètre a une valeur correcte.
b)	un constructeur à un argument permettant de définir le titre de la fenêtre, et fixant le mode graphique à rond.
4) Créez un JPanel (qui sera ajouté au contentPane du JFrame), et affichez les points dans ce JPanel en redéfinissant la méthode paintComponent du JPanel. Testez l’affichage en mode rond.

Si vous avez du temps 
5) Testez l’application pour les autres modes en définissant dans votre main une boucle créant plusieurs JFrame, en faisant varier l’origine de ces cadres et le mode d’affichage.
6) Traitez le cas d’erreur où le mode passé en argument au constructeur de  la fenêtre ne coïncide pas avec l'un des 5 modes préconisés (gérez cette erreur par un traitement d'exception).

Eléments de correction :
Exercice 1:
import java.io.* ;
import java.util.zip.* ;

public class TestDeSortieDeNombresPremiers {
	public static void main (String [ ] args ) {
		long [ ] premiers = new long[200] ;
		premiers[0] = 2 ;
		premiers[1] = 3 ;
		int compteur = 2 ;	// nb premiers trouvés

		long nombre = 5 ; // l’entier suivant à tester 
		for ( ; compteur < premiers.length ; 
nombre += 2L) {
// le div. max à tester est la racine carrée du nombre
			long limite = (long)Math.ceil
(Math.sqrt((double) nombre)) ;
			for (int i=1;i<count && premiers[i]<=limite 
; i++)
if (nombre%premiers[i] == 0) //diviseur? 					continue exterieur ; 
// oui, essayer suivant
			premiers [compteur++] = nombre ; 
// en voilà un !
		}
		// écrire les nombres premiers dans un fichier
		try {
		   String nomDuRepertoire =
 « ../DonneesUtilisables » ;
		   String nomFichier = « premiers.bin » ; 
// nom du fichier 

		   File monRepNbPremiers = new File
 (nomDuRepertoire) ;
		   if ( !monRepNbPremiers.exists()) 
// s’il le rep n’existe pas
				monRepNbPremiers.mkdir() ; // le créer
		   else
			if ( !monRepNbPremiers.isDirectory()) {
				System.out.println(nomDuRepertoire + 
					« n’est pas un répertoire ») ;
				return ;
			}
		   // créer l’objet File
		   File fichierNbPremiers = new File
 (monRepNbPremiers,
									nomFichier) ;
		   fichierNbPremiers.createNewFile() ; 
// s’il n’existe pas, le créer

		   // créer un flot de sortie des données 
		   // mis en tampon pour  le fichier
		   DataOutputStream premiersStream 
					= new DataOutputStream (
						new BufferedOutputStream (
						new FileOutputStream
							(fichierNbPremiers))) ;

		   // écrire les nb premiers dans le fichier
		   for (int i=0 ; i<premiers.length ; i++) 
			premiersStream.writeLong(premiers[i]) ;

		   premiersStream.close() ;
  // vider et fermer le fichier
		   System.out.println(« Taille du fichier = »
						+ premiersStream.size()) ;
		}
		catch (IOException e)
			System.out.println(« IOException  » + e 
							+ «  est survenue ») ;
	}
}

// exercice 2 : Dessin.java 
import java.awt.*;
import javax.swing.*;
import java.util.*;

public class Dessin extends JFrame {
	Vector ensPts ;  // stocke les points à afficher
	final static int rond=0,croix=1,poly=2;
	static int modeMin=rond, modeMax=poly;
	int mode;  
/* mode d'affichage de l'ensemble des points
                            rond : petits ronds
                            croix : petites croix
                            poly : polygone
							*/
	JMonPanel pane; // le panneau dans lequel on dessine

	private void init(int i) {
		mode=i;
		ensPts = new Vector();
		this.setBackground(Color.white);
	}

	public Dessin(String titre, int i)throws Exception {
       			// traitement pour la dernière question
		super(titre);
		if (i < modeMin || i > modeMax)
			throw new Exception(i + " ");
		this.init(i);
		Container content = getContentPane();
		pane = new JMonPanel();
		content.add(pane, BorderLayout.CENTER);
	}

	public Dessin(String titre)  {
		super(titre);
		this.init(rond);
		Container content = getContentPane();
		pane = new JMonPanel();
		content.add(pane, BorderLayout.CENTER);
	}

	public class JMonPanel extends JPanel {
		public void paintComponent(Graphics g)  {
			super.paintComponent(g) ; 
			g.setPaint(Color.red);

			int nbPoints = ensPts.size();
			int[] abs = new int[nbPoints];
			int[] ords = new int[nbPoints];
			for(int i=0; i<nbPoints; i++)  {
				Point p= (Point)ensPts.elementAt(i);
				abs[i]=p.x;
				ords[i]=p.y;
			}
			switch(mode){
				case rond :  
					for(int i=0; i<nbPoints; i++) {
						g.drawOval(abs[i], ords[i], 5, 5);
					}
					break;
         
				case croix :  
					for(int i=0; i<nbPoints; i++)  {
						g.drawLine(…);
						g.drawLine(…);
					}
		
					break;
				case poly :
         				…
					break;
			}   // fin switch
      	}	// fin paintComponent
      }	// fin JMonPanel
      
      public void initAlea(int nb, int larg, int haut)  {
		for (int i=0; i<nb ; i++) {
			Point p = new Point(
					 (int)Math.round(Math.random()*larg),
                     (int)Math.round(Math.random()*haut));
			ensPts.addElement(p);
          }
      }
      
      public void setPaneSize(int largeur, int hauteur) {
			pane.setSize(largeur, hauteur);
			pane.setPreferredSize(new
							 Dimension(largeur,hauteur));
      }

      public static void main (String args[]) {
		int largeur=800,hauteur=500;
		for (int i=Dessin.modeMin;i<=Dessin.modeMax; i++){
			try {
				Dessin f = new Dessin("Dessin de points "
										+ i,i);
				f.setPaneSize(largeur, hauteur);
				f.initAlea(12, largeur, hauteur);
				f.pack();
		 		f.setLocation(20*i, 20*i);
				f.setVisible(true);
			}
			catch (Exception e){ 									System.out.println(e);
			}
		}
	}
}