C. Recanati
IG, Java Swing
Info2, 2008

TP n° 5

Exercice 1 Le but de cet exercice est de visualiser différents bords.
1) Ecrire une classe Bords qui étend JFrame et affiche dans son main une instance placée au milieu de l’écran (utiliser getToolkit 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 labels vont servir à tester des bords et on affichera, comme texte du label, le nom du type de bord qui l’entoure. 
Essayez différents bords (e.g. BevelBorder, EmptyBorder, EtchedBorder, LineBorder et TitledBorder) avec différents arguments.
 Indications : Pour créer un objet Border on peut  
•	utiliser un constructeur de bord, par exemple 
	button.setBorder (new EtchedBorder ());
•	demander à BorderFactory de le faire (il y a des méthodes spécifiques comme createBevelBorder ou createTitledBorder qui créent des bords).
4) Mettez à l’un des labels un bord composé (CompoundBorder). Composez par exemple, un cadre (d’une couleur donnée), et un titre (dans une fonte donnée).

Exercice 2 (reprise de TP 1 et TP4): le but de cet exercice est de créer une application qui tire (aléatoirement) et mémorise un ensemble de points, et les affiche selon différents modes (sous forme de ronds, de croix, ou comme polygone).
Un point est 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) 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 par rond.
2) Ecrire une méthode initAleatoire ayant trois paramètres: nb, le nombre de points que l’on souhaite générer, et la largeur et la hauteur du cadre (fenêtre) qui contiendra les points. Cette méthode crée nb objets de type Point dont les coordonnées (positives) se situent dans le  cadre indiqué, et elle les range dans le vecteur ensPts de la classe principale.
  Pour le tirage aléatoire des points, on trouve dans la classe Math une méthode random() qui retourne un double compris entre 0.0 et 1.0. et une 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 deux constructeurs suivants :
a)	un constructeur à 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 (ajouté au contentPane du JFrame), et affichez les points dans ce JPanel en redéfinissant la méthode paintComponent du JPanel. Testez dans un main l’affichage en mode rond.
5) Testez l’application pour 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 appletviewer, il suffit de définir la balise APPLET (il ignore les autres définitions html) et de lancer la commande
% appletviewer  file.html

Eléments de correction :
exercice 1 : Bords.java
question 1 : voir poly p.292
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.271 et suivantes + p.315

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