Un exemple complet

15.1 Analyse du projet

 On se propose de réaliser une applet qui permet de visualiser la gestion des couleurs utilisables dans les modes RVB (rouge, vert, bleu) et HSB (teinte, saturation, luminosité). Pour modifier la couleur dans chaque mode, il faut introduire trois nombre entiers. En mode RVB chaque valeur est comprise entre 0 et 255. En mode HSB la couleur est un nombre compris entre 0 et 360, la saturation et la luminosité sont compris entre 0 et 100. On fera un contrôle de validité des valeurs entrées. On se propose d'afficher la couleur obtenue dans un cadre et d'utiliser la couleur complémentaire comme couleur du fond d'une partie de l'applet. Le programme proposé offre une solution possible parmi beaucoup d'autres. Il existe en particulier de nombreuses possibilités pour effectuer la mise en place des composants nécessaires au fonctionnement.

 Pour le cadre, on fait le choix d'utiliser un canevas (Canvas). Ce composant impose la surcharge de sa méthode paint( ) : il faut donc définir obligatoirement une classe spécifique. Nous utilisons la classe Cadre qui étend la classe Canvas. Cette classe contient uniquement la variable publique Color col qui sera utilisée comme couleur de pinceau et la méthode paint( ).

 La saisie des valeurs de la couleur en mode RVB ou HSB suppose la mise en place pour chaque cas de 3 zones de texte. Au lieu de définir 6 zones, il est plus simple de définir deux objets identiques qui seront paramétrés pour chacun des deux cas. On va donc construire une classe Panneau qui va étendre la classe Panel. Cette classe va comporter un constructeur permettant le paramétrage des zones de texte et des libellés associés et la méthode action( ) qui va implémenter la réaction du programme aux commandes de l'utilisateur. Pour chaque panneau, il faut introduire 6 composants (3 labels et 3 zones de texte) L'utilisation d'un gestionnaire du type GridLayout avec 2 colonnes de 3 lignes semble être le meilleur choix.

La classe principale est l'applet. La méthode init( ) effectue la mise en place des deux panneaux et du canevas avec un gestionnaire FlowLayout. Un gestionnaire GridLayout avec 1 ligne de 3 colonnes est aussi utilisable. La réponse aux actions de l'utilisateur est implémentée dans la méthode mise_a_jour mais le code correspondant à cette méthode aurait pu être introduit dans la méthode action de la classe Panneau. La méthode paint( ) de cette classe assure la mise à jour finale de l'affichage.

 15.2 Listing commenté

import java.applet.*;
import java.awt.*;

public class ColorTest extends Applet
{ Panneau panRGB,panHSB;
//déclaration des objets Panneau
  Cadre canv;
//déclaration objet Cadre
  Color c1,c2;
  Font font = new Font("Helvetica",0,11);
  Font bold = new Font("Helvetica",1,18);

public void init()
{ setFont(font);
//la taille de la fonte conditionne celle des panneaux
  setBackground(Color.lightGray);
//couleur du fond de l'applet
  setLayout(new FlowLayout(1,40,5));
//protocole de mise en page global
  canv = new Cadre();
//création du Cadre
  panRGB = new Panneau(this,"Rouge","Vert","Bleu");
//appel constructeur
  panHSB = new Panneau(this,"Teinte","Saturation","Luminosité");
  add(panRGB);
//ajout 1er panneau
  add(canv);
//ajout du Cadre à coté du panneau
  canv.setFont(bold);
//fonte du Cadre
  canv.resize(100,60);
//taille du Cadre
  add(panHSB);
  panRGB.tf2.setText("255");
//initialise une zone de texte à une valeur non nulle
  mise_a_jour(panRGB);}
//initialisation globale avec le vert maximum

public void paint(Graphics g)
{ g.setFont(bold);
//fonte pour l'applet
  g.setColor(c2);  
//couleur du pinceau
  g.fillRect(50,100,350,80);
  g.setColor(c1);  
//couleur d'écriture
  g.drawString("Dans l'applet",160,150);
  g.setColor(Color.black);
  g.drawRect(50,100,350,80);}

void mise_a_jour(Panneau pan) //argument = Panneau modifié
{ int v1 = Integer.parseInt(pan.tf1.getText());
/*conversion chaîne vers entier avec contrôle des valeurs
l'entrée d'une valeur non entière provoque une exception*/
  
if (pan==panRGB){
    if ((v1<0) || (v1>255)){
//contrôle de validité 0-255
       v1=128;  pan.tf1.setText("128");}}
    else
      if ((v1<0) || (v1>360)){
//contrôle de validité 0-360
      v1=0;    pan.tf1.setText("0");}
 int v2 = Integer.parseInt(pan.tf2.getText());
 if (pan==panRGB){
   if ((v2<0) || (v2>255)){
//contrôle de validité 0-255
      v2=128;  pan.tf2.setText("128");}}
   else
     if ((v2<0) || (v2>100)){
//contrôle de validité 0-100
     v2=50;   pan.tf2.setText("50");}
int v3 = Integer.parseInt(pan.tf3.getText());
if (pan==panRGB){
  if ((v3<0) || (v3>255)){
    v3=128;  pan.tf3.setText("128");}}
  else
    if ((v3<0) || (v3>100)){
    v3=50;   pan.tf3.setText("50");}
//Modification RVB
if (pan==panRGB)  
  {  c1 = new Color(v1,v2,v3);
//définition de la couleur en RVB
     float[] hsb = Color.RGBtoHSB(v1,v2,v3,(new float[3]));
//conversion en HSB
     hsb[0] *= 360;  hsb[1] *= 100;  hsb[2] *= 100;
//conversion dans les gammes choisies
     panHSB.tf1.setText(String.valueOf((int)hsb[0]));
         
//mise à jour affichage dans les zones de texte du panneau RVB
     panHSB.tf2.setText(String.valueOf((int)hsb[1]));
     panHSB.tf3.setText(String.valueOf((int)hsb[2]));}
  else  
//modification du panneau HSB
  {  c1 = Color.getHSBColor((float)v1/360,(float)v2/100,(float)v3/100);
          
//conversion des valeurs entre 0.0f et 1.0f
     panRGB.tf1.setText(String.valueOf(c1.getRed()));
          
//mise à jour affichage de l'autre panneau
     panRGB.tf2.setText(String.valueOf(c1.getGreen()));
     panRGB.tf3.setText(String.valueOf(c1.getBlue()));}
     int r=255-c1.getRed();
//couleur complémentaire
     int v=255-c1.getGreen();
     int b=255-c1.getBlue();
     c2=new Color(r,v,b);
     canv.setBackground(c1); canv.col=c2;
//variables du Cadre
     canv.repaint();
//mise à jour du Cadre
     repaint();}     
//mise à jour de l'applet
}
//*********************************************** 
class Panneau extends Panel
{ ColorTest applet;
//variables de la classe panel
  TextField tf1,tf2,tf3;

Panneau(ColorTest app,String S1,String S2, String S3)//constructeur
{  applet = app;
   setLayout(new GridLayout(3,2,10,10));
//grille 2 colonnes de 3 lignes
   tf1 = new TextField("0");
//création des zones de texte
   tf2 = new TextField("0");
   tf3 = new TextField("0");
   add(new Label(S1,Label.LEFT));
        
//création des labels avec les paramètres du constructeur
   add(tf1);
   add(new Label(S2,0));   add(tf2);
   add(new Label(S3,0));   add(tf3);}

public boolean action(Event evt, Object arg)
{ if (evt.target instanceof TextField){
     applet.mise_a_jour(this);
//appel d'une méthode de l'applet
     return true;}
     else return false;}
}
//***********************************************
class Cadre extends Canvas
{ Color col;

public void paint(Graphics g) //surcharge de la méthode
{  g.setColor(Color.black);
   g.drawRect(0,0,size().width-1,size().height-1);
   g.setColor(col);
   g.drawString("Canevas",10,20);}
}

15.3 L'applet


 Retour au menu