Ma petite aventure avec le langage JAVA -

     Cette appliquette Java tente d'illustrer les fonctionnalités de base qu'un éditeur vectoriel tel que ''Inkscape'' devrait posséder, selon moi, pour positionner mathématiquement les entités graphiques.

     Je suis bien conscient qu'il y a pas mal à faire dans la partie mathématique et surtout interactive. Qu'importe, c'est un amusement, prenant je dois le dire, je n'ai pas de délai à satisfaire, je prends tout mon temps car, normalement, ce type d'application est plutôt pris en compte par une équipe de développeurs. Par ailleurs, je n'ai pas trouvé sur la toile un éditeur graphique de ce type, un peu conséquent, que je crois utile pour des écoliers comme il l'est pour mes jeunes petits-enfants. Ces derniers se prêtent très volontiers à l'expérience pour me faire corriger les problèmes à côté desquels je suis forcément passé.

Remarques : 

1°) -   Dans un premier temps, j'ai suivi les conseils présentés dans les différents tutoriels sur Java et j'ai expérimenté tout naturellement plusieurs environnements de développement proposés comme Éclipse, NetBeans, JCreator. Je dois dire qu'ils m'ont donné, tous les trois, pas mal de boutons comme cela avait été le cas avec Code::Blocks pour le langage C/C++. Ces environnements pratiquent une telle inflation de fichiers, de répertoires tout en masquant les fonctionnements de base de Java que j'ai fini par tout virer pour n'utiliser que le JDK dans sa version basique : ignorant complètement appletviewer, ''javac'' et l'éditeur ''Notepad++'' me suffisent très amplement sans oublier bien sûr ''EasyPHP'' que j'utilise pour la mise au point de mon site local avant migration vers Free grâce à ''Dreamweaver 2 gratuit'' de 1997-1998 (!!!). Je m'en sors très très bien, aucun problème jusqu'ici, à chacun ses goûts !...
   
2°) -  

L'appliquette proposée s'ajuste dynamiquement à la taille de la fenêtre du navigateur à condition de réactualiser à chaque changement la page qui l'appelle. Pour la démonstration, le dessin est en mémoire. Une réactualisation de la page réactualise l'appliquette. Les données seront alors perdues.
     Mais pour quand même faire plus sérieux, je vais tâcher de trouver une solution pour restaurer le contexte si la taille de la fenêtre est modifiée. A première vue, il me semble que l'utilisation d'un ''cookie'' serait une voie intéressante et sans danger puisqu'aucune information sensible n'est demandée en dehors d'un nom de fichier.
     Ce sera quand même difficile sans signer l'appliquette !...

   
3°) -  

     Mais, mais...
     ... depuis l'écriture des deux paragraphes ci-dessus, il s'est écoulé quelques semaines. Je me suis finalement décidé à traiter ce problème ennuyeux plus tôt que prévu pour l'image défavorable qu'il peut donner à l'exercice. Interrompant momentanément le développement des fonctionnalités de l'appliquette, je me suis donc employé à comprendre comment Java fonctionnait surtout au niveau de l'instance ''new''. Cette dernière m'a beaucoup gêné car, si elle invoque bien un constructeur pour allouer un objet en mémoire, comment opérer pour réaliser une désallocation du même objet comme on peut le faire dans tout système cohérent qui assure la symétrie de ses comportements. Ce n'était pas du tout évident,  pour moi bien sûr à cause de mon manque d'expérience en Java –, je n'avais rien trouvé là-dessus !..

     Je ne sais pas si ma déduction est valable et si cela ne changera pas avec les prochaines versions de Java, j'espère que non,  à moins que les développeurs cherchent à imposer d'autres vues dogmatiques , mais il semblerait qu'une nouvelle instance ''new'', en surcharge d'une précédente sur le même objet, opère la désallocation de la première en espérant qu'elle libère bien la mémoire. M'en étant aperçu fortuitement sur une erreur de programmation, je l'ai aussitôt appliquée sur la pixelmap de mon appliquette qui change bien entendu à chaque réactualisation lors d'un changement de taille de la fenêtre.

     Le problème fut réglé dans la foulée de manière la plus simple qui soit !... en ayant besoin de rien..., pas même d'un cookie, d'un fichier ni même d'une signature. Pourquoi n'y avais-je pas pensé plus tôt !...

   
4°) -  

     Juillet 2012 se dessine tout doucement...
     Depuis le début de mon expérience de février, je fonctionnais avec le JDK version 6 de Java. Je viens d'installer la version 7 et pa-ta-trac, j'ai maintenant des problèmes avec mes images (les palettes de couleurs et de types de trait) qui ne s'affichent pas avec la méthode ''drawImage'' et pour lesquels je n'entrevoie aucune solution pour le moment.. Cette dernière me retourne systématiquement le code ''false'' alors que la même appliquette fonctionne toujours correctement sur mon site en ligne !...

     Encore, une fois de plus !... la compatibilité ascendante n'est pas assurée par les développeurs de Java et je ne sais pas combien de temps je vais perdre en recherche dans les documentations et les forums. Peut-être trouverai-je quelque chose du côté des animations pour traiter correctement le code de retour de la fonction si, toutefois, c'est un problème de synchronisation ?

     Après plus d'une semaine de tentatives infructueuses, je me suis résigné à abandonner l'usage de la méthode "drawImage" pour l'affichage des palettes de couleurs et de types de trait. Je les ai finalement explicitement dessinées dans la méthode "Affiche.java". La méthode est moins élégante, 20 fois plus de code, mais plus efficace. Cela n'a pas grande importance car l'appliquette ne met pas à disposition l'affichage d'images. Pour les télécharger, il faut entrer dans les procédures de signature que j'ai délibérément rejetées.

     Voici donc quelques explications qui ont, en quelques sortes, valeur de ''cahier des charges''.

I - Description sommaire de ses mots-clé dans l'ordre affiché (à réactualiser)

     La mention indique que l'option est implantée complètement. La mention √(!) indique qu'elle l'est partiellement.

A voir la liste des combinaisons ..... il y a du boulot !...

    Les mot-clés sont indiqués avec le bouton gauche de la souris

• ''Fichier''   :  est prévue pour manipuler les fichiers dessin. Une solution que j'espère provisoire est proposée avec des Copier/Coller.
– 
''Entrée''  :  indique la procédure à effectuer pour charger une liste-image d'un dessin.  √ 
– 
''Sortie''  :  affiche sur la console la liste-image du dessin actuel en vue de la copier-coller dans un fichier.  √ 
– 
''SVG''  :  affiche sur la console la liste-image ''Scalable Vectors Graphics'' (SVG) du dessin actuel en vue de la copier-coller dans un fichier ''.svg''.  
L'option reste cependant considérée comme non implantée :
– 
créer un nouveau dessin  
– 
ouvrir un dessin existant  
– 
sauver le dessin en cours  
– 
sauver le dessin sous un autre nom  
 
• ''Point''  :  manipule les points du dessin en appellant un sous menu :
– 
''Points"  :  créer un ou plusieurs points le plus intuitivement possible en indiquant successivement (=> détails dans ''récapitulatif'') :
→ 
un Point puis un Point
 √ 
→ 
un Point puis une Droite
 √ 
→ 
un Point puis un Cercle/Ellipse"  √ 
→ 
un Point puis un Cercloïde"  
→ 
un Point puis une Courbe"  
→ 
une Droite puis un Point
 √ 
→ 
une Droite puis une Droite
 √ 
→ 
une Droite puis un Cercle/Ellipse  
→ 
une Droite puis un Cercloïde  
→ 
une Droite puis une Courbe  
→ 
un Cercle/Ellipse puis un Point  √ 
→ 
un Cercle/Ellipse puis une Droite  
→ 
un Cercle/Ellipse puis un Cercle/Ellipse  
→ 
un Cercle/Ellipse puis un Cercloïde  
→ 
un Cercle/Ellipse puis une Courbe  
→ 
un Cercloïde puis un Point  
→ 
un Cercloïde puis une Droite  
→ 
un Cercloïde puis un Cercle/Ellipse  
→ 
un Cercloïde puis un Cercloïde  
→ 
un Cercloïde puis une Courbe  
→ 
un Courbe puis un Point  
→ 
un Courbe puis une Droite  
→ 
un Courbe puis un Cercle/Ellipse  
→ 
un Courbe puis un Cercloïde  
→ 
un Courbe puis une Courbe  
 √(!) 
– 
''Sup. Pts" : suppression de tous les points  √ 
– 
''Def. Pts" : enregistre les points qui définissent l'entité indiquée.   √ 
– 
''Division" :

crée le nombre de points qui découpe la distance en ''Division'' intervalles entre les deux points indiqués.
Par défaut ''Division=2'' crée le point milieu.

 √ 
 √(!) 
• ''Droite''  :  crée des droites et appelle un sous menu :
– 
''Pt Pt"  :  créer une droite le plus intuitivement possible en indiquant successivement (=> détails dans ''récapitulatif'') :
→ 
un Point puis un Point
 √ 
→ 
un Point puis une Droite
 √ 
→ 
un Point puis un Cercle/Ellipse  
→ 
un Point puis un Cercloïde  
→ 
un Point puis une Courbe  
→ 
une Droite puis un Point
 √ 
→ 
une Droite puis une Droite
 √ 
→ 
une Droite puis un Cercle/Ellipse  
→ 
une Droite puis un Cercloïde  
→ 
une Droite puis une Courbe  
→ 
un Cercle/Ellipse puis un Point  
→ 
un Cercle/Ellipse puis une Droite  
→ 
un Cercle/Ellipse puis un Cercle/Ellipse  
→ 
un Cercle/Ellipse puis un Cercloïde  
→ 
un Cercle/Ellipse puis une Courbe  
→ 
un Cercloïde puis un Point  
→ 
un Cercloïde puis une Droite  
→ 
un Cercloïde puis un Cercle/Ellipse  
→ 
un Cercloïde puis un Cercloïde  
→ 
un Cercloïde puis une Courbe  
→ 
un Courbe puis un Point  
→ 
un Courbe puis une Droite  
→ 
un Courbe puis un Cercle/Ellipse  
→ 
un Courbe puis un Cercloïde  
→ 
un Courbe puis une Courbe  
 √(!) 
– 
''Horiz." : crée une droite horizontale illimitée   √ 
– 
''Vert." : crée une droite verticale illimitée   √ 
– 
''Norm." : crée une droite normale à une entité Droite ou cercle/ellipse  
– 
''Angle" : crée une droite faisant un angle avec l'horizontale  
– 
''Division" : crée le nombre de droites qui découpent la distance en ''Division'' intervalles entre les deux droites indiquées.
Par défaut ''Division=2'' crée la droite milieu. Suivant la position d'indication sur chaque droite, l'option crée les droites à partir des points homologues ou croisés.
  √ 
 √(!) 
• ''Cercle''  :  crée des cercles le plus intuitivement possible en indiquant successivement (=> détails dans ''récapitulatif'') :
–  ''Ent Ent"  : 
→ 
un Point puis un Rayon.
  √ 
→ 
un Point puis un Point puis bouton droit pour Rayon.
 √ 
→ 
un Point puis un Point puis un Point.  
→ 
un Point puis une Droite puis bouton droit pour Rayon.
 √ 
→ 
un Point puis un Point puis une droite.  
→ 
un Point puis une Cercle/Ellipse.  
→ 
un Point puis une Cercloïde.  
→ 
un Point puis une Courbe.  
→ 
une Droite puis un Point puis bouton droit pour Rayon.  
→ 
une Droite puis une Droite puis un Point  
→ 
une Droite puis un Cercle/Ellipse  
→ 
une Droite puis un Cercloïde  
→ 
une Droite puis une Courbe  
→ 
un Cercle/Ellipse puis un Point  
→ 
un Cercle/Ellipse puis une Droite  
→ 
un Cercle/Ellipse puis un Cercle/Ellipse  
→ 
un Cercle/Ellipse puis un Cercloïde  
→ 
un Cercle/Ellipse puis une Courbe  
→ 
un Cercloïde puis un Point  
→ 
un Cercloïde puis une Droite  
→ 
un Cercloïde puis un Cercle/Ellipse  
→ 
un Cercloïde puis un Cercloïde  
→ 
un Cercloïde puis une Courbe  
→ 
un Courbe puis un Point  
→ 
un Courbe puis une Droite  
→ 
un Courbe puis un Cercle/Ellipse  
→ 
un Courbe puis un Cercloïde  
→ 
un Courbe puis une Courbe  
 
 
• ''Cercloïde''  :  est prévue pour créer des courbes fermées définies par les 4 points du quadrilatère circonscrit et basées sur la génération de cercles (=> détails dans ''récapitulatif'') :
– 

''Ent Ent"

 :  Saisie au clavier, indication de points points existants ou dans l'espace graphique des quatre points d'un quadrilatère quelconque qui peut être croisé, dans l'orde suivant :
→ 
le point "0" du coin supérieur gauche,
 
→ 
le point "1" du coin inférieur droit.
    Si le bouton droit de la souris est pressé, le quadrilatère est un rectangle. La courbe est alors une ellipse.
 
→ 
le point "2" du coin inférieur gauche.
    Si le bouton droit de la souris est pressé, le quadrilatère est un parallélogramme. La courbe est alors aussi une ellipse.
 
→ 
le point "3" du coin supérieur droit.
    La courbe est alors tangent au milieu de chaque côté pour formé ce qui est appelé un cercloïde.
 
– 

''Pol. Ctl."

 :  Commutateur permettant d'afficher ou non le quadrilatère de contrôle.
– 

''Domaine"

 :  2 valeurs 'ad' et 'af' correspondant, en degrés, à l'angle de début et l'angle de fin du tracé ( ad < af et comprises entre 0 et 360).
• ''Courbe'' : création d'une suite de courbes Beziers carrées définies par une suite de points de contrôles
– 

''Ent Ent"

 :  Indication des 3 points de contrôle d'une courbe Béziers carrées.
– 

''Pol. Ctl."

 :  Commutateur permettant d'afficher ou non le polygone de contrôle.
– 

''Coeff"

 :  Cofficient d'amlification de la courbe Béziers pour plus ou moins l'applatir. Par défaut, coeff=0.825 pour être proche du quart de cercle.
– 

''Domaine"

 :  2 valeurs 'vd' et 'vf' correspondant, aux valeurs de début et de fin du tracé ( vd < vf ). Par défaut, vd=0 et vf=1.
• ''Texte'' :

crée et manipules des textes :

 √
   
– 
''Texte"  :  Création d'un texte par l'indication de son point-pivot ou saisie au clavier des coordonnées de son point-pivot et éventuellement de la taille et de l'angle que fait le texte avec l'horizontale, puis saisir au clavier du texte à créer :
=> Les attributs du textes sont ceux définis préalablement par défaut
.
 √ 
– 
''Police" :

Permet de définir la police de caractères par défaut des textes saisis ou manipulés par la suite. Les polices génériques de Java sont affichées dans une fenêtre. Les polices de caractères de l'installation (dossier ''C:\Windows\Fonts'' ne sont valables que pour l'installation).Une police manquante devra alors être installée.
Une fois la police saisie puis validée, indiquer un à un tous les textes concernés par cette police.

 √ 
– 
''Liste" : Affiche sur la console toutes les polices disponibles dans le dossier ''C:\Windows\Fonts''. Il est préférable de choisir des police au nom unique comme par exemple ''Georgia''. Si une police du type ''Georgia Bold Italic'' est choisie, il ne sera pas possible de revenir à la police maigre.  √ 
– 
''Taille" : Permet de saisir au clavier la taille de la police par défaut. Dans la foulée, tous les textes indiqués un à un seront affectés par ce changement de taille.  √ 
– 
''Angle" : Permet de saisir au clavier l'angle par défaut que fait la police avec l'horizontale. Dans la foulée, tous les textes indiqués un à un seront affectés par ce changement de l'angle.  √ 
– 
''Descr." :

Permet de saisir au clavier le descripteur par défaut. Dans la foulée, tous les textes indiqués un à un seront affectés par ce changement de descripteur. Le descripteur est composé de :
- [IT/NR] : italique/normal,
- [FI/EP]  : fin/épais,
- [G/C/D] : justifié à gauche/centré/justifié à droite
- [SL,NS] : souligné/non souligné.
Remarque : cette fonction a été installée car, dans les zooms, la taille des textes ne varie pas linéairement comme les dimensions du dessin.

 √ 
– 
''Cadre" :

Permet de saisir au clavier l'épaisseur par défaut du cadre ajusté au texte et de spécifier si le cadre existe ou pas. La palette de couleur est affiché et une couleur peut être indiqué pour modifier le descripteur par défaut. Dans la foulée, tous les textes indiqués un à un seront affectés par cette modification du descripteur par défaut. Le descripteur est composé de :
- [CD/NC] :cadre/pas de cadre.
Remarque : cette fonction a été installée car, dans les zooms, la taille des textes ne varie pas linéairement comme les dimensions du dessin. Le cadre s'ajuste alors exactement à celle du texte.

 √ 
 
• ''Attributs''  :  manipule les attributs des entités et appelle un sous menu :
– 
''Couleur"  :  affichant une palette de couleur à choisir ou attend la saisie au clavier des trois composantes Rouge, Vert, Bleu puis modifie la couleur d'une entité à indiquer.
Si l'option est indiquée avec le bouton droit, la palette n'est pas affichée et c'est le dessin lui-même qui fait office de palette.
 √ 
– 
''Type" : affichant une palette de type de trait à choisir ou attend la saisie au clavier du code du type de trait puis modifie le type de trait d'une entité à indiquer.  √ 
– 
''Epaisseur" : attend la saisie le l'épaisseur des traits puis modifie l'épaisseur du trait d'une entité à indiquer.  √ 
 √ 
• ''Sélection'' : appelle un sous menu :
– 
''Sél/Désel"  :  sélectionner un entité non sélectionnée ou dé-sélectionner entités déjà sélectionnée. √ 
– 
''Sél. tout " : sélectionner toutes les entités du dessin.  √ 
– 
''Désél. tout" : dé-sélectionner toutes les entités du dessin.  √ 
– 
''Sél. cadre" : dé-sélectionner toutes les entités du dessin à l'intérieur d'un cadre.  
– 
''Désél. cadre" : dé-sélectionner toutes les entités du dessin à l'intérieur d'un cadre.  
 √(!) 
• ''Effacer'' : appelle un sous menu :
– 
''Eff. Ent."  :  pour afficher les entités actives et pour en effacer une à une.  √ 
– 
''Eff. Sél. " : pour afficher les entités actives et pour effacer celles sélectionnées  √ 
– 
''Res. Ent. " : pour afficher les entités effacées et pour en restaurer une à une  √ 
– 
''Res. Sél. " : pour afficher les entités effacées et pour restaurer celles sélectionnées  √ 
– 
''Supprimer" : pour afficher les entités effacées et pour les supprimer définitivement.  √ 
 √ 
• ''Coin'' : dessine un cercle joignant deux entités. Le cercle peut avoir un rayon nul (coin par défaut)  
• ''Chanfrein'' : dessine un chanfrein joignant deux entités. Le chanfrein peut avoir une longueur nulle (par défaut)  
• ''Relim'' : appelle un sous menu :
– 
''Relim"  :  relimite une entité,  
– 
''Couper" : effectue une coupure sur une entité,  
– 
''Souder" : soude une entié préalablement coupée,  
 
• ''Déplacer'' : déplace, à partir d'un point-pivot, les entités sélectées vers un autre point.  
• ''Copier'' : copie une entité ou une sélection d'entités de manière répétitive (par défaut =1),  
• ''Echelle'' : applique un facteur d'échelle en abscisse et en ordonnée à une entité ou à toutes les entités d'une sélection.  
• ''Symétrie'' : effectue une symétrie d'une entité ou des entités sélectées par rapport à une droite,  
• ''Rotation'' : effectue autour d'un pivot une rotation d'une entité ou des entités sélectées de manière répétitive (par défaut 1).  
       
• ''Cote'' : permet de coter le dessin,  
• ''Grille'' : permet d'afficher une grille et de modifier la présentation de l'appliquette,  
• ''Info'' : affiche les caractéristiques d'une entité indiquée,  
       
• ''Tout'' : affiche toutes les entités du dessin pour les rendre toutes visibles dans la fenêtre de visualisation,  √ 
• ''Cadre' : affiche pleine fenêtre de visualisation toutes les entités du dessin à l'intérieur d'un cadre ajustable,  √ 
• ''Centre' : affiche le dessin amenant un point-pivot de la fenêtre de visualisation en son centre,  √ 
• ''++' : affiche le dessin par incréments au point pivot indiqué,  √ 
• ''- -' : affiche le dessin par décréments au point pivot indiqué,  √ 
• ''Retour' : retour à l'opération interrompue,

II - Description de l'appliquette ''Dessin.class''

     Quand la page Internet est chargée en mémoire du navigateur, le module complémentaire Java est activé à la rencontre de la balise <object> ou <applet> au moment de l'affichage de la page après son analyse. La main est donnée à la méthode ''init()'' de l'appliquette dont le nom figure dans le paramètre ''classid='' de la balise <object> ou le paramètre ''code='' de la balise <applet>. Puis, suivant les situations, le Noyau Java donnera la main à toutes les autres méthodes standard qui y sont codées.

     Le principe de fonctionnement de l'appliquette est très simple. Il y a deux architectures envisageables décrites par les deux figures ci-dessous explicitant chacune un diagramme d'état particulier :

     A - Technique distributive :

     Dans l'architecture distribuée, la logique est centrée sur un distributeur (Dispatcher en anglais) ''Qu'es acò'' systématiquement appelé dès qu'un évènement souris/clavier se produit. Ce distributeur va alors donner la main aux différentes méthodes de l'application.
     Dans tous les cas, quelque soit le niveau d'exécution, les méthodes retournent au Noyau Java ce qui leur impose de gérer des états leur indiquant à tout moment à quel niveau d'avancement se trouve le traitement. C'est la partie la plus délicate de la programmation.

     B - Technique hiérarchique :

     Dans l'architecture hiérarchique, par une méthode ''att_even(e)'', la logique est centrée sur une consultation cyclique (Polling en anglais) d'un conteneur de variables initialisées à chaque fois qu'un événement souris/clavier se produit.
     Au lancement de l'appliquette, le Noyau Java donne la main à la méthode ''init()'' qui appelle ''att_even()" en attente d'un événement souris/clavier. C'est une entrée dans le niveau 0 primaire de l'application.

     Au premier événement, il y a détection du mot-clé du menu primaire, ''Point'' par exemple. Le maillon du niveau 0 appelle alors à nouveau la méthode ''att_even(e)'' s'il y a un menu secondaire. C'est l'entrée dans le niveau 1.

     Au premier événement, il y a détection du mot-clé du menu secondaire, ''Points'' ou ''Sup. Pts'' ou ''Def. Pts'' ou ''Division'' par exemple. La maillon du niveau 2 appelle à son tour la méthode ''att_even(e)'' s'il y a un menu tertiaire évidemment. C'est l'entrée dans le niveau 2 tertiaire. Et ainsi de suite.....

     C'est une gestion hiérarchisée de menus de mots-clé.

     C - Choix de la méthode :

  Technique distributive              Technique hiérarchique
–  fonctionnement asynchrone      –  fonctionnement synchrone
–  toute option peut être abandonnée si l'utilisateur de ravise      –  pour revenir à une autre option, l'utilisateur doit suivre le chemin de retour pas à pas des mots-clé ''Retour'' si on veut éviter une programmation acrobatique
–  Pas de possibilité de programmation récursive      –  possibilité de programmation récursive
–  programmation pas trop difficile mais un peu délicate qui demande de la rigueur   –  programmation relativement facile
–  assez bien adaptée aux principes de fonctionnement d'une appliquette Java   –  pas très adaptée aux principes de fonctionnement d'une appliquette Java

     L'appliquette ''Dessin.java'' présentée ici est réalisée suivant la technique distributive.

     D - Description :

     Le Noyau Java donne donc la main à la méthode ''init()'' de l'appliquette ''Dessin.java'' qui, après exécution, retourne au Noyau. Ce dernier gère tous les événements. Sur la sollicitation de la souris ou du clavier, les actions de déroulent comme suit :

1) - le Noyau Java donne la main, si elle est codée comme c'est le cas ici, à la méthode standard, ''handleEvent()'' représentée, sur la figure du §A, par le rond central rouge dans lequel l'événement est reconnu et son traitement préparé,
2) - cette dernière appelle successivement :
       •  la méthode de la classe ''Qu_es_aco()'' (anneau bleu clair) qui porte son nom pour regarder si la souris a indiqué :
      –  soit un mot-clé primaire : le mot-clé est marqué ''actif'' et la main est alors donnée à la méthode qui le traite en initialisant le niveau 0 de traitement géré par la méthode elle-même. Elle gérera éventuellement par la suite tous les niveaux descendants niveau 1, niveau 2, etc... correspondant aux sous-menus de mots-clé.
  –  soit un point de la fenêtre de visualisation : la main est alors donnée à la méthode de traitement du mot-clé actif en cours,
  •  la méthode de la classe ''Affiche()'' (anneau vert) pour préparer l'affichage de l'environnement graphique,
  •  la méthode ''repaint()'' pour réactualiser l'image de l'appliquette,
3) - retour au Noyau Java en attente d'un nouvel événement souris ou clavier,
4) - reprise du cycle en 1) -

     Le diagramme de la figure montre le mot-clé ''Point'' (création d'un point) du menu primaire qui attend le choix de l'un des 4 mots-clé du sous-menu de niveau 1, ''Pt-Pt'', ''Def. Pts'', ''Sup. Pts'' ou ''Division''.

     L'un des avantages de cette technique est de pouvoir à tout moment abandonner une option avant son terme si l'utilisateur se ravise.

     L'appliquette décrite ici est représentée par la classe nommée ''Dessin.class''. Elle ne comporte que les méthodes standard suivantes parmi celles indiquées dans les conventions :

     Cette classe appelle un certain nombre de classes-fille composant son architecture générale. Les classes qui gèrent les collections d'entités, Point, Cercle/Ellipse, Cercloïde, Courbe et Texte, sont construites suivant le même modèle ci-après :

•  ''Modèle.class''  : 
      –   "affiche_Modèle()  :  Cette méthode prépare l'affichage des entités Modèle. Elle est appelée par la méthode ''Affiche.class''.
      –   "est_ce_un_Modèle()  :  Cette méthode est appelée pour connaître si la souris a indiqué l'une de ses entités Modèle.
      –   "lec_Modèle()  :  Cette méthode analyse et charge l'entité Modèle décrite dans une commande de la liste image.
      –   "sel_desel_Modèle()  :  Cette méthode sélectionne ou désélectionne toutes les entités Modèle à l'intérieur d'un cadre.
      –   "eff_Modèle()  :  Cette méthode efface une entité Modèle indiquée ou toutes les entités Modèle sélectionnées.
      –   "res_Modèle()  :  Cette méthode restaure une entité Modèle indiquée ou toutes les entités Modèle sélectionnées.
      –   "copie_Modèle()  :  Cette méthode affiche sur la console toutes les commande de l'entité Modèle de la liste image du dessin en vue d'être copiée puis sauvegardée..
      –   "add_Modèle()  :  Cette méthode est appelée pour ajouter une entité Modèle dans la collection.
      –   "sup_Modèle()  :  Cette méthode est appelée pour supprimer une entité Modèle ou toutes les entités Modèle sélectées.
      –   "traitement_Modèle()  :  Cette méthode traite toutes les fonctionnalités de manipulation attachées aux entités Modèle.

     Liste les classes de la classe ''Dessin.class'' :

•  ''Affiche.class''  :  Cette classe contient la structure des variables graphiques et la méthode qui prépare l'affichage de l'image de l'appliquette en vue de l'appel à la méthode ''repaint()'' de réactualisation.
Remarque :  Cette classe référence une pixelmap de la sous-classe ''BufferedImage'' de la classe Java ''Image'' pour permettre le traitement d'images de pixels. Mais comme il est indispensable d'avoir accès aux méthodes de gestion graphique, il est nécessaire de plaquer l'espace graphique de ces méthodes sur celui de la pixelmap. C'est le but des instructions suivantes :
  static BufferedImage pixelmap   ;
  static Graphics2D    g2d        ;
          ......
          ......
  pixelmap = new BufferedImage( Commun.larg_appl
                              , Commun.haut_appl
                              , BufferedImage.TYPE_INT_RGB
                              ) ;
  g2d = (Graphics2D)pixelmap.getGraphics() ;
Par ailleurs, l'anticrénelage (''antialiasing'' en anglais) sur les textes n'est pas du tout convaincant, un peu plus sur les dessins. Pour information, l'instruction ci-après le met en œuvre :
g2d.setRenderingHint(  RenderingHints.KEY_ANTIALIASING
                      , RenderingHints.VALUE_ANTIALIAS_ON
                      ) ;
•  ''Attributs.class''  :  Cette classe ne contient que la méthode qui porte son nom pour modifier les attributs d'une entité. Il s'agit de la couleur, du type et de l'épaisseur du trait. Ces 3 attributs peuvent être aussi défini par une saisie au clavier.
      –   La couleur  :  Pour la couleur, une palette de couleur est affichée sur laquelle une couleur peut être indiqué avec la souris et a affecter aux entités indiquées.
      –   Le type  :  Pour le type de trait, une palette de type de trait est affichée sur laquelle un type de trait peut être indiqué avec la souris et a affecter aux entités indiquées..
      –   L'épaisseur   :  Cette méthode attend la saisie au clavier de l'épaisseur de trait et a affecter aux entités indiquées.
•  ''Cercles.class''  :  Cette classe contient la collection d'entités Cercles/Ellipses qu'elle gère à l'aide des méthodes décrites dans ''Modèle.class'' ci-dessus  :
•  ''Cote.class''  :  Cette classe contient les méthode de traitement des différents types de cotation du dessin. Elle sera traitée quand la partie dessin géométrique sera plus avancée.
•  ''Courbes.class''  :  Cette classe contient la collection d'entités Courbes qu'elle gère à l'aide des méthodes décrites dans ''Modèle.class'' ci-dessus  :
•  ''Droites.class''  :  Cette classe contient la collection d'entités Droites qu'elle gère à l'aide des méthodes décrites dans ''Modèle.class'' ci-dessus  :
•  ''Fichier.class''  :  Cette classe, vide pour le moment, est prévue pour gérer les fichiers de dessins crées par l'appliquette au travers des mots-clé ''Nouveau'', ''Ouvrir'', ''Sauver'' ou ''Sauver sous''. Pour éviter de signer l'appliquette, une solution de dépannage est proposée. Elle vaut ce qu'elle vaut !...
•  ''Grille.class''  :  Cette classe permet de définir les paramètres de définition de tracé d'une grille. Elle sera traitée quand la partie dessin géométrique sera plus avancée.
•  ''Informations.class''  :  Cette classe prépare l'affichage des informations de l'entité indiquée par la souris. Elle est appelée par la méthode ''Affiche.class''.
•  ''MethMath.class''  :  Cette classe contient toutes les méthodes de traitement mathématique entre entités :
      –   "point_droite()  :  Cette méthode calcule les coordonnées du point-projection d'un point donné sur une droite donnée..
      –   "point_cercle()  :  Cette méthode calcule les coordonnées des point-projection d'un point donné sur un Cercle/Ellipse donné. Il y en a 4 au maximum.
      –   "droite_droite()  :  Cette méthode calcule les coordonnées du point d'intersection de deux droites données.
      –   "droite_cercle()  :  Cette méthode calcule les coordonnées du point d'intersection d'une droite donnée avec un Cercle/Ellipse donné. Il y en a 2 au maximum.
      –   "cercle_cercle()  :  Cette méthode calcule les coordonnées du point d'intersection de deux Cercle/Ellipse donnés au plus près du point de sélection. Il y en a 4 au maximum (ellipse).
•  ''Mots_Cle.class''  :  Cette classe contient la collection de mots-clé utilisés dans l'appliquette et les méthodes de traitement qui s'y rattachent :
      –   "addMotCle()  :  Cette méthode ajoute un mot-clé dans la collection.
      –   "testMotCle()  :  Cette méthode renvoie le code du mot-clé qui a été indiqué par la souris.
      –   "affMotCle()  :  Cette méthode affiche tous les mots-cle de l'appliquette dans leur zone appropriée.
•  ''Points.class''  :  Cette classe contient la collection d'entités Points qu'elle gère à l'aide des méthodes décrites dans ''Modèle.class'' ci-dessus  :
•  ''Qu_es_aco.class''  :  Cette classe ne contient qu'une méthode appelée par la méthode ''handleEvent()'' de l'appliquette ''Dessin.class'' pour analyser la position de la souris et donner la main à la méthode appropriée de traitement. C'est en gros la distributrice de tâches.
•  ''Selection.class''  :  Cette classe traite les différents aspects de la sélection d'entitée pour réaliser des traitements multiples d'entités. Les entités sélectées sont dessinées en marron. Cette classe affiche un sous menu comportant 5 options.
•  ''Texte.class''  :  Cette classe contient la collection d'entités Textes qu'elle gère à l'aide des méthodes décrites dans ''Modèle.class'' ci-dessus  :
•  ''Tracer.class''  :  Cette classe contient les différentes méthodes de tracés graphiques :
      –   "Chrw()  :  Cette méthode dessine une chaîne de caractères conformément à un attribut.
      –   "Pltw()  :  Cette méthode dessine un vecteur conformément à un attribut.
      –   "setPixel()  :  Cette méthode initialise un pixel conformément à un attribut.
•  ''Zoom.class''  :  Cette classe contient les différentes méthodes de traitement du zoom de l'appliquette :
      –   "Tout()  :  Cette méthode ramène à la pleine fenêtre de visualisation la totalité de l'espace occupé par le dessin.
      –   "Cadre()  :  Cette méthode ramène à la pleine fenêtre de visualisation le dessin contenu dans un cadre ajustable.
      –   "Centre()  :  Cette méthode ramène au centre de la fenêtre de visualisation la position indiquée par la souris prise comme pivot du dessin.
      –   "Pas()  :  Cette méthode grossit (''++'') ou diminue (''- -'') le dessin d'un incrément à chaque clic de lasouris dont la position est pris comme pivot..
       

III - Un peu de philosophie : loin de moi le désir de refaire le monde ...

     ... en comprenant que l'on ne soit pas d'accord avec moi !...

     Si j'ai bien compris, il semblerait qu'il n'y ait que deux techniques pour réaliser une application tournant dans une page d'un site Internet :

     Alors, pas d'état d'âme, si je veux avoir la possibilité de réaliser ce type de composant, il me faut apprendre le langage Java dans la perspective peut-être d'utiliser "Java Web Start" lorsque j'aurai, je l'espère, bien avancé mon appliquette actuelle. Cela semble être la meilleure solution.

     Donc, j'adopte, j'y vais et.....    j'apprends !...

     Jusqu'à présent, l'écriture de cette appliquette de dessin a été très intéressante, amusante même. J'espère que ce sera encore le cas par la suite. Certes, le travail qu'elle génère est tout de même assez important. Mais je crois avoir une bonne expérience en langage C pratiqué depuis l'époque 1979-1980 ce qui, normalement, malgré une interruption de quelques années, devrait pas mal m'aider. Lire, analyser, écrire, réanalyser voire même récrire... qu'à cela ne tienne, cela fera partie de l'un de mes loisirs de bureau pour occuper les journées d'intérieurs.

     Cependant, au cours de mes lectures de formation et de mes essais, je retrouve les mêmes impressions qui avaient été les miennes lors de la montée en puissance du langage C++. Ce dernier m'avait été imposé dans un projet et, s'il ne m'avait pas posé de trop gros problèmes, il m'avait toutefois donné quelques boutons !... (quelques remarques annexes ICI dans la page ''généralités'' de la rubrique Noyau Graphique d'Images Structurées).

     La programmation orientée objet : Qu'es acò ?

     Voilà une expression qui revient en boucle, à longueur de bouquins, à longueur d'articles comme si le fait d'en parler avec insistance devrait provoquer chez l'auditeur ou le lecteur une sorte de culpabilité à continuer d'utiliser ce qui est censé être déclaré comme non orienté objet. Alors pourquoi cette remarque ?

Tout simplement parce que le monde vit dans un environnement orienté objet depuis la nuit des temps, même depuis le big-bang il y a 14 milliards d'années !...

    On en parle comme si c'était une révolution alors que l'expression est apparue il y a plus d'une quarantaine d'années accompagnée d'un vocabulaire surévaluant des notions déjà existantes à l'image d'un instituteur qu'on appelle un professeur des écoles, une caissière, une hôtesse de caisse, une femme de ménage, une technicienne du nettoiement sans forcément provoquer l'effet escompté. Mais en fin de compte, pourquoi pas après tout ?...

     Qu'est-ce donc un objet en informatique ? Eh bien... ce que tout le monde connaît ... sans même s'en rendre compte, c'est à dire une structure de données décrites par des ''attributs'', et par ''un ensemble d'actions'' qui s'appliquent sur cette structure, le tout moulé dans un moule que l'on appelle un ''programme'', une ''fonction'' (en Java une ''classe''). Il s'en suit une prolifération de vocables pour parfaire la définition et les objectifs à atteindre, typage, héritage, polymorphisme, encapsulation, constructeur, itérateur, etc... vocables parmi lesquels, à lire les forums, beaucoup et moi avec, se perdent. Mais cela doit faire pas mal dans les discussions de salon durant lesquelles on enfonce très souvent des portes ouvertes.

     Le langage est fortement typé : bien ! mais alors à quoi sert-il de sortir, à la compilation, par exemple le message d'erreur ''variable may be not initialized'' alors que le compilateur n'est pas en mesure d'analyser la logique d'exécution du programme. Cette erreur contraint à de fausse initialisations inutiles. Pourquoi pas, à la rigueur, ne pas sortir un message d'alerte (warning) tout au plus ?

     Mais, finalement, quoi de plus simples que les objets ci-après compréhensibles même par de jeunes enfants  :

le nom de la classe Voiture Soleil Maison
les attributs

nombre de places
puissance fiscale
couleur
longueur, largeur

étoile naine jaune
composition
gravitation
éruption

nombre de pièces
nombre d'étages
jardin
garage

les méthodes

démarrer
arrêter
garer
conduire

chauffer
éclairer
rayonner
régler

abriter
cuisiner
dormir
jardiner

     Certes, il n'est pas question de réexposer la POO, il y a tout ce qu'il faut sur la toile et assurément, mieux expliqué que je pourrais le faire mais on prétend qu'il n'est pas possible d'appliquer ce concept de programmation en langage C ce qui me paraît fort étonnant. Dans mes lectures sur Java, il est expliqué que sa grande force est d'éviter aux programmeurs les ''tracas'' (!!!) causés, principalement, par les deux points qui me touchent tout particulièrement et qui font la grande force des compilateurs qui les ont adoptés (Pascal, PL/1, Fortran 95 entre autres) :

     Par ailleurs, j'ai cru comprendre aussi que Java était écrit en C, et pour cause... les pointeurs et les allocations dynamiques de mémoire incontournables du langage C. Ce dernier est faussement appelé langage car c'est, en réalité, un assembleur évolué portable qui ne sait travailler qu'en mémoire et qui n'a donc que les fonctions système ou utilisateur pour communiquer avec l'environnement de la machine. Son taux d'expansion est très faible en comparaison de celui des autres langages comme le C++, le Fortran, le Pascal, le PL/1, le Cobol, pour ceux que j'ai pratiqués.

     Quant au reste, je n'ai ressenti aucun dépaysement puisque le traitement événementiels (incontournable dans mon appliquette), la syntaxe et la structure du programme sont très proches de celui et celles que je connais en C.

     Peut-être me reprocherait-on d'avoir écrit mon appliquette en Java comme je l'aurais écrite en C ?

     La machine virtuelle Java : Qu'es acò aussi ?

     Le concept de machine virtuelle pour Java est judicieux car il a permis à Sun de placer son produit sur le marché d'une manière élégante. Le compilateur Java produit du ''byte code'', un pseudo-code machine qui est interprété par un programme, le JVM, implanté sur chaque plate-forme. Ce ''byte code'' étant composé d'instructions binaires à l'image des réelles permet un traitement plus rapide et un module exécutable plus condensé.

     Pour mon appliquette, qui se limite à l'illustration d'un propos, je disais que le dessin créé n'était pas sauvegardé suivant une procédure normale. En effet, il est interdit, pour une appliquette, d'écrire sur le disque dur du client pour des raisons de sécurité. Or, une machine virtuelle, par excellence, reproduit dans son intégralité, les réactions physiques d'une machine réelle. Elle doit donc pouvoir écrire sur un disque. Le concept de machine virtuelle me parait donc un peu abusif pour ne pas dire usurpé.

     Si toutefois, on désire néanmoins avoir accès aux ressources de la machine cliente, il faut signer l'appliquette en créant un certificat pour lequel on demande l'approbation de l'utilisateur. Et là, si elle est accordée, grosse surprise, l'appliquette semble avoir accès à l'intégralité des ressources, en particulier, celle du disque dur.

     Mon propos n'est pas une critique, je n'en ai pas le niveau, je prends bien volontiers ce que l'on me donne ici, sans pouvoir faire autrement mais j'avoue que la notion de ''Bac à Sable pour Java'' m'avait fait pressentir une solution intéressante. Dommage !... A la lecture de quelques articles sur le sujet, le modèle de sécurité Java peut laisser sceptique car le concept de bac à sable, je cite :

     Cela fait beaucoup de choses pour gérer la sécurité et c'est compliqué. Personnellement, vu les attaques dont Java est la cible, cela ne m'incite pas à donner mon approbation, même à des sites dits de confiance.

     A l'image de l'hyperviseur de machine virtuelle VM/CMS d'IBM sur lequel j'ai travaillé pratiquement toute ma carrière depuis 1972-1973, je voyais plutôt un espace de confinement c'est à dire un espace complètement hermétique dans lequel une machine virtuelle pouvait travailler à sa guise sans absolument aucun moyen d'en sortir. Par contre, cet espace de confinement serait accessible librement en lecture et en écriture par l'utilisateur qui en est quand même le seul propriétaire et aucun certificat serait nécessaire.

Cet espace de confinement n'est pas autre chose qu'un disque virtuel.

J'avais tout simplement faussement imaginé que le bac à sable était cet espace de confinement, ce disque ''dur'' virtuel, un répertoire alloué à Java lors de son installation. Après, dans ce disque virtuel, la protection entre appliquettes aurait été le problème du module complémentaire Java et non pas celui d'un administrateur quelconque.

     Cette vision ne paraît plus judicieuse mais peut-être n'est-elle pas suffisamment globale en Java et suis-je peut-être resté sur une philosophie somme toute assez ancienne ?...

     Il est dit qu'une appliquette ne peut lire et écrire que dans des fichiers du répertoire sur le serveur qui l'héberge. Mais, là aussi, il faut la signer !...

     Que c'est étrange !... Du côté serveur, comme du côté client, l'appliquette fonctionne déjà dans un espace de confinement au sens que je viens d'expliquer. Ce sont le serveur JAVA lui-même côté hébergeur d'une part et le module complémentaire JAVA lui-même du navigateur côté client. Ce sont eux qui interdisent les accès d'un côté comme de l'autre. Ils sont les seuls garants de la sécurité. Ils pourraient donc gérer avec la même sécurité un espace de confinement. A la limite, même si l'utilisateur client chargeait dans l'espace de confinement un fichier contaminé, tout au plus, ce serait l'appliquette qui en subirait les dommages sans risque de propagation vers l'ordinateur : c'est la caractéristique fondamentale d'une machine virtuelle, « on doit pouvoir y faire tout ce que l'on veut, l'arrêter n'importe quand, la relancer, faire des essais, la planter, etc... sans inquiéter l'hyperviseur sinon ce dernier possèderait d'énormes failles ». Durant mon activité d'ingénieur-système, toutes les nouvelles versions du système VM/CMS était en très grandes parties testées dans une machine virtuelle du VM/CMS en exploitation. La fantastique qualité de ce système avait permis de planter et replanter les VM virtuels en test sans que le VM d'exploitation ne bronche un seul instant. C'est peut-être arrivé trois ou quatre fois en 30 ans, pas sur des défaillances du système mais plutôt sur des erreurs de nos manipulations !...

    
Mais si on signe une appliquette comme cela est préconisé, celle-ci a accès à toutes les ressources du client contrairement à un espace de confinement. Pour moi, si j'ai bien compris, une signature c'est transformer son ordinateur en ''vraie passoire''....

     Une dernière remarque : Lors de mes tentatives d'utiliser une BD SQL, pour se connecter, au serveur, il faut tout naturellement fournir un ''userid'' et un ''password'' qui... transitent sur le réseau (ce n'est pas le cas en PHP dont les applications tournent sur le serveur lui-même). Certes, la possibilité n'est pas à la portée de tout le monde, pas même de moi, mais un collègue toujours en activité, à l'aide d'un ''passeur'' (programme analyseur de réseau), m'a montré dans les dumps des transactions, des informations en clair qui ressemblaient étrangement à des ''userid'' et des ''password'' !... Que faut-il en penser ?
Si c'est la même chose avec les transactions JAVA,... « Bonjour la sécurité » avec tout les ''plats'' qu'on en fait !...

     Ma conclusion : provisoire bien sûr, elle n'engage que moi !

     Le concept de machine virtuelle Java me paraît donc assez abusif, dans l'état actuel des choses. J'ai tendance à penser que c'est plutôt un « Super Shell » compilé qui produit du ''byte code'' comme pourrait en produire tout fichier de commandes, tout compilateur du marché même si Java a ses spécificités.

     Je comprends très aisément qu'une éventuelle option ''byte code'' d'un compilateur aurait eu beaucoup moins d'impact commercial et beaucoup moins d'impact de notoriété que la notion de machine virtuelle avec tout le vocabulaire qui l'accompagne. Si j'avais une comparaison à faire sous la forme d'une boutade... je dirais que JAVA est comme une voiture ''suréquipée'' qui possède beaucoup de choses dont on n'a guère besoin. Certes ça ne coûte pas plus cher mais ces équipements superflus risquent de causer beaucoup d'ennuis, pannes qu'il faut corriger surtout à la revente, consommation supplémentaire, mauvaise empreinte écologique pour toutes les matières premières travaillées à leur fabrication, etc... et surtout, pas du tout indispensables au fonctionnement nominal du véhicule.

     Dommage que les concepteurs du langage JAVA n'aient pas repris les fondamentaux du langage C (pointeurs, allocation dynamique de mémoire, gestion des tableaux de structures). Les détracteurs de ces fonctionnalités ne sont nullement obligés de les utiliser. Pourquoi donc avoir imposé cette vision aux autres ? De toute manière, à ce que j'ai pu constater, la majorité des sources Java que j'ai pu observer sont illisibles, souvent non documentés ou documentés sans l'effort, à la ''va-vite'' car considérés comme superflus. On peut plaindre alors les éventuels repreneurs !...

     A ce stade de mise au point de mon appliquette qui représente déjà pas mal de code, je pense pouvoir dire que le langage n'est pas très bien adapté à ce que je voulais faire mais... comment opérer si l'on veut que cela fonctionne dans une page Internet ? ... je continue donc et je m'adapte, mon opinion pourrait très bien changer par la suite.

     Au final, si j'avais à réaliser un projet important, hors Internet, je ne suis pas sûr que je choisirais ce langage surtout pour certaines positions ridicules et dogmatiques de ses promoteurs concernant certains aspects du langage C non reconduits comme le ''goto'' entre bien d'autres, irremplaçable dans pas mal de situations même si, en théorie seulement, on peut s'en passer mais que l'on doit utiliser, j'en conviens, avec parcimonie et intelligence. D'ailleurs, ces promoteurs se gardent bien de dire, qu'en réalité, les instructions ''continue [étiquette]'' et ''break [étiquette]'' sont de magnifiques ''goto'' dissimulés pour se sortir de situations assez difficiles dans des boucles imbriquées par exemple.

     De mon humble point de vue, le langage C reste encore le langage le plus efficace, sans fioriture. Désolé pour ceux qui ne sont pas d'accord, il permet tout à fait la proprammation orientée objet, beaucoup plus l'affaire d'une tournure d'esprit que celle d'un compilateur.

Que fait-on de l'exécution orientée objet ? bouche cousue ?

     Le noyau stratégique d'Androïd, par exemple, écrit en Java reste encore à prouver !... Il ne semble avoir lu que c'est un noyau Linux, donc écrit en C, qui permet de supporter des applications Java.

     Plus j'avance dans l'utilisation de Java, à moins qu'on m'en prouve le contraire, ce langage reste pour moi un Ersatz psychédélique du langage C à voir les positions dogmatiques de leurs promoteurs. Il faut voir ce qu'il faut faire pour assurer des fonctions aussi simples que celle d'afficher, dans une pixelmap graphique, un texte d'une certaine taille de lettres et faisant un angle donné avec l'horizontale !...
    La puissance d'un outil est inversement proportionnel au nombre de fonctions ou de commandes qu'il met à disposition (voir ce que l'on peut faire avec seulement 12 commandes dans le Noyau Graphique d'Images Structurées) mais cela ne fait probablement pas l'affaire des commerciaux.

À quand donc un système Unix/Linux écrit en Java ?

Malheureusement, il n'y a pas d'autre solution pour une appliquette.

--ooOoo--