C. Recanati
Master info 1ère année
InHM, 2009

TP n° 5

Exercice 1 Le but de cet exercice est d’essayer différents bords.
1) Ecrire une classe Bords qui étend JFrame et affiche dans le main une instance placée au milieu de l’écran (utiliser getToolkit et getScreenSize pour récupérer la dimension de l’écran).
2) Ecrire un constructeur qui prend en argument un titre et place dans la fenêtre six objets de type JLabel sur une grille 2x3. 
3) Les six labels vont servir à essayer différents bords. On affichera comme texte pour chaque label le nom du bord qui l’entoure. 
Essayez plusieurs bords (par exemple BevelBorder, LineBorder EmptyBorder, EtchedBorder ou TitledBorder) avec différents arguments.
 Indications : Pour créer un objet Border on peut  
•	utiliser le constructeur d’une classe de bord, par exemple 
	button.setBorder (new EtchedBorder ());
•	demander à BorderFactory de créer un bord (il y a des méthodes dans cette classe, comme createBevelBorder ou createTitledBorder, qui créent des bords).
4) Mettez à l’un des six labels un bord composé de deux bords (CompoundBorder). Composez par exemple, une ligne (d’une couleur spéciale), et un titre (dans une fonte particulière).

Exercice 2 (reprise du TP 1): le but de cet exercice est de créer une application qui crée aléatoirement un ensemble de points, et les affiche dans différents modes : sous forme de petits ronds, de petites croix, ou comme un seul polygone).
Un point est une instance de la classe java.awt.Point. L’ensemble de points sera stocké dans un vecteur ensPts de la classe principale. Un champ mode (int) indique le mode d’affichage des points. Il y a 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 ayant trois paramètres: nb, le nombre de points que l’on souhaite créer, et la largeur et la hauteur du cadre de la fenêtre qui affichera les points. Cette méthode crée nb objets de type Point dont les coordonnées (positives) se situent à l’intérieur du  cadre, et elle les stocke dans le vecteur ensPts de la classe principale.
  Pour le tirage aléatoire des coordonnées (entières) des points, on peut utiliser 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 arrondi le plus proche de a.

3) Ecrire une sous-classe Dessin de JFrame qui possède les deux constructeurs suivants :
a)	un constructeur avec deux arguments permettant de définir le titre de la fenêtre et le mode d’affichage des points. Vous supposerez d’abord que l'entier passé en paramètre est une valeur de mode 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 pour dessiner (il sera ajouté au contentPane du JFrame), et affichez les points dans ce JPanel en redéfinissant la méthode paintComponent de ce JPanel. Testez dans le main l’affichage des points en mode rond.
5) Testez ensuite l’affichage dans les autres modes en définissant une boucle créant plusieurs cadres, et en faisant varier l’origine de ces cadres et leur mode d’affichage.
6) Traitez le cas où le mode passé en argument au constructeur de  la fenêtre n’est pas l'un des 5 modes préconisés. (Vous gérerez cette erreur par le traitement d'une exception).

Exercice n° 3
1) Transformer l’application de l’exercice 1 en applet. Pour cela, créer une procédure init() qui modifie le contenu du JApplet (sans vous occuper du positionnement de la fenêtre).
2) Ecrire un fichier html comportant la balise APPLET correspondant à votre code java et tester la visualisation de ce fichier avec appletviewer.
  pour utiliser appletviewer, il suffit de définir la balise APPLET dans un fichier file.html (les autres définitions html seront ignorées), et de lancer la commande
% appletviewer  file.html

Eléments de correction :
exercice 1 : Bords.java
question 1 : voir poly p.304
questions 2 et 3 : s’inspirer de ce programme qui teste des bords 
sur des objets de type JLabel.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;

public class Bords extends JFrame{

public Bords (String title) {
    super(title);

	// récupérer le panneau de contenu
	// et lui attribuer un gestionnaire d’affichage
	// pour ses futurs éléments
    Container content = getContentPane();
    content.setLayout (new GridLayout (2, 3, 10, 10));

	// créer les labels et les boutons et les ajouter
	// au panneau de contenu
    JLabel label;
    
    label= new JLabel("LineBorder Gray"); 
    label.setBorder (LineBorder.createGrayLineBorder());
    content.add (label);
	
	label= new JLabel("EmptyBorder 5");
 	label.setBorder(new EmptyBorder(5,5,5,5));
    content.add (label);

 	label= new JLabel("Titled CENTER TOP"); 
 	label.setBorder(new TitledBorder(
      				LineBorder.createBlackLineBorder(),
      				"Press Me",
      				TitledBorder.CENTER, 
      				TitledBorder.TOP,
      				new Font ("Serif", Font.ITALIC, 14),
					Color.blue));
    content.add (label);
	/*  etc … */
    Border etched, blackline;

    blackline= BorderFactory.createLineBorder(Color.black,
													4);
    etched = BorderFactory.createEtchedBorder();

    //Simple borders
    label= new JLabel("LineBorder black");
    label.setBorder(blackline);
    content.add (label);

    //Titled borders
    TitledBorder title ;
	title = BorderFactory.createTitledBorder(blackline,
									 		"titled");
	title.setTitleJustification(TitledBorder.CENTER);

	label = new JLabel("Titre centre");
	label.setBorder(title);
	content.add (label);
…
	//faire un label avec un bord composé
…
}}  

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

public class Dessin extends JFrame {
	Vector ensPts ;  // stocke les points à afficher
	/* mode d'affichage de l'ensemble des points
                            rond : petits ronds
                            croix : petites croix
                            poly : comme polygone
							*/
	int mode;  
	MonJPanel pane; // le panneau dans lequel on dessine

// constantes définies normalement dans une interface
	final static int rond=0,croix=1,poly=2;
	static int modeMin=rond, modeMax=poly;

	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("mode " + i +" incorrect");
		this.init(i);
		Container content = getContentPane();
		pane = new MonJPanel();
		content.add(pane, BorderLayout.CENTER);
	}
	public Dessin(String titre)  {
		super(titre);
		this.init(rond);
		Container content = getContentPane();
		pane = new MonJPanel();
		content.add(pane, BorderLayout.CENTER);
	}

	public class MonJPanel 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;
			}   // end switch
      	}	// end paintComponent
      }	// end MonJPanel
      
      public void initAleatoire(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.initAleatoire(12, largeur, hauteur);
				f.pack();
		 		f.setLocation(20*i, 20*i);
				f.setVisible(true);
			}
			catch (Exception e){ 									System.out.println(e);
			}
		}
	}
}

// exercice 3 : voir poly p.285 et suivantes + p.327

//le fichier Dessin.java modifié et compilé avec javac
public class Dessin extends JApplet {
	... 
}
// le fichier  file.html visualisé avec appletviewer
<HTML>
<TITLE> Applet  Dessin </TITLE>
<APPLET CODE="Dessin.class"  
	   WIDTH =800   HEIGHT = 500  >
</APPLET>
</HTML>