Vous êtes sur la page 1sur 543

Javabook Page i Lundi, 12.

juillet 1999 3:58 15

Java : de lesprit la mthode


Distribution dapplications sur Internet
Deuxime dition

Javabook Page ii Lundi, 12. juillet 1999 3:58 15

Javabook Page iii Lundi, 12. juillet 1999 3:58 15

Michel BONJOUR, Gilles FALQUET, Jacques GUYOT et Andr LE GRAND

Java : de lesprit la mthode


Distribution dapplications sur Internet
Deuxime dition

Vuibert Informatique

Javabook Page iv Lundi, 12. juillet 1999 3:58 15

Java : de lesprit la mthode Distribution dapplications sur Internet 2e dition Michel BONJOUR, Gilles FALQUET, Jacques GUYOT et Andr LE GRAND

Conception de la couverture : Jean Widmer Contact : informatique@vuibert.fr Les programmes et exemples figurant dans ce livre ont pour but d'illustrer les sujets traits. Il n'est donn aucune garantie quant leur utilisation dans le cadre d'une activit professionnelle ou commerciale.

Vuibert, Paris, 1999 ISBN 2-7117-8647-1

Toute reprsentation ou reproduction intgrale ou partielle, faite sans le consentement de l'auteur, ou de ses ayants droit, ou ayants cause, est illicite (loi du 11 mars 1957, alina 1er de l'article 40). Cette reprsentation ou reproduction, par quelque procd que ce soit, constituerait une contrefaon sanctionne par les articles 425 et suivants du Code pnal. La loi du 11 mars 1957 n'autorise, aux termes des alinas 2 et 3 de l'article 41, que les copies ou reproductions strictement rserves l'usage priv du copiste et non destines une utilisation collective d'une part, et d'autre part, que les analyses et les courtes citations dans un but d'exemple et d'illustration.

Javabook Page v Lundi, 12. juillet 1999 3:58 15

Anne-Murielle, Florence, Nicky et Sandra

Javabook Page vi Lundi, 12. juillet 1999 3:58 15

Javabook Page vii Lundi, 12. juillet 1999 3:58 15

Table des matires


Remerciements....................................................................... xv propos des auteurs............................................................ xvi Introduction ..........................................................................xix

Partie I Lesprit Java .......................................................... 1


Chapitre 1 Avant Java ....................................................................... 3
1.1 1.2 1.3 1.4 1.5 1.6 1.7 2.1 2.2 2.3 2.4 3.1 3.2 3.3 Interconnexion de rseaux............................................................... 3 Hypertextes ...................................................................................... 7 Web................................................................................................... 7 Perdu dans le cyberespace ............................................................. 12 Cration des nuds ....................................................................... 12 Architecture client-serveur.............................................................. 13 Langages de programmation orients objet.................................. 15 Java, cest quoi? .............................................................................. 19 Caractristiques principales ........................................................... 19 Adquation de Java Internet et au Web ..................................... 23 Code mobile................................................................................... 25 Outils .............................................................................................. 31 Dvelopper avec Java ..................................................................... 32 O trouver Java .............................................................................. 33

Chapitre 2 Rvolution an 4 : Java ................................................... 19

Chapitre 3 Lenvironnement de dveloppement Java ..................... 31

Javabook Page viii Lundi, 12. juillet 1999 3:58 15

viii

Table des matires

3.4 3.5

Mes premiers pas............................................................................34 Chercher de linformation sur Java................................................36

Partie II Le langage .......................................................... 39


Chapitre 4 Les bases ...................................................................... 41
4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 4.10 5.1 5.2 5.3 5.4 5.5 5.6 5.7 6.1 6.2 6.3 6.4 6.5 6.6 6.7 6.8 6.9 6.10 7.1 7.2 Commentaires.................................................................................41 Identificateurs .................................................................................42 Littraux ..........................................................................................44 Dclaration des variables................................................................48 Porte des variables ........................................................................51 Oprateurs ......................................................................................52 Oprateurs relationnels ..................................................................56 Oprateurs de manipulation binaire ..............................................59 Oprateur dallocation....................................................................60 Conversions de types......................................................................61 Bloc dinstructions..........................................................................66 Excution conditionnelle................................................................66 Excution itrative ..........................................................................69 Identifier une instruction................................................................71 Rupture ...........................................................................................72 Continuation...................................................................................73 Exemples dalgorithmes en Java.....................................................73 Comportement des objets..............................................................77 Classes et objets en Java.................................................................78 Et si lon parlait dhritage .............................................................85 Classes et mthodes abstraites .......................................................89 Classes internes...............................................................................90 Classes anonymes ...........................................................................91 Interfaces.........................................................................................91 Packages ..........................................................................................93 Rfrence, copie et galit .............................................................94 Types simples et classes enveloppes ..............................................95 Unit de compilation .....................................................................97 Dclaration de package ..................................................................98

Chapitre 5 Les structures de contrle ............................................. 65

Chapitre 6 Une introduction aux objets........................................... 77

Chapitre 7 Les structures ............................................................... 97

Javabook Page ix Lundi, 12. juillet 1999 3:58 15

ix

7.3 7.4 7.5 7.6 7.7 7.8 7.9 8.1 8.2

Importation des packages et des classes........................................98 Dclaration de types .....................................................................100 Dclaration dune classe ...............................................................100 Dclaration dune interface ..........................................................101 Dclaration de membres ..............................................................102 Dclaration dune mthode et dun constructeur .......................102 Cration dobjets ..........................................................................103 Exceptions.....................................................................................105 Processus et synchronisation ........................................................107

Chapitre 8 Exceptions et processus .............................................. 105

Partie III Utiliser les classes de lenvironnement Java ....109


Chapitre 9 LAPI Java..................................................................... 111
9.1 9.2 9.3 Mthode de travail........................................................................112 La vraie classe Rectangle .......................................................... 114 Invitation explorer .....................................................................118

Chapitre 10 Retour sur les applets .................................................. 119


10.1 Comment crer une applet ..........................................................120 10.2 Le dlimiteur <Applet> en dtail..................................................121 10.3 Vie et mort dune applet ..............................................................126

Chapitre 11 Dessiner ...................................................................... 129


11.1 11.2 11.3 11.4 11.5 11.6 11.7 11.8 11.9 11.10 11.11 11.12 11.13 11.14 11.15 La feuille........................................................................................129 Dessiner une ligne.........................................................................130 Rectangles .....................................................................................131 Polygones ......................................................................................132 Cercles, ovales, arcs ......................................................................132 Gommer, copier............................................................................133 Colorier .........................................................................................134 crire .............................................................................................135 Les polices.....................................................................................136 Reprsenter la troisime dimension en couleur ..........................139 Reprsenter la 3D par une projection en 2D ..............................141 Des rectangles multicolores..........................................................142 Esquisser un rectangle laide dovales .......................................144 Premire et dernire .....................................................................145 Invitation explorer .....................................................................146

Javabook Page x Lundi, 12. juillet 1999 3:58 15

Table des matires

Chapitre 12 Animer ......................................................................... 147


12.1 12.2 12.3 12.4 12.5 12.6 12.7 12.8 12.9 13.1 13.2 13.3 13.4 13.5 13.6 13.7 13.8 13.9 13.10 13.11 14.1 14.2 14.3 14.4 14.5 14.6 14.7 14.8 14.9 14.10 14.11 14.12 Mon applet est un seul processus................................................148 Multithread ...................................................................................150 Mon applet lance un deuxime processus ..................................150 Un squelette gnral pour les animations ...................................152 Une horloge avec des aiguilles .....................................................153 Plusieurs activits indpendantes .................................................156 Encore plus dactivits indpendantes.........................................158 Un peu de posie .........................................................................160 Invitation explorer .....................................................................163 Le modle dvnements de Java 1.0...........................................165 Gestion de la souris......................................................................166 Une alternative la gestion des vnements...............................168 Une applet de brouillon ...............................................................169 Gestion du clavier.........................................................................170 Souris trois boutons...................................................................172 Le modle dvnements partir de Java 1.1 .............................172 Gestion de la souris (trois manires) ...........................................173 Gestion du clavier.........................................................................176 vnements et autres composants dinteraction .........................177 Invitation explorer .....................................................................178 Les libells.....................................................................................180 Les boutons ..................................................................................181 Les botes cocher choix multiple ...........................................184 Les botes cocher choix exclusif ............................................186 Les menus droulants...................................................................187 Les listes de choix.........................................................................189 Les champs de texte sur une ligne...............................................191 Les champs de texte sur plusieurs lignes.....................................193 Les barres de dfilement ..............................................................195 Les fonds.......................................................................................197 Prfrences lors de laffichage......................................................197 Invitation explorer .....................................................................197

Chapitre 13 Interagir ....................................................................... 165

Chapitre 14 Composants dinteraction graphique .......................... 179

Chapitre 15 Gestion des conteneurs .............................................. 199


15.1 Mon applet est trop petite ...........................................................200 15.2 Ouvrir une autre fentre...............................................................201 15.3 Invocation dune applet depuis une application .........................202

Javabook Page xi Lundi, 12. juillet 1999 3:58 15

xi

15.4 Ajouter des menus aux fentres ...................................................204 15.5 Un gestionnaire dalertes..............................................................206 15.6 Invitation explorer .....................................................................208

Chapitre 16 Protocoles de mise en pages ....................................... 209


16.1 16.2 16.3 16.4 16.5 16.6 16.7 17.1 17.2 17.3 17.4 17.5 18.1 18.2 18.3 18.4 18.5 19.1 19.2 19.3 19.4 19.5 19.6 19.7 19.8 19.9 19.10 19.11 19.12 19.13 19.14 Mise en pages glissante ...........................................................210 Mise en pages par spcification des bords ..................................212 Rcursivit de la mise en pages....................................................213 Mise en pages avec une grille.......................................................214 Mise en pages sous forme de cartes ............................................216 Mise en pages avec un quadrillage et des contraintes.................216 Invitation explorer .....................................................................219 Charger des images.......................................................................221 Filtrer des images..........................................................................223 Animation avec double tampon ...................................................227 Ajouter le son................................................................................229 Invitation explorer .....................................................................230 Les limites de lAWT et Swing .....................................................231 Prsentation de Swing ..................................................................232 Composants Swing et AWT .........................................................233 Larchitecture modle-vue-contrleur et Swing............................236 Le look-and-feel modifiable ..........................................................237 Description du package ................................................................241 Constructeurs des fichiers dentre et de sortie ..........................246 Entres-sorties clavier/cran.........................................................247 Variables denvironnement ...........................................................247 Accs au rpertoire de travail.......................................................248 Classe File ................................................................................ 248 Quelques sous-classes de File utiles..............................................248 Affichage du contenu dun rpertoire avec filtrage .....................252 Lecture dun fichier ......................................................................253 Copie dun fichier.........................................................................255 Lecture filtrante dun fichier ........................................................256 Fichier accs direct ....................................................................257 Analyse lexicale .............................................................................259 Dialogues pour louverture et la fermeture dun fichier..............260

Chapitre 17 Manipulation dimages et de sons ............................... 221

Chapitre 18 Les composants Swing ................................................ 231

Chapitre 19 Entres-sorties et persistance des objets .................... 241

Javabook Page xii Lundi, 12. juillet 1999 3:58 15

xii

Table des matires

19.15 Srialisation et persistance des objets ..........................................261 19.16 Invitation explorer .....................................................................263

Chapitre 20 Les accs au rseau (java.net) .................................... 265


20.1 20.2 20.3 20.4 20.5 20.6 20.7 20.8 Description du package................................................................265 Identification du contenu dun URL ...........................................270 Accs un URL protg par un mot de passe ...........................271 Affichage du contenu dun URL dans une fentre .....................271 Vrificateur dURL .......................................................................272 Un exemple client-serveur ............................................................274 Tldiscussion...............................................................................278 Programmation distribue sur Internet........................................286

Partie IV La mthode : dvelopper en Java ................... 287


Chapitre 21 Conception des classes ............................................... 289
21.1 21.2 21.3 21.4 21.5 21.6 22.1 22.2 22.3 22.4 22.5 23.1 23.2 23.3 23.4 23.5 Les origines ...................................................................................289 Objets et classes............................................................................292 Interfaces.......................................................................................295 Spcification dune classe.............................................................296 Exceptions.....................................................................................299 Modliser avec les classes ............................................................301 Hritage et sous-classes ................................................................313 Utilisations de lhritage...............................................................316 Utilisation des classes abstraites ..................................................320 Polymorphisme .............................................................................321 Gnricit et interface ..................................................................322 Les chanes de caractres .............................................................326 Les collections ..............................................................................327 Itrateurs (Iterator) .......................................................................334 Copies et galits de surface et profondes..................................336 Invitation explorer .....................................................................339

Chapitre 22 Mcanismes pour la rutilisation ................................ 313

Chapitre 23 Structures de donnes ................................................ 325

Chapitre 24 Composition du logiciel ............................................... 341


24.1 Les packages .................................................................................341 24.2 Rgles daccessibilit en Java........................................................343 24.3 Les Java Beans...............................................................................346

Javabook Page xiii Lundi, 12. juillet 1999 3:58 15

xiii

24.4 Introspection.................................................................................350

Chapitre 25 Processus et concurrence............................................ 353


25.1 Problme de la concurrence daccs............................................354 25.2 La synchronisation en Java ...........................................................354 25.3 .Interblocages ................................................................................358

Chapitre 26 Intgration des applets ................................................ 359


26.1 Documents et types de contenus .................................................359 26.2 Traiter de nouveaux types de contenu.........................................360 26.3 Dfinir une applet comme gestionnaire de contenu...................360

Chapitre 27 Scurit en Java .......................................................... 363


27.1 27.2 27.3 27.4 28.1 28.2 28.3 28.4 28.5 28.6 28.7 28.8 Le langage et le compilateur ........................................................364 Le vrificateur de byte-code .........................................................365 Le chargeur de classes ..................................................................371 La protection des fichiers et des accs au rseau........................371 Architecture de JDBC ...................................................................374 Principaux lments de JDBC ......................................................375 JDBC et les standards...................................................................379 Utilisation de JDBC ......................................................................381 JDBC et la scurit .......................................................................382 Formats dURL et JDBC ..............................................................383 Base de donnes et Java : un exemple complet ..........................384 Invitation explorer .....................................................................388

Chapitre 28 Java et les bases de donnes ...................................... 373

Chapitre 29 Fabriquer des objets rpartis avec RMI ....................... 389


29.1 Description du package ................................................................389 29.2 Principes de fonctionnement .......................................................390 29.3 Le dveloppement d'une application distribue avec RMI pas pas.......................................................................391

Chapitre 30 Fabriquer des objets rpartis avec CORBA .................. 397


30.1 30.2 30.3 30.4 30.5 30.6 CORBA en quelques mots ...........................................................398 IDL ................................................................................................400 Un objet CORBA..........................................................................402 Le Serveur CORBA.......................................................................403 Le client CORBA..........................................................................405 Persistance des donnes ...............................................................407

Chapitre 31 Les autres API de Java................................................. 411

Javabook Page xiv Lundi, 12. juillet 1999 3:58 15

xiv

Table des matires

Partie V Annexes ............................................................ 413


Du C++ Java................................................................................. 415 Grammaire BNF de Java ................................................................. 443 Les fichiers darchives .jar .............................................................. 455 Rappel sur HTML ............................................................................ 459 JavaScript .................................................................................... 479

Glossaire ........................................................................ 483 Rfrences .................................................................... 491 Liste des applets ............................................................ 493 Liste des applications .................................................... 495 Liste des tableaux .......................................................... 497 Index ............................................................................ 501 Le CD-ROM du livre ........................................................ 513

Javabook Page xv Lundi, 12. juillet 1999 3:58 15

Remerciements
Nous tenons remercier ici : Ian Prince, lorigine de notre intrt pour les hypertextes et les systmes distribus. Nos collgues de travail pour les changes sur Java autour dun caf. Les participants notre premier cours Java pour leur patience, leur intrt et leurs remarques constructives. Les tudiants qui ont travaill avec nous dans nos projets autour de Java et des bases de donnes. Nos familles et nos amis qui ont support notre Javamania.

Javabook Page xvi Lundi, 12. juillet 1999 3:58 15

xvi

propos des auteurs

propos des auteurs


Michel Bonjour, licenci en informatique de gestion, est dsormais employ la socit Unicible (Lausanne) aprs avoir t assistant du groupe Bases de Donnes de lUniversit de Genve.

fdfdfdfdfdfdf
Gilles Falquet, docteur s sciences mention informatique, est actuellement matre denseignement et de recherche lUniversit de Genve. Il mne des travaux de recherche sur les modles et technologies des bases de donnes et hypertextes. Jacques Guyot, docteur s sciences mention informatique, est charg de cours lUniversit de Genve et responsable de linformatique du dpartement des finances de Montres Rolex S.A. Il sintresse lintgration des traitements et des donnes dans le cadre du Web. Andr Le Grand, docteur en informatique de lUniversit de Montpellier II, est actuellement matre-assistant lUniversit de Genve et lInstitut de Hautes tudes en Administration Publique (Lausanne). Ses travaux portent sur les mthodes de conception orientes objet et lingnierie des systmes dinformation.

Carnet de route cybernautique des auteurs


nov 93 hiver 93 sept 94 dc 94 mars 95 Notre premier butineur sur Mac (NCSA Mosaic) Premier support de cours sur le WEB Transparents complets dun cours BD + SQL sur le Web pour les tudiants de sciences conomiques et sociales Cration sur le WEB du BNF Club avec la syntaxe de ADA, puis SQL, PL/ SQL dOracle, SQL2, Modula2, etc. Enseignement post-grade sur Internet et cration dune visite guide du Web Ouverture de WebTerrasse, site exprimental (WWW-BD) Travaux sur la publication des BD sur Internet : - gnration dhypertexte pour une BD (Langage LAZY) - cration de passerelles WWW-SGBD (Oracle, Farandole2)

avril 95

Javabook Page xvii Lundi, 12. juillet 1999 3:58 15

xvii
17 sep 95 dc 95 jan 96 fv 96 Naissance de No Prsentation de LAZY la 4me confrence WWW Boston Test de JavaScript Ajout de la syntaxe de Java au BNF Club Dmarrage du JavaCorner cuiwww.unige.ch/java mars 96 Participation au cours du 3me cycle romand : le Web et ses outils Portage de LAZY sur le WebServer dOracle avril 96 mai 96 Outils hypermdia sur le dictionnaire Oracle Dbut du projet FNRS (Fond national de la recherche suisse) pour ltude de la gnration dhypertextes partir des bases de donnes Organisation dun cours sur Java juin 96 Etude des spcifications de JDBC 1.0 Compilateur de LAZY en Java Gnrateur et gnration dune documentation hypertextuelle pour Java dans le BNF Club 1997 1998 Cours et Evanglisation Java ! Implantation dune uvre dart en Java avec lartiste Herv Grauman, pour lOffice fdral de statistique en Suisse (www.collectivepainting.ch) Utilisation de Java et JDBC dans lenseignement et la recherche (structures de donnes, interfaces de systmes dinformation) mai 98 oct 98 Ecriture dune applet pour dessiner les diagrammes syntaxiques pour une spcification BNF Ecriture dun gnrateur doutils syntaxiques en pur Java

La suite est dcouvrir sur http://cuiwww.unige.ch/java.

Javabook Page xviii Lundi, 12. juillet 1999 3:58 15

Javabook Page xix Lundi, 12. juillet 1999 3:58 15

Introduction
Internet, FTP, TCP/IP, E-Mail, autoroutes de linformation et les derniers en date WWW, HTML, HTTP, XML, IIOP, CORBA, Java sont autant dacronymes remplissant les discussions et les revues dinformatique. Utiles ou simples gadgets ? Technologies sres ou de transition ? Quels nouveaux domaines mergent? Comment linformatique est-elle modifie? Autant dinterrogations qui sont souleves. Rpondre lensemble dentre elles ncessitera certainement plusieurs annes, demandera ce que la socit shabille de ces nouveaux atours, smerveille, seffraie et finalement intgre ces nouvelles technologies productrices de nouvelles valeurs. notre avis, les informaticiens doivent prendre conscience de ces enjeux sociaux et dvelopper une thique de lutilisation de ces nouvelles technologies1. Technologie sans conscience... Notre propos restera plus prosaque et moins polmique : comment utiliser efficacement Java, ce langage de programmation? Notre premire partie, consacre lesprit Java, situe le langage dans son contexte et dcrit la transition avant Java - aprs Java . Nous y introduisons galement les concepts essentiels pour la programmation distribue sur Internet ou pour lanimation, par exemple. La seconde partie dcrit la forme de Java, il sagit ici de dcrire la syntaxe de Java et la smantique associe. Le langage Java tant relativement simple, les rgles de grammaire sont peu nombreuses. La troisime partie sattache examiner le fond de Java. Nous tudierons un ensemble de problmatiques telles que : comment dessiner, animer ou communiquer, et proposerons des solutions programmes en Java. Le lecteur trouvera travers celles-ci de nombreux exemples de la syntaxe Java et pourra ainsi la matriser par la pratique. De plus, il abordera par ces problmatiques lutilisation
1. Le lecteur trouvera la page 491 des rfrences que nous trouvons intressantes.

Javabook Page xx Lundi, 12. juillet 1999 3:58 15

xx

Introduction

des classes standard de Java et lapplication des diffrents concepts propres la programmation oriente objet. La quatrime partie du livre est ddie la mthode. Matrisant la syntaxe, la smantique et les classes standard de Java, le programmeur doit alors faire face la complexit de ses propres crations. Il doit effectuer des choix de conception pour ses objets qui ne seront pas sans importance quant leur rutilisation, leur gnricit, leur testabilit, etc. Cette partie comporte galement une description des mthodes de scurit de Java et de linterface de programmation dapplications bases de donnes JDBC (Java DataBase Connectivity) propose par Sun, Cette partie sachve sur llaboration dapplications distribues avec RMI et CORBA. En annexe on trouvera : la grammaire Java en BNF, une comparaison Java C++, une description du langage HTML et une prsentation de JavaScript.

Trois ans plus tard...


Ecrire une deuxime version dun livre en informatique peut relever du cauchemar... Trois ans aprs avoir crit la premire version de louvrage que vous tenez dans les mains, nous avons t heureux de constater que lobjet de notre enthousiasme des premiers jours (en janvier 96) pour ce qui tait alors une sorte de rvolution est devenu plus mature, plus solide. Les qualits techniques propres Java ont t reconnues par des centaines de milliers de dveloppeurs, la plupart des universits et autres institutions enseignant la programmation lont adopts comme langage de support aux cours dinformatique. Mais surtout, ce sont les packages dfinissant les services de base offerts aux programmeurs qui se sont toffs. De sept, ils sont passs plus de cinquante dans la version 1.2 de Java, qui a t renomme officiellement version 2 par Sun. Cela ne tient pas compte des packages disponibles pour traiter du commerce lectronique, de la manipulation des images en trois dimensions, etc., qui fournissent un cadre solide pour produire rapidement des applications complexes. Mais au del des qualits conceptuelles du langage et de la richesse de ses packages, Java a su muler des efforts consquents autour de lui dans les domaines annexes suivants : les machines virtuelles Java ont t considrablement amliores et les diffrences enregistres entre une excution en code natif et lutilisation dune machine virtuelle excutant une conversion la vole (Just In Time) deviennent de plus en plus minces. Cela a largement contribu faire fondre les rsistances existant chez certains dveloppeurs par rapport lutilisation dun code interprt; les diteurs de logiciel ont produit des environnements de programmation autour de Java qui nont rien envier dautres langages tels que

Javabook Page xxi Lundi, 12. juillet 1999 3:58 15

xxi

Smalltalk, C++, etc. Ces environnements ont pour premier objectif de faciliter la recherche dobjets et de mthodes aidant la rsolution dun problme. Comme nous le constaterons dans la suite de ce livre, la syntaxe et les concepts de Java sont relativement simples. Par contre, la richesse de ses packages demande un investissement certain. On ne peut devenir un bon dveloppeur Java sans les connatre, ils sont incontournables; Java, par un effet de rebond, aprs avoir t Applet est devenu Servlet : la problmatique initiale tait dans le contexte statique du Web, de pouvoir excuter du code sur un poste client. La mobilit du code Java soutenue par le slogan Write once, run everywhere (cris-le une fois, excute-le partout) tait indispensable pour gommer la varit des postes clients connects sur le Web. Mais il existe une varit identique du cot des serveurs: les mmes arguments dconomie de rcriture ont sduit les dveloppeurs dapplications sur serveur. Du coup, Java a quitt son image de gadget pour animer les pages Web; Java sest enfoui au cur du silicium, dans des processeurs spcialiss, dans des cartes puces, dans une bague (JavaRing). Cette cristallisation de la machine virtuelle Java sest accompagne de lcriture dun systme dexploitation, le Java OS, et de la publication dune norme dinterconnexion de composants (JINI). Cette incrustation de la technique au cur dobjet quotidien est nos yeux le rel enjeu de Java et des techniques de la programmation distribue utilisant du code mobile. En effet, mme si vous possdez un ordinateur, vous possdez galement une quantit dautres objets attendant un ajout dintelligence et une connexion au reste du monde. Lincorporation dans le quotidien des processeurs Java et limage de celle des moteurs lectriques si bien intgrs dans les objets que lon a oubli leur existence; Java, travers lEntreprise Java Beans (EJB), devient le cadre conceptuel pour la production dapplications partir de composants. Ici, se dvoile lultime Graal de linformatique. Non seulement, il est possible dutiliser le code Java universellement, mais en plus il serait possible de le rutiliser. Avec les Beans, il est possible de dvelopper des petits composants comme des boutons ou des champs de saisie qui sont assembls dans une interface graphique; les messages mis sont connects aux actions propres lapplication. Cela constitue le degr zro de la rutilisation. Lintrt de la rutilisation crot avec la taille des composants. Avec EJB, il sagit de crer des gros composants. Si pour crer un magasin virtuel, on trouve les composants: gestion des

Javabook Page xxii Lundi, 12. juillet 1999 3:58 15

xxii

Introduction

clients, gestion des fournisseurs, gestion des commandes, gestion des expditions, gestion des paiements par carte, gestion des catalogues alors on peux effectivement assembler et paramtrer les rgles de gestion propres son entreprise. Le projet San Fransisco dIBM est un prototype de ce que peut devenir cette orientation. EJB sera sans doute le modle adopt dans larchitecture CORBA par les socits actives dans le domaine des connecticiels. Mais crire une nouvelle version dun livre nest pas seulement constater que lon a choisi un bon sujet. Cest pour Java 2 : rviser la syntaxe du langage (classe interne, nouveaux usages des modificateurs, etc.); adapter les exemples aux nouvelles API; utiliser la notation UML (Unified Modeling Language) pour les graphes de classes; dcrire le nouveau modle dvnements par dlgation ; dcrire lusage des classes collections (nouvelles classes de java.util) pour crer des structures de donnes; dcrire lutilisation des fichiers archives (jars); introduire les nouveaux composants dinterface SWING; dcrire les composants logiciels JavaBeans; dcrire les mcanismes dintrospection, de srialisation, etc.; ajouter un exemple complet dinteraction avec une base de donnes en utilisant JDBC; ajouter la cration dapplication rpartie avec RMI (Remote Method Invocation); introduire lutilisation de Java dans une architecture CORBA. Nous avons conserv pour ces ajouts le style concis et conceptuel de la premire version. Nous avons limin les annexes sur lAPI. En effet, lexplosion du nombre de packages, de classes et de mthodes de Java 2 rendait impossible limpression papier de tels index. La documentation comprime de Java 2 tient dans seize millions de caractres, notre livre dans peine un: il vous faut donc considrer ce livre comme une synthse des connaissances ncessaires et utiles et vous rfrer constamment la documentation pour les dtails.

Javabook Page xxiii Lundi, 12. juillet 1999 3:58 15

xxiii

Conventions utilises dans cet ouvrage Le texte est en police Sabon. Un mot important est crit ainsi. Dans le texte, un mot-cl, une classe ou une mthode de Java est crit ainsi. Le code Java est en police Courrier :
// ceci est un commentaire dans une ligne de code.

Javabook Page xxiv Lundi, 12. juillet 1999 3:58 15

Javabook Page 1 Lundi, 12. juillet 1999 3:58 15

Partie I

Lesprit Java
Laccs ces diffrents concepts, le sujet, la finalit et linfini, se fait manifestement travers celui de conscience. Voil donc, au regard de toute philosophie qui se dveloppe une mfiance vis--vis de limage informatique de notre esprit, la clef de lirrductible cart! Grard Chazal, Le miroir automate.

1. Avant Java 2. Rvolution an 4 : Java 3. Lenvironnement de dveloppement Java

Javabook Page 2 Lundi, 12. juillet 1999 3:58 15

Javabook Page 3 Lundi, 12. juillet 1999 3:58 15

Chapitre 1

Avant Java
La partie la plus saillante dInternet est le World Wide Web (WWW ou plus simplement Web). Celui-ci matrialise le mtissage de deux concepts : celui des rseaux de communication interconnects (Internet) et celui dhypertexte. Chacun de ces concepts a une origine et des objectifs qui lui sont propres, tandis que leur union ouvre des perspectives absolument novatrices et impensables voil quelques annes encore (le premier outil Web en mode texte a vu le jour en 1991 au CERN). Nous allons maintenant dfinir quelques concepts afin de prparer la transition vers Java... et de clarifier notre discours.

1.1 Interconnexion de rseaux


Linterconnexion de rseaux a pour origine lArpanet (Defense Advanced Research Project Agency Network), un rseau mis en place partir de 1966 aux tats-Unis. La notion dinterconnexion de rseaux permet de connecter des rseaux informatiques bass sur des protocoles diffrents. Pour y parvenir, il est ncessaire de dfinir un protocole dinterconnexion commun au-dessus du protocole de gestion de chaque rseau (voir figure 1.1). LInternet Protocol (IP) fournit ce service, dfinissant des adresses uniques pour un rseau et une machine hte. Le protocole IP assume deux fonctions principales : le routage dun paquet travers des rseaux successifs, depuis la machine source jusqu celle du destinataire, identifie par son adresse IP. Ladresse peut ainsi tre celle de la prochaine passerelle ou celle du destinataire final ;

Javabook Page 4 Lundi, 12. juillet 1999 3:58 15

Chapitre 1 Avant Java

le dcoupage des flux dinformation initiaux en paquets de taille standardise et leur rassemblage ultrieur. Les rseaux emprunts lors dune communication assurent le transfert des paquets IP. Ceux-ci sont encapsuls (au dpart et en quittant une passerelle IP) par le protocole du rseau qui les transmet ; ils sont ensuite dcapsuls lorsquils quittent ce rseau (en entrant dans une passerelle et en arrivant destination). Le succs de ce protocole est principalement d la relative simplicit de ralisation des passerelles IP. La disponibilit de telles passerelles sur de nombreux types de machines a favoris lutilisation de IP dans des environnements htrognes.
FTP Telnet SMTP SNMP application prsentation session

TCP

transport

IP

rseau liaison physique

Ethernet

...

Arpanet

Tokenring

Figure 1.1 Couches logiques selon le modle OSI

Principaux protocoles et services Internet


TCP/IP (Transmission Control Protocol) est la couche de transport au-dessus de IP assurant la connexion de bout bout entre deux htes. TCP/IP fournit un service de circuit virtuel et assure lacquittement des paquets ainsi que la dtection des erreurs. En utilisant TCP/IP, deux htes peuvent changer des paquets dinformation en faisant abstraction des rseaux qui les interconnectent. Au-dessus de TCP/IP, diffrents services ont t dvelopps, afin doffrir une homognit entre applications de mme nature (par exemple entre applications de courrier lectronique). Parmi ces services on peut citer : FTP (File Transfer Protocol) permet dchanger des fichiers entre deux machines connectes Internet. De vastes collections de fichiers, de documents, de programmes et dimages sont disponibles dans des archives FTP. Pour viter des connexions trop lointaines, des sites miroirs ont t mis en place au niveau des principaux acteurs dInternet (nations, universits, etc.), faisant office darchives locales. Ainsi, les utilisateurs suisses peuvent tlcharger de nombreux programmes en provenance des tats-Unis ou du Japon depuis un site miroir situ Zrich.

Javabook Page 5 Lundi, 12. juillet 1999 3:58 15

Interconnexion de rseaux

De plus, des serveurs spcialiss dans le catalogage des documents situs sur diffrents sites FTP ont t dvelopps. De tels serveurs (comme ARCHIE, par exemple) comportent une base de donnes permettant lindexation dun nombre considrable de documents. Telnet (Terminal Protocol) est un protocole daccs un hte en mode terminal . Il permet un utilisateur de se connecter distance des serveurs de calcul, des banques de donnes ou dautres services hbergs par des ordinateurs centraux. NNTP (Network News Transfer Protocol) permet la constitution de groupes de communication (newsgroups) organiss autour de thmes (loisirs, politique, culture, etc.). Une architecture hirarchique de sites miroirs a galement t mise en place afin de limiter le volume dinformations distribuer. SMTP (Simple Mail Transfer Protocol) dfinit quant lui un service de base en matire de courrier lectronique. SNMP (Simple Network Management Protocol) est un protocole charg de la gestion du rseau. Il est gnralement utilis pour la communication avec les systmes lectroniques tels que passerelles, routeurs, multiplexeurs, etc.

Format des adresses IP


Revenons aux adresses IP : une adresse est constitue de quatre octets dont les valeurs sont spares par des points (exemple : 136.102.233.49). Les R premiers octets (avec R = 1, 2 ou 3) sont consacrs ladresse du rseau et les H suivants (avec H = 3, 2 ou 1) celle de la machine hte. Le rapport R/H dfinit trois classes dadresses : A, B et C (voir figure 1.2), chacune permettant didentifier un certain nombre de rseaux et de machines. La classe dune adresse est code dans les deux premiers bits de celle-ci.
plagehte plage hte
class classe A class classe B class classe C

plagerseau plage rseau Figure 1.2 Format dune adresse IP

Attribution des adresses IP


LInterNIC Register est un organisme charg de distribuer les plages dadresse des diffrents rseaux au niveau international. La hirarchie est gnralement la suivante (voir figure 1.3) : zone gographique (pays) ;

Javabook Page 6 Lundi, 12. juillet 1999 3:58 15

Chapitre 1 Avant Java

organisation, entreprise; dpartement; hte. Des serveurs de noms tablissent un niveau logique au-dessus du niveau physique des adresses, afin de supporter des rorganisations au niveau des rseaux et des machines. Ainsi, cui.unige.ch et cuiwww.unige.ch sont deux adresses logiques dun mme hte du Centre universitaire informatique de luniversit de Genve, dont ladresse IP est 129.194.70.1. Dans le cas du courrier lectronique, le format gnralement utilis est la concatnation dun nom dutilisateur et de ladresse IP dun hte hbergeant un serveur SMTP : johnny@rock.musique.fr pourrait correspondre ladresse de qui vous savez. Il nest pas ncessaire de dmontrer limportance prise en quelques annes par Internet et le Web.
Communications internationales

Epine dorsale - pays

Rseau - rgion

Rseau local 132.123.x.y Sous-rseau Niveau hte 132.123.1.12

Niveau utilisateur joe@...

Niveau processus Applet Figure 1.3 Interconnectivit sur le rseau Internet

Javabook Page 7 Lundi, 12. juillet 1999 3:58 15

Hypertextes

1.2 Hypertextes
Lide initiale de liens associatifs entre des donnes et des documents dorigines diverses est attribue Douglas Engelbart, dans les annes 50. Alors directeur de lARC (Augmentation Research Center of Stanford Research Institute), D. Engelbart avait pour but de crer des logiciels capables de supporter le travail coopratif et de faciliter la communication entre les utilisateurs. On notera au passage que ce mme programme de recherche tudiait galement les crans multifentres ou encore lutilisation de la souris pour manipuler des complexes informationnels. Le lien associatif est constitu dune rfrence (la cible) et dune ancre (la source). La rfrence et lancre rsident normalement dans des nuds informationnels (textes, images, voire sons) diffrents. Il est ainsi possible de tisser une vritable toile reprsentant les liens smantiques entre diffrentes informations. Lutilisateur peut alors choisir son chemin dans ce rseau selon ses intrts et ses objectifs, naviguant entre les nuds en suivant les liens (voir figure 1.1). Des outils tels que HyperCard sur Macintosh ou les systmes de documentation et daide en ligne des logiciels Excel, Oracle ou FrameMaker nous ont familiariss avec cette approche navigationnelle o lon doit cliquer pour passer dune explication une autre, suivant les besoins. Plus rcemment, de nombreux CD-ROM ont t raliss selon ce paradigme, utilisant des liens hypertextuels pour prsenter un sujet en proposant de nombreux itinraires de parcours. Le contenu des nuds est dsormais tendu dautres types de donnes tels que : image, graphique, vido, son, etc., faisant voluer le principe de lhypertexte vers celui de lhypermdia.

1.3 Web
Imaginez un instant que vous ayez disposition un hypertexte et que les nuds de celui-ci soient rpartis sur les diffrents htes dInternet, des liens hypertextuels permettant la navigation dun nud lautre, dun hte lautre. Le contenu des nuds serait vari, constitu aussi bien dimages, de textes, danimations ou de sons. Ne rvez plus, vous ne serez pas linventeur de ce systme ! En effet, le Web (World-Wide Web [3]) correspond trait pour trait la description ci-dessus. Restent encore dfinir quelques notions de manire plus prcise. Le Web peut tre vu comme le mtissage de deux toiles (Web en anglais) : une toile physique, constitue des rseaux interconnects formant Internet; une toile smantique, constitue des rseaux dhyperliens.

Javabook Page 8 Lundi, 12. juillet 1999 3:58 15

Chapitre 1 Avant Java

Langage de programmation Un langage possde une syntaxe et une smantique qui Il faut un compilateur pour Par exemple Java

Syntaxe La syntaxe peut sexprimer en BNF ou par des diagrammes

Smantique

Programme

Compilateur Programme qui traduit du langage source vers un

Le langage Java La syntaxe de java est proche de celle de C++

Le compilateur Java

Les ancres sont indiques en gras Figure 1.1 Structure dhypertexte

Ce mtissage entre liens physiques et liens logiques naurait certainement pas suffit lui seul dclencher le vritable ouragan Web que lon connat aujourdhui. Cest sans aucun doute le dveloppement de logiciels de navigation (browsers, butineurs) trs simples utiliser et disponibles (souvent gratuitement) sur les plateformes les plus rpandues (PC, Macintosh, puis Unix) qui a vritablement mis le feu et attir le grand public. Les butineurs les plus rpandus (Mosaic, Navigator, MacWeb, WinWeb, Explorer, HotJava, etc.) se basent tous sur des principes dinterface assez simples que lon peut rsumer ainsi : chaque fentre affiche le contenu dun nud dinformation (texte format, images, etc.); des zones sensibles sont places dans le contenu du nud, signales de manire visuelle (exemple : texte soulign en rouge ou image clignotante); ces zones sensibles sont les ancres de liens hypertextuels (voir point 1.2). Lorsque lutilisateur active une ancre (par un clic de la souris), le nud rfrenc par le lien est tlcharg depuis la machine qui lhberge vers la machine de lutilisateur, cela travers le rseau; le contenu de ce nud est ensuite affich dans la fentre, matrialisant ainsi le nouvel emplacement de lutilisateur dans lespace Web.

Javabook Page 9 Lundi, 12. juillet 1999 3:58 15

Web

Il faut encore prciser que les butineurs ont un rle passif en ce qui concerne la prsentation des informations : les indications de formatage, de dfinition des ancres ou dautres facilits dinteraction sont entirement dtermines dans le nud. Cette particularit a permis le dveloppement de butineurs compatibles entre eux, ne diffrant que par les fonctionnalits supplmentaires quils offrent aux utilisateurs. Certaines de ces fonctionnalits sont destines assister le cybervoyageur dans son priple travers le Web : dition de bookmarks, listes de nuds regroups par lutilisateur selon ses propres thmes dintrt; gestion de lhistorique des nuds visits; gestion dun cache (stockage local dlments frquemment rencontrs : icnes, logos, afin dviter leur tlchargement systmatique). Les points suivants prsentent trois lments importants du Web, savoir : HTML : le langage de description du contenu des nuds dinformation; URL : le format de nommage des nuds; HTTP : le protocole dinteraction entre un client (le butineur) et un serveur (lhte qui hberge le nud dsir).

HTML
HTML (HyperText Markup Language) est un langage de description du contenu et de la structure dun nud dinformation. HTML est lui-mme driv dun ensemble de styles et de descriptions issu dune norme appele SGML (Standard Generalized Markup Language). Pour simplifier notre discours, admettons que le nud dinformation sur lequel nous allons travailler soit un document. Nous pouvons alors dcrire : des lments de structure du document : son titre, ses paragraphes, sousparagraphes, listes numrotes, images; des lments de formatage du contenu : texte en italique, tabulations. HTML permet dexprimer ces diffrentes rgles de structuration et de formatage dune manire indpendante de la machine et du logiciel utiliss pour afficher le document. cet effet, HTML dfinit des dlimiteurs (ou balises) que lon introduit dans le contenu dun document et qui seront dtects et interprts par le logiciel daffichage. Lexemple suivant montre les possibilits de base de HTML :
<TITLE>Jump in the Web</TITLE> <H1>Once Upon a Time ...</H1> Welcome to the world of HTML this is the first paragraph.<P> this is the <B>second</B> and <I>some URL</I><P> <A HREF="http://www.oracle.com"> at Oracle </A><P>

Javabook Page 10 Lundi, 12. juillet 1999 3:58 15

10

Chapitre 1 Avant Java


<A HREF="http://cuiwww.unige.ch"> at SQL7 </A><P> <A HREF="http://mistral.culture.fr/louvre/"> Le Louvre </A><P> <IMG SRC="smile.gif">

La figure 1.1 ci-dessous reproduit notre document tel quil apparat sur un Macintosh, en utilisant le butineur Mosaic. La tche du butineur consiste charger le code HTML du document travers le rseau et en excuter les commandes afin dafficher le document format.

Figure 1.1 Affichage dun document HTML

Les dlimiteurs (tags en anglais) sont entours de crochets <> et vont en gnral par paire : <XXX> et </XXX>. Dcouvrons certains dentre eux en tudiant le code HTML correspondant au document ci-dessus : donne un titre au document.
<TITLE>Jump in the Web</TITLE> <H1>Once Upon a Time ...</H1>

donne un en-tte une partie du document (niveaux 1 6). indique la fin dun paragraphe.
Welcome to the world of HTML this is the first paragraph.<P> this is the <B>second</B> and <I>some URL</I><P> <A HREF="http://www.oracle.com"> at Oracle </A><P>

dfinit une style (dans ce cas : gras et italique).

dfinit une rfrence et son ancre. Cest ainsi que lon dclare des liens hypertextes.

Javabook Page 11 Lundi, 12. juillet 1999 3:58 15

Web
<IMG SRC="smile.gif">

11

inclut une image.

Nous consacrons lannexe D la dfinition des principaux dlimiteurs de HTML. Lintrt de HTML pour un programmeur Java rside dans le fait quun programme Java peut tre invoqu depuis le contenu dun document HTML. On parle alors dapplet Java (voir chapitre 10, page 123).

URL
Un URL (Uniform Resource Locator) permet de localiser de manire unique une ressource (un nud dinformation) sur Internet. Il identifie la fois : le protocole utiliser pour charger la ressource (file, ftp, http, etc.); la machine hte (adresse IP, ventuellement avec un numro de port); le chemin daccs la ressource (arborescence du systme de fichiers); le nom de la ressource (nom de fichier). Le format complet est le suivant :
protocole://hte.organisation.domaine[:port]/chemin/nom

Ce format respecte les conventions de nommage mentionnes au point 1.1. LURL peut encore tre tendu afin dindiquer le nom dune sous-rfrence interne au nud, laide du suffixe (#sous-rfrence), comme dans lexemple suivant :
http://cuicui.unige.ch:9876/db/java/livre/preface.html#merci

Cela permet une navigation lintrieur dun mme nud, comme par exemple des renvois entre paragraphes dun mme document. Nous verrons quun URL peut galement servir dmarrer une application et lui fournir des paramtres, permettant ainsi dinterroger une base de donnes ou dinteragir avec un systme complexe distance.

HTTP
HTTP (HyperText Transfer Protocol) est un protocole destin aux changes entre un client Web (butineur) et un serveur (appel serveur HTTP ou serveur Web ) hbergeant des nuds dinformation. Le serveur HTTP et lensemble des nuds forment ce que lon appelle communment un site Web . Fonctionnement du serveur Le serveur HTTP rceptionne les requtes des clients (exprimes laide dURL) et leur retourne le contenu des nuds rfrencs. Il sert galement de passerelle (gateway) vers des applications invoques par le client. De plus, il gre les droits daccs certains nuds et rcolte des statistiques sur lutilisation des services (nombre de requtes, provenance des clients ou nuds les plus demands).

Javabook Page 12 Lundi, 12. juillet 1999 3:58 15

12

Chapitre 1 Avant Java

Loffre en matire de serveurs HTTP est assez importante, des systmes ayant t dvelopps pour les principales plateformes : Unix, Windows, Macintosh. La mise en uvre dun serveur HTTP est relativement simple. Nanmoins, il faut distinguer les deux cas suivants, trs diffrents en matire de scurit, de charge (nombre daccs simultans)... et de cot de licence : installation intranet (locale), accessible uniquement depuis les machines du rseau interne lorganisation ou lentreprise; installation Internet, accessible (potentiellement du moins) depuis nimporte quelle machine connecte Internet. Ainsi, le cot dun serveur HTTP varie fortement selon la configuration, de quelques centaines de francs franais pour un serveur lmentaire sur PC plusieurs centaines de milliers de francs pour une installation Internet sur une machine UNIX multiprocesseurs.

1.4 Perdu dans le cyberespace


La plupart des entreprises ont mis en place un ou plusieurs sites Web (un investissement minimal pour une visibilit maximale tait le slogan dans les premiers temps du Web!). Cette abondance peut rapidement dcourager un cybernaute : Tout est l, mais comment trouver ce dont jai vraiment besoin? Deux attitudes non exclusives sont alors possibles : utiliser les bases de donnes dindexation (Yahoo, AltaVista, etc.) qui, partir de mots cls spcifis par lutilisateur, retournent les URL de nuds rpondant aux critres de recherche; surfer sur le Web en se promenant au gr des hyperliens. En profiter au passage pour noter les nuds intressants et pour organiser ainsi son propre catalogue dURL (bookmark). Comme vous pouvez le constater, ces dmarches ne sont pas trs loignes de la consultation dun dictionnaire ou dune encyclopdie papier .

1.5 Cration des nuds


Les documents servant de nuds lhypertexte peuvent tre crs laide de traitement de texte (prendre garde sauvegarder les documents en format ASCII), les dlimiteurs tant insrs la main ou au moyen de macros (squences programmes). Des logiciels spcialiss dans ldition de documents HTML ont vu le jour et facilitent grandement ldition de documents trs garnis . La gnration de documents HTML partir dautres formats est trs intressante dans le cas o de gros volumes dinformation (documentation, livre, catalogue) ont dj t structurs et mis en forme dans un traitement de texte. Des

Javabook Page 13 Lundi, 12. juillet 1999 3:58 15

Architecture client-serveur

13

convertisseurs existent pour traduire en HTML des documents issus de Word (format RTF), FrameMaker (format MIF), LaTeX, etc. Dans le cas des images, de nombreux utilitaires permettent de convertir les fichiers issus de logiciels de dessin (CorelDraw, Canvas, Painter, etc.) au format GIF, trs rpandu sur le Web.

1.6 Architecture client-serveur


Le client-serveur, le paradigme de ces dernires annes, visait llaboration dapplications dont la tche se rpartit au moment de lexcution entre le client et le serveur. Le schma (clbre) du Gartner Group tablissait une typologie en fonction des types dactivits excutes et de leur rpartition sur le client et le serveur (voir tableau 1.1). Dans cette table, nous avons ajout une toile (*) lorsquil nexiste pas, nos yeux, une grande classe reprsentative de ce type. Le dveloppement en clientserveur sest principalement bti autour des types 2-3-4.
Type 0 Activit sur le serveur Donnes Traitements Prsentation Donnes Traitements Prsentation Donnes Traitements Donnes Traitements Prsentation Activit sur le client Description Architecture centralise avec des terminaux.

Le client nest utilis que pour la prsentation (par exemple avec X11).

2 3

Prsentation Traitements Prsentation Traitements Prsentation Donnes Traitements Prsentation

Le client est un serveur de prsentation intgrant le contrle de la logique de laffichage. Les traitements sont rpartis entre le client et le serveur (par exemple les procdures PL/SQL dOracle sexcutant sur le client, dans les forms et dans le SGBD serveur). Le serveur est un pur serveur de donnes (une base de donnes sans procdures stockes). Excel + ODBC* EIS (Executive Information System) + BD locale*.

Donnes

Donnes

Javabook Page 14 Lundi, 12. juillet 1999 3:58 15

14
Type 6 Activit sur le serveur Activit sur le client Donnes Traitements Prsentation Description

Chapitre 1 Avant Java

Un poste de travail (PC, Mac) isol.

Tableau 1.1 Typologie client-serveur et rpartition des activits

Les principaux problmes rencontrs dans la mise en uvre du client-serveur sont : la difficult de rpartition de lactivit entre le serveur et le client; cette rpartition est difficile effectuer a priori, lidal tant quelle soit vue comme une optimisation des performances. Cela nest possible que si le langage de programmation est identique sur le serveur et sur le client (PL/SQL par exemple) ou si lensemble de lapplication est obtenu par gnration (avec NSDK de Nat system, par exemple). Lutilisation doutils tels que PowerBuilder ou SQL-Windows introduisent une rupture de langage entre le serveur et le client qui peut rendre cette tche ardue et/ou coteuse en temps de reprogrammation; le cot de distribution des logiciels (versions) et la complexit de la gestion des configurations; gnralement, seul le code excutable du logiciel est distribuer sur le client (run-time) ainsi que les gestionnaires de rseaux. Cette tche peut devenir un cauchemar qui est fonction de nombreux paramtres : N : nombre de postes clients; A : nombre de versions actives du SGBD; B : nombre de versions actives du gestionnaire dcran; C : nombre de versions actives du systme dexploitation client; D : nombre de protocoles rseaux utiliss. Admettons que la complexit soit gale au produit de ces variables. En dbut de projet, on estime les valeurs A, B, C, D 1. La complexit est donc celle du nombre de postes clients. Mais aprs quelques mois ou annes, A, B, C, D ont gnralement pris des valeurs entre 1 et 4... Do une augmentation de la complexit que nous vous laissons calculer; la faible portabilit; nous navons rencontr aucun gnrateur dapplications ne ncessitant pas de retravailler les documents gnrs, bien quils se dclarent tous multicibles. Il est donc difficile de faire cohabiter des communauts dutilisateurs ne partageant pas les mmes types de postes de travail.

Javabook Page 15 Lundi, 12. juillet 1999 3:58 15

Langages de programmation orients objet

15

Le client-serveur reprsente nos yeux une tape transitoire entre larchitecture terminaux en toile autour dun ordinateur central et celle du client universel et du serveur universel baignant dans lintranet/Internet . Cette tape aura essentiellement permis dinstaller les rseaux dans les entreprises.

1.7 Langages de programmation orients objet


Lvolution des langages de programmation depuis les annes 50 a t marque par quelques grandes tapes. Celles-ci correspondent lintgration successive de nouvelles ides issues du domaine du gnie logiciel dans les langages. Elles ont permis chaque fois dtendre le champ dapplication de linformatique.

Langages volus
Lintroduction du langage FORTRAN dans le domaine scientifique et du COBOL pour les applications de gestion marque larrive des langages volus. Ces langages permettent au programmeur de sexprimer dans des termes plus proches de son propre langage, et non plus laide de codes correspondant aux diverses instructions excutables par la machine utilise. Le COBOL introduit galement la structuration hirarchique des donnes.

Langages structurs
Llargissement du champ dapplication de linformatique conduit dvelopper des programmes de plus en plus grands et de plus en plus complexes grer. La programmation structure introduit un ensemble dinstructions de contrle (si alors sinon, rpter jusqu, etc.) permettant dexprimer un algorithme en les combinant entre elles et surtout dliminer les instructions de saut sauvages (goto), jusqualors omniprsentes. Chaque bloc dinstructions possde dsormais un seul point dentre et un seul point de sortie, ce qui facilite grandement la lecture et la comprhension des programmes. Le typage strict des donnes est galement introduit, permettant de dtecter ds la compilation des erreurs graves pouvant conduire la corruption de la mmoire. Algol, puis Pascal et C ont grandement contribu la diffusion de la programmation structure. La mthode de dveloppement sous-jacente la programmation structure est la dcomposition des problmes en sous-problmes par raffinements successifs, appele aussi approche descendante (top-down).

Langages modulaires
Toujours dans le but de matriser des logiciels dont la taille devient considrable (plusieurs millions de lignes dinstructions), des langages comme Modula puis

Javabook Page 16 Lundi, 12. juillet 1999 3:58 15

16

Chapitre 1 Avant Java

Ada mettent en avant le concept de programmation modulaire. Un module regroupe des sous-programmes et des donnes qui ont un but commun, que ce soit la gestion dun type de donnes, dun priphrique, dune fonction complexe du systme, etc. Lide de base de cette approche est de construire les programmes par assemblage de modules.

Langages objets : de Simula Java


Les langages objets proposent de voir un systme informatique comme un ensemble dobjets qui ralisent des activits et communiquent entre eux par envoi de messages. Les objets dun mme type sont regroups dans des classes qui dfinissent leur structure et leur comportement. La rutilisation de classes existantes est facilite par des possibilits dadaptation, comme la notion de sousclasse. Lanctre des langages objets est Simula-67, cr en 1967, sans doute un peu trop tt pour que le commun des programmeurs en saisisse tout lintrt. Le second membre minent de la famille est Smalltalk-80 (1980!). Ce dernier, vritable puriste , pousse lextrme la programmation objet puisque tout y est objet, mme les blocs dinstructions dun programme. Le langage est trs dynamique, le compilateur ne fait pas de vrification de types; ce nest quau moment o un objet reoit un message, lexcution, quil dcide si oui ou non il peut y rpondre et comment. Smalltalk est indissociable de son environnement de dveloppement qui comprend une riche bibliothque de classes prdfinies et des outils graphiques ddition, de dbogage et de butinage. Paralllement, mais dmarrant un peu plus tard, plusieurs langages objets ont t dvelopps partir de langages existants : Object Pascal, dfini par Apple pour la programmation du Macintosh ou Objective C (une extension du C base sur le principe de Smalltalk de typage dynamique), utilis dans lenvironnement NEXTSTEP de NeXT. Parmi les langages objet, cest le langage C++ qui a incontestablement rencontr le plus large succs. Il sest rpandu chez les dveloppeurs grce, entre autres, sa compatibilit avec le langage C. Cette contrainte de compatibilit avec un langage non-objet, fixe ds le dpart, a t magistralement surmonte par larchitecte principal du langage (B. Stroustrup [11]). Il nen reste pas moins que C++ est un langage complexe o le paradigme objet nest pas central. Cest dans ce contexte que Java apparat en 1995 sur Internet. Si les lments de base de la syntaxe Java sont proches de ceux de C++ (donc de C), il nen va pas de mme au niveau smantique. De ce point de vue, Java prend une orientation plus radicalement objet qui le rapproche de Smalltalk ou dEiffel. Il se libre de lusage explicite des pointeurs encore impos par C++ et interdit certaines dfinitions la smantique trs complexe, comme la redfinition doprateurs ou

Javabook Page 17 Lundi, 12. juillet 1999 3:58 15

Langages de programmation orients objet

17

lhritage multiple. La simplicit de Java et le large support dont il jouit dj pourrait bien en faire le Pascal de la fin du sicle, cest--dire le langage qui amne la programmation objet non seulement chez les dveloppeurs professionnels mais aussi chez tous ceux qui veulent sinitier la programmation sans ncessairement en faire leur profession.

Javabook Page 18 Lundi, 12. juillet 1999 3:58 15

Javabook Page 19 Lundi, 12. juillet 1999 3:58 15

Chapitre 2

Rvolution an 4 : Java
Java nest plus radicalement nouveau, il sinscrit dans la continuit de lvolution des langages. Par contre, ses capacits concernant la distribution dapplications sur Internet en font un outil rvolutionnaire. En quatre ans, il aura aussi affirm son ambition de remplacer C++.

2.1 Java, cest quoi?


Dvelopp par Sun Microsystems, Java est un langage de programmation orient objet, adapt la distribution dapplications sur Internet et sintgrant au Web. Les caractristiques du langage et leur adquation Internet et au Web forment des couples indissociables. Commenons par examiner les caractristiques de ce nouveau langage.

2.2 Caractristiques principales


Java est orient objet
Il appartient logiquement la mouvance des langages de programmation orients objet (voir point 1.7). Le paradigme objet est a priori simple expliquer : les objets (instances) sont issus de moules (classes); ils communiquent entre eux laide de messages; les messages sont valus par les mthodes de lobjet, induisant des modifications de son tat ou de son comportement; les objets vivent en famille, ils hritent du comportement de leurs ans (hritage entre classes) et spcialisent ce comportement.

Javabook Page 20 Lundi, 12. juillet 1999 3:58 15

20

Chapitre 2 Rvolution an 4 : Java

Cette orientation objet nest pas en soi la qualit principale de Java (il existe des centaines de langages objets ayant ces proprits!). Les qualits de Java rsident dans lassainissement effectu par ses concepteurs au niveau de limplantation des concepts du langage. Ces choix dimplantation ont t guids dans Java par des objectifs de scurit, de sret de programmation, de portabilit, de distribution et de performance.

Java supprime lutilisation des pointeurs


Lors de la cration dun objet (mthode new), un objet est dsign par une rfrence. Dans les langages tels que C ou C++, les objets sont plus naturellement dsigns par des pointeurs. De plus, des oprations arithmtiques (addition, comparaison, etc.) sont autorises sur ces pointeurs. Cette pratique, considre comme indispensable par certains programmeurs, est une source trs frquente derreurs. En Java, la seule opration possible sur une rfrence est sa copie. Java interdit donc toutes les manipulations arithmtiques sur les dsignateurs dobjets, liminant ainsi de nombreux risques derreurs... voire de virus.

Java supporte les tableaux


En Java, les tableaux ne sont pas reprsents uniquement par une suite demplacements mmoire rfrencs par un pointeur. Ils prennent la forme dune structure, munie dune borne infrieure et dune borne suprieure. Lors de laccs lun des lments du tableau laide dun indice, lappartenance de cet indice lintervalle spcifi par les bornes est vrifie. Cette vrification systmatique peut sembler une vidence, puisquelle permet de dtecter bien des erreurs de programmation. Nanmoins, de nombreux langages comme C ou C++ ne lappliquent pas.

Java supporte et rclame un typage fort


Java supprime les conversions automatiques de types, aucune conversion ntant effectue implicitement. Ds lors, toutes les conversions doivent tre dclares par le programmeur de manire explicite. Labsence de pointeurs autorise une vrification accrue des types dobjets par le compilateur. En effet, aucun pointeur ne pouvant tre forg sur un objet, toutes les oprations sur celui-ci (copie de rfrence, passage de paramtres) sont explicites dans le code du programme, ce qui permet de vrifier la cohrence des types.

Java gre automatiquement la mmoire


Labsence de pointeurs permet galement dtablir pendant lexcution une liste des objets encore utiliss (ceux dont les rfrences sont encore atteignables par

Javabook Page 21 Lundi, 12. juillet 1999 3:58 15

Caractristiques principales

21

les processus en cours) et une liste de ceux qui ne le sont plus. Ces derniers, dsormais inutiles, peuvent donc tre limins de la mmoire par un processus spcialis (le garbage collector ou plus potiquement ramasse-miettes). Afin dviter lmiettement de la mmoire, on peut dplacer des objets dans la mmoire, puisque toutes les rfrences un objet sont connues. Java utilise cet effet des algorithmes performants de nettoyage et de compactage de la mmoire, excuts paralllement au droulement normal du programme. Le prix payer pour cette optimisation de la mmoire est de quelques pour cent sur la performance gnrale du programme (dans les applications critiques, le programmeur peut dsactiver et ractiver le mcanisme volont). Nanmoins, les bnfices sont normes : le programmeur na plus besoin de dsallouer des objets devenus inutilisables; mais surtout le risque derreurs portant sur des objets encore rfrencs mais dj supprims est limin. Ainsi, nous ne devrions plus entendre : Je croyais ne plus avoir besoin de cet objet et je lai supprim, mais javais oubli quil tait rfrenc par cet autre objet, vous comprenez, cest tellement complexe, une erreur est vite arrive et le compilateur na rien dit. Notons enfin que de telles erreurs, responsables dun grand nombre de crash de programmes, sont extrmement difficiles dtecter car elles ne sont pas systmatiquement reproductibles.

Java remplace lhritage multiple par la notion dinterface


Lhritage multiple, du fait de sa complexit, na pas t retenu comme mcanisme dimplantation du polymorphisme en Java. Les concepteurs du langage lui ont prfr la notion dinterface (conceptuellement proche de celle de protocole dans Objective-C). Une interface permet de spcifier des protocoles, des comportements abstraits ou gnriques. Ce mcanisme permet galement dattribuer des comportements multiples un objet et de fdrer des objets selon leurs comportements.

Java est multiprocessus


La notion de processus (thread) est intgre dans le langage Java. Un mcanisme de synchronisation est dfini au niveau de la syntaxe, permettant de protger aussi bien un bloc de code, une mthode ou une variable dune excution concurrente. Autoriser ainsi le programmeur raisonner en termes dactions indpendantes lui permet de simplifier la conception de la programmation. Les vnements sont traits par les processus concerns, les processus communiquent et cooprent pour accomplir des tches plus globales.

Javabook Page 22 Lundi, 12. juillet 1999 3:58 15

22

Chapitre 2 Rvolution an 4 : Java

Java produit du code interprtable par une machine virtuelle


Le rsultat de la compilation dun programme Java est un fichier de byte-code. Ce byte-code spcifie des instructions (appeles aussi pseudo-code) excutables par une machine virtuelle. Cette machine virtuelle est munie de contraintes qui vont garantir certaines proprits lors de lexcution dun programme. Ce niveau intermdiaire dinterprtation du code tablit une indpendance par rapport la machine physique supportant lexcution de la machine virtuelle. Ce principe de pseudo-code a dj connu ses heures de gloire dans le pass, avec le Pascal UCSD qui avait t port sur plusieurs architectures de microprocesseurs 8 bits de la fin des annes 70 (dont lApple II).

Le chargement du code est dynamique


Le code Java est charg uniquement sil est utilis. Le code peut ainsi rsider sur des serveurs diffrents. Il peut tre dvelopp par des quipes diffrentes situes dans des lieux gographiques distants, et relies par le rseau. La gestion des versions est simplifie, le code charg correspondant toujours la version la plus rcente.

Java utilise des standards


Larithmtique flottante de Java est conforme la norme IEEE 754, ce qui garantit que les calculs effectus sur nimporte quelle machine physique supportant Java donnent toujours les mmes rsultats. Il est ainsi possible de distribuer une tche complexe de calcul sur un ensemble htrogne de plateformes (Mips, Pentium, PowerPC, Sparc, etc.). Lencodage des caractres est effectu sur 16 bits selon la norme Unicode, ce qui permet de traiter les signes diacritiques de plusieurs langues autres que langlais (qui nen possde pas!).

La syntaxe de Java est familire


Les concepteurs de Java ont eu la sagesse de conserver les formes syntaxiques de C et de C++ pour spcifier les expressions (i++, <<, &, etc.) et les structures de contrle (if, for, while, etc.). Les programmeurs connaissant dj ces langages peuvent ainsi garder certaines de leurs habitudes.

La syntaxe de Java est simple


Le corpus des rgles est limit et les constructions sont simples, ce qui facilite lapprentissage de Java. Cependant, nous ne pouvons pas en dire autant de Java lui-mme. Les difficults de programmation en Java ne rsident en effet pas dans la syntaxe, mais dans larticulation des concepts objet. Un bon programmeur C++ ou Smalltalk deviendra rapidement un trs bon programmeur Java. Java, une fois matris, peut amliorer la qualit des programmes objet, mais il ne peut en aucun cas amliorer la qualit du choix de la dcomposition en ob-

Javabook Page 23 Lundi, 12. juillet 1999 3:58 15

Adquation de Java Internet et au Web

23

jets. Ds lors, comment traduire la ralit en objets? reste la question primordiale, laquelle nous tenterons par ailleurs de rpondre dans la partie IV.

2.3 Adquation de Java Internet et au Web


Le potentiel commun dInternet et du Web en matire daccs et de distribution dinformations nest plus dmontrer. Les standards tels que HTTP ou HTML offrent un niveau lev de compatibilit qui garantit la portabilit des informations (principalement des documents) dans de nombreux environnements. Malheureusement, cette portabilit est loin dtre aussi vidente au niveau des programmes : les langages, les environnements de dveloppement, les systmes dexploitation et les plateformes matrielles dfinissant tous leurs propres standards , lincompatibilit entre systmes demeure la seule norme. Ds lors, le prochain dfi relever consiste proposer du code pouvant tre dvelopp sur une machine, transmis sur le rseau et excut sur dautres machines totalement diffrentes, quels que soient leur systme dexploitation et leur processeur. De plus, lexcution de ce code doit fournir exactement les mmes rsultats (prcision arithmtique, interface graphique, etc.). Mission impossible? Peut-tre pas, mais les qualits requises pour la distribution travers le rseau sont nombreuses : le code doit tre robuste : cest--dire que tout doit tre mis en uvre pour minimiser les risques de crash . Cela est encore plus vrai si le programme est un assemblage de plusieurs classes provenant de sources diffrentes sur le rseau; le code doit tre indpendant : le client doit pouvoir excuter des programmes sans se soucier du type de matriel utilis par le serveur. Le programmeur doit pouvoir dvelopper son application sans connatre luimme ou imposer aux utilisateurs un type de plateforme particulier; le code doit tre sr : le client doit avoir la certitude de pouvoir charger des applications depuis nimporte quel point du rseau sans craindre des virus, des manipulations ou des destructions de fichiers, ni des problmes de communication avec des serveurs peu scrupuleux (qui sinforment, par exemple, du contenu de vos disques).

Java est robuste


En liminant lutilisation des pointeurs, en grant lallocation et la dsallocation de la mmoire, en dtectant les usages illicites des tableaux, en ne permettant pas la surcharge des oprateurs, en substituant lhritage multiple les interfaces, en utilisant les standards, en ayant une syntaxe allge, Java contribue grandement amliorer la qualit et la scurit des programmes. Les erreurs qui demeurent sont gnralement de type fonctionnel (dues une mauvaise concep-

Javabook Page 24 Lundi, 12. juillet 1999 3:58 15

24

Chapitre 2 Rvolution an 4 : Java

tion). Le programmeur tant dcharg des responsabilits de gestion de la mmoire, il peut mieux se concentrer sur lactivit de lobjet et sur la qualit de sa conception. Linterprtation par une machine virtuelle et le chargement dynamique permettent dviter des phases de compilation et ddition de liens qui peuvent devenir trs lourdes ds que le projet atteint une certaine taille. Le compilateur, avec sa vrification stricte du typage, permet lui aussi de dtecter de nombreuses erreurs de programmation (passage de paramtres, appel de mthodes, etc.). Java possde galement des mcanismes assez subtils en ce qui concerne le rglage de la visibilit et de lhritage entre classes. Ces mcanismes peuvent tre pleinement utiliss pour dvelopper des logiciels complexes et de taille importante, en appliquant les apports mthodologiques du gnie logiciel.

Larchitecture Java est neutre et portable


Lutilisation de byte-code et celle des standards Unicode et IEEE754 rendent Java indpendant de la plateforme dexcution. Les seules parties dpendantes des plateformes sont encapsules dans la machine virtuelle charge dinterprter les byte-codes et dans un package (awt.peer) qui dtermine lapparence des objets graphiques pour chaque systme dexploitation (MacOS, Solaris, Windows95/NT, etc.). Une mme application saura donc sadapter la machine du client afin de respecter les conventions de son interface graphique utilisateur (GUI). Lobjectif de cette neutralit et de cette portabilit est quun programmeur puisse dvelopper son application une seule fois et que tous les utilisateurs potentiels puissent lexcuter, indpendamment des choix quils ont effectus pour leur poste de travail.

Java est sr
La scurit, dans un environnement compltement distribu comme le rseau Internet, est une priorit absolue. Il est impensable de tester tous les programmes avant de les charger, de certifier toutes les sources et tous les serveurs du rseau. La seule solution est que le poste de travail se protge lui-mme. Lencapsulation de lexcution du code dans une machine virtuelle permet la portabilit par rapport la machine physique, mais elle assure aussi un dcouplage par rapport aux ressources (mmoire, systme de fichiers, canaux de communication) de cette dernire. Lapplication, une fois charge, est enferme dans la machine virtuelle et na donc pas directement accs aux instructions de la machine physique, ni ses ressources. Chacune de ces ressources sera alors vue comme un service de la ma-

Javabook Page 25 Lundi, 12. juillet 1999 3:58 15

Code mobile

25

chine virtuelle. Lutilisateur peut ainsi rgler en tout temps les capacits de sa machine virtuelle (donc des applications charges lintrieur), en fonction du degr de confiance quil a envers le serveur ou la socit qui a produit le programme : pour un jeu sduisant, il peut ne donner au programme que le droit de sexcuter; pour grer son compte dpargne, il peut autoriser le programme mis disposition par sa banque crer un fichier local des transactions. Atteindre ce degr de confiance demande une grande rigueur, la machine virtuelle devant se mfier de tous les programmes qui sont chargs. A cet effet, elle effectue sur chacun dentre eux une srie de tests (voir chapitre 27) afin de prouver un certain nombre de proprits attestant que lexcution des bytes-codes ne peut avoir un comportement cach (virus, etc.). De plus, lespace des noms du code est isol de celui de sa provenance; il est ainsi impossible quun objet se substitue un autre. Enfin, le code est test par rapport aux droits qui lui sont attribus (lire/crire des fichiers locaux, communiquer localement/ lextrieur, etc.). Ces trois qualits robustesse, portabilit et sret sont celles qui vont assurer le succs futur de Java.

2.4 Code mobile


Un code (programme compil) est dit mobile sil est transportable (le lieu de son excution est indpendant de son lieu de stockage) et portable (le support de ces excutions ne se restreint pas un type particulier de machine). Il est toujours difficile dtablir laspect rvolutionnaire dvnements pendant leur survenance. Cependant, on peut rutiliser les typologies, examiner les questionnements, tablir quelques bilans. Les remarques que nous faisons ici prennent leur sens dans le cadre dInternet ou dun intranet. Un intranet est lutilisation des technologies dInternet (TCP/ IP, Java, Web, etc.) restreinte une communaut dutilisateurs et de services dfinis pour celle-ci. Lintranet typique est celui dfini par la communaut des employs dune entreprise. Les services et les applicatifs sont ceux leur permettant de raliser leur mission. Lintranet peut tre tendu une ville, une rgion, un regroupement dorganisations (des universits par exemple). Un intranet nest pas dfini par la topologie de son rseau, mais par la spcificit de ses services et de ses utilisateurs. Il peut tre rattach Internet, gnralement travers un mur pare-feu (firewall) qui dfinit les droits daccs des flux entrants et sortants.

Javabook Page 26 Lundi, 12. juillet 1999 3:58 15

26

Chapitre 2 Rvolution an 4 : Java

Programmation distribue en Java


Nous reprenons ici la typologie du modle client-serveur (voir p. 13) en considrant les apports de Java, dInternet et des bases de donnes.
Type 0 Activit sur le serveur Donnes Traitements Prsentation Donnes Traitements Prsentation Donnes Traitements Donnes Traitements Donnes Activit sur le client Description Des terminaux connects par lordinateur central sur Internet avec Lynx (butineur en mode caractres 24x80), traitements par programmes sur le serveur. Utilisation du Web avec un terminal X (par exemple, HotJava depuis un Mac). Le Web avec excution du butineur sur le client (traitements par programmes sur le serveur), situation avant Java. Les traitements sont rpartis entre le client et le serveur (Java, JavaScript sur le client, application Java sur le serveur). Le serveur est un pur serveur de donnes (utilisation de Java et dun kit de connexion aux bases de donnes, JDBC par exemple). Comme dans 4 + une base de donnes locale (Oracle Lite) + une connexion aux outils bureautiques locaux. Application Java sur le client.

Prsentation

Prsentation Traitements Prsentation Traitements Prsentation Donnes Traitements Prsentation Donnes Traitements Prsentation

Donnes

Donnes Traitements Prsentation

Donnes Traitements Prsentation

Au fond, la typologie nest plus classifiante et le mode de travail sera un mlange de tout, sur le client et sur le serveur.

Tableau 2.1 Typologie de la rpartition des activits

Si nous rexaminons les difficults rencontres dans la mise en uvre du clientserveur (voir point 1.6), nous constatons que : la rpartition de lactivit ne pose pas de problme : il est possible de transfrer le code Java du serveur vers le client. Le contenu des documents HTML dtermine ce que le client doit excuter; le cot de la distribution diminue fortement : le client charge lapplication lorsquil charge le document, obtenant ainsi la dernire version de celle-ci. Le cot de distribution se rsume au cot de transfert, celui-ci

Javabook Page 27 Lundi, 12. juillet 1999 3:58 15

Code mobile

27

pouvant tre rduit grce lutilisation dun systme de cache dans le butineur et de miroirs diminuant les distances et augmentant les capacits daccs. Seul le butineur doit tre install sur le client; la portabilit est maximale, autant du ct des clients qui ne connaissent pas les dtails dimplantation des serveurs que du ct des serveurs qui ne connaissent pas les configurations matrielles des clients ou leur systme dexploitation. Le trio Java, BD et Web (y compris TCP/IP) remplit toutes les cases de la typologie. Les serveurs et les clients y acquirent des statuts duniversalit qui les rendent indpendants. La logique du couple client-serveur est remplace par celle dun serveur accessible par tous les clients et dun client connectable sur tous les serveurs.

Des documents statiques aux documents dynamiques anims


La vision classique dun document est celle dune composition dlments euxmmes composs dautres lments plus simples (chapitres composs dun titre et dun ensemble de sections, sections composes dun titre et de paragraphes, etc.), jusqu des lments primitifs comme les caractres ou les images. Un document devient dynamique ds le moment o lun de ses lments nest plus stock tel quel sur un support mais construit (calcul) automatiquement au moment o le lecteur y accde. Ds le dbut du Web, ses concepteurs ont prvu cette possibilit en dfinissant un protocole et une forme dURL qui permettent de demander un serveur non pas le contenu dun nud dinformation dj stock mais le calcul de ce contenu partir de paramtres et de donnes propres au serveur. Cette possibilit est largement utilise pour accder des bases de donnes : le serveur reoit un URL dcrivant les informations recherches; il effectue la recherche correspondante puis transmet le document ainsi cr au client. Les langages de scripting comme JavaScript (voir annexe E) rendent les documents actifs en y introduisant du code excutable. Une partie du document possde alors un comportement propre et peut interagir avec lutilisateur. Les formulaires avaient dj introduit une possibilit dinteraction, limite la saisie de donnes dans des champs et leur envoi un serveur. Avec Java, la dynamicit aborde une nouvelle dimension car le code qui anime certains lments du document na pas besoin dtre inclus dans le document : une rfrence un code stock sur un serveur suffit. Cest au moment o le document est visualis que le code mobile est amen du serveur sur la machine cliente o a lieu la visualisation. Ainsi, on dsynchronise compltement la production du document et celle du code. Des experts en programmation peuvent dvelopper des programmes gnriques de haute qualit pour grer diffrents ty-

Javabook Page 28 Lundi, 12. juillet 1999 3:58 15

28

Chapitre 2 Rvolution an 4 : Java

pes de contenus, le producteur de document peut choisir parmi les codes disposition celui qui convient en fonction du type de contenu quil veut gnrer ou animer.

Examiner les questionnements


Nous avons trouv trois questions qui reoivent une rponse technique dfinitive avec le trio Java, BD et Web. Ces questions semblent priphriques la cration de logiciels, mais pourtant leur apporter quotidiennement une solution accapare une grande partie des ressources informatiques. Qui est mon public cible et comment est-il quip matriellement? Utilise-t-il une architecture PC (386, 486, Pentium, ou P6) ou Macintosh (68000 ou PowerPC) ou de station de travail? Avec quelles configurations mmoire et disque? Sous quel systme dexploitation : MS-DOS, Windows 3.11/95/NT, MacOS, Unix (Linux, AIX, Solaris, etc.)? Rpondre clairement cette question pour une entreprise ou pour un diteur de logiciel est un casse-tte. La rponse du client universel donne par les outils Internet semble si simple : le client na besoin que dune connexion TCP/IP (de capacit adapte son activit) et dun butineur supportant lexcution de Java; Comment distribuer et mettre jour mes applications, mes documents? On revient ici la question des configurations augmente de la problmatique du support : disquette ou CD-ROM. La rponse du chargement du document et de son code associ et/ou du dclenchement dune application sur le serveur semble aussi rgler la question; Comment migrer mes applications? Ici, la question est rendue difficile par le nombre des clients (plusieurs milliers dans une entreprise) et par le fait que le passage de lancien systme au nouveau doit tre effectu le plus rapidement possible (la migration de mille postes clients demande une norme prparation). La rponse apporte par les outils Internet est changer un URL ou modifier une adresse IP dans un serveur de nom . Les questions concernant Internet restent nombreuses : la scurit, le cryptage, la monnaie lectronique (e-cash, digicash), etc. Nanmoins, les solutions dj apportes aux problmes ci-dessus nous semblent suffisamment intressantes pour carter lhypothse quInternet va cesser de se dvelopper ou quil ne sagit que dune mode passagre.

Javabook Page 29 Lundi, 12. juillet 1999 3:58 15

Code mobile

29

Les piliers de la programmation distribue


Dun point de vue physique, linfrastructure des rseaux, les protocoles, les nouvelles architectures de machines constituent les fondations essentielles du dveloppement dapplications distribues lchelle dInternet. Cependant, dun point de vue conceptuel1, les piliers les plus importants pour lcriture des nouvelles applications sont : les bases de donnes ; les hypertextes (Web); le code mobile (Java).
Bases de donnes

Hypertextes Web

Code mobile Java

Figure 2.1 Piliers des applications intranet et Internet

Les bases de donnes sont la mmoire dInternet; en effet, il est impensable de grer un grand nombre de documents (plusieurs milliers de pages HTML sur un mme serveur) sans recourir une base de donnes. La gestion des liens (URL), des droits daccs, de la mise jour des donnes, la construction des index sont simplifies grce elles. De plus, la base de donnes constitue galement un moteur de recherche et de synthse de documents. Les hypertextes dfinissent linterface de prsentation et de navigation entre des documents qui contiennent des donnes, du code mobile et la logique de lapplication. Ainsi, lhypertexte permet dinscrire dans les liens une logique dapplication. Le parcours des liens peut se substituer lactivation de boutons ou darticles dans un menu. Le code mobile dfinit le comportement des objets. Il fait passer un document de ltat statique ltat dynamique en spcifiant des fragments de comportement. On peut alors imaginer qu la description des donnes sera ajoute une description des fragments de comportement, sassemblant pour tre smantiquement pertinents. Par exemple, si lon souhaite grer ses emprunts la banque, le fragment de code dcrivant une calculatrice de gestion damortissement sera charg et prsent en mme temps que ltat de ses comptes.
1. Ces deux points de vue couvrent ce que lon appelle le network-computing.

Javabook Page 30 Lundi, 12. juillet 1999 3:58 15

30

Chapitre 2 Rvolution an 4 : Java

Les documents affichs seront de moins en moins stocks dans des fichiers. Ils seront le rsultat de la synthse : des donnes stockes dans la base de donnes; des fragments de code mobile associs aux types de donnes ; des droits de lutilisateur par rapport son rle; du contexte de lutilisation; du chemin parcouru dans lhypertexte. ... Restent imaginer des mthodes de conception et de dveloppement qui tiennent compte de cette nouvelle donne.

Javabook Page 31 Lundi, 12. juillet 1999 3:58 15

Chapitre 3

Lenvironnement de dveloppement Java


Hormis linfrastructure rseau qui est acqurir, lenvironnement complet de dveloppement Java peut tre tlcharg depuis Internet. On le trouve galement sous forme de CD-ROM.

3.1 Outils
Nous allons rapidement passer en revue les diffrentes situations dutilisation de Java, quil sagisse de dveloppement en local ou reli Internet.

Dveloppement dapplications en local


Pour le dveloppeur dapplications personnelles, il est ncessaire de disposer dun kit comprenant au minimum les outils suivants : un diteur de texte, un compilateur Java, un interprteur du code Java compil. Des environnements de dveloppement sophistiqus intgrent galement des diteurs guids par la syntaxe, des gestionnaires de projet, des dbogueurs, des gnrateurs dinterface, etc.

Utilisation dapplets tlcharges depuis le rseau


Pour lutilisateur dapplets (cest--dire un client), les outils ncessaires sont : une connexion rseau (intranet/Internet); un gestionnaire de protocole TCP/IP; un butineur Web capable dinterprter du code Java.

Javabook Page 32 Lundi, 12. juillet 1999 3:58 15

32

Chapitre 3 Lenvironnement de dveloppement Java

Dautres outils tels que courrier lectronique, transfert de fichiers, compression/ dcompression, encryptage (PGP), etc., peuvent tre utiles.

Pour distribuer des applets


Il existe des sites sur lesquels on peut dposer ses documents pour en faciliter la distribution, sans avoir hberger un serveur sur sa propre machine. Cependant, si lon souhaite raliser un serveur HTTP, les outils ncessaires sont : une connexion rseau (intranet/Internet) supportant un dbit en rapport avec le nombre dutilisateurs; un serveur HTTP; une base de donnes ; nous lincluons ici car il est impensable de grer une multitude de pages sans une base de donnes; un kit de dveloppement Java; un diteur HTML. Si lon hberge un serveur HTTP connect Internet, des outils supplmentaires sont conseiller : gestionnaire de scurit, gestionnaire des statistiques daccs, etc.

Java sans Internet


Il nest pas ncessaire de disposer dune connexion Internet pour utiliser Java. De plus, le code dvelopp tant portable, toutes vos applications peuvent tre diffuses dautres personnes sans recompilation. Vous pouvez dvelopper des applications et des applets sur un PC sans connexion. Lenvironnement de dveloppement pour le MacOS, par exemple, inclut un applet viewer permettant dexcuter des applets sans butineur.

3.2 Dvelopper avec Java


Le cycle de dveloppement dun programme Java est trs semblable celui dautres langages compils puis interprts par une machine virtuelle. Il se droule de la manire suivante : 1. Le programme est stock dans un fichier source de suffixe .java. 2. Le compilateur Java compile ce fichier et le transforme en un fichier de byte-code dont le suffixe est .class. 3. Linterprteur Java charge le byte-code et le vrifie. Cette vrification consiste garantir que le byte-code ne risque pas de perturber le fonctionnement de linterprteur ou de dtruire des ressources sur votre machine. Elle est effectue quelle que soit lorigine du byte-code, quil provienne du rseau ou de votre disque dur. 4. Une fois la vrification effectue, linterprteur excute le byte-code.

Javabook Page 33 Lundi, 12. juillet 1999 3:58 15

O trouver Java

33

Notions dapplet et dapplication


Un programme Java peut prendre deux formes distinctes, chacune tant adapte un contexte dinvocation et dexcution diffrent. La premire (applet) est destine des programmes invoqus depuis des documents HTML et excuts lintrieur dun butineur ou dun applet viewer quip dun interprteur Java. La seconde (application) permet de crer des applications au sens classique du terme, cest--dire sexcutant de manire autonome laide de linterprteur. Le cycle de dveloppement est identique pour les deux formes, seul le contexte dinvocation et dexcution varie : une applet rside en gnral sur un serveur. Un document HTML fait rfrence lapplet laide dun URL. Au moment du chargement du document HTML, le butineur dtecte un dlimiteur dinvocation de lapplet, charge son code dans linterprteur intgr qui lance son excution. Lapplet saffiche alors dans la fentre du butineur; une application quant elle rside habituellement sur la machine o elle est excute. Elle sexcute laide dun interprteur. La figure 3.1 ci-dessous illustre le cycle de dveloppement en Java et les diffrences entre une applet (p) et une application (a). noter la rfrence du document HTML vers lapplet, qui indiquera au butineur de charger son code.
main() a.java application (main()) compilateur Java HTML <APPLET> p.java applet p.class interprteur Java butineur a.class interprteur Java

Figure 3.1 Dveloppement et excution dun programme Java

Nous verrons au paragraphe 16.3 quil est galement possible dexcuter une applet comme une application.

3.3 O trouver Java


Le kit de dveloppement Java (JDK) fourni par Sun est actuellement disponible dans sa version 1.2 pour les plateformes suivantes : SPARC Solaris;

Javabook Page 34 Lundi, 12. juillet 1999 3:58 15

34

Chapitre 3 Lenvironnement de dveloppement Java

Windows NT; Windows 95-98; MacOS. Vous pouvez le charger avec sa documentation depuis le site suivant :
http://java.sun.com/

Contenu du JDK
Le kit de dveloppement contient : un compilateur : le programme qui va traduire vos fichiers de texte source Java en byte-code; un viewer : le programme qui interprte vos fichiers byte-code; lAPI Java : un ensemble de classes qui vous permettront de dvelopper vos programmes ; une documentation : un ensemble de fichiers HTML qui constitue une aide indispensable la bonne comprhension de lAPI Java. Dautres outils de dveloppement sont galement disponibles : un gnrateur de documentation (Javadoc) : il permet de construire des documents partir des commentaires mis dans les programmes; un dbogueur : un programme pour la mise au point de vos programmes; un gnrateur de code natif : gnrant du code natif pour certaines architectures de machine; un dsassembleur.

3.4 Mes premiers pas


Voici deux exemples trs simples vous permettant de tester votre installation.

Java : premire application


Un programme doit possder une mthode main() qui sera le point de dpart de lexcution de ce dernier. crivez le programme suivant dans un fichier nomm MaPremiereApplication.java :
class MaPremiereApplication { public static void main (String args[]) { System.out.println("Ma Premiere Application"); } }

Ensuite, compilez le fichier avec la commande (sous Unix ou Windows/NT) :


javac MaPremiereApplication.java

Javabook Page 35 Lundi, 12. juillet 1999 3:58 15

Mes premiers pas

35

Le rsultat de cette compilation (pour autant quelle ne produise pas derreur) doit crer dans le mme rpertoire un fichier ayant une extension .class, soit : MaPremiereApplication.class. Finalement, excutez le programme avec la commande :
java MaPremiereApplication

Le programme doit alors afficher :


Ma Premire Application

Sous dautres systmes dexploitation (MacOs par exemple), laffichage a lieu dans une fentre (voir figure 3.1) qui correspond au stdout (la sortie standard dUnix).

Figure 3.1 Ma premire application (sous MacOs)

Une application doit toujours possder une mthode main() dclare comme suit :
public static void main (String args[]) { ... instructions excuter ... }

Nous verrons plus loin la signification exacte des termes qui apparaissent dans cet nonc.

Java : premire applet


crivez le programme suivant dans un fichier nomm MaPremiereApplet.java :
import java.awt.Graphics; public class MaPremiereApplet extends java.applet.Applet { public void paint(Graphics g) { g.drawString("Ma premire applet !", 20, 20); }

Compilez ensuite le fichier avec la commande :


javac MaPremiereApplet.java

Le rsultat de cette compilation (pour autant quelle ne produise pas derreur) doit crer dans le mme rpertoire un fichier ayant une extension .class, soit MaPremiereApplet.class.

Javabook Page 36 Lundi, 12. juillet 1999 3:58 15

36

Chapitre 3 Lenvironnement de dveloppement Java

Il nous faut maintenant invoquer cette applet depuis un document HTML qui devra se trouver pour le moment dans le mme rpertoire que le fichier MaPremiereApplet.class. Nous proposons dcrire ceci dans un fichier test.html :
<title>Applet Une</title> <h1>Vraiment la premi&egrave;re</h1> <hr> <applet code=MaPremiereApplet.class width=200 height=50> </applet> <hr> <a href="MaPremiereApplet.java">Le source.</a> <hr>

Ouvrez votre butineur et demandez charger votre document test.html. Vous devriez obtenir le rsultat suivant (figure 3.2) :

Figure 3.2 Ma premire applet (vue dans un butineur)

3.5 Chercher de linformation sur Java


Nous avons essay de ne pas indiquer dURL car ils ne sont pas toujours trs stables : les sites restent mais les documents sont souvent rorganiss. De plus, nous pensons que le plus important est de savoir rechercher linformation. Voici un exemple utilisant lindexeur AltaVista (http://www.altavista.com/) de Digital Equipment Corporation (vous pouvez aussi essayer Yahoo, Lycos, Exite, etc.). Quelques conseils pour dbuter : 1. Ne pas interroger avec un mot trop vague ou trop commun : la recherche avec le mot cl Java retourne plus de 8 millions de liens (seulement 200000 liens en juin 96). 2. Cadrer la recherche avec un mot dsignant un domaine : java AND scurit ne retourne plus que 85 liens. 3. Utiliser les possibilits de tri (terme, liste des liens retourns). 4. Commencer inspecter la liste des liens, tester les liens.

Javabook Page 37 Lundi, 12. juillet 1999 3:58 15

Chercher de linformation sur Java

37

5. Si un nud (ou une liste des liens retourns) vous intresse, sauvez son URL dans une liste de rfrence (bookmark). 6. Recommencer avec des mots proches ou contraires (Java AND virus). 7. Si vous dsirez avoir des liens en franais, introduisez au moins un mot en franais (Java AND programmation). 8. Recommencez rgulirement vos recherches, la frquence dpendant de la vitesse dvolution du domaine (semaine, mois, trimestre, etc.).

Figure 3.1 Recherche laide de lindexeur AltaVista, lpoque o il tait sans publicit!

Javabook Page 38 Lundi, 12. juillet 1999 3:58 15

Javabook Page 39 Lundi, 12. juillet 1999 3:58 15

Partie II

Le langage
Telles des chvres en dtresse, sept Mercedes-Benz vertes, les fentres crpes de reps grge, descendent lentement West End Street et prennent snestrement Temple Street vers les vertes venelles semes de htres et de frnes prs desquelles se dresse, svelte et empes en mme temps, lvch dExeter. Prs de lentre des thermes des gens sempressent. Quels secrets reclent ces fentres scelles? G. Perec, Les Revenantes.

4. Les bases 5. Les structures de contrle 6. Une introduction aux objets 7. Les structures 8. Exceptions et processus

Javabook Page 40 Lundi, 12. juillet 1999 3:58 15

Javabook Page 41 Lundi, 12. juillet 1999 3:58 15

Chapitre 4

Les bases
Pour apprendre un langage, deux approches peuvent tre suivies : la premire, des concepts vers la syntaxe et la seconde, de la syntaxe vers les concepts. Nous avons choisi de suivre cette dernire car elle permet de partir de notions dj rencontres dans dautres langages de programmation et de nous amener un stade o il devient possible de construire des exemples intressants laide de notions dj expliques. De plus, en partant des bases, il est possible de faire rapidement tat des diffrences existant avec dautres langages tels que C ou C++ (voir ce propos lannexe A).

Littraux, types, expressions, instructions


Nous allons examiner la syntaxe des littraux et des types ainsi que les expressions et la structure des primitives indispensables la dfinition des algorithmes. Avant dexaminer comment programmer, il importe de savoir commenter le programme.

4.1 Commentaires
Trois styles de commentaires sont disponibles en Java. Le plus connu est celui qui provient du C, o le commentaire est encadr par /* et */.
/* ceci est un commentaire sur plusieurs lignes ... qui se termine ici */

Javabook Page 42 Lundi, 12. juillet 1999 3:58 15

42

Chapitre 4 Les bases

Le second provient de C++ et permet de placer un commentaire sur la mme ligne quune instruction. Dans ce cas, le commentaire commence par //.
int i // voici une variable entire

Enfin, le troisime style consiste encadrer le commentaire avec /** et */. Cette forme est utiliser uniquement dans les dclarations : elle est reconnue par un gnrateur automatique de documentation (JavaDoc). Le tableau 4.1 cidessous illustre ces trois styles de commentaires.
Style
/* commentaire */ // commentaire /** commentaire */

Dfinition Tous les caractres compris entre /* et */ sont ignors. Tous les caractres compris entre les // et le retour de la ligne sont ignors. Tous les caractres compris entre /** et */ sont ignors par le compilateur mais peuvent tre traits par des outils de documentation automatique.

Tableau 4.1 Styles de commentaires

Bonnes habitudes : il faut commenter les programmes


Noubliez pas quun programme est crit une seule fois, mais quil sera relu des dizaines de fois, par vous-mme et par dautres. Les commentaires doivent tre une reformulation de la spcification du programme. Il faut donc viter les commentaires qui se font simplement lcho de linstruction. Exemple :
int zoom=2 // zoom 2

Ce commentaire ne donne aucun renseignement sur le rle de zoom et sur le choix de la valeur 2.
int zoom=2 // valeur par dfaut du zoom au dmarrage

Ce dernier lui est nettement prfrable. Nous allons maintenant examiner comment nommer prcisment les objets de nos programmes.

4.2 Identificateurs
Les identificateurs permettent de nommer les diffrents lments (variables, classes, mthodes, packages, etc.) des programmes Java.
identifier = "dans {a..z, A..Z, $, _}" < " dans {a..z, A..Z,$,_,0..9,unicode character over 00C0}" >

La rgle de nommage ci-dessus indique que le premier caractre doit tre une

Javabook Page 43 Lundi, 12. juillet 1999 3:58 15

Identificateurs

43

lettre minuscule ou une lettre majuscule, ou encore le caractre soulign _ ou le caractre dollar $. Les caractres suivants (ds le second) peuvent tre soit : des caractres a..z ou A..Z; le _ ou le $; des chiffres de 0 9; les caractres Unicode (voir [13]) suprieurs 0X00C0, permettant dintroduire dans les identificateurs des caractres nationaux tels que , , etc. ( lexclusion cependant des caractres de contrle). Exemples didentificateurs valides en Java :
$valeur_system dateDeNaissance ISO9000

Exemples didentificateurs non valides en Java :


a 9neuf note# long // // // // comme premier caractre 9 comme premier caractre # pas au dessus de 0X00C0 OK mais cest un mot rserv!

long est bien form selon les rgles nonces ci-dessus, mais il appartient la
liste des mots rservs du langage Java (voir tableau 4.2). En effet, en Java comme dans les autres langages de programmation, un certain nombre de mots sont rservs la construction des instructions. Ds lors, un identificateur ne doit pas tre choisi dans cette liste.
abstract case continue extends goto3 int null return synchronized true boolean catch default false if interface package short this try break char do finally implements long private static throw void byte class double float import native protected super throws while byvalue1 const2 else for instanceof new public switch transient

Tableau 4.2 Liste des mots rservs en Java


1. 2. 3. Mot rserv mais pas utilis actuellement. Idem. Idem.

Javabook Page 44 Lundi, 12. juillet 1999 3:58 15

44

Chapitre 4 Les bases

Bonnes habitudes : choix des identificateurs


Nous suggrons de ne pas employer le $ et le _ si vous devez utiliser des librairies en C, de ne pas utiliser le $ en premire position, de sparer les noms composs en mettant en capitale la premire lettre des noms partir du deuxime mot. Le tableau 4.3 illustre ces diffrentes suggestions laide dexemples.
Conseill
nomDeMethode ceciEstUneVariable

Acceptable
nom_de _methode ceci_est_une_variable

Dconseill
$init _type

Tableau 4.3 Choix des identificateurs

4.3 Littraux
Les littraux dfinissent explicitement les valeurs sur lesquelles travaillent les programmes Java. Ils sont intimement lis aux types des variables qui les contiennent. Java supporte trois catgories de littraux : les boolens, les nombres (entiers et flottants) et les caractres.

Diagramme 4.1 literal_expression1

Boolens
Les mots cls false et true dfinissent respectivement les valeurs de vrit faux et vrai. Ils permettent essentiellement dinitialiser des variables boolennes. noter que la valeur dune variable boolenne est toujours associe lun de ces deux littraux et ne peut pas tre assimile un 0 ou un 1 comme dans le cas des langages C ou C++ (voir p. 421).
boolean resultatAtteint = false ; boolean continuer = true ;

Le code ci-dessus dclare deux variables boolennes et initialise leur valeur.

1.

Les diagrammes syntaxiques que nous utilisons ont t tablis partir des spcifications du langage publies par Sun. Nous avons prfr conserver les termes anglais originaux pour dsigner les lments syntaxiques.

Javabook Page 45 Lundi, 12. juillet 1999 3:58 15

Littraux

45

Entiers
Lexpression des nombres entiers peut se faire dans trois formats : en dcimal, en octal et en hexadcimal.

Diagramme 4.2 integer_literal

Lentier exprim en dcimal ne commence jamais par un zro. Cela est extrmement important pour viter des erreurs.
int nbrDeMois = 12;

Pour exprimer un entier en octal, il suffit de le faire prcder dun zro.


int nbrDeDoigts = 012; // = 10 en dcimal

Enfin, pour exprimer un entier en hexadcimal, il suffit de le faire prcder dun zro suivi dun X minuscule ou majuscule.
int dixHuit= 0x12;

Les nombres entiers dclars littralement correspondent au type entier int sur 32 bits. On peut forcer un entier prendre le type entier long en le faisant suivre dun L minuscule ou majuscule; il stend alors sur 64 bits.

Flottants
Le littral flottant est utilis pour dfinir des valeurs dcimales. Il comporte une mantisse et ventuellement une partie exposant exprime en puissances de 10. Un nombre flottant doit obligatoirement avoir un point dcimal ou une partie exposant (sinon rien ne le distingue dun nombre entier). Les diagrammes syntaxiques 4.3et 4.4expriment ces diffrentes possibilits.

Diagramme 4.3 float_literal

Javabook Page 46 Lundi, 12. juillet 1999 3:58 15

46

Chapitre 4 Les bases

Diagramme 4.4 decimal_digits

Exemples de flottants sans partie exposant :


2. .5 2.5 2.0 .001

La partie exposant est prfixe par un E minuscule ou majuscule suivi de la valeur de lexposant (voir diagramme 4.5). Exemples de flottants avec partie exposant :
2E0 2E3 2E-3 .2E3 2.5E-3

Diagramme 4.5 exponent_part

Les nombres flottants dclars littralement correspondent au type flottant double sur 64 bits. On peut forcer un flottant prendre le type float en lui faisant succder un F minuscule ou majuscule; il stend alors sur 32 bits. On peut galement forcer un flottant prendre le type flottant double prcision en lui faisant succder un D minuscule ou majuscule ; il stend alors sur 64 bits (diagramme 4.6) :
3.14F 3.14159D

Diagramme 4.6 float_type_suffix

Caractres
Le littral dun caractre est un caractre entour de deux apostrophes : Il peut tre choisi dans lensemble des caractres Unicode. Le tableau 4.4 ci-dessous montre les caractres de contrle les plus courants ainsi que leur squence de codification.
Caractre Continuation Abrviation <nouvelle ligne> Squence
\

'x'

'a'

'4'

Tableau 4.4 Caractres de contrle

Javabook Page 47 Lundi, 12. juillet 1999 3:58 15

Littraux
Caractre Nouvelle ligne Tabulation Retour arrire Retour chariot Saut de page Backslash Apostrophe Guillemet Caractre octal Caractre hexadcimal Caractre Unicode Abrviation N HT BS CR FF \ ' " 0377 0xFF 0xFFFF Squence
\n \t \b \r \f \\ \' \" \377 \xFF \uFFFF

47

Tableau 4.4 Caractres de contrle

Chanes de caractres
Les chanes de caractres sont formes dune suite de caractres entoure de guillemets (voir diagramme 4.7); elles sont associes au type String. En Java, le type String constitue une classe part entire et ne doit pas tre confondu avec un vecteur de caractres. Le tableau 4.5 montre diffrents exemples de chanes de caractres et le rsultat de leur impression.

Diagramme 4.7 String Chane de caractres


"" "\"" "texte sur une ligne" "texte sur \ndeux lignes" "\ttabul" " texte sur une ligne texte sur deux lignes tabul

Rsultat de limpression

Tableau 4.5 Exemples de Strings

Javabook Page 48 Lundi, 12. juillet 1999 3:58 15

48

Chapitre 4 Les bases

4.4 Dclaration des variables


Lutilisation dune variable dans Java doit toujours tre prcde par la dclaration de celle-ci. Le compilateur va utiliser les informations associes la dclaration de la variable pour effectuer des vrifications : compatibilit de type dans les expressions, visibilit de la variable, etc. Cela peut sembler coteux en temps, mais cest une manire damliorer la qualit des programmes. En effet, le compilateur dtectera des erreurs la compilation qui, sinon, ne le seraient quau moment de lexcution.

Diagramme 4.8 variable_declaration

La dclaration dune variable (diagramme 4.8) seffectue en prfixant le nom de la variable par son type (par exemple int pour un entier) :
int i;

La dclaration dun ensemble de variables du mme type seffectue en prfixant le nom des variables par leur type : Le diagramme 4.8montre galement que lon peut ajouter un modificateur (modifier) la dfinition dune variable. Par exemple, le modificateur final prcise que la valeur de la variable ne pourra plus tre change aprs son affectation initiale : cest ainsi que lon dfinit une constante. Nous examinerons plus en dtail ces diffrents modificateurs lorsque nous traiterons des classes (point 7.5, p. 100).
final int NbreDeRoues=4; final float pi=3.14159; int i,j,k;

Dans les exemples ci-dessus, on constate que lon peut affecter une valeur une variable lors de sa dclaration; le diagramme 4.9indique cette possibilit.

Diagramme 4.9 variable_declarator

Revenons sur la notion de type. Il existe deux catgories de types : les types simples comme les boolens, les entiers, etc., qui sont considrer comme des types primitifs car ils ne sont pas construits partir dautres types;

Javabook Page 49 Lundi, 12. juillet 1999 3:58 15

Dclaration des variables

49

les types composs qui sont construits partir dautres types comme les vecteurs, matrices, classes ou interfaces. Les diagrammes 4.10et 4.11illustrent la dfinition des types en Java.

Diagramme 4.10 type

Diagramme 4.11 type_specifier

Nous allons maintenant examiner les types simples et le type vecteur.

Boolens
Une variable boolenne pourra contenir lune des valeurs vrai ou faux. Cette variable pourra tre assigne par les littraux true ou false et elle pourra recevoir le rsultat dune expression logique :
boolean voitureArretee=true; voitureArretee = (vitesse < 1);

Entiers
Il existe quatre types dentiers : byte, short, int et long. Chacun diffre par la taille des entiers quil peut reprsenter, exprime en nombre de bits (voir tableau 4.6).
Type
byte short int long

Nbre de bits
8 16 32 64

Exemple
byte NbrEnfant; short VolumeSon; int i,j,k; long detteSecu;

Tableau 4.6 Les types dentiers

Javabook Page 50 Lundi, 12. juillet 1999 3:58 15

50

Chapitre 4 Les bases

La dclaration dune variable entire permet de reprsenter un nombre entier limit par le nombre de bits de sa reprsentation. Cette variable pourra tre assigne par les littraux entiers et recevoir le rsultat dune expression entire.

Flottants
Il existe deux types de flottants : float et double. Chacun diffre par la taille de sa reprsentation exprime en nombre de bits (voir tableau 4.7).
Type
float double

Nbre de bits
32 64

Exemple
float ageMoyen; double pi;

Tableau 4.7 Les types de flottants

Une variable flottante pourra contenir un nombre flottant limit par le nombre de bits de sa reprsentation. Cette variable pourra tre assigne par les littraux flottants et recevoir le rsultat dune expression flottante.

Caractres
La dclaration dune variable caractre permet de reprsenter une valeur dfinie sur lensemble des caractres Unicode. Cette variable pourra tre assigne par des littraux caractres et recevoir le rsultat dune expression caractre.
char separateur=\t; // le sparateur est un tabulateur

Un caractre est reprsent sur 16 bits en Java. Il sert conserver la valeur dun seul caractre. Les chanes de caractres quant elles sont reprsentes par la classe String (voir le point Chanes de caractres , p. 47).

Vecteurs et matrices
Les vecteurs, galement appels tableaux, sont dclars en postfixant le type ou la variable par [ ] :
int i[ ]; // vecteur dentiers int[ ] j; // autre notation pour le mme type que i char motsCroises[ ][ ]; // une matrice de caractres

On remarquera que les vecteurs ne sont pas contraints par des bornes au moment de leur dclaration. Lallocation de lespace ncessaire au vecteur se fera explicitement au moyen dune mthode new qui sera prsente dans le prochain chapitre (voir p. 61). On peut cependant allouer de lespace au vecteur et linitialiser lors de la dclaration :
int f[ ] = {1, 1, 2, 3*t, 5, 8, u-13, 21}; double[ ][ ] e1 = {{0.0, 1.0}, {-1.0, 0.0}};

Javabook Page 51 Lundi, 12. juillet 1999 3:58 15

Porte des variables

51

4.5 Porte des variables


Lemplacement de la dclaration dune variable dfinit lespace de visibilit (la porte) de celle-ci. Ainsi, une variable est visible lintrieur du bloc o elle est dclare. Un bloc (voir p. 66) est dfini comme un ensemble dinstructions comprises entre deux accolades { }.
class Test { // debut de test public static void principal(String args[]) { // debut de principal float x ... } // fin de principal public void methodeA () { // debut de methodeA char c ... } // fin de methodeA } // fin de principal

Test principal x methode c Figure 4.1Visibilit dune variable

Dans le programme Test ci-dessus, les variables x et c ne sont visibles que dans leur bloc respectif. Ainsi, dans le bloc de methodeA, il nest pas possible daccder la variable x. La figure 4.1 illustre lespace de visibilit des variables x et c. Examinons maintenant le cas des blocs imbriqus et celui de la redfinition dune variable. Lorsque des blocs sont imbriqus, les variables dfinies un niveau suprieur sont visibles depuis les sous-blocs. Toutefois, si dans un sous-bloc on redfinit une variable visible dans un bloc suprieur, cette nouvelle variable masque la variable suprieure lintrieur du sous-bloc (et de ses propres sousblocs). Voyons cela laide dun exemple :
class Test { // debut de test public static void principal(String args[]) { // debut de principal float echange; int a,b; ... if a < b then { int echange;

Javabook Page 52 Lundi, 12. juillet 1999 3:58 15

52
echange=a;a=b;b=echange }; } // fin de principal public void methodeA () } // fin de principal

Chapitre 4 Les bases

Test principal
a, b, echange

bloc du if
echange

Figure 4.2Visibilit dune variable dans un sous-bloc

Dans le bloc du if, a et b rfrencent les variables du bloc principal, alors que echange rfrence la variable locale echange du bloc (voir figure 4.2). La redfinition des variables est destine des variables temporaires utilises lintrieur dun bloc, comme par exemple lindice dune boucle.

4.6 Oprateurs
Les oprateurs sont regroups par types doprations : numriques, comparaisons, logiques, manipulations de chanes de caractres, manipulations binaires. Leur classification se base sur le nombre doprandes quils ncessitent : 1 (unaire), 2 (binaire) et mme 3 (ternaire).
Prcdence des oprateurs (de la plus grande la plus petite) Les oprateurs de mme niveau sont valus depuis la gauche
. ++ * + << < == & ^ != >> > >>> <= >= [] -/ % () ! ~ instanceof

Tableau 4.8 Prcdence des oprateurs

Javabook Page 53 Lundi, 12. juillet 1999 3:58 15

Oprateurs
Prcdence des oprateurs (de la plus grande la plus petite) Les oprateurs de mme niveau sont valus depuis la gauche
&& || ?: = , op=

53

Tableau 4.8 Prcdence des oprateurs

Les expressions composes sont values de la gauche vers la droite, une table de prcdence (voir tableau 4.8) indiquant la priorit entre les oprations. Prenons comme exemple lexpression suivante :
x=z+w-y/(3*y^2)

Pour cette expression, lordre de lecture (de la gauche vers la droite) est :
= + / ()

La table de prcdence nous donne lordre dexcution suivant :


() / + =

lintrieur des parenthses (), nous avons * ^ par ordre de lecture de mme que par ordre dexcution.

Assignation
Loprateur dassignation est le symbole "=". Lassignation affecte lexpression place droite de loprateur lexpression (une variable) place gauche de celui-ci. Il est intressant de constater que, dans Java, lassignation est considre comme un oprateur binaire qui modifie son oprande gauche.
j=2; i=j*3; i=j*3(j=2); // expression dassignation dun litral // expression dassignation dune expression // expression valide combinant les deux formes

noter que cette dernire expression a pour rsultat : i=6.

Trois autres oprateurs ont des effets de bord : ~, ++ et --. Lutilisation combine de ces oprateurs dans une mme expression risque den rendre la lecture confuse. On essayera donc de dcomposer les expressions afin quelles ne contiennent chacune quun seul oprateur avec effet de bord.

Javabook Page 54 Lundi, 12. juillet 1999 3:58 15

54

Chapitre 4 Les bases

Expressions numriques
Les expresssions numriques sont classiques. Cependant quelques raccourcis syntaxiques sont connatre pour allger le code.

Diagramme 4.12 numeric_expression Oprateur


++ --

Action Ngation Incrmentation de 1 Dcrmentation de 1

Exemple
i=-j; i++; i--;

Tableau 4.9 Oprateurs numriques unaires Diagramme 4.13

On voit que ++ et -- peuvent prfixer ou postfixer la variable. Exemple :


++i; // est quivalent i++;

Oprateur
+ += -= *

Action Addition

Exemple
i=j+k i+=2; //i=i+2

Soustraction

i=j-k; i-=j; //i=i-j

Multiplication

x=2*y

Tableau 4.10 Oprateurs numriques binaires

Javabook Page 55 Lundi, 12. juillet 1999 3:58 15

Oprateurs
Oprateur
*= / /= % %=

55
Action Exemple
x*=x; //x=x*x

Division (tronque si les arguments sont entiers)

i=j/k; x/=10; //x=x/10

Modulo

i=j%k; i%=2; //i=i%2

Tableau 4.10 Oprateurs numriques binaires

Pour les nombres entiers, les rgles suivantes sont appliques (voir diagramme 4.12, tableaux 4.9 et 4.10) : la division par 0 et le modulo par 0 gnrent une exception lexcution; les oprations dont la reprsentation dpasse la valeur maximum du type de lentier dbordent dans les entiers ngatifs. Pour les nombres flottants, les oprations ont la mme smantique : pour les incrmentations et dcrmentations, on ajoute la valeur 1.0; le % (modulo) appliqu un flottant prend le sens de la division dans les entiers; la division par 0 et le modulo par 0 gnrent la valeur inf; les oprations dont la reprsentation dpasse la valeur maximum du type gnrent la valeur inf tandis que les dbordements vers linfiniment petit gnrent 0. Le programme TestNumber illustre le cas o lon approche du maximum de la reprsentation pour les entiers et les flottants.
class TestNumber{ public static void main (String args[]) { int i=1000, j=1000; float x=1, y=1; for (int k=0; k<100;k++) { i*=10; j/=10; x*=10000; y/=10000; System.out.println("\ni="+i+" j="+j+" x="+x+" y="+y); } } } i=10000 j=100 x=10000 y=0.0001

Javabook Page 56 Lundi, 12. juillet 1999 3:58 15

56
i=100000 i=1000000 i=10000000 i=100000000 i=1000000000 i=1410065408 i=1215752192 i=-727379968 i=1316134912 i=276447232 i=-1530494976 i=1874919424 j=10 j=1 j=0 j=0 j=0 j=0 j=0 j=0 j=0 j=0 j=0 j=0 x=1e+08 x=1e+12 x=1e+16 x=1e+20 x=1e+24 x=1e+28 x=1e+32 x=1e+36 x=Inf x=Inf x=Inf x=Inf

Chapitre 4 Les bases


y=1e-08 y=1e-12 y=1e-16 y=1e-20 y=1e-24 y=1e-28 y=1e-32 y=1e-36 y=9.99995e-41 y=9.80909e-45 y=0 y=0

4.7 Oprateurs relationnels


Les oprateurs relationnels permettent de tester tous les types de valeurs sur lesquels une relation dordre a t dfinie : les entiers, les rels, les caractres, etc. Le diagramme 4.14 et le tableau 4.11 dcrivent la syntaxe et donnent un exemple de chacun des oprateurs relationnels.

Diagramme 4.14 testing_expression Oprateur


< > <= >= == !=

Action Plus petit que Plus grand que Plus petit ou gal Plus grand ou gal Egal Diffrent de

Exemple
x<i; i>100; j<=k; c>=a; i==20; c!=z;

Tableau 4.11 Oprateurs relationnels

En ce qui concerne la relation dordre sur les nombres flottants, la prudence simpose, car x==y peut tre vrai sans que y<x || y>x soit forcment vrai. Il faut galement rester vigilant avec loprateur == qui peut tre confondu dans un programme avec =. Mais, contrairement ce qui se passe en langage C, cette erreur est dtecte par le compilateur.

Javabook Page 57 Lundi, 12. juillet 1999 3:58 15

Oprateurs relationnels

57

Oprateurs logiques
Les oprateurs logiques traitent des oprandes dont la valeur est boolenne. Les quatre oprateurs de base sont : la ngation (!), le ET (&), le OU (|), le OU exclusif (^). Le tableau 4.12 prsente ces oprateurs et le rsultat de leur application sur des oprandes logiques (p et q). Le diagramme 4.15et le tableau 4.13 dcrivent lensemble complet des oprateurs logiques.
p
v v f f

q
v f v f

!p
f f v v

p&q
v f f f

p|q
v v v f

p^q
f v v f

Tableau 4.12 Table de vrit des oprateurs logiques

Pour chaque oprateur logique (sauf pour la ngation), on trouve une forme assigne o la variable affecte est aussi loprande de gauche de loprateur. Ainsi :
p&=(i=10); // est quivalent p=p&(i=10)

On trouve aussi pour le ET et le OU une version avec valuation raccourcie, dont les symboles sont respectivement && et ||. Dans ce cas, lvaluation de lexpression logique est stoppe ds la dtermination certaine de sa valeur de vrit. Ainsi, dans :
p1 && p2 && ... & pn

lvaluation est stoppe ds quune expression pi svalue false. De mme, dans :


p1 || p2 || ... || pn

lvaluation est stoppe ds quune expression pi retourne true. Ce mcanisme permet aussi dviter dvaluer des expressions qui pourraient gnrer une erreur, comme dans lexemple suivant o une division par 0 est vite :
(i!=0) && (x > ( y/i)); // y/i nest pas valu si i gale 0

Java possde galement une expression ternaire de la forme :


p?e1:e2;

Dans ce cas, si p est vrai alors lexpression e1 est value, sinon e2 est value. Cette forme, du fait que lassignation est considre comme une expression, peut tre utilise comme une instruction if. Exemple :
p?e1:e2; // est quivalent if (p) e1; else e2;

Javabook Page 58 Lundi, 12. juillet 1999 3:58 15

58

Chapitre 4 Les bases

Diagramme 4.15 logical_expression Oprateur


! & | ^ && || != &= |= ?:

Action Ngation ET OU OU exclusif ET valu OU valu Ngation assigne ET assign OU assign Si alors sinon

Exemple
!p; p & (i<10) p | q p ^ false p && q && r p || q || r p!=p; p&=q p|=q // p= p & q // p= p | q

(i<10)?(j=2):(j=3)

Tableau 4.13 Les oprateurs logiques

Enfin, ajoutons encore que les oprateurs !, &, |, et ^ sont tendus des oprations de manipulation binaire sur les bits de la reprsentation des oprandes entiers. Ces oprateurs appliquent ainsi la table de vrit chaque bit dun entier, substituant false 0 et true 1.

Oprateurs sur les chanes de caractres


La concatnation est lopration que lon effectue avec les chanes de caractres. Cette opration ajoute la seconde chane la fin de la premire.

Javabook Page 59 Lundi, 12. juillet 1999 3:58 15

Oprateurs de manipulation binaire

59

Les oprandes qui ne sont pas des chanes de caractres sont automatiquement convertis. La concatnation de chanes de caractres est dcrite par le diagramme 4.3 et le tableau 4.14. Nous avons dj utilis cet oprateur plusieurs reprises dans des instructions dimpression telles que :
System.out.println("\ni="+i+" j="+j+" x="+x+" y="+y);

o les variables i, j, x, y sont automatiquement converties en chanes de caractres.

Diagramme 4.16 string_expression Oprateur


+ +=

Action Concatnation Ajoute la fin

Exemple
"conca"+"tnation"; s+=" la fin";

Tableau 4.14 Oprateurs de concatnation

4.8 Oprateurs de manipulation binaire


En plus des manipulations directes ralises par les oprateurs logiques (!, &, |, et ^), il est possible deffectuer des dcalages (vers la droite ou la gauche) sur des reprsentations binaires (voir diagramme 4.17 et tableau 4.15). Il sagit doprateurs deux oprandes, le premier tant la valeur binaire sur lequel on effectue le dcalage, le deuxime indiquant le nombre de dcalages effectuer. On a ainsi :
i>>k; // dcaler i vers la droite de k bits avec son signe i<<k; // dcaler i vers la gauche de k bits i>>>k; // dcaler i vers la droite de k bits sans signe

Ces oprateurs ont une version assigne qui permet daffecter directement le rsultat dun dcalage effectu sur une variable celle-ci.

Diagramme 4.17 bit_expression

Javabook Page 60 Lundi, 12. juillet 1999 3:58 15

60
Oprateur
<< >> >>> <<= >>= >>>=

Chapitre 4 Les bases


Action Dcalage gauche Dcalage droite sign Dcalage droite non sign Dcalage gauche assign Dcalage droite sign assign Dcalage droite non sign assign Exemple
i<<n; i>>4; i>>>2; k<<=n; k>>=n; k>>>=n;

Tableau 4.15 Oprateurs de manipulation binaire

Il est intressant de noter les quivalences suivantes (tableau 4.16) entre les oprations de manipulation binaire et les oprations arithmtiques sur les entiers. Pour un nombre entier i, on a :

Oprateur binaire
~i i>>k i<<k i>>>k i>>>k

Oprateur arithmtique
(-i)-1 i/2 i*2 i/2 k k k

Condition

si i>0

si i>0 si i<0

(i<<k)+(2<<(L-k-1)

avec L=32 avec L=64

si i est int si i est long

Tableau 4.16 Correspondances entre oprateurs binaires et arithmtiques

4.9 Oprateur dallocation


Loprateur dallocation new (voir diagramme 4.18) sert la cration dans deux cas distincts. Dans le premier, il sagit de crer un objet, instance dune classe spcifie dans lexpression; nous traiterons ce cas lorsque nous approfondirons le concept de classe en Java (chapitre 6, page 77). Dans le second cas, il sagit de crer et de fixer les dimensions de vecteurs ou de matrices. Nous avons vu prcdemment comment dclarer un vecteur (voir Vecteurs et matrices , p. 50). Pour fixer la taille dun vecteur, on utilise la syntaxe suivante :

Javabook Page 61 Lundi, 12. juillet 1999 3:58 15

Conversions de types

61

int i[] = new int [100]; // i un vecteur de 100 entiers int c[][] = new char[10][10]; // c une matrice de 10x10 caractres

Les indices des vecteurs et des matrices commencent 0, ce qui signifie que la valeur maximum dun indice sera dimension du vecteur 1 :
i[0] = 1; i[9] = 10; c[0][0]=a; c[9][9]=z; // // // // la premire position de i est initialise 1 la dernire position de i est initialise 10 premire case de c dernire case de c

Pour un type ayant plusieurs dimensions, seule la premire dentre elles doit obligatoirement tre fixe au moment de lallocation :
int c[][] = new char[10][]; // c une matrice de 10 par ?

Les autres dimensions peuvent tre dclares ultrieurement :


c[0] = new char [24]; // premire ligne de c = 24 caractres

Des dimensions diffrentes peuvent trs bien exister dans la mme variable :
c[1] = new char [12]; // deuxime ligne de c = 12 caractres

Dune manire gnrale, lallocation dune variable de dimension n peut tre vue comme une srie de n-1 boucles imbriques effectuant chacune une allocation :
int c[][] = new char[10][10]; // est quivalent : int c[][] = new char[10][]; // allocation de la matrice c (10 lignes) for (int i=0; i< c.length; i++) c[i] = new char [10]; //allocation de chaque ligne de c

Diagramme 4.18 creating_expression

Nous reviendrons plus prcisment sur les mcanismes dallocation et sur la gestion de la mmoire en Java au point 6.2.

4.10 Conversions de types


Il arrive frquemment que lon ait besoin de la valeur dun lment exprime dans un type diffrent. On aimerait par exemple connatre la valeur entire dun

Javabook Page 62 Lundi, 12. juillet 1999 3:58 15

62

Chapitre 4 Les bases

caractre ou utiliser un entier en tant que flottant. Pour effectuer ce genre doprations, il faut faire appel la conversion de types. Il y a deux catgories de conversions : les largissements, qui conservent les valeurs, avec une ventuelle perte de prcision et les rtrcissements, qui peuvent compltement modifier les valeurs. Le rtrcissement se prsente lorsquon convertit vers un type moins tendu que le type de dpart. Par exemple, il est vident que les 64 bits dun long ne pourront pas tenir dans les 8 bits dun byte. Dans ce cas il y a troncature, seuls les 8 bits les moins significatifs sont conservs. Une conversion de rtrcissement doit tre indique explicitement laide de loprateur de casting (<type>).

Diagramme 4.19 casting_expression

Llargissement ne ncessite aucune notation particulire. Llargissement dun entier un flottant peut faire perdre de la prcision lorsque la mantisse du type flottant est plus courte que le nombre de bits de lentier. Voici quelques exemples de conversions :
int i; i == (int) ((float) i); // nest pas toujours vrai // Rtrcissement avec troncation ncessaire int a = 911000; byte ba = (byte)a; // rsultat: ba =-104 short sa = (short)a; // rsultat: sa = -6504 // Rtrcissement sans troncation a = 66; char ca = (char)a; // rsultat: ca = 'B' (66 = code Unicode de 'B') ba = (byte)a; // rsultat: ba = 66 // Rtrcissement dun flottant double d = 7.7e+204; int a = (int)d; // rsultat: a = 2147483647 (le plus grand entier) d = 6789.6789; a = (int)d; // rsultat: a = 6789 (arrondi) // Elargissement dun entier a = 2111222333; float f = a; // rsultat: f = 2.11122227e+9 (perte de prcision) double d = a; // rsultat: d = 2.111222333e+9 (pas de perte de prcision)

Javabook Page 63 Lundi, 12. juillet 1999 3:58 15

Conversions de types

63

Le tableau 4.17 ci-dessous numre les conversions autorises (oui), autorises mais pouvant causer une perte de prcision (perte) et celles ncessitant une conversion explicite ().
De \ byte short int long float double char byte oui () () () () () () short oui oui () () () () () int oui ou oui () () () oui long oui oui oui oui () () oui float oui oui perte perte ou () oui double oui oui oui perte oui oui oui char oui () () () () () oui

Tableau 4.17 Conversions entre types

Javabook Page 64 Lundi, 12. juillet 1999 3:58 15

Javabook Page 65 Lundi, 12. juillet 1999 3:58 15

Chapitre 5

Les structures de contrle


Nous avons examin les types, les variables et les expressions. Nous sommes maintenant capables dnoncer une liste dactions squentielles effectuer sur des variables. Un programme ne pouvant malheureusement pas se rduire une squence, il nous faut maintenant ajouter les diffrentes structures de contrle : le si_alors, le faire_tantque, le tantque_faire, le dans_le_cas. Avant de poursuivre, le diagramme 5.1rsume la syntaxe de toutes les instructions (statements).

Diagramme 5.1 statement

Javabook Page 66 Lundi, 12. juillet 1999 3:58 15

66

Chapitre 5 Les structures de contrle

5.1 Bloc dinstructions


Un bloc dinstructions est contenu entre accolades {} (voir diagramme 5.2). Il dfinit la visibilit des variables qui y sont dclares. chaque fois que dans une rgle du langage Java on parle dinstruction, on sous-entend bloc dinstructions si lon doit en dcrire plusieurs.

Diagramme 5.2 statement_block

5.2 Excution conditionnelle


Lexcution conditionnelle dinstructions est la structure de base de la programmation. Il existe deux types dexcution conditionnelle en Java : si_alors_sinon (if then else); dans_le_cas (switch). Nous allons nous attarder quelque peu sur les diffrentes formes prises par ces expressions et les illustrer laide dexemples.

Si_alors_sinon (if then else)


Ce type dexcution conditionnelle (voir diagramme 5.3) est le plus utilis, permettant dexprimer de nombreux cas dalternatives. Lexpression de test place entre () doit toujours tre une expression boolenne (svaluant true ou false).

Diagramme 5.3 if_statement

Les deux formes suivantes peuvent tre employes : if (e) S1; linstruction S1 est excute si e est vraie :
if (i==1) s=" i est gal 1 ";

if (e) S1 else S2; linstruction S1 est excute si e est vraie. Linstruction S2 est excute si e est fausse:
if (i==1) s=" i est gal 1 "; else s=" i est diffrent de 1 ";

De ces deux formes, nous pouvons driver : if (e) {B1}; le bloc B1 est excut si e est vraie :
if (i==1) { s=" i est gal 1 ";

Javabook Page 67 Lundi, 12. juillet 1999 3:58 15

Excution conditionnelle
i=j; }

67

if (e) {B1} else {B2}; le bloc B1 est excut si e est vraie. Le bloc B2 est excut si e est fausse :
if (i==1) { s=" i est gal 1 "; i=j; } else { s=" i est diffrent de 1 "; i=1515; }

if (e1) S1 else if (e2) S2 ... else Sn; cest une cascade de si_alors. Linstruction Si est excute si ei est vraie et que toutes les expressions testes auparavant sont fausses :
if (i==1) s=" i est gal 1 "; else if (i==2) s=" i est gal 2 "; else if (i==3) s=" i est gal 3 "; else s=" i est diffrent de 1,2 et 3 ";

Cette dernire forme nous amne recommander une certaine prudence dans lutilisation de si_alors en cascade. Ainsi, dans lexemple ci-dessus, la dernire clause else se rapporte au dernier si_alors. Dans de tels cas, lutilisation de {} est ncessaire pour bien marquer le dbut et la fin des instructions, comme le montre cet exemple :
i=0; j=3; if (i==0) if (j==2) s=" i est gal 2 "; else i=j; System.out.println(i);

Que va imprimer le programme ci-dessus : 0 ou 3? Il va imprimer 3, car i==0 et j!=2, donc on excute i=j. Le else se rapporte en effet au if le plus imbriqu.

Au cas o (switch)
Linstruction switch se comporte comme un aiguillage, excutant des instructions diffrentes (clauses case) suivant le rsultat dune expression. Pour cela, elle commence par valuer lexpression qui lui est lie puis elle compare la valeur retourne avec celle de chaque expression lie aux case. Dans le cas o il y a galit, elle commence excuter le code li ce case, puis excute toutes les instructions des cas suivants.

Javabook Page 68 Lundi, 12. juillet 1999 3:58 15

68

Chapitre 5 Les structures de contrle

Si lon dsire isoler chaque clause case, il faut terminer son code avec un break. Si aucun cas dgalit nest trouv et quune clause default est spcifie, alors on excute cette clause. Du point de vue syntaxique, les symboles case et default sont considrs comme des tiquettes (voir diagramme 5.4). Examinons la forme gnrale de switch sans break :
switch (e) { case c1: S1; case c2: S2; ... case cn: Sn; default: Sd };

Si lexpression e est value la valeur ci, alors les instructions Si, Si+1, ... Sn, Sd sont excutes. Si lexpression e est diffrente de tous les ci, alors on excute lexpression Sd. Examinons la forme gnrale de switch avec break :
switch (e) { case c1: S1 break; case c2: S2 break; ... case cn: Sn break; default: Sd };

Si lexpression e est value la valeur ci, alors linstruction Si est excute. Si lexpression e est diffrente de tous les ci, alors on excute lexpression Sd.
class TestSwitch{ public static void main (String args[]) { int i=3; switch (i) { case 1: System.out.println("I"); break; case 2: System.out.println("II"); break; case 3: System.out.println("III"); break; case 4: System.out.println("IV"); break; case 5: System.out.println("V"); break; default: System.out.println("pas de traduction"); } }}

Il faut encore prciser que le type de lexpression dune clause case doit tre char, byte, short ou int.

Diagramme 5.4 switch_statement

Javabook Page 69 Lundi, 12. juillet 1999 3:58 15

Excution itrative

69

5.3 Excution itrative


Les structures de contrle itratives permettent dexcuter des instructions de manire rptitive (boucle), lexcution se terminant lorsquune condition de test nest plus remplie. Java dfinit les structures itratives while, do...while et for, prsentes ci-aprs.

Tant que_faire_ (while)


Dans ce cas (voir diagramme 5.5), on ne commence la boucle que si la condition est vraie; on excute alors linstruction lie au while. Si la condition est toujours vraie, on recommence la boucle, le processus sarrtant ds que la condition devient fausse. Linstruction lie au while peut donc ne jamais tre excute, si la condition est fausse au dpart. noter encore que la condition doit tre de type boolen. Deux formes de while peuvent tre utilises : while (c) S1; tant que c est vrai on excute S1; while (c) {B1}; tant que c est vrai on excute le bloc B1.
class TestWhile{ public static void main (String args[]) { int i=100, somme_i=0, j=0; // boucle 1: expression sans effet de bord while (j<=i) { somme_i+=j; ++j; } System.out.println("boucle 1:"+somme_i); // boucle 2: expression avec effet de bord somme_i=0; j=0; while (++j<=i ) somme_i+=j; System.out.println("boucle 2:"+somme_i); } }

Diagramme 5.5 while_statement

Faire_tant que_ (do...while)


Dans ce type de boucle, on commence par excuter linstruction lie au do. Ensuite, si la condition est vraie, on recommence la boucle. Lexcution est interrompue ds que la condition devient fausse. Linstruction lie au do est donc excute au minimum une fois, mme si la condition est fausse au dpart. La condition doit par ailleurs tre du type boolen. Les deux formes de do...while sont : do S1 while(c); excuter S1 et rpter S1 tant que c est vrai;

Javabook Page 70 Lundi, 12. juillet 1999 3:58 15

70

Chapitre 5 Les structures de contrle

do {B1} while(c); excuter B1 et rpter B1 tant que c est vrai.


class TestDo{ /* le rsultat nest pas erron si lon excute une addition de trop si i= 0 ! */ public static void main (String args[]) { int i=100, somme_i=0, j=0; // boucle 1: expression sans effet de bord do { somme_i+=j; ++j; } while (j<=i); System.out.println("boucle 1:"+somme_i); // boucle 2: expression avec effet de bord somme_i=0; j=0; do somme_i+=j; while (++j<=i ); System.out.println("boucle 2:"+somme_i); } }

Diagramme 5.6 do_statement

Pour_faire_ (for)
Une boucle for est dclare laide dune ou plusieurs instructions (S1, B1) et de trois expressions (e1, e2, e3) : la premire (e1) initialise litrateur (aprs lavoir ventuellement dclar); cette expression nest excute quune seule fois; la deuxime (e2) exprime la condition de test (tant quelle est vraie on continue la boucle); elle est vrifie chaque itration; la troisime (e3) modifie litrateur; elle est excute chaque itration, la suite de linstruction (S1). Le diagramme 5.7prcise la syntaxe, dont les deux formes sont : for (e1;e2;e3) S1; excuter e1. Tant que e2 est vrai, excuter linstruction S1 et lexpression e3; for (e1;e2;e3) B1; excuter e1. Tant que e2 est vrai, excuter le bloc B1 et lexpression e3. Les expressions e2 et e3 sont optionnelles. Si elles ne sont pas prcises, le bloc B1 doit alors contenir des instructions pour modifier litrateur et une instruction break pour quitter la boucle. Dune manire gnrale, une boucle for est quivalente la boucle while suivante : e1; while(e2) {S1; e3}.

Javabook Page 71 Lundi, 12. juillet 1999 3:58 15

Identifier une instruction

71

Exemples de boucles for :


class TestFor{ public static void main (String args[]) { int n[] = new int[100]; // boucle 1: calculer la somme des entiers pour // indice du vecteur for (int i=1; i<100; i++) n[i]=n[i-1]+i; // boucle 2: imprimer le rsultat par // ordre dcroissant for (int i=99; i>=0;) { // modification de i dans le bloc dinstructions System.out.println("somme("+i+")="+n[i]); i--; } } }

Dans lexemple TestFor, nous avons deux types de boucles : lune croissante, lautre dcroissante. Dans la seconde, on remarque que litrateur est dcrment en dehors de lexpression de modification (e3), qui est vide. Ce mcanisme permet de modifier litrateur de manire complexe depuis lintrieur du bloc dinstructions.

Diagramme 5.7 for_statement

5.4 Identifier une instruction


Il est possible dattribuer un label (identifier, diagramme 5.8) une instruction ou un bloc dinstructions afin de lidentifier. Cette possibilit est utilise en conjonction avec les instructions de rupture (break) et de continuation ditration (continue). Exemple de label (boucle1) assign une boucle :
class LabelInst{ public static void main (String args[]) { boucle1: for (int i=0;i<10;i++) for (int j=0; j<10;j++){ System.out.println(i+"/"+j); } } }

Diagramme 5.8 identifier:statement

Javabook Page 72 Lundi, 12. juillet 1999 3:58 15

72

Chapitre 5 Les structures de contrle

5.5 Rupture
Linstruction break, dj rencontre dans linstruction switch (voir le point Au cas o (switch) , p. 67), peut galement tre utilise dans les itrateurs while, do et for : elle ordonne alors de quitter la boucle dans laquelle elle est utilise. Il est mme possible de remonter de plusieurs niveaux en accompagnant linstruction break du libell identifiant le bloc dinstructions quitter.

Diagramme 5.9 break


class TestBreak{ public static void main (String args[]) { bloc1: for (int i=0;i<10;i++) for (int j=0; j<10;j++){ System.out.println(i+"/"+j); // quitte la boucle locale if (j==1) break; // quitte la boucle for i ... if (i==2) break bloc1; } } }

Excution du programme TestBreak :


0/0 0/1 1/0 1/1 2/0

Dans lexemple TestBreak, le premier break (sans libell) force le programme quitter la boucle locale (j) tandis que le second (break bloc1) le force quitter le bloc complet identifi par le libell bloc1. Dans lexemple TestBreak2 ci-dessous, linstruction daffichage sera ignore car elle se trouve dans le bloc dinstructions identifi par le libell bloc2 (et non dans la boucle elle-mme!) :
class TestBreak2{ public static void main (String args[]) { bloc2:{ for (int i=0;i<10;i++) if (i==2) break bloc2; System.out.println("ne sera pas crit"); } } }

Javabook Page 73 Lundi, 12. juillet 1999 3:58 15

Continuation

73

5.6 Continuation
Linstruction continue est utilise dans les itrateurs while, do et for. Elle provoque linterruption du droulement normal de la boucle, le contrle tant repris aprs la dernire instruction de celle-ci (on recommence donc une nouvelle itration). Comme pour la rupture, il est possible dindiquer un libell : dans ce cas, le contrle est repris dans la boucle dpendant immdiatement de ce libell, comme le montre lexemple TestContinue :
class TestContinue{ public static void main (String args[]) { bloc3: for (int i=0;i<10;i++) for (int j=0; j<10;j++){ // quitte la boucle locale if (j>1) continue; // quitte la boucle for i ... if (i>2) continue bloc3; System.out.println(i+"/"+j); } System.out.println("en dehors des boucles"); } }

Excution du programme TestContinue :


0/0 0/1 1/0 1/1 2/0 2/1 en dehors des boucles

Malgr leur apparente ressemblance, les instructions break et continue sont trs diffrentes : dans le cas du break, on quitte rellement la boucle, alors que dans le cas du continue, on saute seulement le bloc dinstructions et on continue quand mme excuter les itrations.

Diagramme 5.10 continue

5.7 Exemples dalgorithmes en Java


Nos connaissances actuelles devraient tre suffisantes pour effectuer des calculs ou programmer des procdures algorithmiques telles que des tris. Nous vous proposons donc deux petits exemples destins utiliser nos acquis en matire de syntaxe Java.

Javabook Page 74 Lundi, 12. juillet 1999 3:58 15

74

Chapitre 5 Les structures de contrle

Recherche dintervalles sans nombre premier


Le programme TestPremier recherche les plus grands intervalles (suites de nombres croissants entre 1 et un million) dans lesquels ne figure aucun nombre premier (exemple : entre 7 et 11, nous avons un trou de 4). Afin dacclrer le processus, on stocke les nombres premiers de 1 1 100 (boucle1), avant de rechercher les intervalles (boucle2). Dans la boucle1, on cherche les nombres premiers jusqu 1 100 et on les stocke dans un vecteur p. Quelques remarques propos de cet exemple : i+=2; permet une incrmentation par 2; j< i / j; la condition darrt volue avec lindice; continue boucle1; interrompt les tests ds quun diviseur de i est trouv; seuls sont conservs les nombres nayant pas quitt la boucle prmaturment (en dautres termes, ceux ayant subi le test avec succs). Dans la boucle2, on cherche les intervalles les plus grands sans nombre premier ; on ne retient un intervalle que sil est plus long que ses prdcesseurs : la boucle portant sur lindice j teste la primalit dun nombre en utilisant uniquement les nombres stocks dans le vecteur p (crible dratosthne); p[j]<i/p[j]; la condition darrt ne porte pas directement sur lindice j mais sur les valeurs rfrences; continue boucle2; on quitte la boucle de test si lon trouve un diviseur; quand on trouve un nombre premier, on teste sa distance avec le prcdent. Si elle est plus grande que la dernire trouve, alors on limprime.
class TestPremier{ public static void main (String args[]) { int p[]=new int[200]; int dernierP=1; p[0]=2; p[1]=3; boucle1: for (int i=5;i<1100;i+=2){ for (int j=3; j<=i/j;j+=2) if ((i%j)==0) continue boucle1; dernierP++; p[dernierP]=i; } System.out.println("P entre 2 et 1100: "+dernierP); int dp=11, trou=4; boucle2: for (int i=13;i<1000000;i+=2){ for (int j=1; p[j]<i/p[j];j++) if ((i%p[j])==0) continue boucle2;

Javabook Page 75 Lundi, 12. juillet 1999 3:58 15

Exemples dalgorithmes en Java


if (i-dp>trou) { trou=i-dp; System.out.println(dp+".."+i+" = "+trou); } dp=i; } System.out.println("fin!"); } }

75

Excution du programme TestPremier :


P entre 2 et 1100: 193 31..37 = 6 89..97 = 8 139..149 = 10 199..211 = 12 293..307 = 14 887..907 = 20 1129..1151 = 22 1327..1361 = 34 9551..9587 = 36 15683..15727 = 44 19609..19661 = 52 31397..31469 = 72 155921..156007 = 86 360653..360749 = 96 370261..370373 = 112 492113..492227 = 114 fin!

Recherche de nombres amicaux


Ce deuxime exemple (TestAmicaux) recherche les nombres amicaux (nombres dont la somme des diviseurs de lun est gale lautre et rciproquement). Exemple : les nombres 220 et 284 sont amicaux car : somme_div (220) = 1+2+4+5+10+11+20+22+44+55+110 = 284; somme_div (284) = 1+2+4+71+142 = 220. Dans la boucle1, on calcule (pour les nombres jusqu 10000) la valeur de la somme de leurs diviseurs que lon mmorise dans un vecteur p. Le code est trs semblable celui de la recherche des nombres premiers, sauf quici nous dsirons conserver la valeur des diviseurs. Dans la boucle2, on cherche les nombres amicaux. On remarquera : ((p[i]<10000)&&(p[p[i]]==i)); la condition du test avec abandon : cela permet de tester si la somme des diviseurs est plus grande que 9999; si cest le cas, on neffectue pas le test damiti entre les nombres (lutilisation de && permet ainsi dviter de sortir des valeurs autorises pour le vecteur p).

Javabook Page 76 Lundi, 12. juillet 1999 3:58 15

76

Chapitre 5 Les structures de contrle


class TestAmicaux{ public static void main (String args[]) { int p[]=new int[10000]; int dernierP=1; p[1]=1;p[2]=1; p[3]=1;p[4]=3; p[5]=1;p[6]=6; // boucle 1 for (int i=7;i<10000;i++) for (int j=1; j<=i/2;j++) if ((i%j)==0) p[i]+=j; // boucle 2 for (int i=2;i<10000;i++) if ((p[i]<10000)&&(p[p[i]]==i)) System.out.println(i+" "+p[i]); System.out.println("fin!"); } }

Excution du programme TestAmicaux :


6 6 28 28 220 284 284 220 496 496 1184 1210 1210 1184 2620 2924 2924 2620 5020 5564 5564 5020 6232 6368 6368 6232 8128 8128 fin!

Les nombres qui sont amicaux avec eux-mmes sont appels nombres parfaits . Parmi eux on peut citer : 6 et 28.

Javabook Page 77 Lundi, 12. juillet 1999 3:58 15

Chapitre 6

Une introduction aux objets


Nous avons examin jusquici la partie syntaxique de Java, qui permet dexprimer des algorithmes. Avant daborder celle autorisant la dclaration des classes et des mthodes, il nous faut dcouvrir ce quest un objet.

6.1 Comportement des objets


Pour bien comprendre la notion dobjet, une vision base sur le comportement peut se rvler utile. Dans cet esprit, nous obtenons les dfinitions suivantes : une classe est un archtype qui conditionne tous les comportements; un objet est une instance dune et une seule classe. Cest un individu qui possde tous les comportements de sa classe; une mthode dfinit une action lmentaire que lon peut effectuer sur un objet. Lensemble des mthodes dune classe dfinit le comportement de chaque objet de la classe; un message est une demande dexcution dune mthode un objet. Dans la figure 6.1 ci-aprs, on distingue deux classes, lune dfinissant les rectangles et lautre les disques. La classe sert de moule pour former ses instances. Ainsi, les objets r1, r2 et r3 sont des instances de Rectangle tandis que d1 et d2 sont des instances de Disque. Les mthodes dfinies dans les classes indiquent les services que lon peut demander aux objets de ces classes.

Javabook Page 78 Lundi, 12. juillet 1999 3:58 15

Rectangle surface() perimetre() largeur() hauteur() diagonale()

Disque surface() perimetre() doubler() rayon()

CLASSES

INSTANCES r1 r3 r2 d1 (OBJETS) d2

Figure 6.1Classes, mthodes et instances

6.2 Classes et objets en Java


En Java, lnonc suivant permet de dclarer une classe :
class Rectangle { ... }

Voyons ce quon trouve lintrieur dune dclaration de classe.

Variables et mthodes dinstance


Une classe peut possder des variables dinstance. Comme leur nom lindique, les variables dinstance sont propres chaque instance (objet) de la classe. Elles constituent la mmoire de chaque objet. Dans notre cas, largeur et hauteur peuvent tre dclares comme variables dinstance de la classe Rectangle, qui servira ensuite de moule pour crer nos objets :
class Rectangle { double largeur, hauteur; ... }

Les mthodes de Rectangle dterminent le comportement des objets de ce type. La dclaration dune mthode est compose des lments suivants : le type du rsultat produit, ou void si elle ne produit pas de rsultat; le nom de la mthode; le type et le nom des paramtres, placs entre (); un bloc dinstructions qui constitue le corps de la mthode.

class Rectangle extends Object{ ...

Javabook Page 79 Lundi, 12. juillet 1999 3:58 15

Classes et objets en Java


double perimetre() {return 2*(largeur+hauteur);} double surface() {return largeur*hauteur;} double diagonale() { return Math.sqrt(largeur*largeur+hauteur*hauteur);} void doubler() {largeur*=2; hauteur*=2;} }

79

On remarquera laccs systmatique aux variables dinstance dont chaque Rectangle est muni et qui refltent son tat (sa largeur et sa hauteur). Linstruction return calcule le rsultat et termine lexcution de la mthode. Le type du rsultat, le nom de la mthode et le nom et le type des paramtres forment ce quon appelle la signature de la mthode. Dans le bloc dinstructions dune mthode, on peut utiliser la pseudovariable this pour dsigner lobjet courant, cest--dire lobjet sur lequel la mthode est en train de travailler.

Constructeurs
Finalement, il ne nous reste plus qu dfinir le constructeur de la classe : une mthode particulire qui indique comment initialiser une instance. La rgle de nommage dun constructeur est simple, il doit porter le mme nom que la classe concerne :
class Rectangle { ... Rectangle(double initL, double initH){ largeur=initL; hauteur=initH; } ... }

Ce constructeur initialise les deux variables dinstance du nouvel objet avec les valeurs des deux paramtres initL et initH. Voici donc le code complet de notre classe Rectangle :
class Rectangle { double largeur, hauteur; Rectangle(double initL, double initH){ largeur=initL; hauteur=initH; } double perimetre() {return 2*(largeur+hauteur);} double surface() {return largeur*hauteur;} double diagonale() { return Math.sqrt(largeur*largeur+hauteur*hauteur);} void doubler() {largeur*=2; hauteur*=2;} }

Javabook Page 80 Lundi, 12. juillet 1999 3:58 15

80

Chapitre 6 Une introduction aux objets

Nous procdons de la mme manire pour la classe Disque (variables dinstance, constructeur, mthodes) et obtenons le code suivant :
class Disque { double diametre; static final double pi=3.14159; Disque(double initD){ diametre=initD; } double perimetre() {return pi*diametre;} double surface() {return (pi*diametre*diametre)/4;} double rayon() {return diametre/2;} void doubler() {diametre*=2;}

Notons encore que si aucun constructeur nest dfini, Java cre un constructeur qui na aucun paramtre et ninitialise aucune variable dinstance.

Cration dinstances et assignation


Nous venons de dclarer les classes Rectangle et Disque, mais nous navons pas encore cr dinstances de ces classes (les fameux objets). Pour crer une instance, on invoque un constructeur laide de linstruction new. Par exemple :
new Disque(2.5)

cre un objet de la classe Disque et invoque le constructeur qui initialise la variable diametre 2.5. On peut assigner un objet une variable : pour cela il faut dclarer une variable du type correspondant. La dclaration de type seffectue comme pour les types de base (int, char), en faisant prcder la variable par le nom de la classe :
Disque d1,d2; d1=new Disque(2); d2=new Disque(4); // dclaration de 2 variables de type Disque // invoque le constructeur et assigne lobjet

Invocation des mthodes


Linvocation dune mthode seffectue en nommant linstance et en la faisant suivre du nom de la mthode et dune liste, ventuellement vide, dexpressions : Ainsi, pour obtenir la diagonale du Rectangle r1, nous crirons :
r1.diagonale() instance.mthode(expression1, ...)

Si la mthode possde des paramtres, les expressions donnes lors de linvocation (arguments) sont values et affectes aux paramtres correspondants de la mthode. Si lon veut invoquer une mthode sur linstance courante, on crira :
this.mthode(expression1, ...)

Javabook Page 81 Lundi, 12. juillet 1999 3:58 15

Classes et objets en Java

81

qui peut sabrger en :


mthode(expression1, ...)

Un programme complet
Nous pouvons crire maintenant un petit programme (TestRectDisk1) utilisant les classes Rectangle et Disque (on notera au passage que les noms commenant par une majuscule sont rservs, par convention, aux identifiants des classes, ceux des mthodes commenant par une minuscule).
class TestRectDisk1{ public static void main (String args[]) { Rectangle r1=new Rectangle(2,4); Rectangle r2=new Rectangle(3,4); System.out.println("diagonale de r1: "+r1.diagonale()); System.out.println("primtre de r2: "+r2.perimetre()); r2.doubler(); System.out.println("primtre de r2: "+r2.perimetre()); Disque d1,d2; d1=new Disque(2); d2=new Disque(4); System.out.println("rayon de d1: "+d1.rayon()); System.out.println("primtre de d2: "+d2.perimetre()); d2.doubler(); System.out.println("primtre de d2: "+d2.perimetre()); } }

Excution du programme TestRectDisk1 :


diagonale de primtre de primtre de rayon de d1: primtre de primtre de r1: r2: r2: 1 d2: d2: 4.47214 14 28 12.5664 25.1327

Dclaration de plusieurs constructeurs


Il est pratique de proposer plusieurs constructeurs pour une mme classe (afin de permettre diffrentes formes de reprsentation selon les utilisateurs). Il suffit pour cela de crer un nouveau constructeur, devant obligatoirement se distinguer des autres par le nombre et/ou le type de ses paramtres. Nous avons ainsi ajout un constructeur la classe Rectangle qui, partir des coordonnes du coin suprieur gauche (csgx,csgy) et du coin infrieur droit (cidx,cidy), dtermine la largeur et la hauteur de linstance crer. Nous obtenons le code suivant :
class Rectangle {

Javabook Page 82 Lundi, 12. juillet 1999 3:58 15

82

Chapitre 6 Une introduction aux objets


... Rectangle(double initL, double initH){ largeur=initL; hauteur=initH; } Rectangle(double csgx, double csgy, double cidx, double cidy){ largeur=Math.abs(csgx-cidx); hauteur=Math.abs(csgy-cidy); } ... }

Nous pouvons maintenant choisir comment crer des instances de Rectangle :


class TestRectDisk2{ public static void main (String args[]) { Rectangle r1=new Rectangle(1,1,3,5);// par les coins Rectangle r2=new Rectangle(3,4); // par largeur et hauteur ...

Si une classe possde plusieurs constructeurs, ceux-ci peuvent sinvoquer les uns les autres grce linstruction this(). Par exemple :
Rectangle(double initLH){ this(initLH, initLH);

qui invoque Rectangle(double initL, double initH).

Destruction dobjets
Il ny a en gnral pas besoin de soccuper de dtruire les objets car la machine virtuelle Java sen charge. Ds quun objet nest plus rfrenc par aucune variable ou aucun autre objet, le gestionnaire de mmoire le dtruit et rcupre lespace mmoire quil occupait. Cependant, dans le cas o lobjet avait, au travers de ses mthodes, ouvert des canaux de communication ou des fichiers, il faut les fermer explicitement. Cest pourquoi le systme invoque la mthode finalize(), si elle existe, juste avant la destruction de lobjet. On peut donc placer dans cette mthode le code ncessaire la restitution des ressources occupes par lobjet.

Surcharge des mthodes


On aimerait parfois pouvoir proposer plusieurs mthodes dans une mme classe effectuant une action similaire, sans avoir leur donner des noms diffrents. Pour cela, on peut crer une nouvelle mthode portant le mme nom quune autre, pour autant quelle sen distingue par le nombre et/ou le type de ses paramtres. Nous avons ainsi ajout une mthode doubler() la classe Rectangle permettant

Javabook Page 83 Lundi, 12. juillet 1999 3:58 15

Classes et objets en Java

83

de doubler la largeur et la hauteur de linstance de manire indpendante. Nous obtenons le code suivant :
class Rectangle extends Object{ ... void doubler() { largeur*=2; hauteur*=2;} void doubler(boolean l, boolean h) { if (l) largeur*=2; if (h) hauteur*=2; }

Nous pouvons alors doubler les instances de Rectangle selon nos besoins :
class TestRectDisk2{ public static void main (String args[]) { r2.doubler(); r2.doubler(false,true); } // largeur et hauteur // uniquement la hauteur

On parle dans un tel cas de surcharge des mthodes. Le compilateur examine les types de paramtres et leur nombre au moment de la dclaration de lappel, afin de dterminer la bonne mthode invoquer. Lexemple suivant montre un autre cas de surcharge vu prcdemment :
r2.doubler(); // r2 est un Rectangle d2.doubler(); // d2 est un Disque

Dans ce cas, le compilateur sait (grce la dclaration de type des variables) que pour r2, il doit invoquer la mthode doubler() de la classe Rectangle alors que pour d2, il doit invoquer celle de la classe Disque.

Variables de classe
Une classe peut galement possder ses propres variables de classe (qui ne seront pas cres dans ses instances), lui permettant de grer des informations propos de ses instances, comme par exemple la hauteur moyenne des Rectangles. Les variables de classe sont dclares statiques (static). Elles sont initialises au moment du chargement de la classe. La constante pi, dclare static dans la classe Disque, est un autre exemple de variable de classe. En effet, il nest pas ncessaire (ni mme utile) que chaque instance de Disque possde sa propre copie de la variable pi.

Visibilit des variables dinstance et de classe


En ce qui concerne la visibilit, les variables dune instance sont accessibles : sans tre prfixes, depuis toutes les mthodes de la classe;

Javabook Page 84 Lundi, 12. juillet 1999 3:58 15

84

Chapitre 6 Une introduction aux objets

en tant prfixes par le nom de lobjet, depuis lextrieur de la classe. Ainsi, linstruction suivante imprimera les dimensions de r2 :
System.out.println("dimension:"+r2.largeur+"/"+r2.hauteur); r2.hauteur=45;

Il est bien entendu possible de cacher les variables dinstance (surtout pour viter quon ne les modifie de lextrieur) grce deux modificateurs, private et protected, que nous tudierons plus en dtail au point 24.2. Les variables de classe, quant elles, sont accessibles depuis lextrieur de la classe en les prfixant du nom de la classe. Le fameux System.out nest autre que la variable de classe out de la classe System et System.out.println() invoque la mthode println() de cet objet.

Mthodes de classe
Les mthodes de classe sont destines agir sur la classe plutt que sur ses instances : elles permettent de manipuler les variables de classe. Nous avons ainsi ajout notre exemple une mthode de classe modifierEchelle() que nous devons dclarer static. Lappel cette mthode se fera en la prfixant par le nom de la classe. Lorsque lon dsire effectuer des initialisations complexes des variables de la classe, on peut lui associer un bloc dinstructions qui sera excut lors du chargement de la classe. Un tel bloc doit avoir la forme suivante (on notera labsence de nom de mthode) :
static { instruction; ...}

Nous obtenons le code TestRectDisk3 suivant :


class Rectangle extends Object{ static double echelle=1.0; // var de classe double largeur, hauteur; // var dinstance ... static void modifierEchelle(double e){ // mthode de classe echelle=e; } static { //initialisation complexe des var de classe echelle=0.5; } } class TestRectDisk3{ public static void main (String args[]) { Rectangle r1=new Rectangle(2,4); Rectangle r2=new Rectangle(3,4); System.out.println("dim. r2:"+r2.largeur+"/"+r2.hauteur);

Javabook Page 85 Lundi, 12. juillet 1999 3:58 15

Et si lon parlait dhritage


Rectangle.modifierEchelle(4); System.out.println("echelle "+Rectangle.echelle); }}

85

Excution du programme TestRectDisk3 :


dim. r2: 3/4 echelle 4

6.3 Et si lon parlait dhritage


Jusqu maintenant, nous avons parl de classes sans mentionner la relation dhritage qui existe entre elles. Lhritage permet de conserver certains acquis dune classe et den faire bnficier une autre, sans avoir tout redfinir (comme dans la vie courante o lon hrite de ce fameux oncle dAmrique).

Dfinition de sous-classes
Admettons que nous voulions crer une classe Carr. Sans le mcanisme dhritage, nous devrions redfinir les mthodes perimetre(), surface(), diagonale(), etc., alors quun carr, cest presque un rectangle. Nous allons donc profiter du fait que Java supporte la notion dhritage (et que nous avons dj dfini une classe Rectangle) pour crer une classe Carr qui tend le comportement de Rectangle, hritant ainsi de ses variables dinstance et de ses mthodes. Nous dirons alors que Carr est une sous-classe de Rectangle et que Rectangle est la super-classe de Carr. Nous dfinissons un constructeur pour la classe Carr, qui va invoquer le constructeur de la classe dont elle hrite (Rectangle). On utilise cet effet le dsignateur super(). Nous ajoutons ensuite une mthode cote() la classe Carr.
class Carre extends Rectangle{ Carre(double initC){ super(initC,initC); } double cote() {return this.hauteur;} } class TestRectDisk4{ public static void main (String args[]) { Carre c1=new Carre(4); System.out.println("dim. c1: "+c1.largeur+"/"+c1.hauteur); System.out.println("surf. c1: "+c1.surface()); System.out.println("cot de c1 "+c1.cote()); }}

Javabook Page 86 Lundi, 12. juillet 1999 3:58 15

86

Chapitre 6 Une introduction aux objets

Excution de TestRectDisk4 :
dim. c1: 4/4 surf. c1: 16 cot de c1 4

Assignation, sous-classes et redfinition


Nous avons vu quil faut dclarer une variable de type Rectangle pour pouvoir lui assigner un objet de la classe Rectangle. En fait, une telle variable peut galement recevoir un objet de nimporte quelle sous-classe de Rectangle, comme dans le fragment de code ci-dessous :
Rectangle r1, r2; r1 = new Rectangle(5, 6); r2 = new Carre(4);

Comme r2 est de type Rectangle, et bien quelle dsigne un Carre, son comportement est restreint celui dun Rectangle; on ne peut lui appliquer que les mthodes propres Rectangle.
double s = r2.surface(); // OK double c = r2.cote(); //*** FAUX *** erreur la compilation

Par contre, si une mthode est redfinie dans une sous-classe, cest bien la mthode de la sous-classe qui est appele. Par exemple, sil existe une mthode imprimer() dfinie dans Rectangle, qui imprime la largeur et la hauteur dun rectangle, et une mthode imprime() dans Carre, qui imprime le ct, lexcution de
Rectangle r r = new Rectangle(5, 6); r.imprimer(); r = new Carre(4); r.imprimer();

produira :
largeur: 5 hauteur: 6 cote: 4

Le mcanisme qui, lors de lexcution du programme, choisit la bonne mthode excuter en fonction de la classe de lobjet dsign, sappelle liaison dynamique; nous y reviendrons en dtail au point 22.1, p. 313. Mentionnons aussi que la pseudovariable super sert accder aux mthodes de la super-classe, mme si elles ont t redfinies. Cela est utile lorsquune mthode de la sous-classe veut utiliser la mthode quelle redfinit. Par exemple :
class CarreCouleur extends Carre { String couleur; CarreCouleur(int a, String clr) {... } // constructeur

Javabook Page 87 Lundi, 12. juillet 1999 3:58 15

Et si lon parlait dhritage


... void imprime () { super.imprime(); // utilise la mthode imprime de Carre System.out.println(couleur); // et ajoute la couleur } }

87

Lexcution des instructions


CarreCouleur cc = new CarreCouleur(3, "rouge"); cc.imprime();

produira :
cote: 3 rouge

Assignation et compatibilit des types


Il nous faut encore mentionner un point particulier concernant laffectation des objets. Supposons quune variable soit dclare de type C; on peut alors lui affecter un objet de la classe C ou dune sous-classe de C, comme nous lavons fait ci-dessus.
Rectangle r; r = new Carre(4); // Carre est sous-classe de Rectangle

Linverse nest par contre pas admis :


Carre c; c = new Rectangle(7, 2); // *** Erreur la compilation

Cette rgle peut parfois savrer trop svre et empcher des affectations correctes, comme par exemple :
Rectangle r; Carre c; r = new Carre(5); ... c = r; // r dsigne bien un Carre // *** Refus la compilation

Le compilateur a raison de refuser la dernire instruction car r pourrait trs bien dsigner autre chose quun Carre. Lorsque lon sait quune variable r (ou une expression) de type Rectangle dsigne en fait un Carre, on peut crire :
(Carre) r

afin de changer le type de lexpression en Carre, permettant ainsi dcrire lassignation prvue :
c = (Carre) r;

Le compilateur admet cette instruction, mais Java tant sr, il y aura un contrle au moment de lexcution, afin de vrifier que r dsigne bien un objet de Carre (ou de lune de ses sous-classes). Si ce nest pas le cas, une erreur dexcution se produira.

Javabook Page 88 Lundi, 12. juillet 1999 3:58 15

88

Chapitre 6 Une introduction aux objets

Constructeurs de sous-classes
Lune des rgles de Java impose que tout constructeur appelle directement ou indirectement un constructeur de sa super-classe. Si la premire instruction dun constructeur nest pas super() ou this(), un appel super() est automatiquement ajout avant la premire instruction. Dans ce cas, il faut quun constructeur sans paramtre existe dans la super-classe. Examinons encore un exemple : admettons que lon souhaite tendre le comportement des rectangles celui des paralllpipdes. Nous agissons comme dans le cas prcdent, en tendant la classe Rectangle afin dajouter une variable dinstance pour mmoriser la profondeur dun Parallelepipede et en dclarant le constructeur et les mthodes propres cette nouvelle classe :
class Parallelepipede extends Rectangle{ double profondeur; Parallelepipede(double x, double y, double z){ super(x,y); profondeur=z; } double volume(){return surface()*profondeur;} } class TestRectPar{ public static void main (String args[]) { Parallelepipede p1=new Parallelepipede(2,3,4); System.out.println("prof. p1:"+p1.profondeur); System.out.println("surf. p1:"+p1.surface()); System.out.println("vol. p1:"+p1.volume()); } }

Excution de TestRectPar :
prof. p1:4 surf. p1:6 vol. p1:24

Il y a quelques pages encore, nous ne savions rien de lhritage et voil que nous avons cr une vritable petite famille. En Java, toutes les classes ont pour origine la classe Object. Une classe ne pouvant tendre quune seule classe (appele sa super-classe), nous avons donc une hirarchie stricte que lon peut reprsenter sous forme dun arbre dhritage, dont la racine est la classe Object (voir figure 6.2).

Javabook Page 89 Lundi, 12. juillet 1999 3:58 15

Classes et mthodes abstraites

89

Object

Rectangle

Disque

Carre

Parallelepipede Figure 6.2Arbre dhritage des classes

6.4 Classes et mthodes abstraites


Les classes abstraites sont des classes dont certaines mthodes, dites abstraites, sont dclares (nom et paramtres) mais ne possdent pas de corps dinstructions. Une classe abstraite nest pas instanciable (lopration new est interdite). Si une sous-classe dune classe abstraite redfinit toutes les mthodes abstraites de celle-ci, elle devient concrte, sinon elle est galement abstraite. linverse des classes abstraites, les classes finales se situent forcment en bas des hirarchies de classes car elles interdisent toute dfinition de sous-classes. Une classe peut ne pas tre finale mais dclarer des mthodes comme finales; il est alors interdit de redfinir ces mthodes. Nous reviendrons au point 22.3 sur lutilit des classes abstraites dans la conception et larchitecture des programmes. Contentons-nous pour linstant dun exemple. Dans notre famille gomtrique , nous constatons que nous avons des mthodes communes aux classes Rectangle et Disque (perimetre(), surface()) qui pourraient trs bien tre dfinies pour dautres lments de la gomtrie plane. De mme, la constante pi pourrait leur tre utile. Nous avons donc dfini une classe abstraite GeometriePlane munie de deux mthodes abstraites : perimetre() et surface() et dune constante pi. Les classes Rectangle et Disque tendent cette nouvelle classe en fournissant une implantation pour les mthodes abstraites, en plus de leurs propres mthodes :
abstract class GeometriePlane{ static final double pi=3.14159; abstract double perimetre(); abstract double surface(); } class Rectangle extends GeometriePlane{ ... double perimetre() {

Javabook Page 90 Lundi, 12. juillet 1999 3:58 15

90
return 2*(largeur+hauteur); } double surface(){ return largeur*hauteur; } ...

Chapitre 6 Une introduction aux objets

} class Disque extends GeometriePlane{ ... double perimetre() { return GeometriePlane.pi*diametre; } double surface() { return (GeometriePlane.pi*diametre*diametre)/4; } ... }

La classe abstraite napporte pas grand-chose de nouveau dans le comportement des objets. Par contre, en observant la structure, nous savons dsormais que toutes les sous-classes dune classe abstraite implantent ses mthodes. Exemple :
class Triangle extends GeometriePlane{...}

Cette dclaration nous assure que des mthodes perimetre() et surface() adaptes aux triangles pourront tre invoques sur des instances de la classe Triangle. Nous avons donc structur notre monde dobjets gomtriques.

6.5 Classes internes


Depuis la version 1.1 de Java, il est possible de dclarer une classe I lintrieur dune classe C. Dans ce cas tout objet de I est dpendant dun objet, appel objet englobant, de C. Les objets de I sont des sous-objets de C. Lexemple ci-dessous montre lusage dune classe interne pour dfinir la structure des sommets dun polygone :
class Polygone { int nbSommets; Sommet[] sommets; class Sommet { double x,y,poids; void mirroirY() {x = -x;} double poidsRelatif() {return poids/nbSommets;} } Polygone(int ns) { // cre un polygone de ns sommets nbSommets = ns; sommets = new Sommet[nbSommets];

Javabook Page 91 Lundi, 12. juillet 1999 3:58 15

Classes anonymes
for (int i=0; i<nbSommets; i++) sommets[i] = new Sommet(); } ... }

91

On voit sur cet exemple que les mthodes de la classe interne peuvent accder aux variables dinstance de leur objet englobant. Lexpression poids/nbSommets signifie : diviser la variable poids du sommet courant par la variable nbSommet du polygone auquel appartient le sommet. Linstruction new Sommet() du constructeur de Polygone cre des objets de Sommet dpendant du Polygone en construction. On peut galement crer des objets de Sommet depuis lextrieur de la classe Polygone, pour autant quon indique de quel Polygone ils dpendent. On utilise pour cela une nouvelle syntaxe de linstruction new :
Polygone po = new Polygone(); Polygone.Sommet spo = po.new Sommet();

6.6 Classes anonymes


Les classes anonymes sont une variante des classes internes que lon utilise de prfrence lorsquon veut crer un objet particulier sans avoir dfinir un nom de classe. Une dclaration de classe anonyme est une extension de linstruction new. Par exemple :
Sommet sommetSpecial = new Sommet() { double poidsRelatif() { return poids * 6.25; }

Dans ce cas, la classe anonyme est une sous-classe de Sommet et lobjet sommetSpecial se comporte comme un Sommet mais avec une mthode poidsRelatif redfinie. Lorsque nous tudierons la gestion des vnements, nous verrons que les classes anonymes et les classes internes peuvent simplifier lcriture du code.

6.7 Interfaces
Une interface est assez similaire une classe abstraite, puisquelle dclare un ensemble de mthodes abstraites et de constantes. On ne peut donc pas instancier une interface (pas de new()), par contre linterface dfinit un type (on peut dclarer des variables de ce type). Une classe peut indiquer dans sa dfinition quelle implante une ou plusieurs interfaces. Elle sengage alors fournir une dfinition pour toutes les mthodes dfinies dans linterface.

Javabook Page 92 Lundi, 12. juillet 1999 3:58 15

92

Chapitre 6 Une introduction aux objets

Une interface peut hriter dune ou plusieurs autres interfaces, les interfaces formant une hirarchie spare de celle des classes. Revenons la gomtrie et dclarons une hirarchie dinterfaces :
interface Geometrie{ static final double pi=3.14159; } interface Courbe extends Geometrie{ double longueur(); void doubler(); } interface Surface extends Geometrie{ double surface(); }

Redfinissons maintenant les classes Rectangle et Disque en prcisant quelles implantent ces interfaces :
class Rectangle extends GeometriePlane implements Courbe, Surface { ... comme avant } class Disque extends GeometriePlane implements Courbe, Surface{ ... comme avant }

Les hirarchies de classes et dinterfaces ainsi que les liens dimplantation sont illustrs sur la figure 6.3 :
INTERFACES Gomtrie CLASSES Object

Courbe

Surface

GomtriePlane

Rectangle Disque Figure 6.3Hirarchie des classes et hirarchie des interfaces

Dans le programme TestRectDisk7 ci-aprs, nous montrons quil est possible de manipuler les rectangles et les disques comme des courbes ou des surfaces. On parle alors de polymorphisme :
class TestRectDisk7{ public static void main (String args[]) {

Javabook Page 93 Lundi, 12. juillet 1999 3:58 15

Packages
Courbe c[]=new Courbe[10]; Surface s[]=new Surface[10]; Rectangle r[]=new Rectangle[5]; Disque d[]=new Disque[5]; // crer des rectangles for (int i=0;i<5;i++){ r[i]=new Rectangle(i+1,i+1); c[i]=r[i]; s[i]=r[i]; } // crer des disques for (int i=0;i<5;i++){ d[i]=new Disque(i+1); c[i+5]=d[i]; s[i+5]=d[i]; } // manipuler les objets de chaque classe System.out.println("surf. r[2]: "+r[2].surface()); System.out.println("surf. s[2]: "+s[2].surface()); System.out.println("long. r[2]: "+r[2].longueur()); System.out.println("long. c[2]: "+c[2].longueur()); // considrer les objets comme des lments gomtriques // surface de tous les objets double surfTotal=0; for (int i=0;i<10;i++)surfTotal+=s[i].surface(); System.out.println("surfTotal: "+surfTotal); // doubler tous les primtres for (int i=0;i<10;i++)c[i].doubler(); //surface de tous les objets surfTotal=0; for (int i=0;i<10;i++)surfTotal+=s[i].surface(); System.out.println("surfTotal: "+surfTotal); } }

93

Excution de TestRectDisk7 :
surf. r[2]: 9 surf. s[2]: 9 long. r[2]: 12 long. c[2]: 12 surfTotal: 98.1969 surfTotal: 392.787

6.8 Packages
Un package permet de regrouper physiquement des classes concernant un domaine particulier (exemple : accs au rseau), afin de mieux les organiser. Le package dfinit un systme de nommage (nomDePackage.nomDelement);

Javabook Page 94 Lundi, 12. juillet 1999 3:58 15

94

Chapitre 6 Une introduction aux objets

celui-ci devra tre utilis dans tout programme dsirant accder aux lments (classes, constantes, etc.) du package. En rsum, les trois mcanismes proposs par Java pour structurer et organiser le code sont : lhritage, structure des classes; les interfaces, structure des comportements; les packages, structure du dveloppement.

6.9 Rfrence, copie et galit


Il est important de bien distinguer lassignation et la copie dobjets. Lassignation dun objet une variable place dans la variable une rfrence cet objet. Aprs avoir effectu les oprations :
Rectangle r1=new Rectangle(2,4); Rectangle r2=r1

La situation est celle dcrite par la figure 6.4 ci-dessous : les deux variables r1 et r2 font rfrence au mme objet :
r1 largeur : 2 hauteur : 4 r2 Figure 6.4Deux variables rfrenant le mme objet Rectangle

La mthode clone(), hrite dObject, peut tre invoque pour crer une copie dun objet :
Rectangle r3 = r1.clone()

Les deux objets obtenus aprs un tel clonage sont gaux (ils ont les mmes valeurs dans leurs variables dinstance) mais ne sont pas identiques.
r3 == r1 r3.equals(r1) // retourne false // retourne true

La mthode equals() teste lgalit du contenu des objets alors que loprateur == teste lidentit (sagit-il du mme objet?). Nous reviendrons plus en dtail sur ces questions au point 23.4. Comparaison des chanes de caractres Ce que nous venons de prsenter sapplique en particulier aux chanes de caractres (String). Les chanes de caractres tant des objets part entire, il faut utiliser la mthode equals() pour tester lgalit de deux chanes (mmes caractres) et non pas == (mme objets). On peut galement tester lordre lexicographique entre deux chanes avec la mthode compareTo() de la classe String.

Javabook Page 95 Lundi, 12. juillet 1999 3:58 15

Types simples et classes enveloppes

95

6.10 Types simples et classes enveloppes


Les valeurs des types simples short, byte, int, boolean, etc. ne sont pas des objets. Or, il arrive que certaines mthodes ne traitent que des objets : par exemple, les mthodes dinstance de la classe java.util.Vector, qui gre des squences dobjets. Cest pourquoi il existe des classes enveloppes dont le seul but est dencapsuler un type simple dans un objet. Ces classes sont : Boolean, Character, Double, Float, Integer et Long. Leurs constructeurs prennent comme paramtre une valeur du type simple encapsuler.
boolean int p = Boolean Integer b = true; 20292; bObj = new Boolean(b); pObj = new Integer(p);

Chaque classe fournit une mthode pour extraire la valeur simple de lobjet enveloppant :
boolean b2 = bObj.booleanValue(); int p2 = pObj.integerValue();

Nous sommes maintenant en mesure dutiliser la classe Vector pour crer une squence dentiers :
Vector v = new Vector; v.addElement(new Integer(5)); v.addElement(new Integer(2)); v.addElement(new Integer(90));

et pour en extraire le dernier lment :


int i = (v.lastElement()).integerValue();

Javabook Page 96 Lundi, 12. juillet 1999 3:58 15

Javabook Page 97 Lundi, 12. juillet 1999 3:58 15

Chapitre 7

Les structures
Classes, interfaces, packages
Les diffrents lments permettant dorganiser et de structurer un programme Java, savoir les classes, les interfaces et les packages ont t introduits au chapitre prcdent. Nous allons maintenant y revenir afin dexaminer en dtail la syntaxe de leur dclaration.

7.1 Unit de compilation


Une unit de compilation est un fichier de code source (avec une extension .java) qui contient un ensemble de dclarations de classes et dinterfaces qui appartiennent au mme package. Le compilateur placera le rsultat de la compilation de chaque interface et chaque classe dans un fichier spar, portant le nom de celle-ci (suivi de lextension .class). Cette sparation en diffrents fichiers permettra de charger dynamiquement les classes ncessaires, au moment de lexcution (ou de la compilation lorsque les classes sont importes dans un autre programme). Il ne peut y avoir quun seul lment public (classe ou interface) dans une unit de compilation Les points suivants (7.2 7.4) dcrivent les lments ncessaires la dclaration dune unit de compilation, schmatise par le diagramme 7.1.

Diagramme 7.1 compilation_unit

Javabook Page 98 Lundi, 12. juillet 1999 3:58 15

7.2 Dclaration de package


La dclaration dun package (voir diagramme 7.2) doit tre la premire instruction dun programme (hormis des commentaires). Elle permet de regrouper lensemble des classes dclares dans le mme fichier sous un dnominateur commun. Ces classes devront tre importes individuellement ou de manire globale (package entier) par toute autre unit de compilation qui dsirerait les utiliser. Les rgles de visibilit sont diffrentes pour des objets appartenant un mme package de celles qui sont en vigueur pour des objets de packages diffrents.

Diagramme 7.2 package_statement

7.3 Importation des packages et des classes


Le mcanisme dimportation permet dabrger localement le nom complet dune classe. Pour quune classe soit accessible, il faut : que le package qui la contient ait t compil avec succs; que le chemin (pathclass) du compilateur puisse y accder; que le fichier (.class) soit accessible en lecture. Dans lexemple qui suit, nous navons pas dclar dimportation. Nous devons donc indiquer le nom complet de la classe Point. Dans ce cas, le nom complet reste relativement court car le package rside localement.
class TesImport1{ public static void main (String args[]) { java.awt.Point p=new java.awt.Point(1,2); System.out.println(p.toString()); } }

Limportation peut galement tre utilise pour abrger le nom des interfaces. Sun Microsystems a propos un schma de nommage unique pour les packages, un peu la faon des URL. On trouve dans lidentifiant le nom de domaine assign au site o rside le package, suivi dun chemin dans larborescence des rpertoires menant au package (ou au sous-package). Exemple :
CH.Unige.Cui.java.projet3.pck4.classe

Par convention, le premier composant est crit entirement en majuscules (COM, GOV, FR, etc.), les suivants (commenant par une majuscule) faisant partie du nom de domaine assign au site (dans lordre inverse du format dadresses Internet). Ce schma permet didentifier de manire unique chaque

Javabook Page 99 Lundi, 12. juillet 1999 3:58 15

Importation des packages et des classes

99

classe et vite toute collision. Ainsi chaque dveloppeur peut crer sa propre classe Rectangle! Il existe trois formes pour spcifier limportation. Le diagramme 7.3runit leurs syntaxes respectives tandis que les exemples ci-dessous illustrent leur utilisation :

Forme 1 : import package.comp1.....compn;


Dans cette forme, les classes du dernier composant (compn) peuvent tre utilises en les prfixant par compn. Nous pouvons ainsi rcrire notre exemple de la manire suivante :
import java.awt; class TesImport2{ public static void main (String args[]) { awt.Point p=new awt.Point(1,2); System.out.println(p.toString()); } }

Forme 2 : import package.comp1.....compn.Class;


Dans ce cas, une seule classe est importe. Elle est identifie directement par son nom. Nous pouvons ainsi rcrire notre exemple :
import java.awt.Point; class TesImport3{ public static void main (String args[]) { Point p=new Point(1,2); System.out.println(p.toString()); } }

Forme 3 : import package.comp1.....compn.*;


Dans cette dernire forme, toutes les classes du package sont importes. Elles sont identifies directement par leur nom. Nous pouvons rcrire une dernire fois notre exemple :
import java.awt.*; class TesImport4{ public static void main (String args[]) { Point p=new Point(1,2); Rectangle r; // une autre classe de awt System.out.println(p.toString()); } }

Remarques : si plusieurs classes portent le mme nom dans des packages imports, le compilateur gnre une erreur; les classes java.lang.* sont automatiquement importes par dfaut;

Javabook Page 100 Lundi, 12. juillet 1999 3:58 15

100

Chapitre 7 Les structures

cest pourquoi nous avons pu faire rfrence dans nos exemples aux classes System, Math, etc. du package java.lang sans lavoir import.

Diagramme 7.3 import_statement

7.4 Dclaration de types


Une unit de compilation est forme dun ensemble de dclarations de types (dclarations de classes et dinterfaces). Chaque dclaration peut tre prcde dun commentaire de documentation (style /** ... */), utilis par un outil de gnration automatique de documentation. Lexemple ci-dessous et le diagramme 7.4 montrent cette possibilit :
/** commentaire sur la classe ...*/ class x extends ...{}

Diagramme 7.4 type_declaration

7.5 Dclaration dune classe


La dclaration dune classe dfinit un type qui porte le nom de la classe. Une classe tend une seule et unique classe (sa super-classe). Par dfaut, la classe tend la classe Object. Lidentifiant complet de la classe est dfini par le nom du package et le nom de la classe (package.classe). Une classe peut implanter une ou plusieurs interfaces. Une classe possde un corps qui dfinit ses membres (variables et mthodes). La syntaxe complte de la dclaration dune classe est prsente dans le diagramme 7.5.

Diagramme 7.5 class_description

Javabook Page 101 Lundi, 12. juillet 1999 3:58 15

Dclaration dune interface

101

Les modificateurs de classe sont : abstract : indique que la classe est abstraite : certaines de ses mthodes nont pas de corps, elles seront implantes dans des sous-classes; final : une classe finale ne peut pas tre tendue par des sous-classes (ceci permet au compilateur deffectuer certaines optimisations dans le code, car il ne peut pas y avoir de surcharge); public : une classe est visible pour les classes des autres packages uniquement si elle est dclare publique. Une classe non publique nest visible que pour les classes dfinies lintrieur de son package. Les combinaisons suivantes de modificateurs sont autorises :
public; abstract; public abstract; final; public final

7.6 Dclaration dune interface


La dclaration dune interface dfinit un type. Une interface est dfinie par un nom. Elle peut tendre une ou plusieurs interfaces. Lidentifiant complet de linterface est dfini par le nom du package et le nom de linterface (package.interface). Une interface possde un corps qui dfinit ses membres : un ensemble de mthodes sans implantation et un ensemble de constantes. La syntaxe complte de la dclaration dune interface est illustre par le diagramme 7.6.

Diagramme 7.6 interface_declaration

Les modificateurs dune interface sont : abstract : par dfinition une interface est abstraite; public : une interface est visible pour les classes des autres packages uniquement si elle est dclare publique. Une interface non publique nest visible que pour les classes dfinies lintrieur de son package. Les combinaisons suivantes de modificateurs dinterfaces sont autorises :
public; public abstract

Quand une interface tend une autre interface (super-interface), elle hrite de toutes ses constantes et mthodes. La classe qui implante cette interface doit implanter la fois les mthodes de linterface et celles de sa super-interface.

Javabook Page 102 Lundi, 12. juillet 1999 3:58 15

102

Chapitre 7 Les structures

7.7 Dclaration de membres


Un membre (voir diagramme 7.7) est une composante dune dclaration de classe ou dinterface; il peut contenir une dclaration de mthode, de constructeur ou de variable, ou un initialiseur statique. Un initialiseur statique est un bloc dinstructions qui effectue des initialisations complexes des variables statiques dune classe. Il est excut juste aprs les initialisations simples (variable = expression) de ces variables.

Diagramme 7.7 field-declaration

7.8 Dclaration dune mthode et dun constructeur


La dclaration dune mthode peut commencer par un modificateur (private, private protected, protected ou public) qui indique son degr de visibilit. Contentons-nous pour linstant dindiquer que : par dfaut, la visibilit stend au package; private limite la visibilit la classe; public tend la visibilit tous les packages; private protected tend la visibilit aux sous-classes du mme package; protected tend la visibilit toute sous-classe. Nous tudierons tout ceci en dtail au point 24.2, p. 343. Il faut galement spcifier le type du rsultat retourn, ou void sil ny en a pas, le nom de la mthode, la liste des paramtres (de la forme type identificateur), puis les instructions excuter. Si le rsultat est un tableau, la liste de paramtres doit tre suivie de [ ], autant de fois que le tableau a de dimensions.

Diagramme 7.8 method_declaration

Javabook Page 103 Lundi, 12. juillet 1999 3:58 15

Cration dobjets

103

La dclaration dun constructeur suit le mme principe que celle dune mthode. Il ny a cependant pas de type de rsultat et le nom du constructeur doit tre identique celui de la classe.

Diagramme 7.9 constructor_declaration

7.9 Cration dobjets


Le mot rserv new suivi dun nom de classe et dune liste darguments cre un objet de cette classe et invoque le constructeur dont les types des paramtres correspondent aux types des arguments de la liste (voir diagramme 7.10). La cration dun tableau (vecteur) seffectue en donnant le type des lments suivi de la taille du tableau entre [ et ]. Si les lments sont eux-mmes des tableaux, il faut ajouter [ ] ([ ] [ ] pour des tableaux de tableaux, et ainsi de suite).

Diagramme 7.10 creating_expression

Javabook Page 104 Lundi, 12. juillet 1999 3:58 15

Javabook Page 105 Lundi, 12. juillet 1999 3:58 15

Chapitre 8

Exceptions et processus
8.1 Exceptions
Pour traiter de manire structure les situations exceptionnelles, Java offre un mcanisme dexceptions. Une exception est un objet particulier de la classe Exception ou dune de ses sous-classes qui est cr au moment o une situation anormale est dtecte. Une fois cre, lexception est lance (ou leve) laide de linstruction throw, ce qui a pour effet darrter lexcution normale du programme et de propager lexception jusquau premier bloc dinstructions capable de la capter et de la traiter (catch). Le traitement dexceptions introduit une nouvelle structure dinstruction dcrite par le diagramme 8.1 ci-dessous.

Diagramme 8.1 try_statement

En temps normal, linstruction suivant le try est excute. Si une exception survient, on saute directement au catch dont le type du paramtre correspond au type de lexception. Si aucun catch ne convient, lexception est propage aux blocs englobants puis, sils ne la captent pas, la mthode qui a invoqu celle o se trouve le try, et ainsi de suite, ventuellement jusquau systme dexcution Java qui interrompt alors le programme. Dans tous les cas de figure, linstruction suivant le finally est excute avant de quitter le bloc (mme si lexception na pas t capte et doit se propager).

Quelques exemples classiques


Lopration de conversion dune chane de caractres en un entier ne russit pas toujours, par exemple si la chane contient "*H\!aaa". Dans ce cas, une excep-

Javabook Page 106 Lundi, 12. juillet 1999 3:58 15

tion de type NumberFormatExeception est lance par la mthode Integer.ParseInt() :


String s = ... ; int i; try i = Integer.ParseInt(s); catch (NumberFormatExeception e) { System.out.prinln("erreur: la chane " + s + " ne peut pas tre convertie en un entier"); i = 0; }

Un processus (voir point suivant) peut se mettre en sommeil pour une certaine dure. Ce sommeil peut tre interrompu pour diverses raisons qui gnrent alors une exception de type InterruptedException :
try {Thread.sleep(2000);} // dort 2 secondes catch(InterruptedException signal) {} // continue simplement

Un problme peut survenir lors dune opration dentre-sortie, crant une exception de type IOException :
try {x=System.in.read(); ... catch (IOException e) { ... }

La tentative daccs un lment hors des limites dun tableau cause galement une exception :
try z = tab[i]; catch (ArrayIndexOutOfBounds ai) { System.out.println(ai.getMessage()); z = -1; }

Lexception est un objet qui peut contenir un texte informatif prcisant la nature du problme. La mthode getMessage() rcupre ce texte.

Gnrer des exceptions


Il est possible de crer ses propres types dexceptions en tendant la classe Exception et de lancer des exceptions laide de linstruction throw. Si une mthode lance ou propage des exceptions, elle doit lindiquer dans sa dclaration, sauf sil sagit dexceptions dune sous-classe de Error ou de RuntimeException.
class CalculImpossible extends Exception { public CalculImpossible { super(); } } class UneClasse { void uneMethode(int a, int b) throws CalculImpossible { ... if (a == b) throw new CalculImpossible(); ... } }

Javabook Page 107 Lundi, 12. juillet 1999 3:58 15

Processus et synchronisation

107

Il existe dj toute une hirarchie dexceptions dont le sommet est la classe Throwable.

8.2 Processus et synchronisation


Le langage Java a t prvu ds le dpart pour supporter lexcution concurrente de plusieurs processus. Un processus est un objet de la classe java.lang.Thread qui possde son propre environnement dexcution.

Cration de processus
Pour faire fonctionner un processus, il faut : 1. Crer un objet de la classe Thread (ou de lune de ses sous-classes). 2. Dmarrer lexcution du processus en invoquant la mthode start(). Il y a deux manires de crer des processus en Java : dfinir une sous-classe de Thread qui redfinit la mthode run();
class Pro1 extends Thread { public void run() { // ICI ce que fait le processus // } } ... Pro1 p1 = new Pro1(); p1.start(); // dmarre un processus qui excute p1.run()

crer un objet de Thread avec le constructeur Thread(Runnable obj) auquel on passe un objet qui implante Runnable, cest--dire qui possde une mthode run().
class Pro2 implements Runnable { public void run() { // ICI ce que fait le processus // } ... Pro2 q = new Pro2(); Thread p2 = new Thread(q); p2.start(); // dmarre un processus qui excute q.run()

Synchronisation
Deux processus peuvent vouloir accder aux mmes objets en mme temps, ce qui peut causer des problmes de cohrence. Pensons un processus qui calcule la somme des nombres contenus dans un tableau alors que, simultanment, un autre processus dplace les lments du tableau pour les trier. Pour prvenir ce type de situation, un processus peut sassurer laccs exclusif un objet.

Javabook Page 108 Lundi, 12. juillet 1999 3:58 15

108

Chapitre 8 Exceptions et processus

Linstruction synchronized() rserve un objet pour la dure de lexcution de linstruction qui suit puis le libre. Si lobjet est dj rserv (par un autre processus), synchronized() met le processus en attente jusqu ce que lobjet soit nouveau libre. lintrieur dun synchronized(o), le processus peut librer temporairement lobjet et se mettre en attente en appelant o.wait(). Il attendra jusqu ce quun autre processus excute un o.notify() puis libre lobjet o. Les mthodes wait() et notify() ne peuvent tre invoques que par un processus qui a rserv lobjet. Une mthode peut tre dclare synchronized, ce qui quivaut englober le corps de la mthode avec synchronized (this) {}. Nous verrons plusieurs exemples de processus dans la partie III et nous expliquerons plus en dtail la synchronisation et la concurrence au chapitre 25.

Javabook Page 109 Lundi, 12. juillet 1999 3:58 15

Partie III

Utiliser les classes de lenvironnement Java


Car de quelquun nayant pas toute sa tte peut-on raisonnablement affirmer quil se le demande et qui plus est sous peine dincohrence sacharne sur ce cassette avec tout ce qui lui reste de raison? Samuel Beckett, Soubresauts.

9. LAPI Java 10. Retour sur les applets 11. Dessiner 12. Animer 13. Interagir 14. Composants dinteraction graphique 15. Gestion des conteneurs 16. Protocoles de mise en pages 17. Manipulation dimages et de sons 18. Les composants Swing 19. Entres-sorties et persistance des objets 20. Les accs au rseau (java.net)

Javabook Page 110 Lundi, 12. juillet 1999 3:58 15

Javabook Page 111 Lundi, 12. juillet 1999 3:58 15

Chapitre 9

LAPI Java
Lenvironnement de dveloppement Java est fourni avec une interface de programmation dapplications (API : Application Programming Interface) appele Core API, regroupant un ensemble de classes prdfinies dusage gnral que lon retrouve sur toutes les plates-formes. Cette API dfinit les briques de base utiliser dans tout programme Java afin de lui assurer une portabilit maximale de son code. Le Core package de Java est actuellement constitu dune soixantaine de packages, les 15 de premier niveau figurant dans la table ci-dessous. Chaque package est spcialis dans un domaine particulier. Tous proposent des solutions de nombreux problmes auxquels tout programmeur Java est tt ou tard confront.
Package java.applet Description Fournit les classes ncessaires pour crer une applet et les classes pour que lapplet puisse communiquer dans son contexte dexcution. Fournit toutes les classes pour crer des interfaces avec lutilisateur pour peindre et afficher des images. Contient les interfaces et les classes pour le dveloppement de composants logiciels JavaBeans. Fournit les interfaces et les classes pour la gestion des entres/sorties travers des canaux de donnes, la srialisation et les systmes de gestion de fichiers. Prsent (mais remanie depuis) Java1.0 Prsent Trait 10

java.awt

Prsent en partie

11 17

java.beans java.io

24 19

Tableau 9.1 Les packages de lAPI Java 2

Javabook Page 112 Lundi, 12. juillet 1999 3:58 15

112
Package java.lang java.math Description Fournit les classes fondamentales pour la conception du langage de programmation Java. Fournit les interfaces et les classes pour effectuer des oprations en entier et dcimal dune prcision arbitraire (aussi longue que dsire). Fournit les classes pour la gestion du rseau et des communications. Fournit les services dinvocation distance des mthodes (Remote Method Invocation). Fournit les interfaces et les classes dans le cadre de la scurit. Fournit les services JDBC (Connection aux bases de donnes). Fournit les interfaces et les classes pour la manipulation des textes, des dates, des nombres et des messages dune manire indpendante des langues naturelles. Contient la gestion de quelques structures de donnes des utilitaires pour la manipulation des dates, un modle dvnement, etc. Dfinit un contrat entre les composants interface-utilisateur et des technologies dassistance lutilisateur (loupe, vocaliseur) Fournit un ensemble de composants lgers (entirement crits en Java, pour la gestion des interfaces, ils sont donc compltement indpendants de la plate-forme et ont un comportement similaire sur toutes les plate-formes). Fournit la correspondance entre l'API CORBA de l'OMG et le langage Java. Elle contient la classe ORB qui est un courtier d'objets (Object Request Broker) directement utilisable.

Chapitre 9 LAPI Java


Java1.0 Prsent Trait partout Exercice dans ce chapitre Prsent 20 29 utilis dans 29 et 30 28

java.net java.rmi java.security

java.sql java.text

java.util

Prsent sans les collections

23 et ailleurs

javax.accessibility javax.swing

18

org.omg.CO RBA

30

Tableau 9.1 Les packages de lAPI Java 2

Nous indiquons le chapitre de ce livre o ce package est trait.

9.1 Mthode de travail


Pour aborder cet environnement complexe, notre approche va tre la suivante.

Javabook Page 113 Lundi, 12. juillet 1999 3:58 15

Mthode de travail

113

Tout dabord faire un tour relativement complet des packages de base (java.applet, java.awt, java.io, java.lang, java.net, java.util). Ensuite, examiner les principes et les services spcialiss rendus principalement dans le cadre de la programmation distribue : accs aux bases de donnes (java.sql); invocation des mthodes distance (java.rmi); utilisation dun ORB (approche CORBA avec org.omg.CORBA); programmation des interfaces (javax.swing). Nous considrons ces ensembles de classes comme notre bote outils dont il va falloir apprendre se servir. Ainsi, avant de construire de nouveaux outils, il va tre important de bien connatre ceux dont nous disposons dj. Cette partie est consacre lapprentissage des fonctionnalits proposes par lAPI. Nous avons choisi de ne pas traiter les packages un un, mais de travailler autour de diffrents thmes : comment dessiner, crire? comment animer une applet? comment interagir avec la souris, avec le clavier? comment grer une fentre et son contenu? comment grer des fichiers? comment communiquer sur un rseau? Pour dcouvrir cette bote outils, nous vous proposons quelques lments de mthode ( prendre comme des conseils dami) : comprendre les concepts dfinis dans les packages; se familiariser avec les principales classes de ces packages; ne pas apprendre toutes les mthodes dfinies par ces classes; chercher, fouiller, butiner dans la documentation (trs complte), qui permet par exemple de trouver toutes les mthodes dune classe; examiner galement les mthodes hrites (examiner la super-classe). En rsum, pas de mmorisation systmatique mais plutt de lintuition concernant le comportement gnral dune classe. La mthode propose ici est la seule qui vous permettra de devenir autonome. En effet, les packages de base semblent dj consistants mais lensemble de lAPI java comporte plus de mille classes et plusieurs milliers de mthodes (7000). Seule une utilisation systmatique de la documentation fournie par Sun avec le JDK (Java Development Kit) vous permettra de survivre.

Javabook Page 114 Lundi, 12. juillet 1999 3:58 15

114

Chapitre 9 LAPI Java

9.2 La vraie classe Rectangle


Nous allons maintenant examiner de manire complte une classe et ses diffrentes mthodes. Nous avons choisi la classe Rectangle du package Java.awt (la vraie! ne pas confondre avec celle utilise dans nos exemples du chapitre 6). La documentation nous donne la filiation de Rectangle :
java.lang.Object java.awt.geom.RectangularShape java.awt.geom.Rectangle2D java.awt.Rectangle DefaultCaret

Ainsi que les sous-classes connues drives de Rectangle : Les interfaces qui sont implmentes par Rectangle : Rectangle hrite de la classe Rectangle2D des variables suivantes (des masques binaires pour situer un point (x,y) par rapport au rectangle dans lespace) :
OUT_BOTTOM, OUT_LEFT, OUT_RIGHT, OUT_TOP Shape, Serializable

Un Rectangle est dfini laide des variables dinstance x, y, width et height :


Variable
height width x y

Description Hauteur du rectangle Largeur du rectangle Coordonne en x du rectangle Coordonne en y du rectangle

Tableau 9.2 Variables dinstances de la classe Rectangle

Lobservation du package Java.awt nous indique que ces variables sont de type int et quelles sont public, ce qui signifie quon peut y accder dans toute instance de Rectangle. Le tableau 9.3 numre les constructeurs de cette classe.
Constructeur
Rectangle() Rectangle(int,int) Rectangle(int,int, int,int)

Description Construit un nouveau rectangle. Construit un nouveau rectangle et linitialise avec les paramtres width et height spcifis. Construit un nouveau rectangle et linitialise avec les paramtres x, y, width et height spcifis.

Tableau 9.3 Constructeurs de la classe Rectangle

Javabook Page 115 Lundi, 12. juillet 1999 3:58 15

La vraie classe Rectangle


Constructeur
Rectangle(Dimension) Rectangle(Point) Rectangle(Point, Dimension) Rectangle(Rectangle )

115
Description Construit un nouveau rectangle et linitialise avec le paramtre Dimension (un autre objet). Construit un nouveau rectangle et linitialise avec le paramtre Point (un autre objet). Construit un nouveau rectangle et linitialise avec les paramtres Point et Dimension (deux objets). Construit un nouveau Rectangle, initialis avec les donnes du rectangle spcifi.

Tableau 9.3 Constructeurs de la classe Rectangle

Nous constatons que lon peut travailler soit directement sur les variables dinstance des objets Rectangle, soit dans un modle plus labor bas sur les concepts de Point et de Dimension. Les diffrentes mthodes dclares dans la classe Rectangle (tableau 9.4) fournissent des oprations de composition, de manipulation et de comparaison.
Mthode
add(int, int)

Description Ajoute une coordonne (x,y) au rectangle, redfinit les dimensions du rectangle pour que celuici contienne ce point. Ajoute un Point au rectangle, redfinit les dimensions du rectangle pour que celui-ci contienne ce point. Ajoute un Rectangle au rectangle, redfinit les dimensions du rectangle pour que celui-ci contienne ce rectangle. Dtermine si le rectangle contient le point de coordonnes (x,y). Dtermine si le rectangle contient entirement le rectangle spcifi par les coordonnes (x,y) et les dimensions (w,h). Dtermine si le rectangle contient le point. Dtermine si le rectangle contient entirement le rectangle pass en paramtre. Retourne un nouveau rectangle (type Rectangle2D) reprsentant lintersection des deux rectangles.

add(Point)

add(Rectangle)

contains(int, int) contains(int, int, int, int)

contains(Point) contains(Rectangle) createIntersection(Rectan gle2D)

Tableau 9.4 Mthodes de la classe Rectangle

Javabook Page 116 Lundi, 12. juillet 1999 3:58 15

116
Mthode
createUnion(Rectangle2D)

Chapitre 9 LAPI Java


Description Retourne un nouveau rectangle (type Rectangle2D) reprsentant lunion des deux rectangles (le rectangle qui contient les deux !). Vrifie si deux rectangles sont gaux. Retourne le rectangle contenant ce rectangle (pour satisfaire la compltude demande par component !). Retourne le rectangle (haute prcision) contenant ce rectangle. Retourne la hauteur en double prcision du rectangle. Retourne le point localisant ce rectangle. Retourne les dimensions de ce rectangle. Retourne la largeur en double prcision du rectangle. Retourne la coordonne X en double prcision du rectangle. Retourne la coordonne Y en double prcision du rectangle. Agrandit le rectangle en x et en y. Dprcie. partir de la version JDK 1.1, remplace par contains (int, int). Calcule lintersection de deux rectangles. Vrifie si deux rectangles ont une intersection. Dtermine si le rectangle est vide. Dprcie. partir de la version JDK 1.1, remplace par setLocation (int,int). Dtermine o les coordonnes spcifies ne sappliquent pas avec ce rectangle (voir les champs OUT). Redfinit le rectangle (coordonnes et taille). Redfinit la taille du rectangle.

equals(Object) getBounds()

getBounds2D() getHeight() getLocation() getSize() getWidth() getX() getY() grow(int, int) inside(int,int) intersection(Rectangle) intersects(Rectangle) isEmpty() move(int, int) outcode(double,double)

reshape(int,int,int,int) resize(int, int)

Tableau 9.4 Mthodes de la classe Rectangle

Javabook Page 117 Lundi, 12. juillet 1999 3:58 15

La vraie classe Rectangle


Mthode
setBounds(int, int, int , int) setBounds(Rectangle) setLocation(int,int) setLocation(Point) setRect(double , double, double, double )

117
Description Dfinit les bornes du rectangle avec les coordonnes (x,y) et les dimensions (w,h). Dfinit les bornes du rectangle avec celles du rectangle donnes en paramtre. Dplace ce rectangle la position (x,y). Dplace ce rectangle aux coordonnes du point. Dfinit les bornes du rectangle avec les coordonnes (x,y) et les dimensions (w,h) donnes en double prcision. Dfinit ce rectangle la dimension donne. Dfinit ce rectangle aux dimensions (w,h). Retourne sous forme de String les valeurs dfinissant le rectangle. Effectue une translation sur le rectangle. Calcule lunion de deux rectangles.

setSize(Dimension) setSize(int,int) toString() translate(int, int) union(Rectangle)

Tableau 9.4 Mthodes de la classe Rectangle

On peut constater que loutil Rectangle est bien afft, mais quil peut encore tre tendu (si le cur vous en dit) en dfinissant sa surface, son primtre, etc. Mais ce nest pas tout, un objet hrite de nombreuses mthodes de sa filiation. Examinons cette dernire. Mthodes hrites de la classe java.awt.geom.Rectangle2D :
add, add, add, contains, contains, getPathIterator, getPathIterator, hashCode, intersect, intersects, intersectsLine, intersectsLine, outcode, setFrame, setRect, union

Mthodes hrites de la classe java.awt.geom.RectangularShape :


clone, contains, contains, getCenterX, getCenterY, getFrame, getMaxX, getMaxY, getMinX, getMinY, intersects, setFrame, setFrame, setFrameFromCenter, setFrameFromCenter, setFrameFromDiagonal, setFrameFromDiagonal

Mthodes hrites de la classe java.lang.Object :


finalize, getClass, notify, notifyAll, wait, wait, wait

Comment se rappeler ce quil y a dans cette classe? Fermez les yeux, imaginez un monde de Rectangles : ils se crent, grandissent, se dplacent, interagissent, fusionnent, etc. Nous avons bien l les bonnes mthodes, celles qui rgissent le

Javabook Page 118 Lundi, 12. juillet 1999 3:58 15

118

Chapitre 9 LAPI Java

monde des Rectangles. Aussi vaut-il mieux comprendre ce monde que tenter de mmoriser les dtails des mthodes de cette classe. Dans la suite de cette partie, nous examinerons plusieurs autres mondes sans pour autant tre exhaustif, car nous nous intresserons principalement aux interactions entre tous ces mondes. Dans la documentation de Sun, on trouvera une description dtaille de chacune des classes ou chacun des champs que nous avons cits. Nous donnons sans le traduire un exemple de cette documentation pour la mthode translate.
public void translate(int x, int y) Translates this Rectangle the indicated distance, to the right along the x coordinate axis, and downward along the y coordinate axis. Parameters: dx - the distance to move this Rectangle along the x axis dy - the distance to move this Rectangle along the y axis See Also: setLocation(int, int), setLocation(java.awt.Point)

la fin de chaque chapitre, nous inviterons le lecteur continuer son exploration en lui proposant quelques exercices.

9.3 Invitation explorer


Pour le package java.math, nous navons pas prvu dexplication particulire. Par contre, un petit exercice peut tre aussi utile : dresser un petit tableau des possibilits offertes par le package java.math; calculer avec une prcision arbitraire 100 !,1000 ! (rappelons que n ! (factoriel) est le produit des nombres entiers de 1 n, par exemple 5 ! =1*2*3*4*5=120).

Javabook Page 119 Lundi, 12. juillet 1999 3:58 15

Chapitre 10

Retour sur les applets


Les programmes Java peuvent prendre deux formes : les applications et les applets. Les applications sont des programmes au sens classique du terme, cest--dire quelles sont stockes sur la machine qui va les excuter. Les applets1 quant elles sont destines tre charges depuis une machine (le serveur) et excutes sur une autre machine (le poste du client). Linvocation dune applet est ralise depuis lintrieur dun document HTML. Ainsi, toute page HTML peut faire appel un programme (une applet) dont la taille est souvent moins importante que celle des images dcorant les pages HTML actuelles. Lexcution de lapplet est confie un butineur muni dun interprteur Java (comme par exemple HotJava, Netscape Navigator ou Internet Explorer). Cette configuration, combinant le meilleur du Web et de Java, permet de distribuer des applications indpendamment de la plate-forme utilise pour leur excution. Le butineur sait quand il doit charger une applet, un nouveau dlimiteur <APPLET> ayant t dfini cet effet. Il lui indique lemplacement du code Java charger et les diffrents paramtres de mise en pages de lapplet. Ainsi, seule une rfrence au code Java est incluse dans la page HTML (contrairement JavaScript qui inclut du code dans la page HTML). Afin dassurer au client une excution sre et lui viter certains ennuis (virus, cheval de Troie), le comportement dune applet est quelque peu brid : une applet ne peut pas lire ou crire de fichiers sur le systme du client (ou alors uniquement dans des rpertoires prdfinis) :
1. Prononcez applette.

Javabook Page 120 Lundi, 12. juillet 1999 3:58 15

120

Chapitre 10 Retour sur les applets

une applet ne peut pas communiquer avec dautres machines que celle depuis laquelle elle a t charge; une applet ne peut pas dmarrer lexcution de programmes sur le systme du client; une applet ne peut pas charger de programmes natifs sur le systme du client (DDL, driver, etc.). Le client peut galement configurer le degr de scurit quil dsire. Cette souplesse provient du fait que le code Java est destin tre excut sur une machine virtuelle. Celle-ci (incorpore dans le butineur Web) est le passage oblig entre le systme du client et le code du programme charg. Il est ainsi possible de contrler le comportement de nimporte quel programme : toute opration daccs aux ressources (fichiers, communications) devra obligatoirement transiter par la machine virtuelle, qui peut la refuser si elle nest pas autorise. Nous reviendrons plus en dtail sur ces aspects scurit au chapitre 27.

10.1 Comment crer une applet


Une applet est une classe Java dclare public et tendant la classe java.applet.Applet. Nos applets auront donc toutes la forme suivante :
public nomApplet extends java.applet.Applet {}

Une applet, comme nimporte quelle classe, peut tre plus ou moins complexe et faire rfrence dautres classes. Elle peut galement implanter des interfaces. Lexemple suivant est une applet qui dessine un carr noir (voir applet 1) :
import java.awt.Graphics; public class ComportementApplet extends java.applet.Applet { public void paint(Graphics g) { g.fillRect(5,5,40,40); } }

Pour pouvoir excuter cette applet, il faut tout dabord la compiler. Le rsultat de la compilation (une fois les erreurs corriges) est un fichier portant le nom de lapplet suivi de lextension .class (ComportementApplet.class) indiquant quil sagit de code excutable. Il faut ensuite incorporer un appel ce fichier de code dans une page HTML, laide du dlimiteur <APPLET>. Lexemple qui suit montre les paramtres dclarer, dans le cas o la page HTML et le code de lapplet rsident dans le mme rpertoire. Nous devons obligatoirement prciser : le nom du fichier de code de lapplet (ComportementApplet.class); la taille de la surface occupe par lapplet dans la page HTML lors de son excution.

Javabook Page 121 Lundi, 12. juillet 1999 3:58 15

Le dlimiteur <Applet> en dtail

121

Page HTML minimale pour invoquer lexcution de notre applet :


<html> <head><title>Comportement Applet</title></head> <body><h1>Le minimum</h1> <applet code=ComportementApplet.class width=50 height=50> </applet> </body> </html>

Il ne reste alors plus qu charger la page HTML dans un butineur capable dexcuter du code Java pour obtenir notre premire applet :

Applet 1 : Une applet minimum

Que defforts pour un rsultat bien modeste, alors quune simple image gif ferait aussi bien laffaire! Mais que de promesses galement, si lon y rflchit : il est possible de modifier le programme de lapplet afin de lui donner un nouveau comportement sans modifier la page HTML et sans avoir distribuer la nouvelle version aux clients; il est possible dincorporer cette applet dans plusieurs pages HTML et de lui donner des comportements diffrents, selon les paramtres qui lui sont associs; il est possible que dautres serveurs fassent rfrence cette applet; il est possible quun programmeur dveloppe sur un Macintosh du code destin des utilisateurs de PC ou de stations Unix (et vice versa); il est possible de transformer une page HTML en tableur, en modeleur 3D, en cockpit davion, en machine sous, etc.

10.2 Le dlimiteur <Applet> en dtail


Nous venons de constater quil est ncessaire de prciser dans le dlimiteur <APPLET> la source du code charger et la taille de lespace occup par lapplet dans la page HTML lors de son excution. Le diagramme 10.1 indique quil est aussi possible dassocier des paramtres lapplet quelle pourra rcuprer au moment de son excution. Certains butineurs tant encore incapables dexcuter du code Java, il faut pr-

Javabook Page 122 Lundi, 12. juillet 1999 3:58 15

122

Chapitre 10 Retour sur les applets

voir dans le code HTML un texte de substitution lapplet. Deux solutions existent : placer du code HTML entre les deux dlimiteurs dinvocation <APPLET> et </APPLET>. Ce code sera alors interprt par le butineur; ajouter loption alt=texte dans le dlimiteur. Ce texte sera affich dans le cas o le butineur connat le dlimiteur <APPLET> mais quil ne peut pas excuter lapplet.

Diagramme 10.1 applet_tag

Le diagramme 10.2 dcrit les rgles didentification de lapplet. Loption code est obligatoire, elle dfinit le nom du fichier contenant le code de lapplet. Le chemin daccs doit tre imprativement dfini dans loption codebase sil est diffrent de celui de la page HTML contenant linvocation de lapplet. Loption name permet de donner un nom lapplet lors de son excution dans le butineur. Plusieurs applets peuvent ainsi cohabiter dans une mme page et ventuellement collaborer une tche (changer des informations, se synchroniser).

Diagramme 10.2 applet_id

La taille de lapplet est dfinie laide des deux paramtres width (largeur) et height (hauteur), indiqus en pixels. On peut galement prciser lalignement de lapplet dans la page et lespace laisser vide autour de lapplet (diagramme 10.3).

Diagramme 10.3 applet size

Examinons ces diffrentes options laide dexemples. Ainsi, lapplet 2 montre que :

Javabook Page 123 Lundi, 12. juillet 1999 3:58 15

Le dlimiteur <Applet> en dtail

123

lespace occup par lapplet se comporte de faon similaire lespace occup par une image; lalignement horizontal situe lapplet par rapport au texte; la mme applet peut tre invoque plusieurs fois dans une mme page.
<html> <head><title>Comportement Applet</title></head> <h1>comme une image</h1> <applet code=ComportementApplet.class width=50 height=50 align=left> votre butineur ne sait pas excuter du Java, dommage!<p> </applet> Ce texte doit continuer droite de l'applet et couler sans problme comme avec une image.<p> <applet code=ComportementApplet.class width=50 height=50 align=right> </applet> Ce texte doit continuer gauche de l'applet et couler sans problme comme avec une image.<p> </body> </html>

Applet 2 : Emplacements occups par une applet dans une page HTML

Lapplet 3 illustre lutilisation des options vspace et hspace qui permettent de dfinir un cadre vide autour de la surface occupe par lapplet :
<html> <head><title>Comportement Applet</title></head> <applet code=ComportementApplet.class width=50 height=50 align=left vspace=50 hspace=30> votre butineur ne sait pas executer du Java, dommage!<p> </applet> <h1>alignement</h1> Ce texte doit continuer droite du cadre de l'applet et couler sans problme comme avec une image.<p> </body> </html>

Enfin, examinons les possibilits dalignement vertical (par le haut, par le milieu et par le bas). Chaque alignement peut agir de deux manires : lune relative au

Javabook Page 124 Lundi, 12. juillet 1999 3:58 15

124

Chapitre 10 Retour sur les applets

texte actuellement utilis dans la ligne, lautre absolue. Cette seconde manire permet de saligner sur les lments les plus grands de la ligne courante.

Applet 3 : Cadre vide autour dune applet

Diagramme 10.4 align options

Lapplet 4 illustre ces possibilits laide dune deuxime applet dessinant un carr plus grand, afin de crer des diffrences de taille dans la mme ligne.
<html> <head><title>Comportement Applet</title></head> <h1>alignement ...</h1> ligne de base texttop <applet code=ComportementApplet2.class width=80 height=80 align=texttop></applet> absolu absbottom <applet code=ComportementApplet.class width=50 height=50 align=absbottom></applet><br> ligne de base middle <applet code=ComportementApplet2.class width=80 height=80 align=middle></applet> absolu top <applet code=ComportementApplet.class width=50 height=50 align=top></applet><br> ligne de base bottom <applet code=ComportementApplet2.class width=80 height=80 align=bottom></applet> absolu absmiddle <applet code=ComportementApplet.class width=50 height=50 align=absmiddle></applet><br> </body> </html>

Javabook Page 125 Lundi, 12. juillet 1999 3:58 15

Le dlimiteur <Applet> en dtail

125

Applet 4 : Alignement dapplets dans une page HTML

Comme nous lavons indiqu au point 10.1, une applet peut recevoir des paramtres inclus dans la page HTML, ce qui permet dtendre son comportement (ainsi que celui de HTML). Chaque paramtre est enferm dans un dlimiteur, auquel on associe un nom et une valeur (diagramme 10.5).

Diagramme 10.5 applet parameter

Dans lapplet 5, nous utilisons Java pour dessiner des rectangles noirs de diffrentes tailles donnes en paramtres. Pour accder un paramtre depuis lapplet, nous faisons appel une mthode getParameter("nom_du_paramtre") qui permet de rcuprer (dans une chane de caractres) la valeur associe ce paramtre. Ensuite, nous transformons cette chane de caractres en un entier laide de la mthode approprie. Ce programme utilise galement la mthode resize() qui demande au butineur de redimensionner la taille occupe par lapplet (les paramtres width et height sont alors redfinis).
import java.awt.Graphics; public class BlackRect extends java.applet.Applet { String parametre; int tailleRect;

Javabook Page 126 Lundi, 12. juillet 1999 3:58 15

126

Chapitre 10 Retour sur les applets


public void init() { parametre = getParameter("Rect"); if (parametre == null) tailleRect = 50; else tailleRect = Integer.parseInt(parametre); resize(tailleRect+10, tailleRect+10); } public void paint(Graphics g) { g.fillRect(5,5,tailleRect,tailleRect); }

Code HTML invoquant lapplet avec diffrentes valeurs de paramtres :


<html> <head><title>Comportement Applet</title></head> <body> <h1>utilisation des paramtres</h1> <applet code=BlackRect.class width=50 height=50 align=left> <PARAM NAME=Rect VALUE="10"></applet> <applet code=BlackRect.class width=50 height=50 align=left> <PARAM NAME=Rect VALUE="20"></applet> <applet code=BlackRect.class width=50 height=50 align=left> <PARAM NAME=Rect VALUE="30"></applet> </body> </html>

Applet 5 : Utilisation des paramtres dune applet

On peut aisment imaginer dajouter dautres paramtres permettant de spcifier la couleur ou la forme des objets gomtriques dessiner. On verra plus loin quil est possible de spcifier le chargement dun ensemble de classes dans une applet au moyen des fichiers darchive .jar. Nous avons plac le code permettant de rcuprer les paramtres dans une mthode init() appartenant lapplet. Voyons cela de plus prs, en tudiant le cycle de vie des applets, avant den programmer de plus compliques.

10.3 Vie et mort dune applet


Le cycle de vie dune applet se compose de lexcution successive des mthodes :

Javabook Page 127 Lundi, 12. juillet 1999 3:58 15

Vie et mort dune applet

127

init() : aprs son chargement (ou lors dun rechargement), lapplet excute cette mthode dinitialisation; start() : est invoque directement aprs linitialisation, ainsi quaprs un stop(), si le document contenant lapplet redevient nouveau visible pour lutilisateur; stop() : est invoque lorsque le document contenant lapplet disparat (changement de page HTML); en redfinissant stop(), on peut interrompre un traitement (par exemple une animation) si lapplet nest plus visible par lutilisateur; destroy() : est invoque avant la disparition de lapplet, afin de restituer les ressources et de quitter proprement le systme. On peut redfinir chacune de ces mthodes si lon tient donner un comportement particulier lapplet durant ces transitions. En fait, lapplet hrite de la classe java.awt.Component et sa principale activit sera paint(). Ceci explique pourquoi notre premire applet redfinissait cette mthode.
init()

start() autres activits paint() stop()

destroy() Figure 10.6 Cycle de vie dune applet

Javabook Page 128 Lundi, 12. juillet 1999 3:58 15

Javabook Page 129 Lundi, 12. juillet 1999 3:58 15

Chapitre 11

Dessiner
Nous allons examiner comment dessiner dans lespace occup par une applet. Pour cela, nous dcrivons en dtail la classe Graphics qui contient de nombreuses mthodes de dessin. Elle se trouve dans le package java.awt et doit tre importe par toute classe dsirant lutiliser. Lactivit principale dune applet graphique est dfinie dans sa mthode paint(). Celle-ci est invoque lors dvnements ncessitant de redessiner la surface occupe par lapplet. La mthode paint() reoit comme paramtre un objet de la classe Graphics dcrivant lenvironnement graphique courant (couleurs, fond). Nos applets auront donc lallure suivante :
import java.awt.Graphics; public class Figure extends java.applet.Applet { public void paint(Graphics g) { ... } }

11.1 La feuille
La feuille de dessin est reprsente par une matrice de points dont chaque coordonne est dfinie par un couple dentiers. La classe Point (variables dinstance x pour horizontal et y pour vertical) permet de manipuler des coordonnes. La mthode getSize() fournit la taille de la feuille sous la forme dun objet de la classe Dimension (variables dinstance width : largeur et height : hauteur). Par consquent, les coordonnes des quatre coins de la feuille sont : (0 , 0) : le coin suprieur gauche; (getSize().width , 0) : le coin suprieur droit;

Javabook Page 130 Lundi, 12. juillet 1999 3:58 15

130

Chapitre 11 Dessiner

(0 , getSize().height) : le coin infrieur gauche; (getSizesize().width, getSize().height) : le coin infrieur droit.


0,0 4, 1 +X

2, 5 +Y

Figure 11.1 Systme de coordonnes de Graphics

11.2 Dessiner une ligne


Par dfaut, la feuille est remplie avec une couleur de fond (background) grise, les dessins apparaissant en noir. Pour dessiner une ligne, il faut spcifier son point de dpart et son point darrive. Lapplet 6 dessine une ligne horizontale1 :
public void paint(Graphics g) { g.drawLine(50,25,100,25); }

Applet 6 : Dessiner une ligne

En dessinant un ensemble de segments de droites (applet 7), on peut dessiner une fonction f (ne faites pas attention aux appels getSize(), ils sont l pour cadrer la fonction cosinus dans la feuille de dessin). La boucle for calcule, pour chaque coordonne x de la feuille, le segment de droite qui le relie au prochain point de la courbe.
import java.awt.Graphics; public class Figure extends java.applet.Applet { double f(double x) { return (Math.cos(x/10)+1) * getSize().height / 2; } public void paint(Graphics g) {
1. On ne prsente que les extraits significatifs des applets. Le texte complet de lapplet contient : import...; class...; etc.

Javabook Page 131 Lundi, 12. juillet 1999 3:58 15

Rectangles
for (int x = 0 ; x < getSize().width ; x++) { g.drawLine(x, (int)f(x), x + 1, (int)f(x + 1)); } } }

131

Applet 7 : Dessiner une fonction (cosinus)

11.3 Rectangles
La classe Graphics propose de nombreuses mthodes capables de dessiner des formes gomtriques : rectangles, polygones, ovales et arcs. Pour chacune de ces formes, il existe une paire de mthodes : draw... qui dessine le contour de la forme et fill... qui remplit la forme. Dans le cas des rectangles, nous devons indiquer les paramtres suivants dans lordre : int x : la coordonne x du coin suprieur gauche; int y : la coordonne y du coin suprieur gauche; int width : la largeur du rectangle; int height : la hauteur du rectangle. Lapplet 8 ci-dessous dessine deux rectangles cte cte :
public void paint(Graphics g) { g.drawRect(50,30,20,30); g.fillRect(80,30,20,30); }

Applet 8 : Dessiner des rectangles

La classe Graphics propose galement des rectangles aux coins arrondis; il faut alors ajouter deux paramtres : int arrondiX : largeur de larrondi (axe des X); int arrondiY : hauteur de larrondi (axe des Y). Lapplet 9 le montre en dessinant deux rectangles arrondis cte cte :
public void paint(Graphics g) { g.drawRoundRect(50,70,20,30,15,15); g.fillRoundRect(80,70,20,30,15,20); }

Javabook Page 132 Lundi, 12. juillet 1999 3:58 15

132

Chapitre 11 Dessiner

Applet 9 : Dessiner des rectangles aux coins arrondis

Enfin, des rectangles peuvent tre dessins en relief (peu visible selon les butineurs). Un paramtre supplmentaire de type boolen indique : false : le rectangle est en relief; true : le rectangle est en creux. Lapplet 10 dessine un rectangle en creux ( gauche) et un en relief ( droite) :
public void paint(Graphics g) { g.draw3DRect(50,110,20,30,true); g.fill3DRect(80,110,20,30,false); }

Applet 10 : Dessiner des rectangles en relief

11.4 Polygones
Le dessin dun polygone requiert deux tableaux de coordonnes. Lun pour les valeurs en X et lautre pour les valeurs en Y. Un polygone nest pas ferm automatiquement. Le nombre de points dessiner doit tre indiqu au moment de lappel la mthode de dessin. Lapplet 11 dessine deux polygones, dont lun est rempli en invoquant la mthode fillPolygon(). On notera au passage la manire dinitialiser des tableaux et celle de rcuprer leur taille grce la mthode length() :
public void paint(Graphics g) { int listeX[]={50,40,80,100,55}; int listeY[]={150,170,200,170,160}; int nbrXY=listeX.length; // nombre de points dessiner g.drawPolygon(listeX, listeY, nbrXY); int listeY2[]={200,220,250,220,210}; g.fillPolygon(listeX, listeY2, nbrXY); }

11.5 Cercles, ovales, arcs


Les formes ovales (cercle, ovale, arc) pouvant toutes sinscrire dans un rectangle, leurs mthodes de dessin se basent sur les dimensions de celui-ci. Les paramtres utiliss sont : x, y, largeur, hauteur (x et y indiquant le coin suprieur gau-

Javabook Page 133 Lundi, 12. juillet 1999 3:58 15

Gommer, copier

133

che du rectangle). noter que pour obtenir un cercle, hauteur doit tre gale largeur. Lapplet 12 dessine ainsi un ovale et un cercle :
public void paint(Graphics g) { g.drawOval(120,30,20,30); g.fillOval(150,30,30,30); }

Il est galement possible de dessiner des arcs. Deux paramtres supplmentaires (exprims en degrs) sont ncessaires : le premier indique langle de dpart de larc, le second les degrs ncessaires la ralisation du dessin. Lapplet 13 dessine deux arcs. On remarquera que lon peut associer des valeurs ngatives aux paramtres exprims en degrs.
public void paint(Graphics g) { g.drawArc(120,70,20,30,45,180); g.fillArc(150,70,30,30,45,-150); }

Applet 11 : Dessiner des polygones

Applet 12 : Dessiner des cercles et des ovales

Applet 13 : Dessiner des arcs

11.6 Gommer, copier


La mthode clearRect() efface une zone rectangulaire :
g.clearRect (x, y, largeur, hauteur);

La mthode copyArea() copie une zone rectangulaire une nouvelle coordonne (nx, ny) :
g.copyArea(x, y, largeur, hauteur, nx, ny);

Javabook Page 134 Lundi, 12. juillet 1999 3:58 15

134

Chapitre 11 Dessiner

11.7 Colorier
Le package awt dfinit une classe Color pour reprsenter les couleurs. Une couleur est code sur 24 bits : huit pour chacune des trois couleurs fondamentales de la vido (rouge, vert, bleu), ce qui reprsente environ seize millions de possibilits. Le nombre de couleurs effectivement affiches dpend bien entendu des capacits de votre cran et du butineur. La classe Color propose galement une palette de couleurs prdfinies (voir tableau 11.1).
Couleur Blanc Gris ple Gris Gris fonc Noir Rouge Vert Bleu Jaune Magenta Cyan Rose Orange Nom de couleur
Color.white Color.lightGray Color.gray Color. darkGray Color.black Color.red Color.green Color.blue Color.yellow Color. magenta Color. cyan Color.pink Color.orange

Rouge, Vert, Bleu


255,255,255 192,192,192 128,128,128 64,64,64 0,0,0 255,0,0 0,255,0 0,0,255 255,255,0 255,0,255 0,255,255 255,175,175 255,200,0

Tableau 11.1 Couleurs prdfinies dans la classe Color

On peut dfinir de nouvelles couleurs et tendre la palette laide de la mthode Color(R, V, B) o les valeurs de R, V et B sont comprises entre 0 et 255 (ou entre 0.0 et 1.0). Exemple :
Color bleuPale = new Color(0,0,80);

La couleur du fond (arrire-plan) est dfinie par la mthode setBack ground(Color) de la classe Component (Applet hrite de cette classe abstraite). Lexemple suivant impose un fond blanc :
setBackground(Color.white);

La mthode getBackground() de la classe Component retourne la couleur ac-

Javabook Page 135 Lundi, 12. juillet 1999 3:58 15

crire

135

tuelle du fond tandis que la mthode setForeground(Color) impose une couleur de dessin, par exemple le rose :
setForeground(Color.pink);

La classe Graphics propose encore les mthodes setColor(Color) pour redfinir la couleur avec laquelle on dessine et getColor() pour connatre la couleur de dessin courante. Regardez la documentation pour les autres constructeurs de Color(). Il existe deux mthodes brigther() et darker() qui permettent dobtenir des couleurs plus claires et plus fonces ayant la mme tonalit que la couleur sur laquelle elles sont appliques.

11.8 crire
La classe Graphics traite non seulement des formes gomtriques mais galement du texte de diffrentes tailles, fontes, couleurs, etc. La mthode drawString() permet de dessiner une chane de caractres partir dune coordonne (x,y). Lapplet 14 montre que la couleur courante est galement utilise pour le dessin des caractres.
import java.awt.Graphics; import java.awt.Color; public class MaPremiereApplet extends java.applet.Applet { public void paint(Graphics g) { g.setColor(Color.black); g.drawString("Ma premire applet politise!", 50, 30); g.setColor(Color.blue); g.drawString("Libert", 50, 60); g.setColor(Color.white); g.drawString("Egalit", 50, 90); g.setColor(Color.red); g.drawString("Fraternit", 50, 120); } }

Applet 14 : Dessiner du texte en couleur

Javabook Page 136 Lundi, 12. juillet 1999 3:58 15

136

Chapitre 11 Dessiner

11.9 Les polices


Les polices de caractres (fontes) dterminent lapparence des caractres et des textes affichs. Elles sont gres par la classe java.awt.Font. Pour construire une nouvelle fonte, il faut instancier un objet Font et linitialiser avec les paramtres suivants : le nom de la police : Helvetica, TimesRoman, Courier par exemple sont des fontes disponibles sur tous les butineurs; le style des caractres : trois constantes sont disposition Font.PLAIN (normal), Font.BOLD (gras), Font.ITALIC (italique). Il est possible de spcifier des styles composs en additionnant ces constantes; la taille des caractres : elle est indique en nombre de points. Comme pour les couleurs, il est ncessaire de dfinir la police utiliser, ce que ralise la mthode setFont(). Dans lapplet 15, nous dfinissons plusieurs polices que nous utilisons au fur et mesure de nos besoins.
import java.awt.Graphics; import java.awt.Color; import java.awt.Font; public class MaPremiereApplet extends java.applet.Applet { public void paint(Graphics g) { Font helvetica14Normal = new Font("Helvetica",Font.PLAIN,14); Font courier12Gras = new Font("Courier",Font.BOLD,12); Font timesRoman18Italic = new Font("TimesRoman",Font.ITALIC,18); Font timesRoman18ItalicGras = new Font ("TimesRoman",Font.ITALIC+Font.BOLD,18); g.setColor(Color.black); g.setFont(helvetica14Normal); g.drawString("Le mme avec emphase!", 50, 30); g.setColor(Color.blue); g.setFont(courier12Gras); g.drawString("Libert", 50, 60); g.setColor(Color.white); g.setFont(timesRoman18Italic); g.drawString("Egalit", 50, 90); g.setColor(Color.red); g.setFont(timesRoman18ItalicGras); g.drawString("Fraternit", 50, 120); } }

Javabook Page 137 Lundi, 12. juillet 1999 3:58 15

Les polices

137

Applet 15 : Dessiner des textes dans plusieurs fontes

La classe Font fournit des informations propos dune fonte (voir tableau 11.2). Ainsi, la police courante est obtenue laide de la mthode getFont() applique un composant graphique.
Mthode
getName() getSize() getStyle() isPlain() isBold() isItalic()

Description (information propos de la fonte) Retourne un string indiquant le nom de la fonte. Retourne un entier indiquant la taille de la fonte. Retourne un entier indiquant le style (0, 1, 2, 3). Retourne un boolen, vrai si le style est normal. Retourne un boolen, vrai si le style est gras. Retourne un boolen, vrai si le style est italique.

Tableau 11.2 Mthodes de la classe Font

Java 2 a particulirement dvelopp la class Font. Les concepts de caractre et de glyphe sont entirement spars. Il est donc possible dutiliser les ligatures, par exemple les deux caractres, f suivi de i deviennent un seul glyphe fi. Les police connues par Java sont toutes celles connues par le systme sur lequel sexcute le code. La mthode getAllFonts() permet dobtenir cette liste. Il existe des mthodes pour crer, driver et transformer des polices existantes et ainsi den obtenir de nouvelles. Il nexiste donc priori aucune limitation typographique pour le dveloppeur Java. Il ne lui suffit que dun peu de courage pour entrer dans cet univers! En utilisant des polices connues dun seul systme dexploitation, on risque de perdre la mobilit du code Java. Il faut donc obtenir un quilibre entre la mobilit et lesthtique. Pour permettre la justification prcise des caractres, la classe java.awt.FontMetrics calcule la taille occupe par une chane de caractres. Il sera donc possible, par exemple, de centrer un texte dans une applet dont la taille varie. Prcisons que toutes ces mthodes utilisent le point comme unit.

Javabook Page 138 Lundi, 12. juillet 1999 3:58 15

138
Mthode
stringWidth() charWidth() getAscent() getDescent() getLeading() getHeight()

Chapitre 11 Dessiner
Description (information propos dune chane) Retourne un entier indiquant la largeur dune chane. Retourne un entier indiquant la largeur dun caractre. Retourne un entier indiquant la hauteur de la fonte audessus de la ligne de base. Retourne un entier indiquant la hauteur de la fonte audessous de la ligne de base. Retourne un entier indiquant lespace entre les lignes. Retourne un entier indiquant la hauteur totale de la fonte.

Tableau 11.3 Mthodes de la classe FontMetrics

Dans lapplet 16, nous dsirons centrer nos chanes de caractres. Nous construisons cet effet une mthode writeCenter() qui reoit pour paramtres : g le composant graphique dans lequel elle va dessiner; s la chane crire; y la hauteur de cette chane. La mthode getFontMetrics(g.getFont()) permet de connatre la mtrique actuellement utilise par le composant graphique. Linstruction java.awt.* importe toutes les classes du package awt :
import java.awt.*; public class MonPremierApplet extends java.applet.Applet { Font helvetica18Normal = new Font("Helvetica",Font.PLAIN,18); public void writeCenter(Graphics g, String s, int y){ FontMetrics metriqueCourante=getFontMetrics(g.getFont()); g.drawString( s, (getSize().width-metriqueCourante.stringWidth(s))/2, y); } public void paint(Graphics g) { g.setColor(Color.blue); g.setFont(helvetica18Normal); writeCenter(g, "Le mme avec emphase au centre!", 30); writeCenter(g, "Libert", 60); writeCenter(g, "Egalit", 90); writeCenter(g, "Fraternit", 120); } }

Javabook Page 139 Lundi, 12. juillet 1999 3:58 15

Reprsenter la troisime dimension en couleur

139

Applet 16 : Dessiner du texte centr

Cet exemple est un peu simplifi. Dans labsolu, on ne connat pas la hauteur des caractres qui vont simprimer et nous aurions d interroger la fonte sur sa taille avec les mthodes de FontMetrics et non utiliser un interligne fixe. La classe FontMetrics propose dautres mthodes que celles dcrites ci-dessus pour mesurer lespace pris par une chane de caractres. noter la mthode getStringBounds() qui existe en plusieurs variantes et qui retourne un objet Rectangle2D donnant les dimensions du texte afficher dans un objet Graphics (une applet, par exemple). Dans lexemple suivant, on a utilis cette mthode pour redfinir la mthode writeCenter(). On remarquera la conversion de type (casting) vers le type Rectangle qui possde la mthode width() et qui est sous-classe de Rectangle2D.
public void writeCenter(Graphics g, String s, int y){ FontMetrics metriqueCourante= getFontMetrics(g.getFont()); g.drawString(s,(getSize().width((Rectangle)metriqueCourante.getStringBounds(s,g)).width)/2, y);

11.10 Reprsenter la troisime dimension en couleur


Nous allons maintenant tudier un exemple qui utilise largement les couleurs. Notre objectif est de reprsenter la troisime dimension par lintensit dune couleur. Nous importons tout dabord les classes ncessaires :
import java.awt.Graphics; import java.awt.Color;

Notre programme sera une applet :


public class Figure extends java.applet.Applet {

La fonction f reprsenter est le sinus du carr de la distance dun point sur le plan par rapport lorigine (ou plus simplement : une sorte de vague oscillant de plus en plus vite). La valeur de f est comprise entre 1.0 et -1.0.
double f(double x, double y) { return (Math.sin((x*x+y*y)/5000)); }

Javabook Page 140 Lundi, 12. juillet 1999 3:58 15

140

Chapitre 11 Dessiner

Nous redfinissons la mthode paint() et dclarons une variable pour chacune des couleurs de base. offsetx et offsety sont des constantes nous permettant de recentrer le dessin dans lespace occup par lapplet :
public void paint(Graphics g) { int rouge, vert, bleu; int offsetx, offsety;

Nous initialisons nos variables (on peut aussi le faire lors de la dclaration!). getSize().width et getSize().height permettent de rcuprer la taille de la zone de dessin.
vert=0; bleu = 128; offsetx=getSize().width/2; offsety=getSize().height/2;

Nous allons uniquement faire varier la nuance de la couleur rouge (de 0 255) en fonction de la valeur de f pour chaque coordonne du plan. La premire boucle balaie les valeurs x (axe horizontal) :
for (int x = 0 ; x < getSize().width ; x++) {

La deuxime boucle balaie les valeurs y (axe vertical) :


for (int y = 0 ; y < getSize().height ; y++) {

Pour chaque coordonne (x,y), on calcule la valeur de la fonction et on la convertit en une nuance de rouge :
rouge= (int) ((f(x-offsetx,y-offsety)+1)*128);

Nous pouvons alors dfinir une nouvelle couleur et lutiliser pour dessiner :
g.setColor(new Color(rouge,vert,bleu));

Nous dessinons le point (x,y) (une ligne dont les extrmits sont confondues) :
g.drawLine(x,y,x,y);

Nous refermons tous les blocs dinstructions ouverts :


} } } }

Le programme complet de reprsentation de la troisime dimension laide de nuances de rouge est donn ci-dessous (voir applet 17) :
import java.awt.Graphics; import java.awt.Color; public class Figure extends java.applet.Applet {

Javabook Page 141 Lundi, 12. juillet 1999 3:58 15

Reprsenter la 3D par une projection en 2D


double f(double x, double y) { return (Math.sin((x*x+y*y)/5000)); } public void paint(Graphics g) { int rouge, vert, bleu; int offsetx, offsety; vert=0; bleu = 128; offsetx=getSize().width/2; offsety=getSize().height/2; for (int x = 0 ; x < getSize().width ; x++) { for (int y = 0 ; y < getSize().height ; y++) { rouge= (int) ((f(x-offsetx,y-offsety)+1)*128); g.setColor(new Color(rouge,vert,bleu)); g.drawLine(x,y,x,y); } } } }

141

Applet 17 : Reprsenter la 3e dimension laide de couleurs

11.11 Reprsenter la 3D par une projection en 2D


Lapplet 18 est base sur le mme principe que la prcdente : la couleur met en vidence le relief. Cependant, nous avons effectu une projection 45 degrs permettant de dessiner la courbe en 3D (3 dimensions). Nous avons dplac les variables hors de la dclaration de paint(), sauf pour offsetx et offsety dont les valeurs sont initialises avec la taille de la feuille de dessin, disponible uniquement dans paint().
import java.awt.Graphics; import java.awt.Color; public class Figure extends java.applet.Applet { int rouge; int vert=0; int bleu= 255; int x3,y3;

Javabook Page 142 Lundi, 12. juillet 1999 3:58 15

142
double p45=0.707; double f(double x, double y) { return (Math.sin((x*x+y*y)/5000)); }

Chapitre 11 Dessiner

public void paint(Graphics g) { int offsetx=(getSize().width+(int)( p45*getSize().height))/2; int offsety=(getSize().height)/2; for (int x=(int)(p45*getSize().height);x<getSize().width;x++){ for (int y = 0; y<getSize().height; y++) { x3=(int) (x-y*p45); y3=(int) (y*p45-50*f(x-offsetx,y-offsety) +offsety*p45/2); rouge= (int) ((f(x-offsetx,y-offsety)+1)*128); g.setColor(new Color(rouge,vert,bleu)); g.drawLine(x3,y3,x3,y3); } } } }

Applet 18 : Projeter une figure en 3D sur une surface 2D

11.12 Des rectangles multicolores


Nous allons maintenant dessiner des rectangles dont la taille, la position et la couleur sont choisies au hasard. Nous utilisons cet effet le gnrateur de nombres alatoires Math.random() du package java.lang. Ce gnrateur retourne des nombres flottants entre 0.0 et 1.0 qui nous serviront gnrer les couleurs et les rectangles. Nous importons les classes ncessaires, dont la classe Rectangle :
import java.awt.Graphics; import java.awt.Color; import java.awt.Rectangle;

Javabook Page 143 Lundi, 12. juillet 1999 3:58 15

Des rectangles multicolores

143

Nous dclarons trois variables (une pour chaque couleur de base) et une instance de la classe Rectangle :
public class Figure extends java.applet.Applet { int rouge,vert,bleu; Rectangle r = new Rectangle ();

Nous allons dessiner cent rectangles :


public void paint(Graphics g) { for (int i = 0 ; i < 100 ; i++) {

Pour chaque rectangle, nous gnrons une couleur partir de trois intensits tires au hasard (notez les conversions en nombres entiers) :
vert = (int)(Math.random()*255.99); bleu = (int)(Math.random()*255.99); rouge = (int)(Math.random()*255.99); g.setColor(new Color(rouge,vert,bleu));

Pour chaque rectangle, nous tirons au hasard x et y, (la coordonne de son coin suprieur gauche) et lui attribuons une taille nulle :
r.x= (int)(Math.random()*getSize().width); r.y= (int)(Math.random()*getSize().height); r.width=0; r.height=0;

Ensuite, nous utilisons la mthode add() qui permet de redimensionner le rectangle afin quil contienne un point tir lui aussi au hasard :
r.add((int)(Math.random()*getSize().width), (int)(Math.random()*getSize().height));

Finalement, nous dessinons le rectangle. On remarquera que lon ne peut pas le dessiner directement, mais que lon doit faire appel ses variables dinstance (x, y, largeur, hauteur) qui, elles, le dfinissent :
g.fillRect(r.x,r.y,r.width,r.height); } } }

Le code complet de lapplet 19 est le suivant :


import java.awt.Graphics; import java.awt.Color; import java.awt.Rectangle; public class Figure extends java.applet.Applet { int rouge,vert,bleu; Rectangle r = new Rectangle (); public void paint(Graphics g) { for (int i = 0 ; i < 100 ; i++) { vert = (int)(Math.random()*255.99);

Javabook Page 144 Lundi, 12. juillet 1999 3:58 15

144

Chapitre 11 Dessiner
bleu = (int)(Math.random()*255.99); rouge = (int)(Math.random()*255.99); g.setColor(new Color(rouge,vert,bleu)); r.x= (int)(Math.random()*getSize().width); r.y= (int)(Math.random()*getSize().height); r.width=0; r.height=0; r.add((int)(Math.random()*getSize().width), (int)(Math.random()*getSize().height)); g.fillRect(r.x,r.y,r.width,r.height); } }

Applet 19 : Dessiner des rectangles alatoires

11.13 Esquisser un rectangle laide dovales


Ce programme (applet 20) est une variante du prcdent. Nous avons dclar une zone interdite et nous testons systmatiquement sil y a intersection entre le rectangle gnr et la zone interdite. Si ce nest pas le cas, on dessine lovale inscrit dans le rectangle gnr.
import java.awt.Graphics; import java.awt.Color; import java.awt.Rectangle; public class Figure extends java.applet.Applet { public void paint(Graphics g) { int rouge,vert,bleu; Rectangle r = new Rectangle (); Rectangle interdit = new Rectangle ( (int)(getSize().width/3), (int)(getSize().height/3), (int)(getSize().width/3), (int)(getSize().height/3)); for (int i = 0 ; i < 1000 ; i++) { vert = (int)(Math.random()*255.99); bleu = (int)(Math.random()*255.99); rouge = (int)(Math.random()*255.99);

Javabook Page 145 Lundi, 12. juillet 1999 3:58 15

Premire et dernire
g.setColor(new Color(rouge,vert,bleu)); r.x= (int)(Math.random()*getSize().width); r.y= (int)(Math.random()*getSize().height); r.width=0; r.height=0; r.add((int)(Math.random()*getSize().width), (int)(Math.random()*getSize().height)); if (!r.intersects(interdit)) // test dintersection g.fillOval(r.x,r.y,r.width,r.height); } } }

145

Applet 20 : Dessiner un rectangle laide dovales

11.14 Premire et dernire


Vous nous avez suivis jusquici, alors flicitations! Nous sommes heureux de vous dcerner un prix : la dernire applet de cette partie. Nous en profitons pour vous prsenter une nouvelle classe, java.util.Date, qui permet de manipuler les dates, les heures, etc. Cette classe servira dexemple pour nos futures animations. Le constructeur new Date() retourne la date courante maintenue dans lordinateur qui excute lapplet. La mthode toString() applique un objet Date permet de convertir cette date en une chane de caractres.
import import import import java.awt.Graphics; java.awt.Color; java.awt.Font; java.util.Date;

public class MaPremiereApplet extends java.applet.Applet { Font helvetica14Normal = new Font("Helvetica",Font.PLAIN,14); Date maintenant; public void paint(Graphics g) { g.setColor(Color.black); g.setFont(helvetica14Normal); g.drawString("Certificat de la premire Applet", 50, 30); g.drawString("Dcern ", 50, 60);

Javabook Page 146 Lundi, 12. juillet 1999 3:58 15

146

Chapitre 11 Dessiner
g.setColor(Color.red); g.drawString("Nom: ........... , prnom: .........", 50, 90); maintenant = new Date(); g.drawString(maintenant.toString(), 50, 120); }

Applet 21 : Certificat de la 1re applet

11.15 Invitation explorer


Examinez les mthodes de la classe java.awt.Color : brighter(), darker(), getBlue(), getColor(String), getColor(String,Color), getGreen(), getHSBColor(float, float, float), etc. Esquissez un ovale laide de rectangles, tudier leffet de la taille maximum des rectangles sur laspect de lovale. Dessinez une spirale laide de quarts de cercles, en modifiant leur rayon. Dessinez une spirale dont la couleur varie de manire dgrade ou alatoire.

Javabook Page 147 Lundi, 12. juillet 1999 3:58 15

Chapitre 12

Animer
Avant de dcouvrir comment faire de lanimation en Java, il est important de bien comprendre le cycle de vie de lapplet. Nous rappelons que celui-ci est : init() ! start() " stop() ! destroy() Aprs lactivit start(), lapplet excute la mthode paint() du composant graphique. Cest en redfinissant cette mthode que nous avons introduit nos propres actions. Vous avez sans doute remarqu que si lapplet tait partiellement cache par une autre fentre, celle-ci se redessinait quand elle redevenait visible. En effet, le composant graphique reoit lordre de repeindre le composant. Il excute alors la mthode repaint(), qui elle-mme invoque update(), cette dernire faisant alors appel la mthode paint(). (Voir lapplet 54, p. 229.) Le programme ci-dessous doit vous permettre de tester ces diffrents comportements. chaque fois que le document disparat, il doit changer de couleur lors de son prochain affichage.
import java.awt.Graphics; import java.awt.Color; public class ComportementApplet extends java.applet.Applet { boolean ok; public void init() { ok=true; } public void start() { repaint(); } public void stop() { ok=!ok;}

Javabook Page 148 Lundi, 12. juillet 1999 3:58 15

148

Chapitre 12 Animer
public void paint(Graphics g) { if (ok) g.setColor(Color.green); else g.setColor(Color.red); g.fillRect(0,0,getSize().width,getSize().height); }

Maintenant que nous avons bien compris le comportement dune applet, nous allons faire plusieurs tentatives danimation. Pour simplifier, nous prendrons comme exemple laffichage de lheure (quelque chose de bien suisse et qui change en permanence!). Nous avons repris le programme de notre certificat (applet 21) en retirant tout ce qui ne concerne pas laffichage de la date.

12.1 Mon applet est un seul processus


Cette premire version de lhorloge (applet 22) nest pas une animation, mais elle montre bien leffet des vnements extrieurs au composant graphique de lapplet, qui la forcent se repeindre et donc rafrachir lheure (essayez cette applet en la masquant avec une autre fentre et en la rendant nouveau visible).
import java.awt.*; import java.util.Date; public class Animation extends java.applet.Applet { Font timesRoman24Gras = new Font("TimesRoman",Font.BOLD,24); Date maintenant; public void paint(Graphics g) { g.setColor(Color.red); g.setFont(timesRoman24Gras); maintenant = new Date(); g.drawString(maintenant.toString(), 10, 40); } }

Applet 22 : Animation : une horloge digitale

Lide de lessai ci-dessous est de dessiner continuellement lheure en insrant lappel drawString() dans une boucle sans fin :
import java.awt.*; import java.util.Date; public class Animation extends java.applet.Applet { Font timesRoman24Gras = new Font("TimesRoman",Font.BOLD,24); Date maintenant;

Javabook Page 149 Lundi, 12. juillet 1999 3:58 15

Mon applet est un seul processus


public void paint(Graphics g) { g.setColor(Color.red); g.setFont(timesRoman24Gras); while (true) { maintenant = new Date(); g.drawString(maintenant.toString(), 10, 40); } } }

149

Le rsultat est assez surprenant : on perd pratiquement tout contrle, car la machine se consacre entirement sa nouvelle tche : peindre et repeindre lheure. De plus, on recouvre continuellement ce que lon a dj dessin, de ce fait on ne voit plus rien! Ce dernier problme peut tre vit en effaant la surface que lon vient de dessiner avant dafficher une nouvelle heure. La boucle devient alors :
while (true) { g.clearRect(0,0,size().width,size().height); maintenant = new Date(); g.drawString(maintenant.toString(), 10, 40); }

Le rsultat est un clignotement trs intense de lheure, qui lutte pour tre affiche mais qui est immdiatement efface. Nanmoins, on voit les secondes dfiler. La remarque suivante doit certainement vous venir lesprit : pourquoi vouloir afficher si souvent un phnomne ne changeant que toutes les secondes? Penchons-nous sur la notion de Thread (dtaille au chapitre 25) afin de dcouvrir une meilleure manire de raliser une horloge ou toute autre animation. En Java, tout processus est un Thread, y compris celui excutant notre applet. Nous pouvons donc lui appliquer les mthodes de cette classe, en particulier celle qui met le processus en veille pendant un certain temps (Thread.sleep()), exprim en millisecondes. Nous en profitons pour entourer lappel Thread.sleep() de deux nouvelles instructions, try et catch, que n ous avons vues au point 8.1.
while (true) { g.clearRect(0,0,size().width,size().height); maintenant = new Date(); g.drawString(maintenant.toString(), 10, 40); try {Thread.sleep(1000);} catch(InterruptedException signal) {} }

Le rsultat est acceptable : chaque seconde, lheure est affiche. Cependant, nous navons pas vraiment ralis une animation. Lapplet a perdu son comportement global, elle ne reoit plus les appels repaint(), stop(), etc. car lexcution du processus est mise en veille dans la mthode paint().

Javabook Page 150 Lundi, 12. juillet 1999 3:58 15

150

Chapitre 12 Animer

Rsumons notre situation : nous voulons conserver le comportement normal de lapplet; nous voulons quelque chose qui force lapplet se redessiner toutes les secondes. Ce quelque chose ne peut malheureusement pas provenir de lapplet elle-mme. En effet, notre applet nest compose que dun seul processus, comme lindique le titre de cette section.

12.2 Multithread
Pour contourner ces difficults, il est ncessaire dutiliser un autre processus (Thread) possdant son propre flot dinstructions indpendant de lapplet. Le cycle de vie dun Thread est le suivant : start() : il est activ et commence excuter la mthode run(); run() : cette mthode constitue la tche effectuer par le processus; pour stopper un processus, il faut le laisser terminer lui-mme sa mthode run(). Pendant quil excute son activit (run()), il est possible quil soit : sleep() : endormi pour une certaine dure; join() : mis en attente de la fin dun autre processus. Cependant, aucun de ces vnements ne peut modifier le flot dinstructions dcrit dans la mthode run() quil excute. Tout au plus, il peut tre ralenti, synchronis ou temporis par rapport lexcution normale de ce flot.

12.3 Mon applet lance un deuxime processus


Dans cette version de lhorloge, lapplet va excuter son cycle de vie normal (init(), start(), paint(), repaint(),..., stop()). En dclarant quelle implante linterface Runnable, elle sengage implanter une mthode run() pour les processus quelle active. Dans la mthode start(), lapplet cre le nouveau processus (new Thread(this)) et le fait dmarrer (actif.start()). Celui-ci excute alors automatiquement la mthode run() implante par lapplet. On utilise donc la seconde manire de crer un processus, prsente au point 8.2. La mthode run() invoque la mthode repaint() de lapplet toutes les secondes. Finalement, si lapplet reoit lordre de sarrter stop(), elle met la variable stop true ( vrai), ce qui dclenchera larrt de la boucle while(!stop) du processus actif.

Javabook Page 151 Lundi, 12. juillet 1999 3:58 15

Mon applet lance un deuxime processus

151

La figure 12.1 ci-dessous schmatise ces diverses interactions.


init start

start Applet paint run

actif (le Thread)

while (!stop) repaint stop boolean stop

stop = true

invocation de mthodes interactions Figure 12.1 Interactions entre les processus

Code de lhorloge utilisant les mcanismes de multiprocessus :


import import import import java.awt.Graphics; java.awt.Color; java.awt.Font; java.util.Date;

public class Animation extends java.applet.Applet implements Runnable { boolean stop=false; Font timesRoman24Gras = new Font("TimesRoman",Font.BOLD,24); Date maintenant; Thread actif; public void start() { actif = new Thread(this); actif.start(); } public void stop() { stop = true; actif = null; } public void run() {

Javabook Page 152 Lundi, 12. juillet 1999 3:58 15

152
while (!stop) { repaint(); try {Thread.sleep(1000);} catch(InterruptedException signal) {} } }

Chapitre 12 Animer

public void paint(Graphics g) { g.setColor(Color.red); g.setFont(timesRoman24Gras); maintenant = new Date(); g.drawString(maintenant.toString(), 10, 40); } }

Notre applet est habite par deux processus : le processus habituel qui appelle paint, start, stop suivant les circonstances et le processus actif qui fonctionne dans run et appelle aussi paint (toutes les secondes).

12.4 Un squelette gnral pour les animations


Nous pouvons driver de notre horloge le squelette gnral suivant pour les animations simples (une seule activit) :
import ... public class Animation extends java.applet.Applet implements Runnable { boolean stop = false; // la variable de controle du thread // dclaration des variables de lapplet ... Thread actif; public void start() { // activation du processus danimation if (actif==null); { actif = new Thread(this); actif.start(); } } public void stop() { // arrt du processus danimation if (actif!=null); { stop = true; actif = null; } } public void run() {

Javabook Page 153 Lundi, 12. juillet 1999 3:58 15

Une horloge avec des aiguilles


// dclaration des variables du processus ... // boucle danimation while (!stop) { // attend la fin // modification des variables de lapplet ... // demande de mise jour update() ou repaint() ... // rglage de la vitesse de lanimation try {Thread.sleep(...);} catch(InterruptedException signal) {} } } public void paint(Graphics g) { // excution de lanimation ... } }

153

Nous avons lgrement modifi les mthodes start() et stop() afin de vrifier que nous ne lanons pas un processus dj actif et que nous narrtons pas un processus inexistant (par exemple, si lon arrte lapplet avant quelle excute la mthode start()). Nous allons maintenant nous familiariser avec ce squelette que nous appliquerons dans plusieurs exemples tout au long des chapitres suivants.

12.5 Une horloge avec des aiguilles


Reprenons notre exemple de lhorloge et incorporons nos connaissances sur le dessin afin de raliser une horloge avec des aiguilles (une horloge analogique). Dans ce cas, notre problme est darriver : convertir la valeur de lheure digitale en heure analogique; trouver pour les heures, les minutes et les secondes langle de la position des aiguilles; reprsenter les aiguilles de lhorloge le plus simplement possible, tout en offrant une bonne lisibilit; animer lhorloge toutes les secondes. Dans lhorloge analogique (voir applet 23), nous avons dcid de reprsenter les aiguilles laide darcs de disques que nous savons dessiner avec fillArc(). Pour chaque aiguille (s, m, h), nous dfinissons son origine (ox, oy), sa largeur (i), sa hauteur (h) et son arc de cercle (d). Nous obtenons la srie de donnes suivante :
int oxs = 0, oys = 0, ls=99, hs=99, ds=2;

Javabook Page 154 Lundi, 12. juillet 1999 3:58 15

154
int oxm = 10, oym = 10, lm=79, hm=79, dm=4; int oxh = 20, oyh = 20, lh=59, hh=59, dh=6;

Chapitre 12 Animer

Applet 23 : Animation, une horloge analogique (15h 56mn 7s)

En examinant la classe Date, on remarque que les mthodes getHours(), getMinutes(), et getSeconds() nous permettent de rcuprer les valeurs utiles pour notre horloge. La seule difficult est dassocier une valeur horaire une position du cercle trigonomtrique : le sens horaire et le sens trigonomtrique tant opposs, on utilise linversion (le signe moins) pour rtablir la situation; le zro horaire et le zro trigonomtrique ntant pas situs au mme endroit, on utilise une constante (450) pour les dcaler. Douze heures devant correspondre 360 degrs, on multiplie par 30. Soixante minutes ou secondes devant correspondre 360 degrs, on multiplie par 6. On ajoute un petit coup de modulo 360 pour le cas o lon fait plusieurs tours et laffaire est rgle. Nous avons intgr la valeur des minutes dans le calcul de la position des heures, afin que le mouvement de laiguille soit continu (sinon elle ne se dplacerait quune fois toutes les heures). En utilisant ce qui vient dtre dit, nous obtenons les formules suivantes :
h=(-maintenant.get(Calendar.HOUR_OF_DAY)*30(maintenant.get(Calendar.MINUTE)*30)/60+450)%360; m=(-maintenant.get(Calendar.MINUTE)*6+450)%360; s=(-maintenant.get(Calendar.SECOND)*6+450)%360;

Il ne nous reste plus qu utiliser notre squelette danimation et dcrire compltement la mthode paint() afin quelle demande lheure au systme, calcule la position des aiguilles et les dessine chacune dans une couleur diffrente. Nous obtenons alors lapplet suivante :
import java.awt.Graphics; import java.awt.Color; import java.util.*; //<pre> public class Animation extends java.applet.Applet

Javabook Page 155 Lundi, 12. juillet 1999 3:58 15

Une horloge avec des aiguilles


implements Runnable {

155

GregorianCalendar maintenant; // on craint pas le bug de lan 2000 Thread actif; boolean stop = false; int int int int h,m,s; oxs = 0, oys = 0, ls=99, hs=99, ds=2; oxm = 10, oym = 10, lm=79, hm=79, dm=4; oxh = 20, oyh = 20, lh=59, hh=59, dh=6;

public void start() { if (actif==null); { actif = new Thread(this); actif.start(); } } public void stop() { stop = true; actif = null; } public void run() { while (!stop) { repaint(); try {Thread.sleep(1000);} catch(InterruptedException signal) {} } } public void paint(Graphics g) { maintenant = new GregorianCalendar(); g.setColor(Color.green); h=(-maintenant.get(Calendar.HOUR_OF_DAY)*30(maintenant.get(Calendar.MINUTE)*30)/60+450)%360; g.fillArc(oxh,oyh,lh,hh,h+dh,-2*dh); g.setColor(Color.blue); m=(-maintenant.get(Calendar.MINUTE)*6+450)%360; g.fillArc(oxm,oym,lm,hm,m+dm,-2*dm); g.setColor(Color.red); s=(-maintenant.get(Calendar.SECOND)*6+450)%360; g.fillArc(oxs,oys,ls,hs,s+ds,-2*ds); } }

Javabook Page 156 Lundi, 12. juillet 1999 3:58 15

156

Chapitre 12 Animer

12.6 Plusieurs activits indpendantes


Linconvnient de notre squelette est quil ne gre quune seule activit (ou plusieurs activits ayant toutes le mme comportement). Dans lexemple qui suit, nous allons crer deux activits supplmentaires : la premire sera en charge du contrle de la coordonne x dun rectangle, lautre de la coordonne y. Nous importons les classes Rectangle et Graphics :
import java.awt.Graphics; import java.awt.Rectangle;

La classe Actif1 tend la classe Thread. Nous devons donc redfinir la mthode run(). Comme variable dinstance, nous lui fournissons le rectangle dont elle doit contrler la coordonne x; ceci est effectu lors de linstanciation dun objet de la classe Actif1 (dans le constructeur). La mthode run() dfinit deux boucles (aller et retour) qui modifient la coordonne x du rectangle de manire incrmentale. Lattente entre deux modifications est proportionnelle lloignement de lorigine (ce qui donnera une impression dacclration du mouvement de lobjet) lors de son affichage. On remarquera la mthode arret() qui permet de mettre vrai la variable stop et qui permet de terminer la mthode run(). Code de la classe Actif1 :
//<pre> import java.awt.Graphics; import java.awt.Rectangle; class Actif1 extends Thread { private Rectangle r1; boolean stop = false; Actif1(Rectangle r){ r1=r; } public void run() { while (!stop) { for (int i=0;i<80;++i){ r1.x=i; try {Thread.sleep(i+5);} catch(InterruptedException signal) {} } for (int i=80;i>0;--i){ r1.x=i; try {Thread.sleep(i+5);} catch(InterruptedException signal) {} } } }

Javabook Page 157 Lundi, 12. juillet 1999 3:58 15

Plusieurs activits indpendantes


public void arret() {stop=true;} }

157

La classe Actif2 est trs semblable, mais elle modifie laxe y. Code de la classe Actif2 :
class Actif2 extends Thread { private Rectangle r1; boolean stop = false; Actif2(Rectangle r){ r1=r; } public void run() { while (!stop) { for (int i=0;i<80;++i){ r1.y=i; try {Thread.sleep(i+5);} catch(InterruptedException signal) {} } for (int i=80;i>0;--i){ r1.y=i; try {Thread.sleep(i+5);} catch(InterruptedException signal) {} } } } public void arret() {stop=true;} }

Dcrivons maintenant notre nouvelle applet, 24e du nom. Nous dclarons deux objets a1 et a2 de type Actif1 et Actif2. Nous conservons le squelette original danimation. La mthode run() de lanimation va initialiser nos deux processus en leur fournissant le rectangle sur lequel elles doivent travailler puis elle va lancer ces processus. Nos deux processus vont travailler sur le mme rectangle, lun le dplaant horizontalement, lautre verticalement. Ensuite, elle demandera rgulirement que lon redessine lapplet. La mthode paint() dessine le rectangle.
public class Animation extends java.applet.Applet implements Runnable { Thread actif; Actif1 a1; Actif2 a2; Rectangle r= new Rectangle(0,0,20,20); public void start() {

Javabook Page 158 Lundi, 12. juillet 1999 3:58 15

158
if (actif==null); { actif = new Thread(this); actif.start(); } } public void stop() { if (a1!=null) a1.arret(); if (a2!=null) a2.arret(); } public void run() { a1=new Actif1(r); a1.start(); a2=new Actif2(r); a2.start(); while (true) { repaint(); try {Thread.sleep(10);} catch(InterruptedException signal) {} } } public void paint(Graphics g) { g.fillRect(r.x,r.y,r.width,r.height); } }

Chapitre 12 Animer

Le rsultat est un rectangle noir qui oscille le long de la diagonale, en ayant une vitesse variable. En laissant fonctionner lapplet assez longtemps, une drive peut apparatre : le rectangle ne reste plus sur la diagonale. Ce comportement prouve bien que les processus ne sont pas compltement synchrones.

Applet 24 : Animation, un rectangle sur une diagonale

12.7 Encore plus dactivits indpendantes


Nous avons repris les classes Actif1 et Actif2 et nous avons modifi les lignes de mise en attente de la faon suivante :
try {Thread.sleep((int)Math.random()*40+5);}

Javabook Page 159 Lundi, 12. juillet 1999 3:58 15

Encore plus dactivits indpendantes

159

Nous avons ainsi une attente alatoire qui va faire dvier la trajectoire du rectangle autour de la diagonale. Modifions notre applet afin de contrler trois rectangles (voir applet 25) : les processus a1 et a2 contrlent le rectangle ra; les processus b1 et b2 contrlent le rectangle rb; les processus c1 et c2 contrlent le rectangle rc. La mthode paint() est redfinie afin de dessiner les trois rectangles. Code de lapplet avec trois rectangles :
public class Animation extends java.applet.Applet implements Runnable { boolean stop = false; Thread actif; Actif1 a1,b1,c1; Actif2 a2,b2,c2; Rectangle ra= new Rectangle(0,0,20,20); Rectangle rb= new Rectangle(0,0,10,10); Rectangle rc= new Rectangle(0,0,5,5); public void start() { if (actif==null); { actif = new Thread(this); actif.start(); } } public void stop() { if (actif!=null); { stop=true; if (a1!=null) a1.arret(); if (b1!=null) b1.arret(); if (c1!=null) c1.arret(); if (a2!=null) a2.arret(); if (b2!=null) b2.arret(); if (c2!=null) c2.arret(); actif = null; } } public void run() { a1=new Actif1(ra);a1.start(); a2=new Actif2(ra);a2.start(); b1=new Actif1(rb);b1.start(); b2=new Actif2(rb);b2.start(); c1=new Actif1(rc);c1.start(); c2=new Actif2(rc);c2.start(); while (!stop) { repaint(); try {Thread.sleep(10);}

Javabook Page 160 Lundi, 12. juillet 1999 3:58 15

160
catch(InterruptedException signal) {} } } public void paint(Graphics g) { g.fillRect(ra.x,ra.y,ra.width,ra.height); g.fillRect(rb.x,rb.y,rb.width,rb.height); g.fillRect(rc.x,rc.y,rc.width,rc.height); } }

Chapitre 12 Animer

Nous avons maintenant trois rectangles se dplaant dans le cadre de lapplet.

Applet 25 : Animation, trois rectangles grs chacun par deux threads

Ces exemples montrent que lon peut grer de nombreux processus : on peut ainsi dclarer des matrices de processus. Cependant, cela peut poser quelques difficults de gestion. Dans notre cas, chaque processus travaillant sur une variable non partage (x ou y), il ny avait pas de risque de collision dans les activits. Nous verrons plus loin que lon doit utiliser des techniques de synchronisation pour grer des cooprations plus intenses entre les processus.

12.8 Un peu de posie


... En comptant 45 secondes pour lire un sonnet et 15 secondes pour changer les volets, 8 heures par jour, 200 jours par an, on a pour plus dun million de sicles de lecture... Raymond Queneau dans 100 000 000 000 000 pomes, Gallimard, 1982. Ce magnifique livre se compose de dix pages cartonnes; sur chacune delles est imprim un sonnet de quatorze vers. Les pages sont dcoupes de manire ce que chaque vers soit libre. Il est alors possible de slectionner au hasard un vers dans une des dix planches et de constituer ainsi un nouveau sonnet. Lapplet 26 que nous proposons ci-dessous ralise le rve de Raymond Queneau en affichant un nouveau sonnet toutes les minutes. Les rsultats sont surprenants et pourraient correspondre ce qui suit :

Javabook Page 161 Lundi, 12. juillet 1999 3:58 15

Un peu de posie

161

Applet 26 : Un pome gnr partir de la structure de R. Queneau

Pour raliser notre ide, il nous faut un endroit pour mmoriser les dix planches de quatorze sonnets. Une matrice de String fera parfaitement laffaire :
String q[] [] = new String[10][14];

Dans la mthode init() de lapplet, nous initialisons notre matrice :


public void init() { // la premire planche q[0][0]="Le roi de la pampa retourne sa chemise"; q[0][1]="pour la mettre scher aux cornes des taureaux";

La mthode run() doit, pour composer un sonnet, tirer au hasard une des dix planches. Ensuite, elle demande redessiner le sonnet nouvellement compos et elle attend une minute. Le rsultat du tirage au sort est mmoris dans le vecteur p :
int p[] = new int[14]; public void run() { while (!stop) { for (int i=0; i<p.length;i++) p[i]=(int)(Math.random()*9.99999); repaint(); try {Thread.sleep(60000);} catch(InterruptedException signal) {} } }

Javabook Page 162 Lundi, 12. juillet 1999 3:58 15

162

Chapitre 12 Animer

La mthode paint() doit redessiner le sonnet gnr (stock dans p). Pour chaque vers i, elle recherche la planche p[i] qui lui donne le vers q[p[i]][i]. Le vecteur strophe[] est utilis pour faire apparatre la structure du sonnet (4-4-3-3).
public void paint(Graphics g) { g.setColor(Color.red); g.setFont(timesRoman14Gras); for (int i=0; i<14;i++) g.drawString(q[p[i]][i], 10, 40+i*20+strophe[i]); } }

Comme toujours, nous utilisons notre squelette pour grer lanimation de lapplet.
import java.awt.Graphics; import java.awt.Color; import java.awt.Font; public class Animation extends java.applet.Applet implements Runnable { boolean stop=false; Font timesRoman14Gras = new Font("TimesRoman",Font.BOLD,14); int p[] = new int[14]; String q[] [] = new String[10][14]; int strophe[] = {0,0,0,0,15,15,15,15,30,30,30,45,45,45}; Thread actif; public void start() { if (actif==null); { actif = new Thread(this); actif.start(); } } public void stop() { if (actif!=null); { stop=true; actif = null; } } public void run() { while (!stop) { for (int i=0; i<p.length;i++) p[i]=(int)(Math.random()*9.99999); repaint(); try {Thread.sleep(60000);} catch(InterruptedException signal) {} }

Javabook Page 163 Lundi, 12. juillet 1999 3:58 15

Invitation explorer
}

163

public void init() { // la premire planche q[0][0]="Le roi de la pampa retourne sa chemise"; q[0][1]="pour la mettre scher aux cornes des taureaux"; q[0][2]="le corndbif en bote empeste la remise"; ... // la deuxime planche q[1][0]="Le cheval Parthnon s'nerve sur sa frise"; q[1][1]="depuis que lord Elgin ngligea ses naseaux"; q[1][2]="le Turc de ce temps-l pataugeait dans sa crise"; ... // les autres planches } public void paint(Graphics g) { g.setColor(Color.red); g.setFont(timesRoman14Gras); for (int i=0; i<14;i++) g.drawString(q[p[i]][i], 10, 40+i*20+strophe[i]); } }

Le lecteur patient pourra se procurer lintgrale des sonnets chez Gallimard afin de complter (pour son usage personnel) le code de la mthode init(). Il possdera ainsi une source inpuisable de posie!

12.9 Invitation explorer


Nous invitons le lecteur explorer les animations bases sur des processus cooprant entre eux, comme par exemple une applet dessinant un carr qui poursuit un cercle.

Javabook Page 164 Lundi, 12. juillet 1999 3:58 15

Javabook Page 165 Lundi, 12. juillet 1999 3:58 15

Chapitre 13

Interagir
Jusqu prsent, nos programmes taient insensibles toutes les sollicitations extrieures. Dans ce chapitre, nous allons apprendre grer les interactions provenant de la souris et du clavier (pour dautres priphriques, il faut crire les classes capables de grer les vnements quils gnrent). Entre les versions 1.0 et 1.1 de Java, la gestion des vnements a t profondment modifie. tant donn quil existe encore beaucoup de codes crits selon la version 1.0 et que tous les utilisateurs nont pas encore de butineurs adapts la version 1.1, nous avons choisi de prsenter les deux modles de gestion dvnements. Si vous navez pas grer du code crit pour la version 1.0, vous pouvez aller directement au point 13.7.

13.1 Le modle dvnements de Java 1.0


Les interactions sont gres comme des vnements fournis un objet (dans notre cas, le composant graphique associ lapplet). Pour traiter lvnement, il suffit de redfinir la mthode correspondant son type, cette mthode devant tre rattache lobjet recevant lvnement. Event est une classe qui dfinit un ensemble de constantes utiles la gestion du clavier et de la souris et qui a pour variables dinstance les valeurs dcrivant lvnement (heure, position, tat des touches de fonction, etc.). Prenons tout de suite un exemple afin de clarifier les choses. Le programme suivant (applet 27) permet denregistrer les mouvements de la souris (lorsque le bouton nest pas enfonc). mouseMove() est une mthode de Component dont hrite la classe Applet. Nous redfinissons donc mouseMove() dans notre applet afin de rcuprer les vnements provoqus par les

Javabook Page 166 Lundi, 12. juillet 1999 3:58 15

166

Chapitre 13 Interagir

mouvements de la souris : chaque fois que cette mthode sera invoque, nous recevrons une instance de lvnement qui lui est associe. Nous pourrons alors connatre linstant (e.when) et la position (x,y) auxquels lvnement sest produit. Nous conservons ces valeurs dans des variables de lapplet (sourisX, sourisY et quand). La mthode mouseMove() doit retourner un boolen. Si celui-ci est vrai, cela signifie que lvnement est considr comme trait, sinon cet vnement peut tre transmis un autre objet pouvant aussi le traiter (par exemple si plusieurs objets sont empils sur la mme coordonne, il peut tre souhaitable que chacun dentre eux reoive lvnement). Code permettant dafficher les mouvements de la souris :
import java.awt.Graphics; import java.awt.Event; public class Interaction extends java.applet.Applet { int sourisX, sourisY; long quand; public boolean mouseMove(Event e, int x, int y){ quand=e.when; sourisX=x; sourisY=y; repaint(); return true; } public void paint(Graphics g) { g.drawString(quand+"=("+sourisX+","+sourisY+")" ,10,20); } }

En dplaant la souris, les coordonnes du curseur sont affiches, une estampille indiquant linstant de lvnement (en millisecondes) :

Applet 27 : Afficher les coordonnes de la souris

13.2 Gestion de la souris


Les mthodes suivantes grent les vnements concernant la souris : public boolean mouseDown(Event e, int x, int y) : invoque quand le

Javabook Page 167 Lundi, 12. juillet 1999 3:58 15

Gestion de la souris

167

bouton de la souris est enfonc dans la surface de lapplet; public boolean mouseUp(Event e, int x, int y) : invoque quand le bouton de la souris est relch dans la surface de lapplet; public boolean mouseMove(Event e, int x, int y) : invoque quand la souris se dplace, le bouton tant relch; public boolean mouseDrag(Event e, int x, int y) : invoque quand la souris se dplace, le bouton tant enfonc; public boolean mouseEnter(Event e, int x, int y) : invoque quand la souris entre dans la surface de lapplet; public boolean mouseExit(Event e, int x, int y) : invoque quand la souris sort de la surface de lapplet. Exemple de programme traitant les vnements de la souris : dans celui-ci, la position du bouton de la souris dtermine la couleur du dessin (enfonc = blanc, relch = rouge). Le rsultat est reprsent ci-dessous (applet 28) :
import java.awt.Graphics; import java.awt.Color; import java.awt.Event; public class Interaction extends java.applet.Applet { Color c=new Color(0,0,255); public boolean mouseDown(Event e, int x, int y){ c= new Color(255,255,255); repaint(); return true; } public boolean mouseUp(Event e, int x, int y){ c= new Color(255,0,0); repaint(); return true; } public void paint(Graphics g) { g.setColor(c); g.drawLine(0,0,size().width ,size().height); } }

Applet 28 : Capter ltat du bouton de la souris

En ajoutant le traitement de lvnement mouseDrag(), on peut modifier lextrmit du trait. Il suit alors tous les mouvements de la souris pendant que le bouton est enfonc (voir applet 29).

Javabook Page 168 Lundi, 12. juillet 1999 3:58 15

168
import java.awt.Graphics; import java.awt.Color; import java.awt.Event;

Chapitre 13 Interagir

public class Interaction extends java.applet.Applet { Color c=new Color(0,0,255); int dx=size().width; int dy=size().height; public boolean mouseDown(Event e, int x, int y){ c= new Color(255,255,255); repaint(); return true; } public boolean mouseUp(Event e, int x, int y){ c= new Color(255,0,0); repaint(); return true; } public boolean mouseDrag(Event e, int x, int y){ dx=x; dy=y; repaint(); return true; } public void paint(Graphics g) { g.setColor(c); g.drawLine(0,0,dx,dy); } }

Applet 29 : Capter la position de la souris

13.3 Une alternative la gestion des vnements


La mthode handleEvent(Event e) est une autre mthode permettant de grer les vnements. En redfinissant cette mthode, il est possible de collecter tous les vnements adresss la surface graphique de lapplet. La dtermination du type dun vnement se fera en examinant sa variable dinstance id et en la comparant aux constantes dfinies dans la classe Event. Pour rcuprer les coordonnes (x,y) de la souris, on examinera les variables dinstance x et y de lvnement. Le programme prcdent peut tre modifi afin dutiliser les constantes Event.MOUSE_DOWN, Event.MOUSE_UP et Event.MOUSE_DRAG pour d-

Javabook Page 169 Lundi, 12. juillet 1999 3:58 15

Une applet de brouillon

169

terminer le type de lvnement. Dans le cas o lon ne sait pas comment traiter cet vnement, on fait appel la mthode de la super-classe.
import java.awt.Graphics; import java.awt.Color; import java.awt.Event; public class Interaction extends java.applet.Applet { Color c=new Color(0,0,255); int dx=size().width; int dy=size().height; public boolean handleEvent(Event e){ switch(e.id){ case Event.MOUSE_DOWN: c= new Color(255,255,255); break; case Event.MOUSE_UP: c= new Color(255,0,0); break; case Event.MOUSE_DRAG: dx=e.x; dy=e.y; break; default: return super.handleEvent(e); } repaint(); return true; } public void paint(Graphics g) { g.setColor(c); g.drawLine(0,0,dx,dy); } }

13.4 Une applet de brouillon


En utilisant les informations sur la position de la souris, il est possible de transformer les squences de coordonnes (x,y) en segments de droites et de dessiner ainsi une trace des mouvements de la souris (voir applet 30). Le programme suivant permet de dessiner avec la souris. On remarquera que : le cas Event.MOUSE_DRAG ne possde pas de break, lexcution se poursuit donc en excutant les instructions de Event.MOUSE_DOWN; on ne fait pas appel la mthode repaint() (qui effacerait tout dans notre cas), mais on demande la mthode getGraphics() de nous fournir le composant graphique sur lequel on travaille et on sadresse directement lui pour dessiner.
import java.awt.Graphics;

Javabook Page 170 Lundi, 12. juillet 1999 3:58 15

170
import java.awt.Event;

Chapitre 13 Interagir

public class Interaction extends java.applet.Applet { int x0,y0; public boolean handleEvent(Event e){ switch(e.id){ case Event.MOUSE_DRAG: Graphics g= getGraphics(); g.drawLine(x0,y0,e.x,e.y); case Event.MOUSE_DOWN: x0=e.x; y0=e.y; break; default: return super.handleEvent(e);} return true;} }

Applet 30 : Une applet de brouillon pour dessiner

13.5 Gestion du clavier


La gestion des vnements du clavier est trs similaire celle de la souris. On peut rcuprer les vnements en redfinissant la mthode keyDown(Event e, int touche) (ou bien handleEvent(); dans ce cas la valeur de la touche du clavier se trouve dans la variable dinstance key). La classe Event dfinit des constantes pour les principales touches du clavier (voir tableau 13.1).
Constante
Event.UP Event.DOWN Event.LEFT Event.RIGHT Event.HOME

Touche reprsente Flche haut Flche bas Flche gauche Flche droite Touche home

Tableau 13.1 Constantes associes aux principales touches

Javabook Page 171 Lundi, 12. juillet 1999 3:58 15

Gestion du clavier
Constante
Event.END Event.PGUP Event.PGDN Event.F1 Event.F12

171
Touche reprsente Touche fin Dfilement page haut Dfilement page bas Touches de fonction F1 F12

Tableau 13.1 Constantes associes aux principales touches

Pour tester les touches de modification du clavier, il existe trois mthodes : public boolean shiftDown() : la touche majuscule est-elle enfonce? public boolean controlDown() : la touche de contrle est-elle enfonce? public boolean metaDown() : la touche de mta (alt) est-elle enfonce? Lapplet suivante (applet 31) montre comment grer le clavier. Ce programme modifie la taille des caractres affichs en utilisant les touches flche haut et flche bas. Il teste galement ltat de la touche majuscule.
import java.awt.Graphics; import java.awt.Font; import java.awt.Event; public class Interaction extends java.applet.Applet { int taille=12; char toucheCourante='?'; boolean majuscule; public boolean keyDown(Event e, int touche){ switch(touche){ case Event.DOWN:--taille;break; case Event.UP: ++taille;break; default: toucheCourante=(char)touche ; } setFont(new Font("Helvetica",Font.BOLD,taille)); majuscule=e.shiftDown(); repaint(); return true; } public void paint(Graphics g) { g.drawString("Taille="+taille+" maj="+majuscule,10,25); g.drawString(String.valueOf(toucheCourante),100,60); } }

Javabook Page 172 Lundi, 12. juillet 1999 3:58 15

172

Chapitre 13 Interagir

Applet 31 : Gestion du clavier

13.6 Souris trois boutons


Les vnements se rapportant la souris peuvent tester les touches de modification (maj, ctrl, meta). Il est donc possible de distinguer un clic souris avec ou sans une ou plusieurs de ces touches enfonces. Afin de rendre Java indpendant des diffrentes plates-formes matrielles, seule une souris un bouton est supporte. Cependant, les conventions suivantes (voir tableau 13.2) permettent de rintroduire les autres boutons. La variable dinstance modifiers dun vnement contiendra ventuellement une valeur de modificateur.
Bouton de la souris Gauche Milieu Droite Modificateur pas de modificateur
Event.ALT_MASK Event.ALT_META

Tableau 13.2 Modificateurs pour une souris trois boutons

13.7 Le modle dvnements partir de Java 1.1


partir de la version 1.1 de lAPI Java, le modle de gestion des vnements est bas sur le principe de la dlgation. Cest un principe trs gnral qui ne sapplique pas seulement aux vnements physiques (dplacement de la souris, frappe au clavier, etc.), mais aussi la communication entre composants dun systme. Chaque vnement est reprsent par un objet qui constitue la mmoire de lvnement. Ce dernier contient des informations gnrales telles que la source de lvnement ou le moment auquel il a eu lieu et des informations spcifiques dpendant du type dvnement. Nimporte quel objet peut recevoir des vnements de son choix, il lui suffit pour cela : de sinscrire comme couteur auprs dun objet source dvnement;

Javabook Page 173 Lundi, 12. juillet 1999 3:58 15

Gestion de la souris (trois manires)

173

de possder les mthodes requises pour traiter ce type dvnement. De mme, tout objet peut tre source dvnements, il doit alors : possder une mthode dinscription et de dsinscription dcouteurs; transmettre les vnements en appelant les mthodes requises des couteurs. En gnral, une source peut avoir plusieurs couteurs diffrents qui lui sont attachs et un couteur peut tre inscrit auprs de plusieurs sources diffrentes.

13.8 Gestion de la souris (trois manires)


Prenons le cas des vnements gnrs par les mouvements de la souris. Un objet qui veut recevoir ces vnements, de type MouseEvent, doit possder toutes les mthodes dfinies dans linterface MouseMotionListener, cest--dire mouseMoved() et mouseDragged(). En dautres termes, sa classe doit implmenter MouseMotionListener. Lobjet doit galement sinscrire auprs dune source dvnements de type MouseMotion en appelant la mthode addMouseMotionListener() de cette source. En gnral, on effectue cet appel lors de linitialisation de lobjet. Le cas des applets est un peu particulier car une applet est source dvnements souris quelle va consommer elle-mme. On crira donc lappel dinscription :
this.addMouseMotionListener(this);

Nous voil prts pour crire une applet qui affiche en permanence les coordonnes de la souris :
import java.awt.Graphics; import java.awt.Event; import java.awt.event.*; public class Interaction extends java.applet.Applet implements MouseMotionListener { int sourisX, sourisY; long quand; public void init() { this.addMouseMotionListener(this); // inscription } public void mouseMoved(MouseEvent e){ // extrait les informations de lvnement quand=e.getWhen(); sourisX=e.getX(); sourisY=e.getY(); repaint(); } public void mouseDragged(MouseEvent e) {} public void paint(Graphics g) {

Javabook Page 174 Lundi, 12. juillet 1999 3:58 15

174

Chapitre 13 Interagir
g.drawString(quand+"=("+sourisX+","+sourisY+")",10,20); }

On obtient le mme comportement que lapplet 27 p.166. Cette manire dcrire une applet qui rpond des vnements est la plus proche de celle utilise avec JDK 1.0, mais elle nest pas la plus lgante car il faut dfinir toutes les mthodes de linterface dcoute (en loccurrence MouseMotionListener), mme celles quon nutilise pas. Pour simplifier lcriture des couteurs, le package java.awt.event propose des classes toutes faites, appeles adaptateurs, qui ralisent chacune un couteur inactif. On dfinira alors un couteur par extension dun adaptateur, ce qui nous donne le code suivant :
import java.awt.Graphics; import java.awt.Event; import java.awt.event.*; public class InteractionI extends java.applet.Applet{ int sourisX, sourisY; long quand; class EcouteSouris extends MouseMotionAdapter { public void mouseMoved(MouseEvent e){ quand=e.getWhen(); sourisX=e.getX(); sourisY=e.getY(); repaint(); } } public void init() { this.addMouseMotionListener(new EcouteSouris()); } public void paint(Graphics g) { g.drawString(quand+"=("+sourisX+","+sourisY+")",10,20); } }

Ici, ladaptateur est une classe interne, ce qui lui permet daccder aux variables de lapplet. Lors de lappel denregistrement, on cre lobjet couteur (new EcouteSouris()). Finalement, on peut utiliser le mcanisme des classes anonymes pour viter de dfinir explicitement une classe couteur :
public class InteractionA extends java.applet.Applet { int sourisX, sourisY; long quand; public void init() { this.addMouseMotionListener(

Javabook Page 175 Lundi, 12. juillet 1999 3:58 15

Gestion de la souris (trois manires)


new MouseMotionAdapter(){ public void mouseMoved(MouseEvent e){ quand=e.getWhen(); sourisX=e.getX(); sourisY=e.getY(); repaint(); } }); } public void paint(Graphics g) { g.drawString(quand+"=("+sourisX+","+sourisY+")",10,20); } }

175

Lexpression new MouseMotionAdapter() { } dfinit une classe qui tend MouseMotionAdapter et cre un objet de cette classe (lcouteur). Lcriture est plus compacte mais nest plus trs lisible car on mlange des dclarations de mthodes lintrieur dexpressions. Il vaut mieux viter dabuser de ce mcanisme. Si linterface MouseMotionListener permet de sinscrire pour recevoir les vnements de dplacement de la souris, linterface MouseListener permet de recevoir les clics souris (mthodes mousePressed(), mouseReleased() et mouseClicked()) et les entres/sorties du curseur sur la surface de composant (mouseEntered() et mouseExited()). Lvnement de type MouseEvent reu contient diffrentes informations que lon peut extraire laide de mthodes telles que : getWhen() : le temps auquel sest produit lvnement; getX(), getY() : la position du pointeur; getClickCount() : le nombre de clics sur ce mme point; isAltDown(), isAltGraphDown(), isControlDown(), isMetaDown(), isShiftDown() : vrai si la touche (modificateur) Alt, AltGr, Ctrl, Meta ou Shift tait enfonce lors de lvnement; getModifiers() : un codage sous forme dun int des touches enfonces. Dans le cas dune souris plusieurs boutons, on peut tester quel bouton a dclench lvnement avec lexpression :
(getModifiers() & BUTTONi_MASK) // i = 1, 2 ou 3

Le rsultat est diffrent de 0 si le bouton i a t press, relch ou cliqu (cest-dire press puis relch). Cependant, pour tre vraiment portable, une application ne devrait pas faire dhypothses sur le nombre de boutons dont est munie la souris.

Javabook Page 176 Lundi, 12. juillet 1999 3:58 15

176

Chapitre 13 Interagir

13.9 Gestion du clavier


Les vnements clavier sont reprsents par des objets de la classe KeyEvent qui tend InputEvent. Lapplet ci-dessous est la version 1.1 de lapplet 31 p.172 :
import java.awt.Font; import java.awt.event.*; public class Interaction31 extends java.applet.Applet { int taille=12; char toucheCourante='?'; boolean shiftPresse; class Clavier extends KeyAdapter { public void keyPressed(KeyEvent e){ int touche = e.getKeyCode(); shiftPresse = e.isShiftDown(); switch(touche){ case KeyEvent.VK_DOWN: --taille; break; case KeyEvent.VK_UP: ++taille; break; default: toucheCourante=e.getKeyChar(); } setFont(new Font("Helvetica",Font.BOLD,taille)); repaint(); } } public void init() { this.addKeyListener(new Clavier()); } public void paint(Graphics g) { g.drawString("Taille="+taille+" majuscule="+ shiftPresse, 10, 25); g.drawString(String.valueOf(toucheCourante),100,60); } }

La mthode keyPressed est invoque lorsquune touche est enfonce. La mthode getKeyCode de la classe keyEvent fournit le code de la touche. Il sagit de codes correspondant un clavier virtuel indpendant de la machine utilise. Ces codes sont dfinis par une liste de constantes KeyEvent.VK_xxx. Dans cet exemple, nous utilisons VK_DOWN et VK_UP qui correspondent aux flches vers le bas et vers le haut. La mthode getKeyChar fournit un caractre lorsque la ou les touche(s) presse(s) corresponde(nt) un caractre. Il existe aussi une mthode keyTyped() qui nest invoque que lorsquun caractre est gnr par la ou les touches presse(s). Cette mthode ne permet videmment pas de capter les actions sur les touches de flches, de fonctions, majuscule, ctrl, alt, etc.

Javabook Page 177 Lundi, 12. juillet 1999 3:58 15

vnements et autres composants dinteraction

177

De mme que pour les vnement souris, les vnements clavier ont des mthodes isAltDown(), isAltGraphDown(), isControlDown(), isMetaDown() et isShiftDown() pour savoir quelle(s) touche(s) tai(en)t enfonce(s) au moment du clic.

13.10 vnements et autres composants dinteraction


linstar de lapplet, qui est un composant dinterface graphique, il existe dautres types dobjets (boutons, tiquettes, menus, textes, barres de dfilement, etc.) qui peuvent entrer dans la composition dune interface graphique. Ces composants, que nous dcrirons dans le chapitre suivant, peuvent gnrer diffrents types dvnements en fonction des actions de lutilisateur. La table qui suit en montre quelques exemples.
Action qui cre lvnement Un utilisateur clique sur un bouton, choisit un article dans un menu, tape la touche Return dans un champ de texte. Un utilisateur ferme une fentre. Un utilisateur presse un bouton de la souris quand le curseur est sur un composant. Un utilisateur bouge la souris sur un composant. Un composant se cache ou devient visible Un composant reoit lattention du clavier. Une table ou une liste de slection est modifie. Tableau 13.3 Actions et vnements gnrs Type dvnement
ActionEvent

WindowEvent MouseEvent MouseMotionEvent ComponentEvent FocusEvent ListSelectionEvent

Lorsque nous tudierons les composants dinteraction graphique nous indiquerons chaque fois quels sont les types dvnements quils peuvent gnrer. Il est intressant de noter quon peut considrer les actions de lutilisateur diffrents niveaux de dtail. Par exemple, lorsque lutilisateur agit sur un bouton de linterface on peut sintresser : uniquement au dclenchement de la commande associe au bouton (suite un clic souris); laction enfoncer le bouton (presser sur le bouton de la souris) suivie de laction relcher le bouton (relcher le bouton de la souris); tous les mouvements du pointeur de la souris sur ce composant. Il est donc possible de capter les vnements les plus pertinents selon le degr de sophistication de linterface que lon doit programmer.

Javabook Page 178 Lundi, 12. juillet 1999 3:58 15

178

Chapitre 13 Interagir

Finalement, rappelons que le mcanisme dvnement ne sert pas uniquement grer linterface utilisateur. Il offre un moyen de communication gnral entre objets. On peut, par exemple, concevoir un objet qui signale ses couteurs tout changement de valeur de lune de ses variables.

13.11 Invitation explorer


Nous vous invitons examiner de plus prs le package java.awt.event qui contient toutes les classes dvnements relatifs linterface graphique. Vous pouvez galement reprendre une applet danimation et tenter de la contrler laide de la souris.

Javabook Page 179 Lundi, 12. juillet 1999 3:58 15

Chapitre 14

Composants dinteraction graphique


Nous allons examiner de manire plus exhaustive le package java.awt. Nous avons dj tudi les objets graphiques (Graphics, Rectangle, Point, etc.), leurs attributs (Fonts, Color, etc.) et la gestion des vnements (Event). Ce chapitre prsentera des composants graphiques dont le comportement est dj tabli (les boutons, les listes, etc.). Lensemble de ces composants (voir figure 14.1) constitue linterface graphique utilisateur (Graphical User Interface). Le package awt contient la dfinition conceptuelle des objets (leur comportement et leur spcification), tandis que laspect graphique des objets dpend quant lui de la plateforme dexcution : une mme applet aura donc un comportement similaire sur des plates-formes diffrentes, par contre sa reprsentation graphique sera adapte au style en vigueur sur cette plate-forme (Macintosh, PC, Unix, etc.). Laddition dun composant au contenant graphique seffectue au moyen de la mthode add(). Dans le cas dune applet, lobjet adress est du type Panel (panneau daffichage). La mthode de mise en pages par dfaut est coulissante, cest-dire que les composants graphiques sont ajouts de gauche droite et que lon revient la ligne ds que ncessaire. Nous reviendrons en dtail sur les conventions de mise en pages au chapitre 16. Nous allons examiner systmatiquement le paramtrage, la construction et la manipulation des principaux objets graphiques proposs dans java.awt.

Javabook Page 180 Lundi, 12. juillet 1999 3:58 15

180

Chapitre 14 Composants dinteraction graphique

Button

Canvas

CheckBox

Choice

Container Abstraite Object Component Abstraite Label

List

ScrollBar

TextArea TextComponent TextField

Figure 14.1 Hirarchie des composants graphiques

14.1 Les libells


Les libells sont des objets de la classe Label. Ils permettent dafficher un texte dans un contenant graphique (voir applet 32). Jusqu prsent, nous avons dessin (peint) du texte dans le composant graphique; ici nous associons un texte et un type dalignement un composant graphique. La spcification dun libell peut tre modifie tout moment. Lexemple suivant montre la cration de libells et leur association lapplet :
import java.awt.*; public class Composant extends java.applet.Applet { public void init() { add(new Label ("A gauche par defaut")); add(new Label ("-Au centre-",Label.CENTER)); add(new Label ("A droite---------->", Label.RIGHT)); }

Javabook Page 181 Lundi, 12. juillet 1999 3:58 15

Les boutons
public void paint(Graphics g) { g.drawString("Texte dessine", 100, 150); } }

181

Applet 32 : Affichage, les libells

Les paramtres dalignement sont des variables de classe constantes : Label.CENTER, Label.LEFT, Label.RIGHT. Par dfaut, lalignement gauche est utilis. Le tableau 14.1 dcrit les principales mthodes de la classe Label.
Mthode
Label() Label(String l) Label(String l, int a) getAlignment() getText() setAlignment(int a) setText(String label)

Dfinition Cre un libell sans texte. Cre un libell de texte. l Cre un libell de texte l et dalignement a. Retourne lalignement du libell. Retourne le texte du libell. Impose un alignement. Assigne un texte au label.

Tableau 14.1 Mthodes de la classe Label

14.2 Les boutons


Les boutons sont des objets de la classe Button. Ils correspondent ce que lon attend : des objets portant un titre et ragissant quand on clique sur eux. Ils mettent des vnements de type ActionEvent qui sont envoys aux objets qui implmentent linterface ActionListener et qui se sont inscrits. Lapplet 33 montre la cration de boutons (new Button()) et leur ajout lapplet, add()), puis lassociation dun couteur (en loccurrence lapplet ellemme) chaque bouton (addActionListener(this)). Lorsquun bouton est enfonc la mthode actionPerformed() est appele et on rcupre la commande, en loccurrence le nom du bouton, dans lvnement transmis. Finalement, la

Javabook Page 182 Lundi, 12. juillet 1999 3:58 15

182

Chapitre 14 Composants dinteraction graphique

mthode paint() choisit la fonte utiliser en fonction de la dernire commande reue.


import java.applet.*; import java.awt.*; import java.awt.event.*; public class Composant extends Applet implements ActionListener { String commande = "Normal"; Button bn, bg, bi; Font fgras, fnormal, fitalic, fdef; public void init() { add(bn = new Button ("Normal")); add(bg = new Button("Gras")); add(bi = new Button("Italique")); bn.addActionListener(this); bg.addActionListener(this); bi.addActionListener(this); fgras = new Font("Helvetica",Font.BOLD,40); fnormal = new Font("Helvetica",Font.PLAIN,40); fitalic = new Font("Helvetica",Font.ITALIC,40); fdef = new Font("Helvetica",Font.PLAIN,12); } public void actionPerformed(ActionEvent e) { commande = e.getActionCommand(); repaint(); } public void paint(Graphics g) { if (commande.equals("Normal")) g.setFont(fnormal); if (commande.equals("Gras")) g.setFont(fgras); if (commande.equals("Italique")) g.setFont(fitalic); g.drawString("Exemple", 20, 80); g.setFont(fdef); }

Applet 33 : Affichage, les boutons

Le tableau 14.2 dcrit les principales mthodes de la classe Button.


Mthode
Button()

Dfinition Cre un bouton sans libell.

Tableau 14.2 Mthodes de la classe Button

Javabook Page 183 Lundi, 12. juillet 1999 3:58 15

Les boutons
Mthode
Button(String b) getLabel() setLabel(String b)

183
Dfinition Cre un bouton avec libell b. Retourne le libell du bouton. Assigne un libell b. Ajoute un couteur daction l. Supprime un couteur. Dfinit le nom de commande qui sera donn aux vnements ActionEvent produits (par dfaut cest le libell du bouton). Retourne le nom de commande dfini.

addActionListener (ActionListener l) removeActionListener (ActionListener l) setActionCommand(String c)

getActionCommand()

Tableau 14.2 Mthodes de la classe Button

Pour accder aux informations transmises par un vnement de type ActionEvent, on utilisera les mthodes de cette classe dcrites dans le tableau 14.3 cidessous.
Mthode
getSource() getActionCommand() getModifiers()

Dfinition Fournit lobjet qui a mis lvnement (mthode hrite de EventObject). Retourne le String reprsentant la commande associe cet vnement. Retourne un entier qui contient les codes des modificateurs (shift, alt, ctrl) associs lvnement. Retourne une reprsentation sous forme de String de lvnement (utile pour la mise au point).

paramString()

Tableau 14.3 Mthode de la classe ActionEvent

Le recours la mthode getSource() est ncessaire dans le cas o un objet (par exemple notre applet) est abonn plusieurs sources du mme type dvnement (par exemple, plusieurs boutons). Il faut noter que plusieurs boutons peuvent produire la mme commande et quun bouton peut produire diffrentes commandes au cours du temps. La classe ActionEvent fournit quatre constantes : ALT_MASK, CTRL_MASK,

Javabook Page 184 Lundi, 12. juillet 1999 3:58 15

184

Chapitre 14 Composants dinteraction graphique

META_MASK, SHIFT_MASK pour tester quel(s) modificateur(s) tai(en)t enfonc(s) au moment de lvnement. Par exemple :
public void actionPerformed(ActionEvent e) { if (e.getModifiers() & ActionEvent.SHIFT_MASK) { ... la touche SHIFT tait enfonce ...}

14.3 Les botes cocher choix multiple


Il existe deux types de botes cocher : dans le premier, chaque bote est indpendante, ce qui permet la slection multiple doptions. Dans lautre type (voir point 14.4), elles sont regroupes et fonctionnent en mode exclusif (une seule bote coche la fois). Les botes cocher sont toutes issues de la classe Checkbox. Lorsquune bote change dtat, parce que lutilisateur a cliqu dessus, la bote appelle la mthode itemStateChanged() des objet inscrits comme ItemListener. Lapplet 34 montre la cration de botes cocher, linscription de lapplet en tant quItemListener, le traitement des vnements et laffichage de rsultats en fonction de ltat des botes.
public class Composant extends Applet implements ItemListener { String message = "", composition; Checkbox[] ingredients; double[] prix = {5.00, 5.00, 2.00, 1.50, 1.50, 1.00}; public void init() { ingredients = new Checkbox[6]; add(ingredients[0] = new Checkbox ("Fromage", null, true)); add(ingredients[1] = new Checkbox ("Tomates", null, true)); add(ingredients[2] = new Checkbox ("Jambon")); add(ingredients[3] = new Checkbox ("Champignons")); add(ingredients[4] = new Checkbox ("Thon")); add(ingredients[5] = new Checkbox ("Anchois")); for (int i=0; i<ingredients.length; i++) ingredients[i].addItemListener(this); } public void itemStateChanged(ItemEvent e) { Checkbox lequel = (Checkbox)e.getItemSelectable(); message = lequel.getLabel(); int changement = e.getStateChange() ; if (changement == ItemEvent.SELECTED) message = "Ajout de "+message; else message = "Suppression de "+message; repaint(); }

Javabook Page 185 Lundi, 12. juillet 1999 3:58 15

Les botes cocher choix multiple

185

public void paint(Graphics g) { composition = ""; double p = 5.00; for (int i=0; i<ingredients.length; i++) if (ingredients[i].getState()) { composition += (" " + ingredients[i].getLabel()); p += prix[i]; } g.drawString(message, 20, 100); g.drawString("Une pizza du chef avec "+composition, 20, 120); g.drawString("Prix: "+p, 20, 140); } }

Applet 34 : Affichage, les botes cocher

Le tableau 14.4 regroupant les principales mthodes de la classe Checkbox.


Mthode
Checkbox() Checkbox (String b) getLabel() setLabel(String getState() setState(boolean c) b)

Dfinition Cre une bote cocher sans libell. Cre une bote cocher avec libell b. Retourne le titre de la bote cocher. Assigne un libell b. Retourne ltat de la bote cocher (boolen). Assigne ltat c la bote cocher.

Tableau 14.4 Mthodes de la classe Checkbox

Pour reconnatre le type de changement subi par une bote, on utilise la mthode getStateChange() de la classe ItemEvent.

Javabook Page 186 Lundi, 12. juillet 1999 3:58 15

186

Chapitre 14 Composants dinteraction graphique

14.4 Les botes cocher choix exclusif


Les botes cocher de ce type travaillent dans un mode exclusif et sont associes un groupe de botes. Ce groupe est spcifi laide dun objet CheckboxGroup (voir tableaux 14.5 et 14.6). Lapplet 35 montre la cration de botes cocher associes un groupe et leur association lapplet :
import java.applet.*; import java.awt.*; import java.awt.event.*; public class Composant extends Applet implements ItemListener { String message, composition; CheckboxGroup dessert; Checkbox[] ingredients; public void init() { dessert = new CheckboxGroup(); ingredients = new Checkbox[6]; add(ingredients[0] = new Checkbox("Fromage blanc", dessert, false)); add(ingredients[1] = new Checkbox ("Tarte au citron", dessert, true)); add(ingredients[2] = new Checkbox ("Glace", dessert, false)); add(ingredients[3] = new Checkbox ("Flan", dessert, false)); add(ingredients[4] = new Checkbox ("Mousse au chocolat", dessert, false)); add(ingredients[5] = new Checkbox ("Crpe", dessert, false)); for (int i=0; i<ingredients.length; i++) ingredients[i].addItemListener(this); } public void itemStateChanged(ItemEvent e) repaint(); } {

public void paint(Graphics g) { Checkbox choix = dessert.getSelectedCheckbox(); g.drawString("Un dessert au choix: "+choix.getLabel(), 20, 120); } }

Javabook Page 187 Lundi, 12. juillet 1999 3:58 15

Les menus droulants

187

Applet 35 : Affichage, les botes cocher en mode exclusif Mthode ou constructeur


Checkbox(String b, CheckboxGroup g, boolean s) setCheckboxGroup(CheckboxGroup g)

Dfinition Cre une bote cocher avec libell b, associe au groupe g dans ltat s. Associe la bote au groupe g.

Tableau 14.5 Mthodes de la classe Checkbox utilisant la notion de groupe Mthode ou constructeur
CheckboxGroup() getSelectedCheckbox() setSelectedCheckbox (Checkbox b)

Dfinition Cre un groupe. Retourne la bote cocher actuellement slectionne. Slectionne la bote cocher b.

Tableau 14.6 Mthodes de la classe CheckboxGroup

14.5 Les menus droulants


Les menus droulants sont des objets de la classe Choice. Un menu droulant est compos darticles (item). ltat de repos, il affiche larticle slectionn. En cliquant sur lui, on affiche lensemble des articles slectionnables et on peut alors modifier la slection. On accde aux menus droulants en termes de position dans le menu (index) ou de libell dun article (label). Un seul article est slectionnable la fois. Lors dune slection, un vnement ItemEvent est gnr. Lexemple suivant (applet 36) montre la cration dun menu droulant et laffichage de lindex de llment slectionn :
import java.applet.*; import java.awt.*; import java.awt.event.*;

Javabook Page 188 Lundi, 12. juillet 1999 3:58 15

188

Chapitre 14 Composants dinteraction graphique


{

public class Composant extends Applet implements ItemListener Choice parfum; public void init() { parfum = new Choice(); parfum.addItem("Vanille"); parfum.addItem("CHocolat"); parfum.addItem("Fraise"); parfum.addItem("Pistache"); parfum.addItem("Noisette"); parfum.addItem("Citron"); add(new Label("Parfum de la glace")); add(parfum); // ajoute le menu aprs le libell parfum.select("Vanille"); parfum.addItemListener(this); // l'applet coute le menu } public void itemStateChanged(ItemEvent e) { repaint(); } public void paint(Graphics g) { int parfumNo = parfum.getSelectedIndex() ; g.drawString("Glace no. "+parfumNo, 20, 100); }

Applet 36 : Affichage, les menus droulants (phase de slection)

Le tableau 14.7 dcrit les principales mthodes de la classe Choice.


Mthode
Choice() addItem(String b) getItem(int p) remove(String getItemCOunt() b)

Dfinition Cre un menu. Ajoute un article de libell b. Retourne le libell de larticle la position p. Supprime le premier article libell b. Fournit le nombre darticles du menu.

Tableau 14.7 Mthodes de la classe Choice

Javabook Page 189 Lundi, 12. juillet 1999 3:58 15

Les listes de choix


Mthode
getSelectedItem() getSelectedIndex() select(int p) addItemListener(ItemListener l) removeItemListener()

189
Dfinition Fournit le libell de larticle slectionn. Fournit la position de larticle slectionn. Slectionne larticle la position p. Ajoute (supprime) un couteur de slection darticles.

Tableau 14.7 Mthodes de la classe Choice

14.6 Les listes de choix


Pour les slections multiples, les listes de choix sont appropries. Les listes de choix sont des objets de la classe List. Un vnement ActionEvent est gnr lors dun double clic sur un article ou lorsquon presse la touche retour alors quun article est slectionn. La slection ou la dslection dun article (clic simple) gnre un vnement ItemEvent. Lapplet 37 montre la cration dune liste de choix et la dtection des slections et dslections.
import java.applet.*; import java.awt.*; import java.awt.event.*; public class Composant extends Applet implements ItemListener List parfum; public void init() { parfum = new List(5,true); parfum.add("Vanille"); parfum.add("Chocolat"); parfum.add("Fraise"); parfum.add("Pistache"); parfum.add("Noisette"); parfum.add("Citron"); parfum.add("Orange"); parfum.add("Abricot"); parfum.setMultipleMode(true); add(new Label("Parfums de la glace")); add(parfum); // ajoute la liste aprs le libell parfum.select(3); // prselectionne Pistache parfum.addItemListener(this); // l'applet coute le menu } public void itemStateChanged(ItemEvent e) repaint(); } public void paint(Graphics g) { { {

Javabook Page 190 Lundi, 12. juillet 1999 3:58 15

190

Chapitre 14 Composants dinteraction graphique


int[] parfumNos = parfum.getSelectedIndexes(); String message = "Code glace: "; for (int i=0; i<parfumNos.length; i++) message = message + parfumNos[i]; g.drawString(message, 20, 100); }

Applet 37 : Affichage, les listes de choix

Le tableau 14.8 regroupe les principales mthodes de la classe List.


Mthode ou constructeur
List() List(int lignes, boolean choixMultiple) add(String l) add(String l,int p) remove(String l) remove(int p) replaceItem(String l, int p) getItemCount() getItem(int p) setMultipleMode (boolean b) select(int p) deselect(int p)

Dfinition Cre une liste de choix. Cre une liste de choix de n lignes visibles spcifiant si le choix multiple est autoris. Ajoute un article de libell l. Ajoute un article de libell l la position p. Supprime un article de libell l. Supprime larticle la position p. Remplace le libell de larticle la position p par l. Retourne le nombre darticles de la liste. Retourne le libell (String) de larticle la position p. Autorise ou non le choix multiple. Slectionne larticle la position p. Dslectionne larticle la position p.

Tableau 14.8 Mthodes de la classe List

Javabook Page 191 Lundi, 12. juillet 1999 3:58 15

Les champs de texte sur une ligne


Mthode ou constructeur
getSelectedIndex() getSelectedItem() getSelectedIndexes() getSelectedItems() isIndexSelected(int p) addActionListener (ActionListener l) addItemListener (ItemListener l)

191
Dfinition Retourne la position (int) de larticle slectionn. Retourne le libell (String) de larticle slectionn. Retourne les positions (int[]) des articles slectionns. Retourne les libells (String[]) des articles slectionns. Retourne un boolen qui indique si larticle p est slectionn ou non. Ajoute un couteur dactions (double clic et retour). Ajoute un couteur pour les changements de slection.

Tableau 14.8 Mthodes de la classe List

14.7 Les champs de texte sur une ligne


Les champs de texte hritent tous de la classe TextComponent dans laquelle sont dfinies les mthodes permettant la manipulation de texte (voir tableau 14.9).
Mthode
pas de constructeur! getText() getSelectedText() getSelectionEnd() getSelectionStart() isEditable() select(int dbut, int fin)

Dfinition Les classes TextField et TextArea ont leur propres constructeurs. Retourne le texte contenu dans le champ (String). Retourne le texte slectionn (String). Retourne la position de la fin du texte slectionn (int). Retourne la position du dbut du texte slectionn (int). Teste si le champ est ditable. Slectionne le texte de la position dbut la position fin.

Tableau 14.9 Mthodes de la classe TextComponent

Javabook Page 192 Lundi, 12. juillet 1999 3:58 15

192
Mthode
selectAll() setText(String l) setCaretPosition(int pos) getCaretPosition()

Chapitre 14 Composants dinteraction graphique


Dfinition Slectionne la totalit du texte. Assigne le texte du champ la valeur l spcifie. Place le symbole dinsertion (caret) la position indique. Retourne la position du symbole dinsertion.

Tableau 14.9 Mthodes de la classe TextComponent

Le champ de texte sur une ligne est un objet de la classe TextField. Le contenu du champ peut tre dit par lutilisateur. La touche retour (return) gnre un vnement ActionEvent qui est transmis aux ventuels ActionListeners inscrits. Lvnement gnr contient la valeur du champ au moment o la touche fut presse. De plus, chaque modification du texte gnre un vnement TextEvent transmis aux TestListeners par appel de leur mthode textValueChanged(). Il est possible de spcifier un caractre dcho (exemple : -) afficher la place des caractres entrs, ce qui permet par exemple de saisir des mots de passe sans quils apparaissent en clair lcran. Les mthodes de la classe TextField sont prsentes dans le tableau 14.10; lapplet 38 montre la cration dun masque de saisie comportant plusieurs champs, elle coute les vnements TextEvent du champ code et vrifie si le contenu de ce champ correspond au mot de passe1 :
import java.applet.*; import java.awt.*; import java.awt.event.*; public class Composant extends Applet implements TextListener { String msg; TextField np, adr, tel, code, message; public void init() { add(new Label("Nom et prenom")); add(np = new TextField(30)); add(new Label("Adresse")); add(adr = new TextField(30)); add(new Label("Telephone")); add(tel = new TextField("022/",30)); add(new Label("Code du club pizza!")); add(code = new TextField(10)); code.setEchoChar('-'); add(message = new TextField(15));

1. Attention, ne mettez jamais un mot de passe en clair dans une applet, il pourrait facilement tre retrouv !

Javabook Page 193 Lundi, 12. juillet 1999 3:58 15

Les champs de texte sur plusieurs lignes

193

code.addTextListener(this); } public void textValueChanged(TextEvent e) { if (e.getSource() == code) { if (code.getText().equals("secret")) // vrif. mot de passe message.setText("code OK"); else message.setText("entrez le code!"); } } }

Applet 38 : Affichage, les champs de texte sur une ligne

La table ci-dessous prsente les principales mthodes de la classe TextField :


Mthode ou constructeur
TextField() TextField(int n) TextField(String l) TextField(String l,int n) echoCharIsSet() getColumns() setColumns(int n) getEchoChar() setEchoChar(char c)

Dfinition Cre un champ. Cre un champ de n caractres. Cre un champ initialis avec le texte l. Cre un champ de n caractres (approximativement), initialis avec le texte l. Teste si le caractre dcho est dfini. Retourne la longueur (int) du champ. Dfinit la longueur du champ de manire ce quil puisse contenir environ n caractres. Retourne le caractre dcho. Dfinit le caractre dcho.

Tableau 14.10 Mthodes de la classe TextField

14.8 Les champs de texte sur plusieurs lignes


Le champ de texte sur plusieurs lignes est pour lessentiel identique celui sur une seule ligne. Les objets sont de la classe TextArea, qui comprend une gestion du nombre de lignes en plus de celle des colonnes. Lapplet 39 montre la cration dun champ sur plusieurs lignes :

Javabook Page 194 Lundi, 12. juillet 1999 3:58 15

194
import java.awt.*;

Chapitre 14 Composants dinteraction graphique

public class Composant extends java.applet.Applet { public void init() { add(new Label("Vos commentaires: ...")); add(new TextArea("Entrez vos commentaires ici ...",4,30)); } public void paint(Graphics g) { g.drawString("Merci de votre confiance", 100, 150); } }

Applet 39 : Affichage, les champs de texte sur plusieurs lignes

En plus des mthodes hrites de TextComponent, TextArea possde les mthodes ci-dessous :
Mthode ou constructeur
TextArea() TextArea (int n, int j) TextArea (String t) TextArea (String t, int n, int j) append(String t) insert(String t,int n) replaceRange(String t, int d, int f)

Dfinition Cre un champ. Cre un champ de n caractres de j lignes. Cre un champ initialis avec t. Cre un champ initialis avec t, de n caractres et j lignes. Ajoute le texte t la fin du champ. Insre le texte t la position n. Remplace le texte des positions d f par le texte t.

Tableau 14.11 Mthodes de la classe TextArea

Javabook Page 195 Lundi, 12. juillet 1999 3:58 15

Les barres de dfilement


Mthode ou constructeur
getColumns() setColumns(int n)

195
Dfinition Retourne la longueur (int) du champ. Dfinit la longueur du champ. Retourne le nombre de lignes (int) du champ. Dfinit le nombre de lignes.

getRows() setRows(int k)

Tableau 14.11 Mthodes de la classe TextArea

14.9 Les barres de dfilement


Les barres de dfilement sont des objets de la classe Scrollbar. Une barre peut tre soit verticale soit horizontale, elle comporte diffrentes parties (lascenseur, les flches, la piste) sur lesquelles lutilisateur peut agir par des mouvements de la souris. Ltat courant de la barre reprsente une valeur entire que lutilisateur modifie par ses actions. Lorsque la valeur de la barre est modifie, celle-ci envoie un vnement AdjustmentEvent que lon capte en implmentant la mthode adjustmentValueChanged() de linterface AdjustmentListener. On peut connatre le type de mouvement effectu en appliquant la mthode getAdjustmentType() sur lvnement reu. Les mouvements possibles sont : TRACK (lutilisateur a tir lascenseur); UNIT_INCREMENT (clic sur la flche vers la droite ou vers le haut); UNIT_DECREMENT (clic sur la flche vers la gauche ou vers le bas); BLOCK_INCREMENT (clic droite ou au dessus de lascenseur); BLOCK_ DECREMENT (clic gauche ou au-dessous de lascenseur). La variable associe la barre possde une valeur minimum et une valeur maximum que lon indique au moment de la cration. La taille de lascenseur peut aussi tre dfinie et modifie, par exemple pour reprsenter la proportion du texte visible dans une fentre. Lapplet suivante montre lutilisation de deux barres de dfilement qui servent dterminer deux angles de rotation dun objet en trois dimensions. Chaque modification de la valeur dune barre entrane le rafrachissement du dessin pour tenir compte des nouveaux angles. Pour pouvoir placer correctement les barres, on utilise une mise en pages de type bord que nous dcrirons dans le chapitre consacr aux protocoles de mise en pages.
import java.applet.*; import java.awt.*; import java.awt.event.*; public class Composant extends Applet implements AdjustmentListener { static final int N = 100, X = 0, Y = 1, Z = 2;

Javabook Page 196 Lundi, 12. juillet 1999 3:58 15

196

Chapitre 14 Composants dinteraction graphique


int initial = 0, visi = 1, min = 0, max = 100; Scrollbar sba, sbb; double [][] points; // points 3D de la figure double alpha, beta; // angles de vision

public void init() { points = new double[N][3]; // construction d'une spirale en 3D dans le cube [-80,80]^3 for (int i = 0; i<N; i++) { points[i][Y] = i*160.0/N - 80.0; double r = 80 - i*80.0/N; double a = i*2*Math.PI/8; points[i][X] = Math.cos(a)*r; points[i][Z] = Math.sin(a)*r; } setLayout(new BorderLayout()); sba = new Scrollbar(Scrollbar.VERTICAL, initial, visi, min,max); add(sba, BorderLayout.WEST); sba.addAdjustmentListener(this); sbb = new Scrollbar(Scrollbar.HORIZONTAL, initial, visi, min,max); add(sbb, BorderLayout.SOUTH); sbb.addAdjustmentListener(this); } public void paint(Graphics g) { double x,y,z; int xp = 0, yp = 0; // mmoire du point prcdent g.setColor(Color.blue); for (int i = 0; i<N; i++) { // rotation selon z x = points[i][X]*Math.cos(alpha)points[i][Y]*Math.sin(alpha); y = points[i][X]*Math.sin(alpha)+points[i][Y]*Math.cos(alpha); z = points[i][Z]; // rotation selon y x = x*Math.cos(beta)-z*Math.sin(beta); z = x*Math.sin(beta)+z*Math.cos(beta); // projection sur (X,Y) (laxe Z est celui qui sort de lcran) if (i>0) g.drawLine(xp, yp, (int)x+150,(int)y+150); xp = (int)x+150; yp = (int)y+150; } } public void adjustmentValueChanged(AdjustmentEvent e) { if (e.getSource() == sba) alpha = e.getValue()*2*Math.PI/100; if (e.getSource() == sbb) beta = e.getValue()*2*Math.PI/100; repaint(); } }

Javabook Page 197 Lundi, 12. juillet 1999 3:58 15

Les fonds

197

Applet 40 : Deux barres de dfilement dterminent les angles de vue

14.10 Les fonds


Les fonds sont des objets de la classe Canvas. Ils permettent de crer une surface de travail pour dessiner, afficher des images, etc. En tendant cette classe, il est possible de redfinir le comportement dun fond en surchargeant la mthode paint(). Un Canvas est sensible aux vnements gnrs par la souris et par le clavier.

14.11 Prfrences lors de laffichage


Nous avons omis de dcrire pour chaque classe les prfrences daffichage, la taille minimum et les divers paramtres de mise en pages. Ces paramtres sont spcifier dans le cas dinterfaces complexes destines tre largement diffuses. Ils permettent de dfinir des contraintes utilises lors du calcul automatique de la mise en pages.

14.12 Invitation explorer


Parcourez les documents HTML dcrivant ces diffrentes classes. Examinez la classe Toolkit qui indique certains paramtres dimplantation de la plate-forme physique utilise. Examinez la classe Component de manire plus dtaille.

Javabook Page 198 Lundi, 12. juillet 1999 3:58 15

Javabook Page 199 Lundi, 12. juillet 1999 3:58 15

Chapitre 15

Gestion des conteneurs


Le dernier composant graphique quil nous reste dcrire est la classe abstraite Container. Un conteneur est un espace graphique destin recevoir plusieurs composants (boutons, fonds, listes, botes cocher, etc.) dont la mise en pages graphique dpendra du gestionnaire de mise en pages utilis. Les mthodes de la classe Container sont donc spcifiques la gestion des composants (add(), countComponent(), getComponent(), etc.) et des gestionnaires de mise en pages (layout(), getLayout(), etc.). partir de Container, nous avons la hirarchie de classes suivante :
Panel Container Abstraite Window Frame Dialog FileDialog

Figure 15.1 Hirarchie des conteneurs

La classe Panel (panneau) reprsente des conteneurs destins tre placs dans un espace existant (un autre conteneur ou un butineur dans le cas des applets). La classe Applet tend la classe Panel (voir figure 15.2). La classe Window cre des espaces indpendants (nouvelles fentres). Les deux classes directement utilisables sont Dialog, qui permet la gestion des dialogues (avec un comportement modal) et Frame qui cre une surface de travail dans une fentre afin de recevoir des composants graphiques simples. noter que

Javabook Page 200 Lundi, 12. juillet 1999 3:58 15

200

Chapitre 15 Gestion des conteneurs

Frame implante linterface MenuContainer, ce qui signifie quil est possible de spcifier les interactions avec des menus propres chaque fentre. La classe FileDialog est une spcialisation de Dialog pour la gestion des interactions par rapport un rpertoire de fichiers (voir point 19.14, p. 260). Nous allons maintenant voir quelques utilisations possibles de ces conteneurs travers des exemples.

15.1 Mon applet est trop petite


Dans lapplet 41, nous reprenons notre programme permettant de dessiner avec la souris (applet 30, p. 170). Nous dsirons ajouter un champ de texte dans lequel nous afficherons les coordonnes des segments dessins. Lors de linitialisation, nous dclarons donc un objet de type TextArea que nous ajoutons notre applet (qui est galement un Panel par hritage).
t=new TextArea("(x,y)",5,20); this.add(t);

Ensuite, chaque fois que lon dessine un segment, on ajoute sa coordonne dans le champ :
import java.applet.*; import java.awt.*; import java.awt.event.*; public class Dessin extends Applet { int x0 = 0, y0 = 0; TextArea t; class MSouris extends MouseMotionAdapter { public void mouseDragged(MouseEvent e) { Graphics g = getGraphics(); g.drawLine(x0, y0, e.getX(), e.getY()); t.append("\n("+x0+","+y0+")>("+e.getX()+","+e.getY()+")"); x0 = e.getX(); y0 = e.getY(); } } class CSouris extends MouseAdapter { public void mousePressed(MouseEvent e) { x0 = e.getX(); y0 = e.getY(); } } public void init() { t = new TextArea("(x, y)", 5, 20); this.add(t); addMouseListener(new CSouris()); addMouseMotionListener(new MSouris()); } }

Javabook Page 201 Lundi, 12. juillet 1999 3:58 15

Ouvrir une autre fentre

201

Nous constatons que les coordonnes sinscrivent bien dans le champ de texte. Malheureusement, celui-ci occupe une partie importante de notre espace de travail (par ailleurs limit), nous privant ainsi dune large zone de dessin. Que faire dans ce cas? Cest ce que nous allons voir.

Applet 41 : Dessiner et afficher les coordonnes dans un champ de texte

15.2 Ouvrir une autre fentre


Pour conserver la fois lensemble des fonctionnalits de lexemple prcdent et un espace complet pour dessiner, il est ncessaire de crer une fentre spare destine laffichage des coordonnes (voir applet 42). cet effet, nous crons une nouvelle classe Fenetre tendant Frame, qui possdera un champ de texte et une mthode afficher() pour ajouter du texte dans ce champ. Le constructeur de Fenetre cre le champ texte et lajoute la fentre, il invoque ensuite de la mthode pack() qui positionne correctement les composants de la fentre en fonction de leur taille, puis rend la fentre visible avec show(). Lapplet est modifie de manire dclarer une fentre f1. chaque nouveau segment, nous ajoutons les coordonnes de celui-ci dans la fentre f1 laide de la mthode afficher(). On notera galement la dfinition de la mthode stop() dans lapplet, qui demande la fentre quelle a cre de disparatre (dispose()).
import java.applet.*; import java.awt.*; import java.awt.event.*; class Fenetre extends Frame { TextArea t; Fenetre(String titre) { super(titre); // constructeur de Frame t = new TextArea("(x, y)", 5, 20); add("Center", t); pack();

Javabook Page 202 Lundi, 12. juillet 1999 3:58 15

202
show(); } public void afficher(String s) { t.append(s); }

Chapitre 15 Gestion des conteneurs

} public class Interaction extends Applet { int x0 = 0, y0 = 0; Fenetre f1; class MSouris extends MouseMotionAdapter { public void mouseDragged(MouseEvent e) { Graphics g = getGraphics(); g.drawLine(x0, y0, e.getX(), e.getY()); f1.afficher("\n("+x0+","+y0+")>("+e.getX()+","+e.getY()+")"); x0 = e.getX(); y0 = e.getY(); } } class CSouris extends MouseAdapter { public void mousePressed(MouseEvent e) { x0 = e.getX(); y0 = e.getY(); } } public void init() { f1 = new Fenetre("f1"); addMouseListener(new CSouris()); addMouseMotionListener(new MSouris()); } public void stop() { f1.dispose(); } }

Applet 42 : Gestion dun champ de texte dans une fentre spare

15.3 Invocation dune applet depuis une application


Depuis le dbut du livre nous avons toujours fait la diffrence entre une application Java (mthode main()) et une applet Java (invoque depuis une page HTML).

Javabook Page 203 Lundi, 12. juillet 1999 3:58 15

Invocation dune applet depuis une application

203

Dans lexemple ci-dessous, nous montrons comment crer une application qui dmarre une ou plusieurs applet(s). Dans notre cas, chaque applet est un panneau qui demande un cadre afin de pouvoir safficher; nous proposons dutiliser un Frame cet effet.

Object

Component Abstraite

Container Abstraite

Panel

Java.lang

Java.awt

Applet

Java.applet

Figure 15.2 La classe Applet hrite de Container

Nous dclarons une nouvelle classe Fenetre tendant la classe Frame. Nous dclarons ensuite une variable appletCourante permettant de rfrencer lapplet excuter. La classe interne WAction sert dfinir un objet qui coute lvnement de fermeture de la fentre (mthode windowClosing()). Au moment de la fermeture, lapplet sera stoppe et supprime (destroy()) puis la fentre sera supprime (dispose()). Aprs avoir initialis la fentre et son couteur, le constructeur de fentre ajoute lapplet au centre, linitialise (init()) puis rend la fentre visible (show()), et finalement dmarre lapplet (start()). Notons encore que la taille de la fentre est fixe avec setSize() et non calcule par pack() comme dans lexemple prcdent.
import java.applet.*; import java.awt.*; import java.awt.event.*; class Fenetre extends Frame {

private Applet appletCourante; class WAction extends WindowAdapter { public void windowClosing(WindowEvent e) { appletCourante.stop(); appletCourante.destroy(); ((Window)e.getSource()).dispose(); } } Fenetre(Applet a,String titre, int l, int h) { super(titre);

Javabook Page 204 Lundi, 12. juillet 1999 3:58 15

204

Chapitre 15 Gestion des conteneurs


setSize(l, h); addWindowListener(new WAction()); appletCourante = a; add(a, BorderLayout.CENTER); a.init(); // !! initialiser avant de montrer show(); a.start(); }

Nous rutilisons lapplet 41 afin dillustrer linvocation depuis une application. noter que lapplet ne doit pas utiliser de paramtres (getParameter()).
class Dessin extends java.applet.Applet { ... // comme dans lexemple ''mon applet est trop petite'' ... }

Le programme se rsume lassociation de lapplet sa fentre dexcution. Nous en profitons (applet 43) pour lancer deux excutions simultanes de la mme applet :
import java.awt.*; import java.applet.*; public class Interaction{ public static void main(String args[]){ Fenetre f1=new Fenetre(new Dessin(),"f1",100,200); Fenetre f2=new Fenetre(new Dessin(),"f2",200,250); } }

Applet 43 : Applet lance deux fois par une application Java

15.4 Ajouter des menus aux fentres


La classe Frame implante linterface MenuContainer. On peut ainsi ajouter des menus aux fentres. Les menus sont principalement grs par trois classes : MenuBar : gre la barre de menus;

Javabook Page 205 Lundi, 12. juillet 1999 3:58 15

Ajouter des menus aux fentres

205

MenuItem : gre les entits de chaque menu de la barre; CheckboxMenuItem : gre les entits cochables des menus.
MenuBar MenuComponent Abstraite MenuItem CheckBoxMenuItem

Object

Menu

Figure 15.3 Hirarchie des menus

Reprenons lexemple de lapplet de dessin munie dune fentre daffichage des coordonnes (applet 42) et voyons comment ajouter des menus cette fentre (applet 44). Nous crons une nouvelle barre de menus laquelle nous rattachons des menus Fichier, Edition, Aide (ajouts au fur et mesure avec add()). Ensuite, nous associons chaque menu ses articles (galement avec add(), sans oublier dassocier un couteur dactions ceux que nous voulons rendre actifs(addActionListener()). Nous insrons galement des sparateurs entre les groupes darticles (addSeparator()). Finalement, nous demandons de rendre la barre de menus active (setMenuBar()).
Fenetre(String titre, int l, int h) { super(titre); setSize(l, h); t = new TextArea("(x, y)", 5, 20); add(t, BorderLayout.CENTER); MenuBar barreDeMenu = new MenuBar(); Menu m1 = new Menu("Fichier"); barreDeMenu.add(m1); Menu m2 = new Menu("Edition"); barreDeMenu.add(m2); Menu m3 = new Menu("Aide"); barreDeMenu.add(m3); barreDeMenu.setHelpMenu(m3); m1.add(new MenuItem ("Nouveau")); m1.add(new MenuItem("Ouvrir...")); m1.addSeparator(); m1.add(new MenuItem ("Enregistrer")); m1.add(new MenuItem ("Enregistrer sous...")); m1.add(new MenuItem ("Enregistrement automatique")); m1.addSeparator(); m1.add(m1Quitter = new MenuItem ("Quitter")); m1Quitter.addActionListener(this); m2.add(m2Effacer= new MenuItem ("Effacer"));

Javabook Page 206 Lundi, 12. juillet 1999 3:58 15

206

Chapitre 15 Gestion des conteneurs


m2Effacer.addActionListener(this); m2.add(m2Separ= new MenuItem ("Separer")); m2Separ.addActionListener(this); setMenuBar(barreDeMenu); show(); }

La gestion de lvnement gnr par la slection dun article de menu est similaire celle dun bouton. La mthode actionPerformed() de lcouteur est appele chaque slection. Cette dernire agit en fonction de la commande transmise (par dfaut, cest le nom de larticle slectionn).
public void actionPerformed(ActionEvent e) { if (e.getActionCommand().equals("Quitter")) this.dispose(); if (e.getActionCommand().equals("Effacer")) t.setText(""); if (e.getActionCommand().equals("Separer")) afficher("\n-------\n"); } }

Applet 44 : Cration et utilisation de menus

15.5 Un gestionnaire dalertes


Lexemple suivant (applet 45) montre comment tendre la classe Dialog afin dobtenir une classe Alerte qui affiche un message puis attend une rponse de lutilisateur (clic dans le bouton OK) et finalement disparat. Il faut noter quune fentre Dialog doit toujours tre rattache un Frame ou un Dialog parent que lon passe comme paramtre du constructeur.
import java.applet.*; import java.awt.*; import java.awt.event.*; class Alerte extends Dialog implements ActionListener{ Button boutonOK = new Button("OK"); Fenetre messages;

Javabook Page 207 Lundi, 12. juillet 1999 3:58 15

Un gestionnaire dalertes
Alerte (Fenetre f, String alerteTexte) { super(f, "Alerte", true); messages = f; add(new Label(alerteTexte), BorderLayout.CENTER); add(boutonOK, BorderLayout.SOUTH); boutonOK.addActionListener(this); pack(); show(); } public void actionPerformed(ActionEvent e) { messages.afficher("--OK--\n"); dispose(); } }

207

Lutilisation de cette classe se rsume ajouter une ligne du type :


Alerte x=new Alerte("<message>",f1);

chaque fois que lon dsire solliciter lattention de lutilisateur. Lapplet ci-dessous dessine en suivant les mouvements de la souris, mais interdit tout dessin dans la zone 50 < x < 100 et 50 < y < 100. La variable boolenne bloque signale quon a pntr dans la zone interdite. Elle est ncessaire car on peut encore recevoir des vnements souris alors que lalerte est dj affiche et il faut viter douvrir plusieurs alertes superposes.
public class Interaction extends Applet { int x0 = 0, y0 = 0; Fenetre f1; Alerte al; boolean bloque = false; class MSouris extends MouseMotionAdapter { public void mouseDragged(MouseEvent e) { Graphics g = getGraphics(); int x = e.getX(), y = e.getY(); if (!bloque) if (50 < x && x < 100 & 50 < y && y < 100) { bloque = true; f1.afficher("Point interdit: "+x+" "+y+"\n"); Alerte a = new Alerte (f1,"Zone interdite !"); } else { g.drawLine(x0, y0, x, y); x0 = x; y0 = y; } } } class CSouris extends MouseAdapter { public void mousePressed(MouseEvent e) { x0 = e.getX(); y0 = e.getY(); bloque = false;

Javabook Page 208 Lundi, 12. juillet 1999 3:58 15

208

Chapitre 15 Gestion des conteneurs


} } public void init() { // on utilise la classe Fentre dfinie dans lapplet 42 f1 = new Fenetre("f1", 200, 500); addMouseListener(new CSouris()); addMouseMotionListener(new MSouris()); } public void stop() { f1.dispose(); }

Applet 45 : Une alerte gre dans une fentre spare

15.6 Invitation explorer


Essayez douvrir une fentre de dialogue affichant les rpertoires de fichiers laide dune application. Dfinissez les composants graphiques dun mini-diteur de textes que lon compltera dans la partie suivante.

Javabook Page 209 Lundi, 12. juillet 1999 3:58 15

Chapitre 16

Protocoles de mise en pages


Nous venons dexaminer les composants graphiques et les conteneurs. Il nous faut maintenant aborder les protocoles de mise en pages associs aux conteneurs. Un protocole dfinit la mthode de placement des composants dun conteneur les uns par rapport aux autres.
GridLayout

BorderLayout

FlowLayout Object CardLayout

GridBagLayout

GridBagConstraints

Figure 16.1 Hirarchie des protocoles de mise en pages

Il existe plusieurs protocoles de mise en pages : la mise en pages glissante : classe FlowLayout;

Javabook Page 210 Lundi, 12. juillet 1999 3:58 15

210

Chapitre 16 Protocoles de mise en pages

la mise en pages par spcification des bords : classe BorderLayout; la mise en pages avec une grille : classe GridLayout; la mise en pages sous forme de cartes : classe CardLayout; la mise en pages avec une quadrillage et des contraintes : classe GridBagLayout et GridBagConstraints. Chaque conteneur est associ un seul protocole de mise en pages. Tous ses composants seront soumis ce protocole. Par contre, il est possible que parmi les composants, il se trouve des conteneurs qui eux sont soumis dautres protocoles de mise en pages. Lutilisation de protocoles de mise en pages permet de rester indpendant de la plate-forme physique. On spcifie les contraintes de la mise en pages plutt que des pixels sur la surface de travail. Tous les protocoles de mise en pages implantent linterface LayoutManager, dont le tableau 16.1 mentionne les principales mthodes.
Mthode
addLayoutComponent(String n, Component c) layoutContainer(Container c) minimumLayoutSize(Container p)

Description Ajoute le composant c et lassocie au nom n. Excute la mise en pages pour le conteneur c. Calcule la taille minimum (Dimension) pour le panneau p pour le parent le contenant. Calcule la dimension prfre (Dimension) pour le panneau p pour le parent le contenant. Supprime le composant c.

preferredLayoutSize(Container)

removeLayoutComponent(Component c)

Tableau 16.1 Mthodes de linterface LayoutManager

16.1 Mise en pages glissante


La mise en pages glissante spcifie le protocole suivant : les composants graphiques sont ajouts lun aprs lautre de gauche droite, avec un saut la ligne ds quil ne reste plus despace suffisant droite. Les constantes FlowLayout.LEFT, FlowLayout.CENTER et FlowLayout.RIGHT reprsentent lalignement dans une ligne (par dfaut, centr). Lexemple suivant montre lutilisation de ce protocole :
import java.awt.*;

Javabook Page 211 Lundi, 12. juillet 1999 3:58 15

Mise en pages glissante


public class Composant extends java.applet.Applet { public void init() { setLayout (new FlowLayout(FlowLayout.LEFT,8,10)); add(new Button ("b1")); add(new Button ("b2")); add(new Button ("b3")); add(new Button ("b10")); add(new Button ("b20")); add(new Button ("b30")); add(new Button ("b100")); add(new Button ("b200")); add(new Button ("b300")); add(new Button ("b1000")); add(new Button ("b2000")); add(new Button ("b3000")); add(new Label ("ici le centre")); add(new TextArea ("entrez vos ...",4,30)); } }

211

Lutilisation de protocoles de mise en pages permet dadapter celle-ci dynamiquement lors du changement de la taille du conteneur. Les applets 46 et 47 illustrent bien ce phnomne.

Applet 46 : Mise en pages glissante

Applet 47 : Mise en pages glissante sadaptant la taille du conteneur

Les mthodes des classes grant les protocoles de mise en pages ne doivent pas tre invoques directement. Elles sont appeles travers les conteneurs qui demandent respecter le protocole. Nous allons nous contenter de dcrire les constructeurs, renvoyant le lecteur la description de lAPI pour plus de dtails.

Javabook Page 212 Lundi, 12. juillet 1999 3:58 15

212
Constructeur
FlowLayout(); FlowLayout (int alignement); FlowLayout (int alignement, int xBord, int yBord);

Chapitre 16 Protocoles de mise en pages


Description Cre un protocole. Cre un protocole en spcifiant lalignement des lignes. Cre un protocole en spcifiant lalignement des lignes et lespace entre les composants en x et en y.

Tableau 16.2 Constructeurs de la classe FlowLayout

16.2 Mise en pages par spcification des bords


La mise en pages glissante laisse trop de degrs de libert aux composants. Les protocoles que nous allons examiner maintenant augmentent les contraintes entre les composants. La mise en pages par spcification des bords (classe BorderLayout, tableau 16.3) dcompose le conteneur en cinq zones (North, South, East, West, Center) qui pourront recevoir chacune au plus un composant. Lexemple suivant montre lutilisation de ce protocole :
import java.awt.*; public class Composant extends java.applet.Applet { public void init() { setLayout (new BorderLayout(10,10)); add("North",new Button ("b3")); add("South",new Button ("b30")); add("East",new Button ("b300")); add("West",new Button ("b3000")); add("Center",new TextArea ("entrez vos ...",4,30)); }

} On peut ainsi observer (applet 48) quen modifiant la dimension du conteneur, la dimension des objets peut varier, mais que leur position relative reste par contre inchange.
Constructeur
BorderLayout(); BorderLayout(int xBord, yBord);

Description Cre un protocole. Cre un protocole en spcifiant lespace entre les composants en x et en y.

Tableau 16.3 Constructeurs de la classe BorderLayout

Javabook Page 213 Lundi, 12. juillet 1999 3:58 15

Rcursivit de la mise en pages

213

Applet 48 : Mise en pages par spcification des bords

16.3 Rcursivit de la mise en pages


Un conteneur contient des composants graphiques, mais un conteneur est lui aussi un composant graphique. Il est donc possible de construire des mises en pages imbriques, pour lesquelles le panneau (Panel) est le mieux adapt. Dans lexemple suivant (applet 49), nous avons cr cinq panneaux, placs dans un mme panneau. A chacun des cinq panneaux, nous associons un protocole de mise en pages et les composants graphiques quil doit contenir.
import java.awt.*; public class Composant extends java.applet.Applet { public void init() { setLayout (new BorderLayout(10,10)); Panel panneauAuNord = new Panel(); add("North",panneauAuNord); Panel panneauAuSud = new Panel(); add("South",panneauAuSud); Panel panneauAlEst = new Panel(); add("East",panneauAlEst); Panel panneauAlOuest = new Panel(); add("West",panneauAlOuest); Panel panneauAuCentre = new Panel(); add("Center",panneauAuCentre); panneauAuNord.add(new Button ("b1")); panneauAuNord.add(new Button ("b2")); panneauAuNord.add(new Button ("b3")); panneauAuSud.add(new Button ("b10")); panneauAuSud.add(new Button ("b20")); panneauAuSud.add(new Button ("b30"));

Javabook Page 214 Lundi, 12. juillet 1999 3:58 15

panneauAlEst.setLayout (new BorderLayout(10,10)); panneauAlEst.add("North",new Button ("b100")); panneauAlEst.add("Center",new Button ("b200")); panneauAlEst.add("South",new Button ("b300")); panneauAlOuest.setLayout (new BorderLayout(10,10)); panneauAlOuest.add("North",new Button ("b1000")); panneauAlOuest.add("Center",new Button ("b2000")); panneauAlOuest.add("South",new Button ("b3000")); panneauAuCentre.setLayout (new BorderLayout(10,10)); panneauAuCentre.add("North",new Label ("ici le centre")); panneauAuCentre.add("Center",new TextArea ("entrez vos ...",4,30)); } }

Applet 49 : Mise en pages imbrique

16.4 Mise en pages avec une grille


Le protocole dfini par la classe GridLayout spcifie une grille dont chaque cellule peut contenir un composant graphique. Les composants sont ajouts de gauche droite, ligne par ligne (voir tableau 16.4). De nouveau, il est possible dimbriquer les conteneurs comme le montre lapplet 50 ci-dessous :
import java.awt.*; public class Composant extends java.applet.Applet { public void init() { setLayout (new GridLayout(2,3,10,10));

Javabook Page 215 Lundi, 12. juillet 1999 3:58 15

Mise en pages avec une grille

215

Panel panneau1 = new Panel(); add(panneau1); Panel panneau2 = new Panel(); add(panneau2); Panel panneau3 = new Panel(); add(panneau3); Panel panneau4 = new Panel(); add(panneau4); Panel panneauAuCentre = new Panel(); add(panneauAuCentre); panneau1.add(new Button ("b1")); panneau1.add(new Button ("b2")); panneau1.add(new Button ("b3")); panneau2.add(new Button ("b10")); panneau2.add(new Button ("b20")); panneau2.add(new Button ("b30")); panneau3.setLayout (new BorderLayout(10,10)); panneau3.add("North",new Button ("b100")); panneau3.add("Center",new Button ("b200")); panneau3.add("South",new Button ("b300")); panneau4.setLayout (new BorderLayout(10,10)); panneau4.add("North",new Button ("b1000")); panneau4.add("Center",new Button ("b2000")); panneau4.add("South",new Button ("b3000")); panneau5.setLayout (new BorderLayout(10,10)); panneau5.add("North",new Label ("ici le centre")); panneau5.add("Center",new TextArea ("entrez vos ...",4,30)); } }

Applet 50 : Mise en pages laide dune grille

Javabook Page 216 Lundi, 12. juillet 1999 3:58 15

216
Constructeur
GridLayout (int n, int m); GridLayout (int n, int m , int xBord, yBord);

Chapitre 16 Protocoles de mise en pages


Description Cre un protocole de grille n lignes et m colonnes. Cre un protocole de grille n lignes et m colonnes en spcifiant lespace entre les composants en x et en y.

Tableau 16.4 Constructeurs de la classe GridLayout

16.5 Mise en pages sous forme de cartes


Le conteneur soumis ce protocole naffiche quun seul composant la fois. On utilise gnralement des panneaux comme composants, chaque panneau pouvant possder ses propres composants. La classe CardLayout propose les mthodes first(), last(), next(), previous() et show() pour naviguer entre les cartes. Celles-ci sont associes des boutons de navigation gnralement affichs sur la carte elle-mme. Ce protocole permet de raliser des interfaces ressemblant celles dHyperCard.
Constructeur
CardLayout(); CardLayout(int xBord, yBord);

Description Cre un protocole. Cre un protocole en spcifiant lespace entre les composants en x et en y.

Tableau 16.5 Constructeurs de la classe CardLayout

16.6 Mise en pages avec un quadrillage et des contraintes


La mise en pages avec un quadrillage et des contraintes est la plus sophistique. Chaque composant graphique est insr dans le conteneur et on lui associe une contrainte qui dcrit son emplacement sur une grille, sa taille en termes de cellules de la grille, son ancrage, la taille des marges, etc. La contrainte est spcifie par la classe GridBagConstraints qui implante linterface Cloneable. En effet, lors de lassociation du composant graphique et de la contrainte, le gestionnaire de mise en pages va effectuer une copie de la contrainte. Celle-ci pourra donc tre manipule ultrieurement. La contrainte est exprime par linitialisation des variables dinstance prsentes dans le tableau 16.6 :

Javabook Page 217 Lundi, 12. juillet 1999 3:58 15

Mise en pages avec un quadrillage et des contraintes


Variable dinstance
public int gridx

217

Dfinition Position en x sur la grille du composant. La constante RELATIVE indique un dplacement relatif par rapport au dernier composant. Idem mais pour la position en y. Indique combien de cellules en x sont utilises sur la grille pour ce composant. La constante REMAINDER indique que ce composant est le dernier et quil doit occuper lensemble des cellules restantes. Idem mais pour la taille en y. Permet de pondrer lespace disponible entre les diffrents composants dans la dimension x. la valeur 0 indique que le composant ne doit pas participer cette distribution. Cette variable permet de dfinir plus finement le comportement lors du redimensionnement dun conteneur. Idem mais pour la pondration en y. Permet dindiquer quel coin ou bord de la cellule le composant est attach sil est plus petit que la cellule. Les constantes suivantes sont valides : CENTER, EAST, NORTH, NORTHEAST, NORTHWEST, SOUTH, SOUTHEAST, SOUTHWEST, WEST. Permet dindiquer comment remplir la cellule si elle est plus grande que le composant. Les constantes suivantes sont valides : NONE, BOTH, HORIZONTAL, VERTICAL. Spcifie les marges autour dun composant (haut, bas, gauche, droite). Permet de dfinir la taille interne ajouter en x pour chaque composant. Idem en y.

public int gridy public int gridwidth

public int gridheight public double weightx

public double weighty public int anchor

public int fill

public Insets insets public int ipadx public int ipady

Tableau 16.6 Variables dinstance de la classe GridBagConstraints

Pour faciliter la spcification des contraintes, il est recommand de construire une mthode reprsentant une catgorie de contraintes. En effet, le nombre des paramtres peut rapidement rendre la spcification de la contrainte incomprhensible. Dans lexemple suivant, nous avons dfini une mthode xyPosition() qui dclare la contrainte, lassocie au composant graphique et finalement ajoute le composant dans le conteneur. Cette mthode nutilise que les coordonnes

Javabook Page 218 Lundi, 12. juillet 1999 3:58 15

218

Chapitre 16 Protocoles de mise en pages

du composant placer sur la grille, les autres lments de la contrainte tant dfinis par dfaut dans la mthode. Lapplet 51 ci-dessous place les boutons sur la diagonale de la grille.
import java.awt.*; public class Composant extends java.applet.Applet { GridBagLayout g=new GridBagLayout(); public void init() { this.setLayout(g); // le Panel de l'applet xyPosition(this,new xyPosition(this,new xyPosition(this,new xyPosition(this,new } public void xyPosition(Container conteneur, Component element, int x, int y) { GridBagConstraints c= new GridBagConstraints(); c.gridx=x; c.gridy=x; c.gridwidth=1; c.gridheight=1; c.fill=GridBagConstraints.BOTH; c.weightx=1;c.weighty=1; c.anchor=GridBagConstraints.CENTER; c.insets=new Insets(3,3,3,3); ((GridBagLayout)conteneur.getLayout()).setConstraints (element, c); conteneur.add(element); } } Button Button Button Button ("b0"),0,0); ("b1"),1,1); ("b2"),2,2); ("b3"),3,3);

Applet 51 : Contrainte de mise en pages dfinie laide dune mthode

Javabook Page 219 Lundi, 12. juillet 1999 3:58 15

Invitation explorer

219

Lutilisation efficace de ce protocole demande donc la cration dun ensemble de mthodes de placement. Sa souplesse en fait pour le programmeur une sorte de gnrateur de protocoles de mise en pages. Nous pensons quil ne faut pas trop investir dans une connaissance approfondie de ces protocoles car des gnrateurs graphiques et interactifs dinterfaces devraient rapidement voir le jour. Ces gnrateurs vous permettront de placer des lments sur la surface de travail et gnreront ensuite le code Java ncessaire.

16.7 Invitation explorer


Examinez les mthodes de la classe GridBagLayout. crivez une interface pour lapplet de dessin (voir point 13.4, p. 169) qui permette de choisir la couleur du trait (rouge, vert, bleu, jaune). Compltez lditeur de texte sans vous proccuper de la sauvegarde.

Javabook Page 220 Lundi, 12. juillet 1999 3:58 15

Javabook Page 221 Lundi, 12. juillet 1999 3:58 15

Chapitre 17

Manipulation dimages et de sons


Les images constituent une classe dobjets du package java.awt. Cependant, les mthodes pour rcuprer les images partir de la dfinition dun URL sont spcifiques la classe Applet. La notion de son est actuellement dfinie et gre dans la classe Applet.
DirectColorModel ColorModel Abstraite IndexColorModel FilteredIMageSource Object ImageFilter RGBImageFilter Abstraite MemoryImageSource CropImageFilter

PixelGrabber

Figure 17.1 Hirarchie de gestion des images

17.1 Charger des images


Les images sont gres laide dobjets du type Image. Elles peuvent tre charges en utilisant les mthodes indiques dans le tableau 17.1 :

Javabook Page 222 Lundi, 12. juillet 1999 3:58 15

222
Mthode
getImage(URL url) getImage(URL url, String n) getCodeBase()

Chapitre 17 Manipulation dimages et de sons


Description Retourne une image se trouvant ladresse indique par url. Retourne une image se trouvant ladresse indique par url en lui concatnant la chane n. Retourne lurl de lapplet.

Tableau 17.1 Mthodes de chargement dune image (classe Applet)

Limage doit correspondre au type dextension signal dans lURL. Les mthodes suivantes de la classe Graphics permettent de dessiner une image : drawImage(Image img, int x, int y,ImageObserver o); drawImage(Image img, int x, int y, Color f, ImageObserver o); drawImage(Image img, int x, int y, int l, int h, ImageObserver o); drawImage(Image img,int x,int y,int l,int h,Color f,ImageObserver o). Ces mthodes retournent toujours un boolen, en particulier false si limage nest pas compltement charge au moment de la demande daffichage. Dans ce cas, le gestionnaire de limage (ImageObserver) mettra des messages de mise jour provoquant des affichages rptitifs de limage incomplte. Ceux-ci risquent alors de pnaliser le chargement, augmentant le temps ncessaire laffichage complet. Les diffrents paramtres des mthodes daffichage ont le sens suivant : img : image afficher; x : coordonne horizontale de limage (coin suprieur gauche); y : coordonne verticale de limage (coin suprieur gauche); l : largeur de limage en pixels; h : hauteur de limage en pixels; f : couleur du fond; o : gestionnaire de limage (celui de lapplet). Pour les mthodes drawImage() nincluant pas les paramtres l et h, limage saffiche en taille relle. En modifiant les paramtres l et h, il est possible de crer des effets de zoom ou de rduction. Lapplet 52 charge trois images se trouvant dans un rpertoire (Desimages) situ dans le mme dossier que lapplet. On remarquera lutilisation de la mthode getCodeBase() qui permet de rendre relatif le positionnement des fichiers contenant les images. Initialement, les images ont toutes la mme taille (320x240 pixels), lutilisation des paramtres l et h ayant pour effet de rduire leur taille.
import java.awt.Graphics;

Javabook Page 223 Lundi, 12. juillet 1999 3:58 15

Filtrer des images


import java.awt.Image; public class UneImage extends java.applet.Applet { Image img1, img2, img3 ; public void init(){ img1=getImage(getCodeBase(),"DesImages/un.gif"); img2=getImage(getCodeBase(),"DesImages/deux.gif"); img3=getImage(getCodeBase(),"DesImages/trois.gif"); } public void paint(Graphics g) { g.drawImage(img1,5,5,this); g.drawImage(img2,100,100,100,100,this); g.drawImage(img3,200,200,75,75,this); } }

223

Applet 52 : Chargement de trois images

17.2 Filtrer des images


Sans vouloir donner un cours sur le traitement des images et sur lanimation, on peut signaler quelques points utiles. La classe MediaTracker (gestionnaire de mdias) permet de synchroniser le chargement des images tandis que le package java.awt.image supporte leur traitement. Ce package permet de manipuler les couleurs, dextraire des zones de limage, de manipuler les pixels, de construire des filtres, etc. Nous avons construit un exemple (voir code de lapplet 53 ci-dessous) illustrant

Javabook Page 224 Lundi, 12. juillet 1999 3:58 15

224

Chapitre 17 Manipulation dimages et de sons

ces possibilits. Cette applet charge une image, lance une activit danimation qui attend la fin du chargement de limage, puis affiche la mme image mais rduite 25% et effectue ensuite un travelling sur une zone de limage, de la gauche vers la droite. Le gestionnaire de mdias est utilis de la manire suivante : cration de lobjet; ajout dobjets (images) surveiller avec un identifiant; test ou mise en attente jusqu ce que lobjet soit charg. Tout cela est ralis par le programme suivant :
MediaTracker traceur; ... public void init(){ traceur = new MediaTracker(this); this.showStatus("Chargement de l'image"); img1=getImage(getCodeBase(),"DesImages/imgsmall.gif"); // img1 est identifi par le numro 0 traceur.addImage(img1,0); ... public void run() { // le processus attend le chargement de id 0) try {traceur.waitForID(0); } catch(InterruptedException e){} // test du chargement this.showStatus("Chargement de l'image OK"); if (traceur.isErrorID(0)) { this.showStatus("erreur durant le chargement"); }

Le principe du traitement dune image (voir figure 17.2) est assez lgant : on cre un filtre (ImageFilter) qui est la fois un consommateur et un producteur dimages (deux sous-classes dImageFilter implantent un traitement de limage : CropImageFilter et RGBImageFilter); on cre un producteur dimages (FilteredImageSource, qui implante linterface ImageProducer) qui on fournit limage source (obtenue laide de la mthode getSource()) et le filtre; on demande au producteur dimages de crer limage (createImage()). Chacun de ces lments se comporte comme un consommateur-producteur , ce qui permet de les relier ( la manire des pipes) afin de produire de vritables chanes de traitement dimages. Ces diffrentes tapes se traduisent de la manire suivante :
Image img1, crop; ... ImageFilter filtre= new CropImageFilter(i,50,120,120); ImageProducer producteur=new

Javabook Page 225 Lundi, 12. juillet 1999 3:58 15

Filtrer des images


FilteredImageSource(img1.getSource(),filtre); crop=this.createImage(producteur);

225

img1 producteur crop createImage() filtre getSource()

Figure 17.2 Traitement dune image

Applet 53 : Travelling sur une image

Programme complet :
import import import import java.awt.Graphics; java.awt.Image; java.awt.MediaTracker; java.awt.image.*;

public class UneImage extends java.applet.Applet implements Runnable { boolean stop=false; Image img1, crop; MediaTracker traceur; Thread actif; public void init(){ traceur = new MediaTracker(this); this.showStatus("Chargement de l'image");

Javabook Page 226 Lundi, 12. juillet 1999 3:58 15

226

Chapitre 17 Manipulation dimages et de sons


img1=getImage(getCodeBase(),"DesImages/imgsmall.gif"); traceur.addImage(img1,0); } public void start() { if (actif==null); { actif = new Thread(this); actif.start(); } } public void stop() { if (actif!=null); { stop = true; actif = null; } } public void run() { try {traceur.waitForID(0); } catch(InterruptedException e){} this.showStatus("Chargement de l'image OK"); if (traceur.isErrorID(0)) { this.showStatus("erreur durant le chargement"); } while (!stop) { for (int i=1; i<200;++i){ ImageFilter filtre= new CropImageFilter(i,50,120,120); ImageProducer producteur=new FilteredImageSource(img1.getSource(),filtre); crop=this.createImage(producteur); repaint(); try {Thread.sleep(500);} catch(InterruptedException signal) {} } } }

public void paint(Graphics g) { g.drawImage(img1,0,0,img1.getWidth(this)/ 4,img1.getHeight(this)/4,this); g.drawRect(0,0,img1.getWidth(this)/4,img1.getHeight(this)/4); g.drawRect(0,0,img1.getWidth(this)/4,img1.getHeight(this)/4); } public void update(Graphics g) { g.drawImage(crop,20+img1.getWidth(this)/4, 20+img1.getHeight(this)/4,120,120,this); paint(g); } }

Javabook Page 227 Lundi, 12. juillet 1999 3:58 15

Animation avec double tampon

227

17.3 Animation avec double tampon


Nos animations taient jusquici relativement simples (lhorloge, par exemple) et leffet de scintillement d la rgnration de limage ntait pas trop perceptible. Dans le cas o la rgnration de limage est plus longue, leffet de scintillement peu devenir trs gnant. Revenons sur le droulement exact de la rgnration : le processus danimation invoque repaint(); la mthode repaint() invoque update(); update() efface le composant graphique, peint le composant avec la couleur de fond, initialise la couleur de dessin et invoque la mthode paint() afin quelle redessine compltement le composant graphique. Le scintillement provient donc du dlai de latence scoulant entre leffacement complet de la surface graphique de lapplet et sa reconstruction. Les mthodes danimation cherchant diminuer le scintillement (et amliorer la performance de lanimation) tenteront donc dviter deffacer compltement lapplet et de ne redessiner que les parties qui sont modifies, diminuant ainsi le dlai de latence. Afin dviter de devoir effacer compltement la surface de lapplet, il suffit de redfinir la mthode update(), dont le code classique est :
public void update(Graphics g) { paint(g); }

La mthode update() intelligente se chargera alors de minimiser leffacement. Pour ne redessiner quune partie de lapplet, on peut utiliser la mthode clipRect() qui slectionne une zone rectangulaire, puis invoquer paint() qui ne redessinera alors que cette zone. Les coordonnes de la zone redessiner sont mises jour par le processus de lanimation. Exemple :
public void update(Graphics g) { g.clipRect(x1,y1,x2,y2) paint(g); }

Pour diminuer le dlai de latence, on peut galement utiliser une mthode dite double tampon . Elle consiste prparer la nouvelle image dans un tampon (zone en mmoire) sans lafficher, puis afficher limage lorsquelle est prte. Pour raliser ce principe en Java, on procdera de la manire suivante. On dclare une image et une surface de dessin (Graphics) :
Image imgTampon; Graphics gTampon;

On cre une image de la taille de lapplet et on lie limage la surface de dessin :

Javabook Page 228 Lundi, 12. juillet 1999 3:58 15

228

Chapitre 17 Manipulation dimages et de sons


imgTampon=createImage(getSize().width,getSize().height); gTampon=imgTampon.getGraphics();

On prpare ensuite une image laide des mthodes de Graphics appliques au tampon (gTampon). Lorsque limage est prte, on invoque repaint(). Dans la mthode paint(), on dessine limage prpare :
g.drawImage(imgTampon,0,0,this);

Pour des cas plus complexes, on imagine bien quil est ncessaire de combiner lensemble de ces principes. Lapplet 54 utilise le double tampon pour dessiner un disque qui sinsre dans un carr.
import java.awt.Graphics; import java.awt.Image; import java.awt.image.*; public class UneImage extends java.applet.Applet implements Runnable { boolean stop=false; Image imgTampon; Graphics gTampon; Thread actif; public void init(){ imgTampon=createImage(getSize().width,getSize().height); gTampon=imgTampon.getGraphics(); } public void start() { if (actif==null); { actif = new Thread(this); actif.start(); } } public void stop() { if (actif!=null); { stop=true; actif = null; } } public void run() { gTampon.clearRect(0,0,getSize().width,getSize().height); while (!stop) { for (int i=1; i<100;++i){ gTampon.clearRect(100,100,i,i); gTampon.fillOval(100,100,i,i); repaint(); try {Thread.sleep(100);} catch(InterruptedException signal) {} }

Javabook Page 229 Lundi, 12. juillet 1999 3:58 15

Ajouter le son
} } public void paint(Graphics g) { g.drawImage(imgTampon,0,0,this); } }

229

Applet 54 : Affichage laide dun double tampon

17.4 Ajouter le son


Actuellement, le son est un peu le parent pauvre de Java. Il nexiste que le strict minimum pour grer des donnes sonores : les squences doivent tre stockes dans des fichiers dont lextension est .au (format -law). Ce format est trs compress, ce qui diminue le temps de transfert et lespace de stockage, au dtriment de la qualit du son. Supposons que nous ayons un fichier sonore dingdong.au dans un rpertoire audio. Si nous ne devons jouer quune seule fois le son, le plus simple est dinvoquer la mthode play() de la classe Applet (voir tableau 17.2) : Le son est charg en mmoire (au plus vite) puis jou. noter que le son est jou en parallle lexcution des autres processus. Ainsi, plusieurs sons peuvent tre jous simultanment.
Mthode
play() loop() stop()

play(getCodeBase(),"audio/dingdong.au");

Description Joue le son. Si le son nest pas termin et quon le rejoue, la squence sonore redmarre au dbut. Joue le son et le rpte indfiniment. Arrte de jouer le son. Doit imprativement tre invoque si lapplet se termine, car le son ne dpend pas directement du processus de lapplet.

Tableau 17.2 Mthodes de la classe Applet pour jouer un son

Si le son doit tre jou plusieurs fois, il est intressant de le stocker dans une variable de type AudioClip. Le son est alors charg en utilisant la mthode getAu-

Javabook Page 230 Lundi, 12. juillet 1999 3:58 15

230

Chapitre 17 Manipulation dimages et de sons

dioClip() de linterface AudioClip. Cette interface dfinit les mthodes de gestion des sons (voir tableau 17.3). Dans le code ci-dessous, nous avons repris lapplet prcdente et nous lui avons ajout les instructions ncessaires pour jouer le son dingdong chaque fois que lanimation recommence son cycle (vos voisins apprcieront!).
public class UneImage extends Applet implements Runnable { ... AudioClip dingdong; public void init(){ ... dingdong=getAudioClip(getCodeBase(),"audio/dingdong.au"); } ... public void stop() { ... dingdong.stop(); } public void run() { while (!stop) { if (dingdong!=null) dingdong.play(); for (int i=1; i<100;i+=3){ ... } ... }

Mthode
play(URL url) play(URL url, String n) getAudioClip(URL url) getAudioClip(URL url, String n)

Description Joue un son se trouvant ladresse indique par url. Joue un son se trouvant ladresse indique par la concatnation de url (nom de dossier) et n (nom de fichier). Charge un son se trouvant ladresse indique par url. Charge un son se trouvant ladresse indique par la concatnation de url et n.

Tableau 17.3 Mthodes de linterface AudioClip

17.5 Invitation explorer


Reprenez lapplet du travelling et intgrez la capture des vnements de la souris sur limage rduite de faon diriger limage affiche (une sorte de zoom). Utilisez le son pour signaler le choc de deux boules rebondissant dans un cadre.

Javabook Page 231 Lundi, 12. juillet 1999 3:58 15

Chapitre 18

Les composants Swing


Comme son nom lindique, lAbstract Window Toolkit (AWT) a t conu comme un systme abstrait de gestion de linterface utilisateur, donc indpendant de la plate-forme dexcution. Si cette indpendance est effectivement ralise au niveau de la programmation, elle nest pas complte au niveau de lapparence et du comportement (look-and-feel) de linterface. En effet, les composants de lAWT tels que les boutons, menus, libells, etc., sont implants par des objets de lenvironnement dexcution. Ce qui signifie, par exemple, quun objet Button aura lapparence et le comportement dun bouton Windows sous Windows, dun bouton MacOS sous MacOS, etc.

18.1 Les limites de lAWT et Swing


Swing a pour objectif doffrir des composants dinterfaces totalement indpendants de la plate-forme dexcution car eux-mmes crits en Java. Ces composants, appels composants lgers, ont la mme apparence et le mme comportement sur toutes les plate-formes. De plus, il est possible de changer dynamiquement lapparence et le comportement de tous les composants dune interface par la technique dite du plugable look-and-feel. Ainsi, une application fonctionnant sous Solaris pourrait prendre au choix un look-and-feel Java standard, Solaris, Mac, ou autre. Comme tous les composants sont crits en Java, toute amlioration ou adjonction de nouveaux composants sera automatiquement disponible sur toutes les plates-formes. Swing est donc ouvert et de nouveaux composants pourront sy adjoindre. Ce qui nest pas le cas de lAWT car celui-ci dpend de lexistence dune implantation pour chaque composant sur chaque plate-forme. Swing propose, par exemple, un composant JTable qui permet de prsenter des informa-

Javabook Page 232 Lundi, 12. juillet 1999 3:58 15

232

Chapitre 18 Les composants Swing

tions sous forme de table deux dimensions (lignes/colonnes). Un tel composant nexiste en gnral pas tel quel sur les plates-formes habituelles.

18.2 Prsentation de Swing


Tous les composants Swing ne sont pas lgers car il faut bien en fin de compte communiquer avec linterface de fentrage de la plate-forme sur laquelle sexcute lapplication. Il y a donc quatre composants lourds , qui sont les conteneurs de base JFrame, JDialog, JWindow et JApplet. Hormis ceux-ci, tous les autres composants sont des descendants de la classe JComponent.

Les conteneurs de base


Lune des principales diffrences de la programmation avec Swing par rapport lAWT vient du fait que les conteneurs de base JFrame, JDialog, JWindow et JApplet contiennent plusieurs surfaces daffichage (panes) : la contentPane contient tous les composants habituels de linterface (boutons, champs de texte, etc.); la glassPane est une surface transparente au-dessus des autres surfaces, qui permet dafficher temporairement des informations (par exemple, des aides contextuelles), par dfaut la glassPane nest pas visible; la menuBar est une surface rserve une barre de menu, qui prend place en haut de la totale visible; la layeredPane est un ensemble de surfaces superposes, qui contient au dpart la contentPane et la menuBar mais laquellec on peut ajouter dautres surfaces (par exemple, pour crer ses propres menus pop-up). Lorganisation des surfaces est illustre sur la figure 18.1.
glassPane

(autres surfaces) menuBar contentPane Figure 18.1 Organisation des surfaces daffichage dun conteneur de base

La prsence de ces diffrentes surfaces ne permet plus lajout simple et direct de composants un conteneur de base. Par exemple, pour ajouter une tiquette

Javabook Page 233 Lundi, 12. juillet 1999 3:58 15

Composants Swing et AWT

233

(JLabel) e dans un JFrame f on ne fait plus : mais :


f.add(e) f.getContentPane().add(e) // on ajoute e sur la surface de contenu.

Les JComponents
Tous les composants Swing sont des descendants de JComponent. Il faut remarquer que JComponent est une sous-classe de Container, ce qui signifie que tout composant Swing peut contenir dautres composants, contrairement aux composants AWT. La classe JComponent est pour le moins complexe puisquelle possde 105 mthodes propres, en hrite 39 de java.awt.Container et 106 de java.awt.Component! Pour y voir un peu plus clair, on peut regrouper ces mthodes selon quelques grandes fonctions. Look-and-feel : associer au composant un objet responsable de son apparence et de son comportement; Dessin : dessiner et redessiner le composant, sa bordure et ses souscomposants; Focus : dterminer quand le composant devient actif ou inactif par rapport aux entres du clavier; Taille et position : dfinir et contrler la taille et le positionnement du composant (taille minimum, maximum, prfre, etc.); Clavier : dterminer les ractions aux frappes clavier, les raccourcis clavier, etc.; Aide immdiate : fixer le texte daide afficher quand la souris passe sur le composant; Accessibilit : dterminer la manire dont le composant doit apparatre des personnes souffrant de handicaps (affichage de trs grosse taille, remplacement de limage par le son, le braille, etc.).

18.3 Composants Swing et AWT


Pour faciliter la conversion aise des programmes bass sur AWT vers Swing, la plupart des composants AWT ont un quivalent Swing offrant les fonctions supplmentaires lies Swing. Le tableau suivant donne ces correspondances en indiquant les principales diffrences.
AWT Button Swing AbstractButton JButton Commentaires On peut associer une icne plutt quun texte un JButton.

Tableau 18.1 Diffrences principales en AWT et Swing

Javabook Page 234 Lundi, 12. juillet 1999 3:58 15

234
AWT Canvas Checkbox JToggleButton JCheckBox JRadioButton ButtonGroup JCheckboxMenuItem JPopupMenu JComboBox JComponent Swing

Chapitre 18 Les composants Swing


Commentaires Pas dquivalent. On fait la distinction entre les JCheckBox destines aux slections multiples et les JRadioButton pour les slections uniques dans un groupe. Un groupe de tout ce qui est bouton (checkbox, boutons, etc.). Un article de menu qui peut porter une marque de slection. Le JComboBox permet non seulement de choisir dans une liste mais aussi de saisir un texte dans un champ. 1. Un JComponent comprend un look-and-feel modifiable, des aides immdiates, des composants daccessibilit, etc. (voir ci-dessus). 2. Un JComponent est un conteneur, tout composant Swing peut donc en contenir dautres. JDialog est un conteneur de base qui contient un RootPane. Ajout de nombreuses mthodes de configuration et de contrle du dialogue de choix dun fichier. Extension de Frame qui permet la gestion de surfaces de dessin et dinteractions superposes (glassPane, LayeredPane, rootPane) et des barres de menus. Peut galement contenir une image. Une JList na pas de barre de dfilement, il faut linclure dans le viewPort dun JScrollPane. Un JMenu est essentiellement un bouton associ un JPopupMenu. Une barre forme de JMenus. Un JMenuItem est en fait un bouton plac dans une liste. Il peut contenir un texte, une icne ou les deux.

CheckboxGroup CheckboxMenuItem Choice

Component

Dialog FileDialog

JDialog JFileChooser

Frame

JFrame

Label List Menu MenuBar MenuItem

JLabel JList JMenu JMenuBar JMenuItem

Tableau 18.1 Diffrences principales en AWT et Swing

Javabook Page 235 Lundi, 12. juillet 1999 3:58 15

Composants Swing et AWT


AWT MenuShortcut Panel PopupMenu JPanel JPopupMenu Swing Commentaires Les quivalents clavier sont grs globalement pour tous les composants Swing. Le composant qui sert grouper dautres composants. Dans AWT le menu pop-up est une sorte de menu, dans Swing cest le menu qui est compos dun bouton et dun menu pop-up. En gnral associ un JViewport qui montre une partie dun texte ou dune image. Un JSrollPane est compos de barres de dfilement et dun objet JViewport qui gre laffichage dun objet. Le JTextArea ne possde pas de barre de dfilement mais il implmente linterface Scrollable, ce qui permet de le placer dans un JScrollPane. Le contenu (modle) dun JTextComponent nest pas un simple String mais un Document. La gestion des champs de type mots de passe doit se faire dans un JPasswordField. Une fentre simple, sans titre ni bouton de manipulation.

235

Scrollbar ScrollPane

JScrollBar JScrollPane

TextArea

JTextArea

TextComponent TextField Window

JTextComponent JTextField JPasswordField JWindow

Tableau 18.1 Diffrences principales en AWT et Swing

Swing propose galement de nouveaux composants. Ils sont dcrits dans le tableau suivant.
Classe Box JColorChooser JDesktopPane JEditorPane JInternalFrame Description Un conteneur qui utilise la mise en pages Box. Un panneau pour slectionner une couleur. Un conteneur pour crer des bureaux (desktop) virtuels contenant plusieurs fentres (InternalFrames). Composant texte qui permet dditer diffrents types de contenus : texte simple, HTML, RTF, etc. Comme un JFrame mais lger et fait pour vivre lintrieur dun DesktopPane.

Tableau 18.2 Nouveaux composants introduits dans Swing

Javabook Page 236 Lundi, 12. juillet 1999 3:58 15

236
Classe JLayeredPane JOptionPane JProgressBar JRootPane Description Panneaux superposs.

Chapitre 18 Les composants Swing

Panneau dinformation ou derreur avec boutons (OK, Cancel, etc.). Un composant montrant lvolution dun processus sous forme dune barre qui grandit. Le composant de dpart dans une hirarchie de composants. Contient dautres panneaux : contenu, transparent, barre de menu, panneaux superposs. Un rgle gradue avec un curseur pour choisir une valeur. Juxtaposition de deux composants gauche/droite ou haut/ bas, avec possibilit de dplacer la limite. Panneaux superposs avec des onglets slectionner au choix. Prsentation dinformation sous forme de table deux dimensions (lignes/colonnes). Prsentation de texte contenant des indications de style. Barre doutils. Contient un texte daide associ un composant qui apparat et disparat en fonction des mouvements de la souris. Prsentation dinformations arborescentes sous forme de listes imbriques (exemple : une arborescence de rpertoires). La partie visible dun composant se trouvant dans un JScrollPane.

JSlider JSplitPane JTabbedPane JTable JTextPane JToolBar JToolTip JTree JViewport

Tableau 18.2 Nouveaux composants introduits dans Swing

On notera que tous ces composants correspondent ceux que lon a lhabitude de trouver dans les interfaces de type X-Windows, Windows et MacOS. Swing ne propose ce jour aucun composant sortant de lordinaire.

18.4 Larchitecture modle-vue-contrleur et Swing


Larchitecture modle-vue-contrleur (MVC) sert concevoir des interfaces graphiques modulaires en sparant clairement les trois composantes dun lment dinterface. Le modle est une reprsentation de ltat dun objet par un ensemble de donnes (exemple : ltat dun bouton peut tre reprsent avec une variable boolenne (enfonc = oui/non); ltat dun champ de texte est plus complexe

Javabook Page 237 Lundi, 12. juillet 1999 3:58 15

Le look-and-feel modifiable

237

puisquil comprend la liste de caractres formant le texte afficher, plus dventuelles indications de formatage). La vue est la manire dont ltat de lobjet (dfini par le modle) est reprsent sur lcran (ou sur un autre dispositif). Par exemple, un bouton peut tre reprsent comme un rectangle avec un texte lintrieur, lorsque le bouton est enfonc, on dessine une ombre sous le rectangle. Le contrleur dfinit la raction de lobjet aux actions de lutilisateur. Que se passe-t-il si on clique sur le bouton, si on double-clique, si on tape sur une touche du clavier, etc.? Dans Swing, larchitecture MVC est utilise pour rendre le systme dinterface trs ouvert et reconfigurable dynamiquement. Chaque objet dinterface Swing est associ deux objets : un objet modle, qui stocke ltat du composant et un objet dinterface utilisateur (appel dlgu), qui gre la fois la vue (look) et le contrle (feel) du composant. Dans le cas dun simple bouton, lobjet modle reprsente simplement ltat (enfonc/non enfonc et le nom du bouton); lobjet dinterface dessine le bouton en fonction de son tat et interprte les clics souris sur le dessin du bouton pour modifier ltat (le modle) en consquence.

18.5 Le look-and-feel modifiable


tant donn larchitecture prsente ci-dessus, pour changer le look-and-feel dun composant il suffit de lui associer un autre objet dinterface. Pour changer le look-and-feel de toute une application, il faut changer le look-and-feel de chaque composant comme illustr sur la figure 18.2.

look-and-feel B look-and-feel A

Objets dinterface

Composants

Objets modles

Figure 18.2 Associations entre les composants et leurs objets dinterface

Javabook Page 238 Lundi, 12. juillet 1999 3:58 15

La dfinition dun nouveau look-and-feel complet est une tche denvergure puisquil faut redfinir toutes les classes dinterface utilisateur de tous les types de composants (ButtonUI, ColorChooserUI, , TreeUI, ViewPortUI). Heureusement, il existe dj un certain nombre de look-and-feel prts lemploi : Metal, Windows, Motif, MacOS. Pour utiliser un look-and-feel particulier, ici Metal, il faut crire les instructions suivantes :
UIManager.setLookAndFeel( "javax.swing.plaf.metal.MetalLookAndFeel"); SwingUtilities.updateComponentTreeUI(topComponent);

Lexemple qui suit montre : la cration dune interface avec des composants Swing (curseur, panneau, libells, boutons); la cration et lajout de bords certains composants; lutilisation dun nouveau gestionnaire de mise en pages : BoxLayout; lobtention de la liste des look-and-feel disponibles; le changement dynamique de look-and-feel (chaque fois quon clique sur le bouton).
import java.awt.*; import java.awt.event.*; import javax.swing.event.*; import javax.swing.border.*; import javax.swing.*; class SliderF extends JFrame implements ChangeListener, ActionListener { JLabel l1; JSlider s; JPanel p, pi; DisquePanel dp; JButton changeLAF; int diametre = 50; Color clr = Color.red; UIManager.LookAndFeelInfo laf[]; int lafNo = 0; // un panneau avec un disque de taille variable au centre class DisquePanel extends JPanel { DisquePanel() { setPreferredSize(new Dimension(130,130)); } public void paint(Graphics g) { g.setColor(clr); g.fillOval(65-diametre/2,65-diametre/2,diametre, diametre);

Javabook Page 239 Lundi, 12. juillet 1999 3:58 15

Le look-and-feel modifiable
} } public void init() { // liste des LAF disponibles laf = UIManager.getInstalledLookAndFeels(); // on cre linterface dans le contentPane getContentPane().add(p = new JPanel()); BoxLayout bxl = new BoxLayout(p, BoxLayout.Y_AXIS); p.setLayout(bxl); p.add(l1 = new JLabel("LAF: " + UIManager.getLookAndFeel().getName() + " (initial)")); l1.setBorder(BorderFactory .createMatteBorder(5, 8, 5, 8, Color.orange)); // un curseur avec divisions et subdivisions p.add(s = new JSlider(0,120,40)); s.setMajorTickSpacing(30); s.setMinorTickSpacing(5); s.setPaintTicks(true); s.addChangeListener(this); p.add(pi = new JPanel()); pi.add(dp = new DisquePanel(), BorderLayout.CENTER); pi.setBorder(BorderFactory.createEtchedBorder()); p.add(changeLAF = new JButton("Change")); changeLAF.addActionListener(this); setSize(300,250); setVisible(true); } public void stateChanged(ChangeEvent e) { // lit la valeur du curseur if (e.getSource() == s) diametre = s.getValue(); repaint(); } public void actionPerformed(ActionEvent e) { // change de LAF - on prend le suivant dans la liste lafNo = (lafNo + 1) % laf.length; try { UIManager.setLookAndFeel(laf[lafNo].getClassName()); SwingUtilities.updateComponentTreeUI(this); } catch (Exception exc) { } l1.setText("LAF: " + UIManager.getLookAndFeel().getName()

239

Javabook Page 240 Lundi, 12. juillet 1999 3:58 15

240
+ "(" + lafNo + ")"); repaint(); } } // la classe de lapplication public class SF {

Chapitre 18 Les composants Swing

public static void main(String[] sss) { SliderF sf = new SliderF(); sf.init(); } }

Application 1 : Composants Swing et look-and-feel modifiable

La figure 18.4 montre deux copies dcran effectues pendant lexcution de cette application sous MacOS. On remarquera que la fentre englobante (JFrame) est gre par la plate-forme dexcution (MacOS), alors qu lintrieur Swing gre aussi bien un look-and-feel Metal quun look-and-feel CDE/Motif.

Figure 18.4 Excution

Pour terminer, signalons quil vaut mieux viter de mlanger les composants AWT et Swing car il peut en rsulter des conflits daffichage. Il faut galement tre prudent dans la redfinition de la mthode paint() qui risque dempcher le dessin dventuels sous-composants.

Javabook Page 241 Lundi, 12. juillet 1999 3:58 15

Chapitre 19

Entres-sorties et persistance des objets


Ce chapitre prsente le package java.io grant les entres-sorties sur les priphriques clavier, cran et units de mmoire principales et secondaires. Ce package contient galement des classes permettant la srialisation des objets et par consquent leur persistance. Pour tudier ce package, nous allons considrer successivement les classes manipulant des flux de caractres, puis celles qui manipulent des flux doctets, et enfin celles qui manipulent des flux dobjets et par consquent rendent possible la persistance des objets. Aprs un examen des principales classes, interfaces et exceptions du package, nous dcrirons les entres-sorties clavier/cran. Nous construirons ensuite six classes qui seront rutilises dans les autres exemples de ce chapitre. Ces classes sont : Fichier, FichierLecture, FichierEcriture, Repertoire, RepertoireLecture et RepertoireEcriture. Les classes du package seront ensuite prsentes laide dexemples (moins anims que ceux du chapitre prcdent).

19.1 Description du package


Les classes du package io sont presque toutes des sous-classes de la classe Object. La plupart dentre elles sont illustres dans les exemples du chapitre. Le concept principal sur lequel reposent ces classes est celui de flux. Un flux est un canal dans lequel on lit et/ou crit des caractres (16 bits) ou des octets (8 bits). Les flux utilisant des octets sont utiliss pour tout ce qui est image ou son. Tou-

Javabook Page 242 Lundi, 12. juillet 1999 3:58 15

242

Chapitre 19 Entres-sorties et persistance des objets

tes les entres-sorties utilisent donc la notion de flux pour la circulation des informations.

Classes
Les classes permettant la lecture et lcriture de caractres dans des flux sont prsentes respectivement sur les figures 19.1 et 19.2. Elles hritent des classes abstraites Reader ou Writer dont elles utilisent le nom comme suffixe. La plupart de ces classes ont leur quivalent pour les octets (voir figures 19.3 et 19.4), elles hritent alors de la classe abstraite servant de suffixe leur nom, InputStream ou OutputStream.
BufferedReader LineNumberReader

CharArrayReader FilterReader Abstraite java.lang. Object Reader Abstraite InputStreamReader

PushBackReader

FileReader

PipedReader

StringReader

Figure 19.1 Classes pour la lecture de caractres dans des flux

Les classes BufferedReader et BufferedWriter (BufferedInputStream et BufferedOutputStream pour les octets) lisent ou crivent sur un canal en plaant les caractres (ou les octets) dans un tampon (buffer), ce qui diminue le nombre daccs au flux. Ces oprations sont videmment beaucoup plus performantes que celles impliquant des flux sans tampon. Les classes LineNumberReader et LineNumberInputStream conservent le numro de ligne courant durant toute la lecture du flux. Les classes CharArrayReader, CharArrayWriter, ByteArrayReader et ByteArrayWriter lisent ou crivent des tableaux de donnes en mmoire principale. Les classes abstraites FilterReader, FilterWriter, FilterInputStream et FilterOutputStream effectuent des lectures et des critures filtrantes. Les classes filtrantes PushBackReader et PushBackInputStream sont des sous-classes de leur lecteur respectif, elles autorisent des retours en arrire sur des donnes dj lues, la longueur du retour en arrire est fixe la cration de linstance.

Javabook Page 243 Lundi, 12. juillet 1999 3:58 15

Description du package

243

BufferedWriter

CharArrayWriter

java.lang. Object

Writer Abstraite

FilterWriter Abstraite

OutputStreamWriter

FileWriter

PipedWriter

PrintWriter

StringWriter

Figure 19.2 Classes pour lcriture de caractres dans des flux

Les classes InputStreamReader et OutputStreamWriter convertissent respectivement les octets en caractres et les caractres en octets, et ce, en fonction dun encodage spcifi la cration de linstance. Les classes FileReader, FileWriter, FileInputStream et FileOutputStream lisent ou crivent des fichiers de donnes en mmoire secondaire. On accde aux fichiers directement partir de leur nom. Les classes PipedReader, PipedWriter, PipedInputStream et PipedOutputStream lisent ou crivent des donnes dans des pipelines (pipes) qui permettent, par exemple, la communication entre processus. La classe StringReader lit les caractres dun String. La classe StringWriter crit dans un StringBuffer qui peut tre converti en String. La classe StringBufferInputStream, qui est dprcie en Java 2.0, convertit de manire incorrecte en octets des caractres lus partir dun String. Les classes PrintWriter et PrintStream sont des classes qui facilitent lcriture de diffrents types de donnes dans des flux de caractres. Elles sont par exemple trs utiles pour imprimer la valeur dun rel ou dun entier. Les classes DataInputStream et DataOutputStream lisent et crivent des types de donnes prdfinis dans Java, indpendamment du systme dexploitation. La classe SequenceInputStream concatne logiquement plusieurs fichiers dentre en un seul, la lecture senchanant dun fichier lautre de manire transparente.

Javabook Page 244 Lundi, 12. juillet 1999 3:58 15

ByteArrayInputStream BufferedInputStream FileInputStream DataInputStream java.lang. Object InputStream Abstraite FilterInputStream Abstraite LineNumberInputStream PipedInputStream PushBackInputStream SequenceInputStream

StringBufferInputStream

Figure 19.3 Classes pour la lecture doctets dans des flux

ByteArrayOutputStream

java.lang. Object

OutputStream Abstraite

FileOutputStream BufferedOutputStream FilterOutputStream Abstraite

DataOutputStream

PrintStream PipedOutputStream

Figure 19.4 Classes pour lcriture doctets dans des flux

Outre la persistance et les flux dentres-sorties, le package java.io contient quelques autres classes utiles illustres figure 19.5. La classe File permet de construire des noms de fichiers et de rpertoires. Elle permet ainsi de reprsenter les fichiers du systme dexploitation sous-jacent. La classe FileDescriptor permet dobtenir des poignes (handles) de bas niveau sur des fichiers ou des sockets ouverts. La classe RandomAccessFile est utilise pour la manipulation de fichiers accs direct. La classe StreamTokenizer sert faire de lanalyse lexicale en lisant le flux dentre, unit lexicale par unit lexicale.

Javabook Page 245 Lundi, 12. juillet 1999 3:58 15

Description du package

245

File

FileDescriptor finale java.lang.Object

RandomAccessFile

StreamTokenizer

Figure 19.5 Classes diverses


InputStream Abstraite

ObjectInputStream

ObjectInputStream.GetField

ObjectOutputStream.PutField java.lang. Object ObjectStreamClass

ObjectStreamField

OutputStream Abstraite

ObjectOutputStream

Figure 19.6 Classes pour la srialisation des objets

La srialisation consiste lire et crire un objet dans un flux. Lobjet est transform en une squence doctets, qui est lue ou crite en une seule fois. Les classes qui permettent la srialisation dobjets sont prsentes la figure 19.6 Les classes ObjectInputStream et ObjectOutputStream permettent la lecture et lcriture dobjets srialisables dans des flux (ventuellement des fichiers). Elles comportent respectivement une mthode de lecture et dcriture qui effectue lopration souhaite en une seule fois, les objets qui composent lobjet considr subissant ipso facto la mme opration de manire transparente. Un objet est srialisable si sa classe implante linterface Serializable. Les deux classes internes ObjectInputStream.GetField et ObjectOutputStream.PutField permettent laccs aux champs persistants dun objet. Les classes ObjectStream-

Javabook Page 246 Lundi, 12. juillet 1999 3:58 15

246

Chapitre 19 Entres-sorties et persistance des objets

Class et ObjectStreamField donnent accs aux informations dcrivant la srialisabilit dune classe quelconque. Elles ne sont utiles que pour la gestion de problmes de version entre la dfinition de la classe et celle de lobjet persistant ou srialis.

Interfaces
Linterface Serializable ne contient ni champ ni mthode, il suffit de la mentionner dans la dclaration de la classe des objets srialiser. Une autre interface trs utile de ce package est FilenameFilter. Elle dfinit une seule mthode, accept(), permettant la slection des entres dun rpertoire. Cette interface est rfrence par une mthode list() de la classe File et par la classe FileDialog du package AWT.

Exceptions
Les exceptions les plus utilises sont les suivantes : la classe EOFException sert indiquer que la fin de fichier a t atteinte lors de la lecture. La plupart des classes, hormis DataInputStream, retournent une valeur spciale en fin de fichier; la classe FileNotFoundException indique quun fichier na pu tre trouv; la classe IOException signale quun problme dentre-sortie est survenu. Beaucoup de mthodes du package la gnre; la classe InterruptedIOException signale quune entre-sortie a t interrompue.

19.2 Constructeurs des fichiers dentre et de sortie


Seules les classes FileReader et FileInputStream permettent de construire une instance partir dun nom de fichier ou dune instance de File. Les instances des autres classes ne peuvent tre labores qu partir dun Reader ou dun InputStream. Il est cependant possible de construire une instance de nimporte quelle sousclasse de InputStream ou dun Reader partir dun nom de fichier, comme le montre lexemple suivant : En effet, toute instance dune sous-classe peut tre considre comme une instance dune de ses super-classes. Une instance de FileReader peut tre considre comme une instance de Reader, qui est la classe du paramtre du constructeur de BufferedReader. Pour les fichiers de sortie, les classes qui permettent la cration dune instance partir dun nom de fichier sont FileWriter et FileOutputStream.
BufferedReader b = new BufferedReader(new FileReader("toto.txt"));

Javabook Page 247 Lundi, 12. juillet 1999 3:58 15

Entres-sorties clavier/cran

247

Les fichiers accs direct (classe RandomAccessFile) peuvent eux aussi tre crs directement avec un nom de fichier ou un File.

19.3 Entres-sorties clavier/cran


La classe System possde trois canaux dentres-sorties permettant la saisie de caractres (in), laffichage sur cran (out) et laffichage des erreurs (err). Ces canaux sont des variables de classe.
public static PrintStream err; public static InputStream in; public static PrintStream out;

La classe InputStream est abstraite, ainsi la classe effective du canal in est une sous-classe de InputStream. Le programme suivant calcule et affiche cette classe, savoir java.io.BufferedInputStream.
import java.io.*; public class classSystemIn { static public void main(String[] args) {System.out.println(System.in.getClass().getName());}}

Exemple : Affiche le nom de la classe de in

Ainsi, toute saisie au clavier est insre dans un tampon (buffer). La mthode available() renvoie le nombre doctets en attente dans le tampon. Selon votre systme dexploitation, ce nombre peut varier en fonction du caractre spcifiant la fin de la saisie, Control-D (Unix), Control-Z (MSDOS) ou retour chariot (Entre).

19.4 Variables denvironnement


Outre les canaux permettant les entres-sorties standard, la classe System permet daccder aux variables denvironnement. Lune dentre elles conserve le nom du rpertoire courant que nous utiliserons dans un des programmes cidessous. Le programme suivant affiche lensemble des variables denvironnement; ce sont des objets de la classe Properties. La mthode list() de cette classe admet comme paramtre un objet de la classe OutputStream. On peut donc lui fournir comme paramtre effectif nimporte quel objet dune des sous-classes de OutputStream. Dans notre programme, nous lui fournissons System.out qui est un objet de la classe PrintStream.
import java.io.*; import java.util.Properties; public class DemoProperties { static public void main(String[] args) {Properties p=System.getProperties(); p.list(System.out);}}

Javabook Page 248 Lundi, 12. juillet 1999 3:58 15

248

Chapitre 19 Entres-sorties et persistance des objets

19.5 Accs au rpertoire de travail


Le programme suivant affiche le rpertoire courant partir de la variable denvironnement adquate (user.dir).
import java.io.*; public class getWorkingDir { static public void main(String[] args) {System.out.println(System.getProperty("user.dir"));}

19.6 Classe File


De manire indpendante du systme dexploitation, la classe File permet : de rfrencer des fichiers et des rpertoires partir de leur nom; de tester leur existence, de connatre leurs droits daccs; daccder leurs proprits (date de modification, longueur); de crer des fichiers (temporaires ou non) et des rpertoires; de dtruire ou renommer des rpertoires et des fichiers; de lister (ventuellement avec un filtre) les entres dun rpertoire. Selon les systmes dexploitation, les caractres pour sparer les noms de rpertoires sont des / ou des \, ou encore des deux-points (:). Pour la construction de noms de rpertoire ou de fichier indpendante du systme dexploitation, la classe File dfinit des variables de classes constantes dsignant ces sparateurs, les valeurs de ces constantes tant dpendantes du systme utilis.

19.7 Quelques sous-classes de File utiles


Nous avons dvelopp les classes Fichier, FichierLecture, FichierEcriture, Repertoire, RepertoireLecture, RepertoireEcriture qui sont souvent utilises dans ce chapitre. Leur utilit tient ce quelles nautorisent la cration dobjets que si les droits de lecture ou dcriture requis sont respects. La figure 19.7 ci-dessous montre la hirarchie de ces diffrentes classes. En utilisant ces classes, on tente de crer une instance qui a les droits dsirs. En cas dchec de la cration, une exception est gnre. La rutilisation de ces classes favorise lcriture de programmes plus simples dvelopper et relire ensuite.

La classe Fichier
La classe abstraite Fichier est une sous-classe de File. Son intrt est de disposer dune mthode retournant le rpertoire dans lequel se trouve le fichier correspondant. Ce sont ses deux sous-classes (FichierLecture et FichierEcriture) qui testeront les droits daccs lors de la cration dinstances.

Javabook Page 249 Lundi, 12. juillet 1999 3:58 15

Quelques sous-classes de File utiles

249

FichierLecture Fichier FichierEcriture File RepertoireEcriture Repertoire RepertoireLecture

Figure 19.7 Quelques classes utiles, sous-classes de File


import java.io.*; public abstract class Fichier extends File{ public Fichier(String s) throws NullPointerException { super(s);} protected String repertoireDe() { String NomComplet=this.getAbsolutePath(); return NomComplet.substring(0, NomComplet.lastIndexOf(File.separator)); } }

La classe Fichier

La classe FichierLecture
Elle tend la classe Fichier en nautorisant que la cration de rfrences des fichiers pour lesquels on dispose dun droit de lecture.
import java.io.*; public class FichierLecture extends Fichier{ public FichierLecture(String s) throws IOException, NullPointerException super(s); if (!this.exists() || !this.isFile()) throw new IOException( this.getName() + ": fichier inexistant."); if (!this.canRead()) throw new IOException( this.getName() + ": fichier non lisible."); } }

La classe FichierLecture

La classe FichierEcriture
Elle tend la classe Fichier en nautorisant que la rfrence des fichiers pour lesquels on dispose dun droit dcriture (sur le fichier ou sur le rpertoire de sa rfrence, selon lexistence ou non du fichier considr).

Javabook Page 250 Lundi, 12. juillet 1999 3:58 15

250

Chapitre 19 Entres-sorties et persistance des objets

import java.io.*; public class FichierEcriture extends Fichier{ public FichierEcriture(String s) throws IOException { super(s); if (this.exists()){ if (this.isFile()){ if (!this.canWrite()) throw new IOException( this.getName() + ": n'est pas modifiable."); } else throw new IOException( this.getName() + ": n'est pas un fichier."); } else // le fichier n'existe pas { // il faut tester le droit en ecriture dans le repertoire File Dir=new File(this.repertoireDe()); if (!Dir.exists()) throw new IOException( Dir.getName() + ": n'est pas un repertoire"); if (!Dir.canWrite()) throw new IOException( Dir.getName() + ": n'est pas modifiable."); } } }

La classe FichierEcriture

La classe Repertoire
Cest une sous-classe abstraite de File permettant de rfrencer un rpertoire et dafficher des informations sur toutes les entres de celui-ci. Cette classe ne teste aucun droit daccs sur les rpertoires. Son rle est doffrir des mthodes daccs au contenu du rpertoire pour ses deux sous-classes : RepertoireLecture et RepertoireEcriture.
import java.io.*; public abstract class Repertoire extends File { private static final int lim=20; public Repertoire(String s) throws IOException{ super(s);} private void afficheUnFichier(String ref){ File unElement= new File(this,ref); System.out.print((unElement.canRead())? "L":" "); System.out.print((unElement.canWrite())? "E":" "); System.out.print(" "+ref); if (unElement.isDirectory()) System.out.println("\t"+"repertoire"); else if (unElement.canRead())

Javabook Page 251 Lundi, 12. juillet 1999 3:58 15

Quelques sous-classes de File utiles


System.out.println("\t"+unElement.length()); else System.err.println(" ????"); } public void afficheListe(String[] fichiers){ System.out.println(this.getName()); if (fichiers.length==0){ System.out.println("aucun fichier"); return;} for(int i=0;i<fichiers.length;i++) { if ((i>0) && ((i % lim)==0)){ System.out.println("<retour> pour continuer"); try {System.in.read();} catch (IOException e){}} this.afficheUnFichier(fichiers[i]); }; //for System.out.println(" "+fichiers.length+ " fichiers"); } }

251

La classe Repertoire

La classe RepertoireLecture
Son instanciation nest autorise que pour les rpertoires existants pour lesquels on dispose du droit de lecture.
import java.io.*; public class RepertoireLecture extends Repertoire { public RepertoireLecture(String s) throws IOException { super(s); if (!this.exists() || !this.isDirectory()) throw new IOException( this.getName() + ": repertoire inexistant."); if (!this.canRead()) throw new IOException( this.getName() + ": repertoire non lisible."); } }

La classe RepertoireLecture

La classe RepertoireEcriture
Son instanciation nest autorise que pour les rpertoires existants pour lesquels on dispose du droit dcriture.
import java.io.*; public class RepertoireEcriture extends Repertoire{ public RepertoireEcriture(String s) throws IOException super(s); if (!this.exists() || !this.isDirectory()) throw new IOException( this.getName() + ": repertoire inexistant."); if (!this.canWrite()) throw new IOException( this.getName() + {

Javabook Page 252 Lundi, 12. juillet 1999 3:58 15

252

Chapitre 19 Entres-sorties et persistance des objets


": repertoire non modifiable."); }

La classe RepertoireEcriture

Les exemples suivants illustrent les diffrentes classes de ce package et rutilisent les classes ci-dessus.

19.8 Affichage du contenu dun rpertoire avec filtrage


La classe AfficheRepertoire (voir lapplication 2 ci-dessous) qui utilise la classe RepertoireLecture, affiche la liste des entres du rpertoire1. Chaque entre est affiche par la mthode Repertoire.afficheListe. La liste affiche ne contient pas ncessairement toutes les entres du rpertoire : un filtre permet de ne retenir quune slection de ces entres. Cest le nombre darguments passs en paramtres qui dtermine sil y a filtrage ou non.
import java.io.*; public class AfficheRepertoire{ public static void main(String args[]){ Repertoire rep; String[] fichiers; try { rep= new RepertoireLecture(args[0]); switch (args.length) {case 1: fichiers=rep.list(); break; case 2: FilenameFilter ff; ff= new FiltreSuffixe(args[1]); fichiers=rep.list(ff); break; default: System.out.println( "Usage: java AfficheRepertoire <nom> [filtre]"); return;} // switch rep.afficheListe(fichiers);} // try catch (IOException e) {System.err.println(e.getMessage());} } }

Application 2 : AfficheRpertoire

Filtrage
La dfinition dun filtre seffectue en implantant linterface FileNameFilter. Le
1. Comme la commande dir de MSDos ou ls de Unix.

Javabook Page 253 Lundi, 12. juillet 1999 3:58 15

Lecture dun fichier

253

filtrage de la liste proprement dit se fait grce la mthode list() de la classe File qui admet comme paramtre linterface FileNameFilter. Le filtre implant dans la classe ci-dessous permet la slection des entres du rpertoire (fichiers ou sous-rpertoires) se terminant par un mme suffixe.
import java.io.*; class FiltreSuffixe implements FilenameFilter{ private String suffixe; public FiltreSuffixe(String suffixe) {this.suffixe=suffixe;} public boolean accept(File dir, String nom) {return nom.endsWith(suffixe);} }

La classe FiltreSuffixe

19.9 Lecture dun fichier


La classe suivante (Afficheur) implante un ensemble de mthodes permettant dafficher le contenu dun fichier ou dun URL dans une fentre graphique. Cette classe utilise des composants graphiques du package awt : champs de texte, menus, fontes. Elle utilise galement la classe FichierLecture.
import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; public class Afficheur extends Frame implements ActionListener { MenuItem Quitter; private void RemplitFenetre(InputStream dis,int taille) throws IOException {TextArea text; // lecture du fichier dans un tableau byte[] contenu= new byte[taille]; dis.read(contenu,0,taille); dis.close(); // definition et remplissage de la zone de texte text= new TextArea(new String(contenu),24,40); text.setFont(new Font("Courier",Font.PLAIN,10)); text.setEditable(false); this.add("Center",text); // creation de la barre de menus MenuBar barreMenu= new MenuBar(); this.setMenuBar(barreMenu); Menu menuFichier= new Menu("Fichier"); Quitter = new MenuItem("Quitter"); Quitter.addActionListener(this); menuFichier.add(Quitter); barreMenu.add(menuFichier); // positionnement des composants graphiques this.pack(); // affichage de la fenetre

Javabook Page 254 Lundi, 12. juillet 1999 3:58 15

254

Chapitre 19 Entres-sorties et persistance des objets


this.setVisible(true); } public Afficheur(FichierLecture fichier) throws IOException { super(fichier.getName()); FileInputStream canal=new FileInputStream(fichier); this.RemplitFenetre(canal,(int) fichier.length()); } // Afficheur

public Afficheur(URLConnection urlc) throws IOException { super(urlc.getURL().toExternalForm()); DataInputStream canal=new DataInputStream(urlc.getInputStream()); this.RemplitFenetre(canal,(int) urlc.getContentLength()); } // Afficheur public void actionPerformed (ActionEvent e) { if (e.getSource()==Quitter) {this.setVisible(false); this.dispose(); System.exit(0);} } //actionPerformed }

La classe Afficheur

Laffichage du contenu dun URL (voir point 20.3) est rendu possible car une connexion labore partir dun URL ouvre un flux de lecture.

Utilisation
Le programme suivant, dont un exemple dexcution est prsent dans la figure 19.8, utilise la classe Afficheur. Le nom du fichier afficher est pass comme argument sur la ligne de commande. On tente de crer une instance de la classe FichierLecture qui servira de paramtre au constructeur de Afficheur.
import java.io.*; public class AfficheUnFichier { static public void main(String[] args){ if (args.length!=1) { System.out.println ("Usage: java AfficheUnFichier <nom de fichier>"); System.exit(0);} try { FichierLecture fichier= new FichierLecture(args[0]); Afficheur f= new Afficheur(fichier);} catch (IOException e) {System.out.println(e);} } //main }

Application 3 : AfficheUnFichier

Javabook Page 255 Lundi, 12. juillet 1999 3:58 15

Copie dun fichier

255

Figure 19.8 Exemple dexcution de AfficheUnFichier

19.10 Copie dun fichier


La copie de fichier ralise par lapplication 4 ci-aprs requiert de tester les droits daccs suivants : en lecture du fichier source; en criture du fichier destination (sil existe); en criture du rpertoire du fichier destination (si le fichier est cr par lopration de copie). Le programme suivant utilise donc les classes FichierLecture et FichierEcriture (qui utilise RepertoireEcriture). Ce programme montre lintrt des sous-classes que nous avons dfinies puisquil permet de crer directement des objets ayant des proprits dsires, plutt que den manipuler de plus gnriques (en loccurrence des objets de la classe File).
import java.io.*; public class CopieurFichier { public static void copie(String src,String dest){ FileInputStream s=null; FileOutputStream d=null; try { FichierLecture Source= new FichierLecture(src); FichierEcriture Destination=new FichierEcriture(dest); s=new FileInputStream(Source); d=new FileOutputStream(Destination); byte[] tampon=new byte[1024]; int lu=0; do { lu=s.read(tampon); if (lu!=-1) d.write(tampon,0,lu);} while (lu!=-1);

Javabook Page 256 Lundi, 12. juillet 1999 3:58 15

256

Chapitre 19 Entres-sorties et persistance des objets

s.close(); d.close(); } // try catch (IOException e) {System.err.println(e.getMessage());} } // copie public static void main(String args[]){ if (args.length!=2){ System.err.println("Usage: java CopieurFichier <src> <dest>"); return;} copie(args[0],args[1]); } }

Application 4 : Copie de fichiers

19.11 Lecture filtrante dun fichier


Lexemple suivant (classe Ponctuation, application 5) illustre le filtrage des caractres durant la lecture. La classe Ponctuation rtablit, sil ny sont pas, les espaces typographiques ncessaires autour des virgules, deux-points et pointsvirgules. Le filtrage consiste analyser chaque caractre lu et si celui-ci correspond lun des trois signes de ponctuation ci-dessus, de rajouter ou de supprimer des espaces si ncessaire.

Dfinition du filtre
La classe Ponctuation est une sous-classe de la classe PushbackReader qui permet de rinsrer des caractres dj lus dans le flux de ceux qui restent lire (mthode unread). Nous avons redfini les deux mthodes read de la classe PushbackReader dans la sous-classe afin de raliser le filtrage qui consiste ponctuer correctement un texte.
import java.io.*; public class Ponctuation extends PushbackReader { private int dernierLu=-1; public Ponctuation (Reader fichier) { super(fichier,1); } public int read() throws IOException { int c=super.read();//appel read de PushbackReader if ((",;:".indexOf(dernierLu)>=0) && (c!=' ')) { unread(c); c=' '; } if (c==' ') { int d=super.read(); if (d!=',') unread(d); else c=',';

Javabook Page 257 Lundi, 12. juillet 1999 3:58 15

Fichier accs direct


} if (((c==';') || (c==':')) && (dernierLu!=' ')){ unread(c); c=' '; } dernierLu=c; return c;

257

} public int read(char[] cbuf , int off,int len) throws IOException { int c=0; for (int i=0;(i<len) && (c!=-1);i++) { c=read(); cbuf[off++]=(char) c; } if (c!=-1) return len; else return -1; } }

La classe Ponctuation

Utilisation du filtre
import java.io.*; public class Ponctue { public static void main(String args[]) { char[] buf= new char[20]; int c; if (args.length!=1) { System.err.println("java Ponctue <nom de fichier>"); return; } try { FichierLecture f=new FichierLecture(args[0]); Ponctuation fp=new Ponctuation (new FileReader(f)); do { c=fp.read(buf,0,20); if (c!=-1) System.out.print(buf); } while (c!=-1); fp.close();} catch (IOException e) {System.err.println(e.getMessage());} } //main } //class

Application 5 : Corriger la ponctuation dun fichier texte.

19.12 Fichier accs direct


La classe RandomAccessFile permet simultanment la lecture et lcriture dans un fichier. Le byte est lunit de mesure des positions et des dplacements. Cette classe comporte plus dune trentaine de mthodes et manipule tous les types de base du langage Java, en lecture comme en criture.

Javabook Page 258 Lundi, 12. juillet 1999 3:58 15

258

Chapitre 19 Entres-sorties et persistance des objets

Comment faire une classe implantant la gestion de fichiers accs direct dentiers?
La gestion des fichiers accs direct dentiers ne requiert (outre un constructeur au moins pour la cration dinstance) que les mthodes suivantes, lunit de positionnement tant alors lentier :
void close(); int read(); void write(int v); void seek(long pos); public long getFilePointer(); public long length();

Nous ne pouvons pas implanter la classe dsire par extension de la classe RandomAccessFile puisque nous ne pouvons pas interdire lhritage de certaines mthodes. Il nous faut alors composer ou, sans faire de jeu de mots, construire la classe dsire par composition.

Fichier dentiers accs direct


La classe FichierEntierAccesdirect est ainsi labore par composition dune variable dinstance de la classe RandomAccessFile et dune constante permettant de dfinir lunit de positionnement en nombre de bytes (en loccurrence 4).
import java.io.*; public class FichierEntierAccesDirect { private static final int taille=4; //taille d'un entier protected RandomAccessFile f; // constructeurs public FichierEntierAccesDirect(File file, String mode) throws IOException {f=new RandomAccessFile(file, mode);} public FichierEntierAccesDirect(String name, String mode) throws IOException {f=new RandomAccessFile(name,mode);} public void close() throws IOException {f.close();} public int read() throws IOException {return f.readInt(); // si read(), il y a des erreurs } void write(int v) throws IOException {f.writeInt(v); // si write(int v), il y a des erreurs } void seek(long pos) throws IOException {f.seek(taille*pos);}; public long getFilePointer() throws IOException { return f.getFilePointer() / taille;} public long length() throws IOException { return f.length() / taille;} } // FichierEntierAccesDirect

La classe FichierEntierAccesDirect

Javabook Page 259 Lundi, 12. juillet 1999 3:58 15

Analyse lexicale

259

Utilisation des fichiers dentiers accs direct


Le programme suivant (application 6) utilise la classe FichierEntierAccesDirect. On cre un fichier dentiers avec des valeurs choisies au hasard puis on le ferme. On louvre ensuite pour le lire. En fin de lecture, on positionne le curseur sur le 5e entier du fichier.
import java.util.Random; import java.io.IOException; public class DemoIntFichier { static public void main(String[] args) { FichierEntierAccesDirect f; Random v=new Random(); int x; try { f=new FichierEntierAccesDirect("Monfichier", "rw"); for (int i=0;i<10;i++) {x=v.nextInt(); System.out.println(i+":" +x); f.write(x);} f.close();} catch (IOException e) {System.exit(1);} // lecture du fichier que nous venons de crer try { f=new FichierEntierAccesDirect("Monfichier", "r"); System.out.println("taille du fichier: "+f.length()); long y; for (int i=0;i<f.length();i++) {y=f.getFilePointer(); x=f.read(); System.out.println(y+":"+x);} // positionnement sur le 5eme entier du fichier f.seek(5); System.out.println("le 5 eme element est:" + f.read()); f.close();} catch (IOException e) {System.out.println(e);}} // main }

Application 6 : Utilisation des fichiers dentiers accs direct

19.13 Analyse lexicale


Lapplication 7 illustre lutilisation de la classe StreamTokenizer qui permet de lire des units lexicales (tokens) et de connatre leur type. Cette classe est trs utile pour faire de lanalyse lexicale et existe aussi en version StringTokenizer, la lecture seffectuant alors partir dune chane de caractres et non partir dun fichier. La variable dinstance ttype indique le type de lunit lexicale lue. Les valeurs des types sont dfinies par des variables de classes constantes (TT_WORD,

Javabook Page 260 Lundi, 12. juillet 1999 3:58 15

260

Chapitre 19 Entres-sorties et persistance des objets

TT_NUMBER, etc.). Si lunit lexicale est de type nombre, sa valeur est stocke dans la variable dinstance nval, si cest un mot dans sval. La mthode nextToken() permet de lire les units lexicales les unes aprs les autres. Le programme suivant utilise la classe StreamTokenizer pour compter les mots et les nombres dun fichier.
import java.io.*; public class Compteur { public static void main(String args[]){ int nNombres=0; int nMots=0; Reader r=null; StreamTokenizer st=null; try { r = new BufferedReader(new FileReader(args[0])); st = new StreamTokenizer(r);} catch (IOException e) {System.out.println("usage : java Compteur <filename>"); try {r.close();} catch (IOException e1) {}; System.exit(1);} st.eolIsSignificant(true); st.wordChars((int) '_',(int)'_'); st.ordinaryChar((int) '.'); try {while (st.nextToken()!=st.TT_EOF) {if (st.ttype== st.TT_WORD) {System.out.println(st.sval); nMots++;} if (st.ttype== st.TT_NUMBER) {System.out.println(st.nval); nNombres++;} } } catch (IOException e) {System.out.println("error when reading.");} finally {try {r.close();} catch (IOException e1) {};} System.out.println("mots : "+ nMots); System.out.println("nombres : "+ nNombres); } //main }

Application 7 : Compteur de mots et de nombres dun fichier

19.14 Dialogues pour louverture et la fermeture dun fichier


La classe FileDialog du package awt permet la cration dune fentre de dialogue pour louverture ou la sauvegarde dun fichier. Cette fentre correspond la

Javabook Page 261 Lundi, 12. juillet 1999 3:58 15

Srialisation et persistance des objets

261

fentre standard douverture et de fermeture de fichiers de linterface graphique du systme dexploitation utilis. Le constructeur de cette classe admet un paramtre indiquant le type de fentre souhait : pour louverture dun fichier, sa valeur est FileDialog.LOAD, pour la sauvegarde dun fichier, sa valeur est FileDialog.SAVE. Cette classe a des mthodes permettant de rcuprer et de spcifier le rpertoire et le fichier. Ces mthodes sont : getDirectory(); getFile(); setDirectory(String dir); setFile(). La mthode setFileNameFilter(FileNameFilter f) permet le filtrage des noms dentres affichs dans la fentre.

19.15 Srialisation et persistance des objets


La srialisation est une opration qui consiste lire et crire un objet dans un flux, lobjet tant transform en une squence doctets lue ou crite en une seule fois. Cette opration fonctionne galement pour des objets complexes, cest-dire des objets dont les valeurs des champs sont elles-mmes des objets. Le graphe dobjets est alors lu ou crit intgralement en une seule opration. La srialisation a deux usages essentiels : faire circuler (via des flux) des objets entre des applications distribues, sans encodage ni dcodage spcifiques programmer; rendre persistant des objets, toujours sans aucune programmation. Un objet est dit persistant si sa dure de vie est suprieure celle du programme qui la cr. La persistance des objets est implante par leur srialisation dans des fichiers. Lexemple ci-dessous montre lintrt de la srialisation pour la persistance des objets. On cre dynamiquement un arbre de chane de caractres que lon sauve dans un fichier pour tre relu ultrieurement. La classe Arbre implante la notion darbre binaire de recherche, et dclare linterface Serializable (qui ne contient, on le rappelle, ni champ, ni mthode).
import java.io.Serializable; class Arbre implements Serializable { Arbre sag, sad; // sous-arbres gauche et droit String Label; public Arbre (String l) { Label=l; sag=null; sad=null; }

Javabook Page 262 Lundi, 12. juillet 1999 3:58 15

262

Chapitre 19 Entres-sorties et persistance des objets


void inserer(String l) { if (Label==null) Label=l; else if (l.compareTo(Label)<0) { if (sag==null) sag=new Arbre(l); else sag.inserer(l); } else if (l.compareTo(Label)>0) { if (sad==null) sad=new Arbre(l); else sad.inserer(l); } } void parcours() { if (sag!=null) sag.parcours(); System.out.print(Label+" "); if (sad!=null) sad.parcours(); }

La classe Arbre

Le programme ci-dessous cre un arbre binaire de recherche partir dune phrase passe en paramtre sur la ligne de commande, puis appelle la mthode parcours qui imprime les nuds de larbre dans lordre alphabtique. Larbre est rendu persistant par lcriture de lobjet (mthode writeObject) dans un ObjectOutputStream.
import java.io.*; class DemoArbre { static public void main(String[] args) { Arbre a=new Arbre(null); if (args.length==0) { System.out.println("Usage : java DemoArbre <X1> .. <Xn>"); System.exit(0); } for (int i=0; (i<args.length); i++) { a.inserer(args[i]); } a.parcours(); // rendre l'arbre persistant try { FileOutputStream fos = new FileOutputStream("arbre.tmp"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(a); oos.flush(); oos.close(); } catch (Exception e) { e.printStackTrace(); System.exit(1); } } // main }

Application 8 : Rendre un arbre persistant

Javabook Page 263 Lundi, 12. juillet 1999 3:58 15

Invitation explorer

263

Le programme ci-dessous lit cet objet persistant (mthode readObject de la classe ObjectInputStream).
import java.io.*; class DemoArbreLecteur { static public void main(String[] args) { Arbre b=null; try { FileInputStream fis = new FileInputStream("arbre.tmp"); ObjectInputStream ois = new ObjectInputStream(fis); b = (Arbre) ois.readObject(); ois.close(); } catch (Exception e) { e.printStackTrace(); System.exit(1); } b.parcours(); } // main }

Application 9 : Lecture dun objet arbre persistant

La srialisation de la racine a entrane bien celle de tous les autres nuds de larbre. La persistance des objets est donc ralise avec la lecture ou lcriture dun objet en une seule opration. Les difficults apparaissent seulement si des versions diffrentes des classes dobjets srialiss sont incompatibles. Il est prfrable de ne pas modifier la dfinition dune classe tant quil en existe des instances persistantes. Certaines modifications peuvent en effet poser des problmes dincompatibilit comme, par exemple, la destruction dun champ. La srialisation permet galement, avec une grande facilit, la circulation des objets aussi complexes soient-ils, entre des applications distribues.

19.16 Invitation explorer


Compltez lditeur de texte pour ajouter les fonctions douverture et de sauvegarde de fichiers.

Javabook Page 264 Lundi, 12. juillet 1999 3:58 15

Javabook Page 265 Lundi, 12. juillet 1999 3:58 15

Chapitre 20

Les accs au rseau (java.net)


Ce package fournit un ensemble de classes pour communiquer sur le rseau Internet, tlcharger des URL, dfinir des gestionnaires de type MIME et de protocoles. Dans ce chapitre, nous dvelopperons des applications client-serveur partir dexemples complets. Aprs avoir dcrit les composants principaux de ce package, nous en prsentons des exemples dutilisation illustrant lidentification du contenu dun URL et laffichage de son contenu dans une fentre graphique. Un autre exemple prsente la vrification de tous les URL contenus dans une page de type text/html tlcharge partir de son URL. Les deux derniers exemples de ce chapitre sont bass sur le principe du clientserveur. Le premier montre la ralisation dun service simple et dfinit une architecture de base rutilisable. Le second, une relation client-serveur plus labore, la tldiscussion. Ces exemples peuvent tre tendus la ralisation de vos propres serveurs.

20.1 Description du package


Les classes
Deux types de classes constituent ce package : les classes de bas niveau permettent de dfinir des gestionnaires de protocoles et de types MIME1 ;

Javabook Page 266 Lundi, 12. juillet 1999 3:58 15

266

Chapitre 20 Les accs au rseau (java.net)

les classes de haut niveau permettent de se connecter sur un URL, den tlcharger le contenu et de faire de la communication interprocessus sur le rseau Internet. Les classes de bas niveau Ces classes sont trs utiles si lon souhaite grer de nouveaux types MIME absents dans lenvironnement Java ou des protocoles. Les classes permettant de dfinir des types MIME sont (figure 20.1) : ContentHandler : cette classe abstraite dfinit ce quest un gestionnaire de type MIME. Un tel gestionnaire tlcharge un contenu partir dune connexion sur un URL et transforme ce contenu en une instance dune classe dobjets, classe prdfinie dans Java ou implante par vousmme. La mthode getContent() ralise cette transformation. Par exemple, Java incorpore un gestionnaire pour les images au format gif. Ce gestionnaire dimages est une sous-classe de la classe ContentHandler; URLStreamHandler : cette classe abstraite dfinit ce quest un protocole pour la connexion sur un URL. Par exemple, Java implante un protocole permettant la connexion sur des serveurs HTTP. Ce gestionnaire de protocole est une sous-classe de la classe URLStreamHandler.
ContentHandler Abstraite Object URLStreamHandler Abstraite

Figure 20.1 Classes pour implanter des gestionnaires

Les classes permettant lenvoi et la rception de paquets sur le rseau sont (figure 20.2) : DatagramPacket : cette classe reprsente un paquet envoyer ou recevoir travers le rseau. Un paquet envoyer est compos dun tableau doctets et dune adresse Internet (un objet de la classe InetAddress). Un paquet recevoir est compos dun tableau doctets; DatagramSocket : cette classe reprsente un metteur-rcepteur de paquets (mthodes send() et receive()) mais sans aucune garantie concernant lordre darrive des paquets ni leur arrive elle-mme. Il est
1. MIME est un acronyme de Multipurpose Internet Mail Extensions. LURL http://www.imc.org/rfcs.html#mime dcrit compltement cette spcification pour la mise en forme de messages Internet.

Javabook Page 267 Lundi, 12. juillet 1999 3:58 15

Description du package

267

prfrable dutiliser des objets des classes Socket et ServerSocket pour communiquer de manire plus sre sur le rseau; la classe MulticastSocket permet lenvoi et la rception de paquets un groupe de destinataires et plus un seul, comme la classe prcdente; SocketImpl : cette classe dfinit un ensemble de mthodes ncessaires limplantation de la communication travers des sockets.
DatagramPacket finale DatagramSocket MulticastSocket

InetAddress Object ServerSocket finale Socket finale SocketImpl Abstraite

Figure 20.2 Classes pour la communication de paquets par des sockets

Les classes de haut niveau La classe InetAddress reprsente des adresses Internet. Elle est utilise par lun des constructeurs de la classe Socket et par celui de la classe DatagramSocket pour lenvoi de paquets. La classe ServerSocket permet la construction de serveurs : un serveur attend des demandes de connexion manant de clients sur un port particulier. La mthode accept() renvoie un socket lorsquune demande est reue. La classe Socket permet la communication interprocessus travers le rseau. En spcifiant une machine (ou une adresse Internet) et un numro de port, un socket peut tre construit. Le protocole par dfaut est celui des flots (streams). Les mthodes getInputStream() et getOutputStream() permettent la rcupration des canaux de lecture et dcriture. La classe URL (Uniform Resource Locator) permet le tlchargement des ressources rfrences par un URL. Elle offre trois possibilits de tlchargement : directement par la mthode getContent(). Cette mthode renvoie un objet dont la classe correspond un type MIME pour lequel on dispose dun gestionnaire (un ContentHandler);

Javabook Page 268 Lundi, 12. juillet 1999 3:58 15

indirectement par une URLConnection obtenue par la mthode openConnection(), puis ensuite par la mthode getContent() qui est similaire la prcdente; par un canal de type InputStream obtenu par la mthode openStream(). Cette voie est la seule possibilit si lURL contient des informations qui ne sont pas dun type MIME pour lequel on dispose dun gestionnaire.
Authenticator Abstraite PasswordAuthentication finale URL finale

URLClassLoader Object URLConnection Abstraite JarURLConnection Abstraite URLDecoder HttpURLConnection Abstraite

URLEncoder

Figure 20.3 Classes pour utiliser les URL

Les classes Authenticator et PasswordAuthentication permettent laccs par des programmes Java des ressources dsignes par un URL et protges par mot de passe, condition videmment dtre un utilisateur autoris de ces ressources. La classe abstraite URLConnection a pour rle doffrir un meilleur contrle sur le tlchargement de ressources rfrences par un URL. Cette classe dispose de mthodes permettant de connatre le type, len-tte, la date de dernire modification dun contenu. Cette classe permet le tlchargement des donnes brutes de ce contenu. La classe abstraite HttpURLConnection tablit des connexions vers des URL en utilisant les spcificits du protocole HTTP; il est par exemple possible de savoir si la connexion passe au travers dun proxy ou non. La classe abstraite JarURLConnection tablit des connexions vers des archives Java ou des entres dune archive Java partir dun URL afin de les tlcharger. Les classes URLDecoder et URLEncoder offrent chacune une seule mthode de

Javabook Page 269 Lundi, 12. juillet 1999 3:58 15

Description du package

269

classe, dont le but est de coder/dcoder un URL en une chane de caractres plus portable et inversement. Les espaces et les caractres non alphanumriques sont cods diffremment.

Interfaces
Les interfaces de ce package fournissent les signatures des mthodes pour les classes de bas niveau. Ces interfaces sont : ContentHandlerFactory : cette interface ne dfinit que la signature dune seule mthode, ContentHandler createContentHandler(String mimetype). Cette mthode dfinit lassociation entre un type MIME et le gestionnaire correspondant; FileNameMap : cette interface sert dterminer, partir du nom dun fichier, le nom du type MIME qui va en permettre la lecture; URLStreamHandlerFactory : cette interface joue le mme rle pour les protocoles que linterface ContentHandlerFactory pour les gestionnaires de type MIME; SocketImplFactory : cette interface est utilise par les classes Socket et ServerSocket pour raliser les implantations effectives des sockets; SocketOptions : cette interface est utilise pour lire et crire des options lies une nouvelle implantation de sockets.

Exceptions
BindException : cette classe dexception indique un problme dtablissement de liaison entre un socket, une adresse et un port locaux; ConnectException et NoRouteToHostException : ces deux classes dexception indiquent un problme dtablissement de la connexion entre un socket, une adresse et un port distants; MalformedURLException : cette classe dexception permet de signaler la non-reconnaissance dun protocole connu dans la chane de caractres spcifiant un URL, ou lchec de lanalyse lexicale de cette chane; ProtocolException : cette classe dexception signale les erreurs dans un protocole, par exemple une erreur TCP; SocketException : cette classe dexception signale une mauvaise utilisation des sockets; UnknownHostException : cette classe dexception signale que ladresse IP dun hte na pu tre dtermine; UnknownServiceException : cette classe dexception signale la nonreconnaissance dun type MIME ou une tentative dcriture sur un URL avec accs en lecture seulement.

Javabook Page 270 Lundi, 12. juillet 1999 3:58 15

270

Chapitre 20 Les accs au rseau (java.net)

De nombreuses classes de ce package ont des mthodes signalant des exceptions de la classe IOException. Les exemples suivants utilisent les classes URL, URLConnection, Socket, ServerSocket, Authenticator et PasswordAuthentication.

20.2 Identification du contenu dun URL


Lapplication 10 utilise les classes URL et URLConnection pour afficher le type MIME de la ressource rfrence par un URL pass sur la ligne de commande. La mthode openConnection() de la classe URL peut signaler une exception de la classe IOException; cette classe est donc importe dans notre application.
import java.io.IOException; import java.net.*; public class ContenuURL { public static void afficheInfos(URLConnection u){ // affiche l'URL et les infos s'y rattachant System.out.println(u.getURL().toExternalForm() + ":"); System.out.println("Contenu :"+ u.getContentType()); System.out.println("Longueur :"+ u.getContentLength()); try { Reader r=new InputStreamReader(u.getInputStream()); BufferedReader br=new BufferedReader (r); for (int i=0;i<3;i++) { System.out.println(br.readLine()); } System.out.println(" ..."); br.close(); } catch (IOException e) {System.out.println(e.getMessage());} } static public void main(String[] args) throws MalformedURLException, IOException { if (args.length==0) return; URL url=new URL(args[0]); URLConnection connection=url.openConnection(); afficheInfos(connection); }

Application 10 : Identification du contenu dun URL

Dans lexemple dexcution suivant, le contenu est du type text/html.


>java ContenuURL http://java.sun.com/ http://java.sun.com/: Contenu:text/html Longueur:3495 .....+ trois 1res lignes HTML du fichier

Javabook Page 271 Lundi, 12. juillet 1999 3:58 15

Accs un URL protg par un mot de passe

271

20.3 Accs un URL protg par un mot de passe


Lexemple prcdent a illustr lidentification du contenu dun URL. Un programme Java peut accder des contenus protgs dun URL, la condition vidente den possder les droits daccs. Un droit daccs est dfini par un nom dutilisateur et un mot de passe. Tout dabord, dfinissons une classe dont le rle est dacqurir une demande daccs et de fabriquer une demande didentification qui sera envoye de manire transparente au serveur HTTP qui hberge la ressource protge.
import java.net.*; import java.io.*; class Identification extends Authenticator { protected PasswordAuthentication getPasswordAuthentication() { PasswordAuthentication ident=null; System.out.print("username :");System.out.flush(); try { BufferedReader r= new BufferedReader( new InputStreamReader(System.in)); String u=r.readLine(); System.out.print("password :"); String p=r.readLine(); ident =new PasswordAuthentication(u,p.toCharArray()); } catch (IOException e) {System.out.println(e.getMessage());} return ident; } }

La Classe Identification

La seconde tape consiste installer une instance de cette classe dans le programme daccs aux URL. La ligne de code ci-dessous peut se rajouter lapplication 10 dans la mthode main avant linstruction qui demande la connexion.
Authenticator.setDefault(new Identification());

Lorsque lapplication accde un URL protg, la mthode getPasswordAuthentication de la classe Identification est appele afin dobtenir un compte utilisateur et un mot de passe.

20.4 Affichage du contenu dun URL dans une fentre


Les exemples ci-dessus nous ont montr comment vrifier un URL et accder son contenu que celui-ci soit protg ou non. Ce nouvel exemple montre le tlchargement du contenu des URL. Dans le chapitre sur les entres-sorties, nous avons dfini la classe Afficheur permettant dafficher le contenu dun fichier ou dun URL. Nous rutilisons donc cette classe dans lapplication 11 :
import java.io.*; import java.net.*;

Javabook Page 272 Lundi, 12. juillet 1999 3:58 15

272

Chapitre 20 Les accs au rseau (java.net)

public class AfficheUnURL { static public void main(String[] args){ if (args.length!=1) { System.out.println("Usage : java AfficheUnURL <URL>"); System.exit(0);} try { URL url= new URL(args[0]); Afficheur f= new Afficheur(url.openConnection());} catch (IOException e) {System.out.println(e);} }

Application 11 : Affichage du contenu dun URL

20.5 Vrificateur dURL


Lapplication suivante tlcharge le contenu dun URL et vrifie tous les URL qui le composent. Cette application utilise la classe ValiditeURLConnexion dote de deux mthodes de classe charges de vrifier la validit dun URL et de lever une exception si ncessaire.
import java.io.*; import java.net.*; public class ValiditeURLConnexion { public static void test(URL url) throws IOException { URLConnection c=url.openConnection(); DataInputStream dis =new DataInputStream(c.getInputStream()); dis.close(); } public static void test(String s) throws MalformedURLException,IOException{ test(new URL(s)); }

La classe ValiditeURLConnexion

Ce vrificateur dURL est trs simple puisquil suppose que : les balises autour dun URL sont spcifies ainsi : <A HREF="un url">texte affich</A>, les guillemets dlimitant la chane de caractres spcifiant lURL vrifier; les URL sont des rfrences absolues et non relatives un URL courant; Le principe de cette vrification est le suivant : 1. partir dune URLConnexion obtenue par la cration dun URL pass dans la ligne de commandes, on teste son type MIME. Sil sagit dun text/html, son contenu est vrifi. Ce contenu est lu, unit lexicale par unit lexicale. 2. Pour chaque ligne, on cherche le motif <A, puis on saute deux units lexicales correspondant HREF et =. LURL analyser est contenu

Javabook Page 273 Lundi, 12. juillet 1999 3:58 15

Vrificateur dURL

273

entre deux guillemets. On appelle ensuite la mthode test() de la classe ValiditeURLConnexion pour vrifier la validit de cet URL. Les rglages de lextracteur dunits lexicales (StreamTokenizer) sont importants puisquils assemblent en une seule unit lexicale, dune part, le symbole < avec les mots (voir la mthode wordChars) et, dautre part, tous les caractres compris entre deux guillemets en une chane de caractres (voir la mthode quoteChar).
import java.io.*; import java.net.*; public class VerifieURL { public static void verifie(URLConnection u) throws IOException { if (!u.getContentType().equals("text/html")) { System.out.println("seuls les text/html sont verifies."); System.exit(0);}; Reader r=new InputStreamReader(u.getInputStream()); StreamTokenizer st=new StreamTokenizer (r); st.wordChars('<','<'); st.quoteChar('"'); while (st.nextToken()!=st.TT_EOF) { if ((st.ttype== st.TT_WORD) && (st.sval.compareToIgnoreCase("<a")==0)) { st.nextToken(); // saute href st.nextToken(); // saute = st.nextToken(); // extrait l'URL System.out.println(st.sval); try {ValiditeURLConnexion.test(st.sval);} catch (IOException e) { System.out.println("URL incorrect :"+st.sval);} } // if } // while r.close(); } public static void main(String args[]) throws MalformedURLException, IOException { if (args.length!=1) {System.out.println("Usage : java verifieURL <URL>"); System.exit(0);} URLConnection c=null; try { URL url =new URL(args[0]); ValiditeURLConnexion.test(url); c= url.openConnection(); System.out.println(c.getClass().getName());} catch (IOException e) {System.out.println("URL incorrect : "+args[0]); System.exit(0);} verifie(c); }}

Application 12 : Vrificateur dURL

Javabook Page 274 Lundi, 12. juillet 1999 3:58 15

274

Chapitre 20 Les accs au rseau (java.net)

20.6 Un exemple client-serveur


La communication entre les clients et le serveur seffectue travers le rseau Internet. Dans ce premier exemple de client-serveur, les clients ne communiquent pas entre eux. Lorsquune application demande une connexion, le serveur lui en construit une. Le service que rend cette connexion est de renvoyer en majuscule tous les messages que le client lui envoie. Un client se dconnecte du serveur par lenvoi du message fin.
processus serveur

cration processus connexion

demande de connexion

message MESSAGE

application client

machine hte processus sexcutant sur la machine du client Figure 20.4 Schma de communication entre processus

La demande de connexion par le client est la cration dune instance de la classe Socket indiquant la machine hte et un numro de port. Le lancement du serveur sur lhte de nom mycpu seffectue ainsi :
>java Serveur Serveur en ecoute sur le port: 45678

Le serveur est en attente de connexions de la part des clients. Un client demande une connexion ainsi :
>java Client mycpu Connexion: mycpu/189.154.12.87 port: 45678 ?toto !TOTO ?lulu !LULU ?fin Connexion stoppee par le serveur

Le point dinterrogation indique que le client attend un message de lutilisateur. Le point dexclamation prfixe le service rendu par la connexion.

Javabook Page 275 Lundi, 12. juillet 1999 3:58 15

Un exemple client-serveur

275

Serveur
Le serveur est un processus dont lune des variables dinstance est une instance de ServerSocket initialise la cration du serveur. La mthode run() de ce processus est une boucle interruptible par un signal de la classe IOException. Cette boucle effectue le cycle suivant : attente dune demande de connexion (mthode accept()) puis cration dune instance de la classe Connexion partir du Socket que lui a renvoy la mthode accept(). Cest la classe Connexion qui ralise le service de transformation des caractres en majuscules.
import java.io.*; import java.net.*; public class Serveur extends Thread { protected static final int PORT=45678; protected ServerSocket ecoute; public Serveur () { try { ecoute=new ServerSocket(PORT);} catch (IOException e) { System.err.println(e.getMessage()); System.exit(1); } System.out.println("Serveur en ecoute sur le port :"+PORT); this.start(); } public void run() { try { while (true) { Socket client=ecoute.accept(); Connexion c= new Connexion(client); }} catch (IOException e) { System.err.println(e.getMessage()); System.exit(1); } } public static void main(String[] args) { new Serveur(); } }

La classe Serveur

Connexion
Une instance de la classe Connexion est cre par le serveur. Cette Connexion ralise la transformation des caractres en majuscules. Il y a un processus de cette classe pour chaque client. Le canal de communication entre le client et une connexion est le socket que le serveur a fourni la suite dune demande de connexion dun client.

Javabook Page 276 Lundi, 12. juillet 1999 3:58 15

276

Chapitre 20 Les accs au rseau (java.net)

processus connexion

application client

in out

socket

socket

canalEcriture canalLecture

Figure 20.5 Les canaux de lecture, dcriture et les sockets

Les canaux de lecture et dcriture sur les sockets sont rcuprs par les mthodes getInputStream() et getOutputStream() de la classe Socket.
import java.io.*; import java.net.*; class Connexion extends Thread{ protected Socket client; protected BufferedReader in; protected PrintStream out; public Connexion(Socket client_soc) { client=client_soc; try {in =new BufferedReader(new InputStreamReader(client.getInputStream())); out =new PrintStream(client.getOutputStream());} catch (IOException e) { try {client.close();} catch (IOException e1) {}; System.err.println(e.getMessage()); return; } this.start(); } public void run() { String ligne; try { while(true) { ligne=in.readLine(); // lecture avec attente message client // test de la fin de connexion demande par le client if (ligne.toUpperCase().compareTo("FIN")==0) break; out.println(ligne.toUpperCase()); //ralisation du service }} catch (IOException e) {System.out.println("connexion :"+e.toString());} finally {try {client.close();} catch (IOException e){};} }

La classe Connexion

Javabook Page 277 Lundi, 12. juillet 1999 3:58 15

Un exemple client-serveur

277

Un client est une application sexcutant sur une autre1 machine. La connexion se fait par la demande de cration dun socket sur un hte et sur un numro de port. Ce numro de port doit tre identique celui du serveur.
import java.io.*; import java.net.*; public class Client { protected static final int PORT=45678; public static void erreur() { System.err.println("Usage: java Client <hostname>"); System.exit(1); public static void main(String[] args) { Socket s=null; if (args.length!=1) erreur(); try { s=new Socket(args[0],PORT); BufferedReader canalLecture=new BufferedReader(new InputStreamReader(s.getInputStream())); BufferedReader console=new BufferedReader(new InputStreamReader(System.in)); PrintStream canalEcriture= new PrintStream(s.getOutputStream()); System.out.println("Connexion : "+ s.getInetAddress()+ " port : "+s.getPort()); String ligne; while (true) { System.out.print("?"); System.out.flush(); ligne=console.readLine(); // saisie message utilisateur canalEcriture.println(ligne); //demande du service ligne=canalLecture.readLine();//lecture service ralis // test de fin de connexion if (ligne==null){ System.out.println("Connexion stoppee par le serveur"); break;} // le service rendu est affich lcran System.out.println("!"+ ligne); } } // try catch (IOException e) {System.err.println(e);} finally {try {if (s!=null) s.close();} catch (IOException e2){}} } // main }

Client du serveur

Application 13 : Client
1. Lapplication fonctionne galement si le client est sur la mme machine que le serveur.

Javabook Page 278 Lundi, 12. juillet 1999 3:58 15

278

Chapitre 20 Les accs au rseau (java.net)

Le client indique la fin dune connexion par lenvoi du message fin. Lorsque ce message est reu par linstance de la classe Connexion, celle-ci ferme le socket. Le processus termine alors son excution. Le client identifie la fin effective de la connexion en dtectant la fin du fichier sur le canal de lecture. En effet, la mthode readLine() renvoie la chane null en fin de fichier.

20.7 Tldiscussion
Cet exemple est bas sur une relation client-serveur avec des clients communiquant par lintermdiaire du serveur, celui-ci maintenant une liste des connexions. Le fonctionnement de ce serveur est simple. Il envoie tous les clients le message quil a reu dun client. Un tel service constitue une tldiscussion entre plusieurs personnes communiquant par lintermdiaire de leur clavier. Tous les messages envoys sont prfixs par le nom du client afin didentifier les propos des diffrents interlocuteurs. La tldiscussion n personnes ncessite le maintien dune liste des connexions courantes. Cette liste doit tre mise jour chaque nouvelle connexion dun client et chaque dpart dun client de la discussion. Ds quune connexion re oit un message de son client, elle doit accder la liste des connexions pour envoyer ce message tous les clients. Plusieurs processus accdent en lecture et en criture cette liste des connexions, qui doit tre protge (voir p. 107). Le mot cl synchronized garantit cette protection.

Identification et rle des processus ncessaires la tldiscussion


La figure 20.6 illustre les processus ncessaires : un serveur en attente de connexions : lorsquune nouvelle demande arrive, le serveur cre une connexion et linsre dans la liste, puis attend une nouvelle demande; une connexion pour chaque client : cette connexion attend un message de son client puis demande un accs la liste des connexions afin de leur envoyer le message pour quelles le transmettent leur client respectif. Lorsquun client indique une fin de connexion, sa connexion avertit un processus nettoyeur charg de la retirer de la liste des connexions; le processus nettoyeur : il sexcute sur la machine hte du serveur comme toutes les connexions. Ce processus se rveille priodiquement

Javabook Page 279 Lundi, 12. juillet 1999 3:58 15

Tldiscussion

279

ou est rveill par une connexion. Son rle est de tester lactivit dune connexion. Si celle-ci est inactive, elle est retire de la liste. Une connexion est inactive si sa mthode run() a termin son excution; lapplication client : son rle est de permettre la saisie des messages de lutilisateur, et dafficher les messages de sa connexion (venant en fait dautres clients via leur connexion respective). Contrairement lexemple prcdent, o lmission et la rception de messages taient synchronises, ici un client peut rester couter la discussion, en intervenant de temps en temps; lcoute et la rception sont donc asynchrones. Un second processus, lcouteur est donc ncessaire; le processus couteur : il sexcute sur la mme machine que le client. Son rle est dafficher tous les messages quil reoit de la connexion. Il fonctionne indpendamment de lutilisateur; Tous les processus sexcutant sur la machine hte accdent de manire exclusive la liste des connexions : le serveur pour ajouter des connexions; le nettoyeur pour en enlever; chaque connexion pour rpercuter les messages sur toutes les connexions (y compris elle-mme) afin que la discussion soit partage par tous.

Le serveur
Le constructeur de ce processus cre une instance de ServerSocket pour grer les demandes de connexions, une instance de Vector pour stocker la liste des connexions et une instance du processus Nettoyeur.
import java.io.*; import java.net.*; import java.util.*; public class ServeurTD extends Thread { protected static final int PORT=45678; protected ServerSocket ecoute; protected Vector connexions; protected Nettoyeur nettoyeur; public ServeurTD () { try {ecoute=new ServerSocket(PORT);} catch (IOException e) {System.err.println(e.getMessage()); System.exit(1); } System.out.println("Serveur en ecoute sur le port :"+PORT); connexions=new Vector(); nettoyeur=new Nettoyeur(this);

Javabook Page 280 Lundi, 12. juillet 1999 3:58 15

280

Chapitre 20 Les accs au rseau (java.net)

processus serveur processus connexion

application client A couteur

application client B processus connexion couteur

application client C processus connexion couteur

application client D processus connexion couteur

processus nettoyeur machine hte machine du client

processus sexcutant sur la

Figure 20.6 Les processus de la tldiscussion


this.start(); } public void run(){ try{ while (true){ Socket client=ecoute.accept(); System.out.println("Demande de connexion..."); ConnexionTD c= new ConnexionTD(client,nettoyeur,this); synchronized (connexions) {connexions.addElement(c);} }} catch (IOException e) {System.err.println(e.getMessage()); System.exit(1); } } public static void main(String[] args) {new ServeurTD(); } }

La classe ServeurTD

Javabook Page 281 Lundi, 12. juillet 1999 3:58 15

Tldiscussion

281

La cration dune nouvelle connexion entrane son ajout dans la liste connexions, cet ajout tant protg de lexcution simultane dautres processus.

Une connexion
Les instances de cette classe sont galement des processus. Le constructeur de cette classe reoit plusieurs rfrences en paramtres. Le socket est la liaison entre le client et la connexion. La rfrence au serveur permet laccs la liste des connexions; celle du nettoyeur permet son rveil par la connexion. La mthode run() de ce processus attend un message du client sur son socket. Lorsquelle en reoit un, elle demande laccs exclusif la liste des connexions, puis crit sur le socket de chaque connexion de cette liste le message quelle a reu. Pendant cette criture, il est noter que toutes les connexions de la liste (si elles sont actives) sont en attente soit dun message de leur client, soit de laccs la liste des connexions (cest--dire quelles ont reu un message, mais ne lont pas encore trait). Une connexion non active peut figurer dans la liste car le nettoyeur nest pas prioritaire pour laccs la liste; cela ne produira pas derreur car la mthode println() de la classe PrintStream ne signale pas dexception en cas de problme.
import java.io.*; import java.net.*; import java.util.*; import java.io.*; import java.net.*; import java.util.*; class ConnexionTD extends Thread{ protected Socket client; protected ServeurTD serveur; protected BufferedReader in; protected PrintStream out; protected Nettoyeur nettoyeur; public ConnexionTD(Socket client_soc, Nettoyeur n, ServeurTD s) {client=client_soc; nettoyeur=n; serveur=s; try{ in =new BufferedReader(new InputStreamReader(client.getInputStream())); out =new PrintStream(client.getOutputStream());} catch (IOException e){ try {client.close();} catch (IOException e1) {}; System.err.println(e.getMessage()); return; } this.start(); }

Javabook Page 282 Lundi, 12. juillet 1999 3:58 15

282

Chapitre 20 Les accs au rseau (java.net)


public void run() { String ligne; ConnexionTD c; try {while(true) {ligne=in.readLine(); // envoyer a tous les clients la ligne synchronized(serveur.connexions) {for (int i=0;i<serveur.connexions.size();i++) {c=(ConnexionTD) serveur.connexions.elementAt(i); c.out.println(ligne);}} if (ligne.endsWith("FIN")) break; }} catch (IOException e){} finally{ try {client.close();} catch (IOException e){}; System.out.println("Fin de connexion..."); synchronized(nettoyeur) {nettoyeur.notify();} } }}

La classe ConnexionTD

Le nettoyeur
Le nettoyeur est un processus dont le constructeur requiert une rfrence au serveur pour laccs la liste des connexions. La mthode run() de ce processus est une boucle sans fin (larrt du serveur entranera larrt du nettoyeur). Cette boucle fait attendre le nettoyeur cinq secondes puis demande laccs exclusif la liste des connexions pour en vrifier lactivit. Une connexion inactive est retire de la liste. Le parcours de cette liste se fait de la fin au dbut car la mthode de retrait de la liste compacte les lments restant dans la liste1. La veille du nettoyeur peut tre interrompue par une notification provenant dune connexion.
import java.io.*; import java.net.*; import java.util.*; class Nettoyeur extends Thread{ protected ServeurTD serveur; protected Nettoyeur(ServeurTD serveur) {this.serveur=serveur; this.start(); }
1. Le faire dans lautre sens impliquerait, en cas de retrait, de ne pas incrmenter lindice de la boucle. Dans les boucles for, cet indice est mis jour automatiquement et une bonne pratique de programmation consiste ne pas le modifier dans le corps de la boucle. Un second intrt de ce parcours lenvers rside dans le temps pass conserver exclusivement une ressource partage : lvaluation de la taille de la liste na lieu quune seule fois pour initialiser lindice, et non chaque itration dans un parcours du dbut la fin. Le paralllisme est donc augment.

Javabook Page 283 Lundi, 12. juillet 1999 3:58 15

Tldiscussion
public synchronized void run() { while(true) {try {this.wait(5000);} catch (InterruptedException e){}; synchronized(serveur.connexions) {for (int i=serveur.connexions.size()-1;i>=0;i--) {ConnexionTD c= (ConnexionTD) serveur.connexions.elementAt(i); if (!c.isAlive()) {serveur.connexions.removeElementAt(i); System.out.println("Fin de connexion : OK"); } }} // for } // while }

283

La Classe Nettoyeur

Lapplication client
Linterface de cette application (application 14, figures 20.7 et 20.8) est une fentre compose de deux champs de texte : un en bas pour la saisie et un en haut pour laffichage des messages. Cette fentre contient galement deux boutons envoi et stop. La classe AppliClient est une sous-classe de la classe Frame. Le constructeur de lapplication client appelle le constructeur de la classe Frame, puis demande la cration dun socket sur la machine sur laquelle fonctionne le serveur. Le processus couteur est cr pour permettre la lecture sur le socket de manire asynchrone avec la saisie des messages de lutilisateur. La mthode actionPerformed() traite les messages de fin de ligne dans la zone de saisie et lappui sur le bouton envoi. Le traitement de ce message consiste crire sur le socket le texte que lutilisateur a tap. Lappui sur stop signale la demande de fin de connexion de la part dun client puis arrte lapplication client.
import java.io.*; import java.net.*; import java.awt.*; import java.awt.event.*; public class AppliClient extends Frame implements ActionListener { public static final int PORT=45678; Socket s; PrintStream canalEcriture; TextField entree; TextArea visu; Button envoi,stop; Panel boutons; String Nom; public AppliClient(String n, String host) {

Javabook Page 284 Lundi, 12. juillet 1999 3:58 15

284

Chapitre 20 Les accs au rseau (java.net)


super("client"+ " "+n); try { Nom=n; s=new Socket(host,PORT); canalEcriture=new PrintStream(s.getOutputStream()); // construction de l'interface graphique entree=new TextField(); visu=new TextArea(); visu.setEditable(false); this.setLayout(new BorderLayout()); this.add("North",visu); this.add("Center",entree); entree.addActionListener(this); boutons=new Panel(); envoi=new Button("envoi"); stop =new Button("stop"); boutons.add(envoi); envoi.addActionListener(this); boutons.add(stop); stop.addActionListener(this); this.add("South",boutons); this.pack(); this.show(); // la connexion est etablie : visu.setText("Connexion : "+ s.getInetAddress()+ " port : "+s.getPort()); // lancement du processus accedant en lecture au socket Ecouteur ecoute=new Ecouteur(s,visu); } catch (IOException e) {visu.setText(e.toString());} } // constructeur AppliClient

public void actionPerformed(ActionEvent e) { if ((e.getSource()==envoi) || (e.getSource()==entree)) { canalEcriture.println(Nom+">"+entree.getText()); entree.setText(""); } if (e.getSource()==stop) { canalEcriture.println(Nom+">FIN"); System.exit(0); } } // actionPerformed public static void main(String[] args) { Frame f= new AppliClient(args[0],args[1]); } //main

Application 14 : Client de la tldiscussion

Le client prend un paramtre sur la ligne de commande, le nom de lutilisateur, afin de prfixer chaque message par son auteur.

Javabook Page 285 Lundi, 12. juillet 1999 3:58 15

Tldiscussion

285

Le processus couteur
Le processus couteur est assez simple. Il attend les messages provenant du socket et les affiche au fur et mesure dans le champ de texte adquat de la fentre graphique.
import java.io.*; import java.net.*; import java.awt.*; class Ecouteur extends Thread{ BufferedReader canalLecture; TextArea visu; public Ecouteur(Socket s,TextArea out) throws IOException { canalLecture= new BufferedReader (new InputStreamReader(s.getInputStream())); visu=out; this.start(); } public void run() { String ligne; try {while (true) {ligne=canalLecture.readLine(); if (ligne==null) break; visu.append("\n"+ligne); }} catch (IOException e) {visu.setText(e.toString());} finally {visu.setText("connexion interrompue par le serveur");} }

Le processus Ecouteur

Les copies dcrans ci-dessous montrent une tldiscussion entre Gilles et Andr. Les deux clients fonctionnent respectivement sur Windows 95 et sur Sun.

Figure 20.7 Tldiscussion : client sous Sun/solaris

Javabook Page 286 Lundi, 12. juillet 1999 3:58 15

286

Chapitre 20 Les accs au rseau (java.net)

Figure 20.8 Tldiscussion : client sous Windows 95

20.8 Programmation distribue sur Internet


Ces exemples vous ont montr laccs des ressources Internet et des applications client-serveur distribues sur ce mme rseau. Un premier type daccs illustr dans ces exemples ncessitait un gestionnaire de contenu charg de donner du sens au nud dinformation. Un autre type daccs consistait interprter soi-mme le contenu comme, par exemple, le programme de vrification des URL contenus dans un nud dinformation. Les exemples client-serveur nous ont montr la facilit dcriture de clients qui ne sont pas des butineurs, et de serveurs qui ne sont pas seulement des serveurs de documents. La relation client-serveur fournit la base de la programmation distribue sur Internet. La distribution de services sur Internet passe par la distribution des clients. Les nuds dinformation dynamiques (cest--dire un nud dinformation statique associ une applet) favorisent la diffusion dapplets clients. Les applets sont les meilleures candidates pour cet objectif car leur fonctionnement ne peut perturber les ressources du systme sur lequel elles sexcutent. Lun des intrts majeurs de Java est la facilit de programmation dapplications clientserveur qui ne se rsument pas butiner des URL ici ou l. Nous aborderons, dans dautres chapitres, la distribution dobjets et linvocation de mthodes distance. Dici l, vous dimaginer de nouveaux services...

Javabook Page 287 Lundi, 12. juillet 1999 3:58 15

Partie IV

La mthode : dvelopper en Java


Je mtais fourr dans la tte quenvol et locomotion ne pouvaient tre raliss que dans un processus en deux temps. Dabord monter aussi haut que je le pouvais, ensuite me propulser de lavant. Je mtais entran faire la premire de ces choses, et je croyais pouvoir accomplir la seconde partir de la premire. Mais en ralit, la seconde annulait ce qui la prcdait. Paul Auster, Mr Vertigo.

21. Conception des classes 22. Mcanismes pour la rutilisation 23. Structures de donnes 24. Composition du logiciel 25. Processus et concurrence 26. Intgration des applets 27. Scurit en Java 28. Java et les bases de donnes 29. Fabriquer des objets rpartis avec RMI 30. Fabriquer des objets rpartis avec CORBA 31. Les autres API de Java

Javabook Page 288 Lundi, 12. juillet 1999 3:58 15

Javabook Page 289 Lundi, 12. juillet 1999 3:58 15

Chapitre 21

Conception des classes


Dans les chapitres prcdents, nous avons abondamment utilis les classes de lAPI Java, et cr des classes pour raliser des applets et de petites applications. Lobjectif de cette partie est de prsenter des lments mthodologiques de programmation oriente objet pour permettre le dveloppement de projets plus ambitieux. Nous passerons en revue les principaux concepts de lapproche objet tels quils apparaissent dans Java et nous montrerons comment les employer pour dvelopper un logiciel de qualit. Le prsent chapitre revient en dtail sur la notion de classe et ses diffrents aspects, nous tudierons ensuite la notion de rutilisation, puis larchitecture du logiciel.

21.1 Les origines


Pour bien comprendre quoi sert une classe dans un systme logiciel, il nous semble important de remonter des notions qui sont lorigine de l invention des classes : la modularit, lencapsulation et les types abstraits.

Modularit et encapsulation
La modularit est une technique de dveloppement, que lon retrouve du reste dans la plupart des disciplines dingnierie, qui consiste voir un systme complexe comme un assemblage de parties plus simples, appeles modules. Pour que la technique soit efficace, il est primordial que la construction de chaque module soit aussi indpendante que possible de celle des autres modules. Lencapsulation est une technique pour raliser cette indpendance entre modules ; elle est base sur une nette sparation entre les parties publique et prive de chaque module. La partie publique dun module, souvent appele inter-

Javabook Page 290 Lundi, 12. juillet 1999 3:58 15

290

Chapitre 21 Conception des classes

face, dfinit les services que ce module offre aux autres. La partie prive, appele implantation, dfinit la faon dont le module ralise les services offerts; cette partie contient des structures de donnes et les instructions excutables ncessaires. Lorsquun module veut obtenir un service dun autre module, il sadresse toujours et uniquement linterface publique de ce dernier, il na aucun accs sa partie prive. La figure 21.1 illustre ce principe.
A
public demande du service B

priv

rponse

structures de donnes

instructions

C
Figure 21.1 Demande dun service un module

Lintrt de cette sparation public-priv rside dans le fait que la partie prive peut tre ralise et modifie sans que les clients du module ne soient perturbs, puisquils voient toujours la mme interface. Un logiciel modulaire avec encapsulation sera donc plus facile dvelopper et surtout maintenir quun logiciel monolithique dont toutes les parties sont interdpendantes.

Les types abstraits


Le principe de base des types abstraits est de dcrire un type de donnes uniquement par les oprations quon peut lui appliquer, sans soccuper de lensemble de ses valeurs. Ainsi, lorsquun programmeur utilise des nombres entiers dans un programme, il ne sintresse gnralement quaux oprations possibles sur les entiers et peut compltement ignorer la manire dont ils sont reprsents sous forme de chanes de bits. La mme observation peut sappliquer pour nimporte quel type de donnes. Peu importe quun rectangle soit reprsent par les coordonnes du coin suprieur gauche et du coin infrieur droit ou encore par les coordonnes du coin suprieur droit, la largeur et la hauteur; ce qui compte, cest de pouvoir dfinir un rectangle, le translater, lagrandir, tester sil contient un point donn, etc.

Javabook Page 291 Lundi, 12. juillet 1999 3:58 15

Les origines

291

Il sensuit une manire de dfinir les types de donnes en deux phases : premirement, on sintresse aux oprations et leur signification, cest la partie abstraite de la dfinition; deuximement, on choisit une reprsentation pour ce type de donnes et on crit le corps (les instructions) des oprations, cest la concrtisation (aussi appele rification). Une mme dfinition abstraite peut donner lieu plusieurs ralisations concrtes suivant les moyens disposition, les contraintes, les normes de programmation, etc. Si lon reprend lexemple prcdent du type rectangle, on commencera par dfinir un ensemble doprations telles que : rect : (entier, entier, entier, entier) ! rectangle; translation : (rectangle, entier, entier) ! rectangle; agrandissement : (rectangle, entier, entier) ! rectangle; qui servent produire des rectangles. Lopration rect(X, Y, L, H) fournit le rectangle dont le coin suprieur gauche est (X, Y), la largeur L et la hauteur H. Lopration translation(R, DX, DY) fournit le rectangle obtenu par translation du rectangle R dune distance horizontale DX et verticale DY. Lopration agrandissement(R, DL, DH) fournit le rectangle situ au mme endroit que R mais dont la largeur et la hauteur sont celles de R agrandies de DL et DH respectivement.

R1 = rect(X,Y,L,H) R3 = agrandissement(R,DL,DH) R2 = translation(R1,DX,DY)

Figure 21.2 Mthodes agissant sur des rectangles

Les oprations suivantes sont des oprations daccs qui fournissent des proprits dune valeur de type rectangle. gauche : (rectangle) ! entier; haut : (rectangle) ! entier; bas : (rectangle) ! entier; droite : (rectangle) ! entier; largeur : (rectangle) ! entier; hauteur : (rectangle) ! entier; Pour complter la description dun type abstrait, il faut expliquer la signification des oprations. On peut bien sr le faire laide dun texte en fran ais mais si

Javabook Page 292 Lundi, 12. juillet 1999 3:58 15

292

Chapitre 21 Conception des classes

lon veut une explication absolument non ambigu, il est prfrable de recourir un ensemble dquivalences telles que : 1. 2. 3. 4. 5. 6. Gauche(rect(X, Y, L, H)) " X. Largeur(rect(X, Y, L, H)) "L. Gauche(translation(R, DX, DY)) " gauche(R) + DX. Gauche(agrandissement(R, DL, DH)) " gauche(R). Largeur(agrandissement(R, DL, DH)) " largeur(R) + DL. Droite(R) " gauche(R) + largeur(R).

Ces quivalences dfinissent formellement la signification des oprations, de sorte quun utilisateur du type abstrait peut comprendre prcisment ce qui va se passer lorsquil utilisera telle ou telle opration. Par exemple, lquivalence 5 exprime le fait que le rectangle obtenu par agrandissement est plus large de DL que le rectangle original. La dfinition complte dun type abstrait peut savrer assez fastidieuse, car il faut videmment noncer toutes les proprits des oprations. Le lecteur intress trouvera de nombreux ouvrages de gnie logiciel traitant de ce sujet, comme par exemple [12] ou [1].

21.2 Objets et classes


Les langages objets ont intgr les concepts de modularit, dencapsulation et de type abstrait dans leurs notions dobjet et de classe.

Un objet est un module


Chaque objet est un module qui contient des donnes entoures par des oprations appeles mthodes qui permettent daccder ces donnes et de les modifier. Laccs aux donnes dun objet ne peut se faire quau travers des mthodes, comme le veut le principe dencapsulation. Les noms et paramtres des mthodes forment la partie publique de lobjet alors que les structures de donnes internes et le corps des mthodes en forment la partie prive. Exemple : un objet reprsentant un rectangle La structure de donnes interne est forme de quatre variables entires reprsentant les coordonnes du coin suprieur gauche (haut, gauche), la largeur et la hauteur du rectangle. Linterface publique de lobjet est forme des mthodes qui lui sont applicables (deplacer(), positionner(), ).

Une classe est un schma et un gnrateur dobjets


Une classe est un schma dobjet qui en dcrit la partie prive et la partie publique. Par instanciation, on peut fabriquer des objets obissant tous ce schma. En Java, ce sont lopration new et les constructeurs qui ralisent linstanciation.

Javabook Page 293 Lundi, 12. juillet 1999 3:58 15

Objets et classes
class Rectangle { /* schma de la partie prive */ private int gauche, haut, largeur, hauteur; /* schma de la partie publique */ public void positioner(int posX, int posY) { haut = posX; gauche = posY; } public void deplacer(int dv,int dh) { haut += dv; gauche += dh; } // etc. } ... /* instanciation */ Rectangle r = new Rectangle();

293

deplacer() positionner()

haut largeur

105 gauche 10 12 33

hauteur

Figure 21.3 Structure dun objet

Une classe est elle-mme un objet


Une classe nest pas seulement un lment syntaxique utilis pour dfinir en un seul endroit la structure de tous les objets de mme nature, cest galement un objet qui peut possder ses propres variables internes et ses mthodes. En fait, chaque classe est une instance de la classe java.lang.Class. Le modificateur static introduit les variables et mthodes de classe dans une dfinition de classe. Par exemple :
class Rectangle { /* variables et mthodes de classe */ static double echelle // variable communes tous les rectangles public static void defEchelle(int e) { echelle = e; } /* variables et mthodes dinstance */ public double surface() { return hauteur * largeur * echelle; // utilise echelle } ... }

La variable echelle appartient la classe elle-mme, elle est partage par toutes les instances. Dans lexemple ci-dessus, la mthode surface() utilise la variable

Javabook Page 294 Lundi, 12. juillet 1999 3:58 15

294

Chapitre 21 Conception des classes

de classe echelle. Les variables de classe se rapprochent des variables globales qui existent dans les langages procduraux comme Pascal ou C. Pour excuter une mthode de classe, il faut la prfixer du nom de sa classe. Par exemple :
Rectangle.defEchelle(4.25);

En fait, tout se passe comme si defEchelle() tait une mthode dinstance dun objet appel Rectangle.

Une classe spcifie un type abstrait


Lensemble des mthodes de la partie publique dune classe est en fait la spcification dun type abstrait puisquil dtermine toutes les oprations possibles sur les objets de la classe. La dfinition de Rectangle ci-dessus dfinit un type abstrait Rectangle dont la spcification est compose des oprations : positionner : (Rectangle, int, int) ! Rectangle; deplacer : (Rectangle, int, int) ! Rectangle; etc. Cette spcification est bien sr partielle car elle ne contient pas les quations qui permettraient de donner un sens prcis chaque opration. Elle est cependant suffisante pour utiliser correctement ce type dans un programme ( condition quune description prcise des mthodes soit disponible, par exemple sous forme de commentaires). Une dclaration de la forme :
Rectangle r;

qui apparat dans un programme indique que lon peut utiliser les instructions (aprs la cration de lobjet r) :
r.positionner(x, y) r.deplacer(dx, dy) etc.

La ralisation est dcouple de la spcification


Nous avons dj dit quun mme type abstrait, par exemple Rectangle, peut tre reprsent de diffrentes manires. Selon la reprsentation (soit haut-gauche, largeur, hauteur, soit haut-gauche, bas-droite, soit une autre), on obtiendra diffrentes versions de la classe Rectangle. Cependant, chacune dentre elles doit offrir les mthodes prvues par le type abstrait; les parties publiques seront donc toutes les mmes alors que les parties prives prsenteront des variantes. Exemple de deux classes Rectangle (en gras : linterface abstraite commune),
/* variante 1. */

Javabook Page 295 Lundi, 12. juillet 1999 3:58 15

Interfaces
class Rectangle { private int haut, bas, gauche, droite; public void positionner(int x, int y) { int l = droite - gauche; int h = bas - haut; haut = x; gauche = y; bas = haut + h; droite = gauche + l; } public int bas() { return bas; } public defBas(int b) { bas = b; } public int surface() { return (bas-haut)*(droite-gauche); } /* variante 2. */

295

class Rectangle { private int haut, gauche, hauteur, largeur; public void positionner(int x, int y) { haut = x; gauche = y; } public int bas() { return haut + hauteur; } // les coordonnes croissent vers le bas ! public defBas(int b) { hauteur = b - haut; } public int surface() { return (hauteur * largeur); }

21.3 Interfaces
La notion dinterface en Java correspond une spcification de type abstrait sans aucune implantation, cest--dire une spcification de type dcrite uniquement par la liste de ses oprations. Une interface est compose dun ensemble den-ttes de mthodes et ventuellement de constantes. Par exemple :
interface public public public } Vendable { int prix(); int rabais(int quantite); void changerPrix(int prix);

Javabook Page 296 Lundi, 12. juillet 1999 3:58 15

296

Chapitre 21 Conception des classes

La ralisation concrte dune interface est dlgue une classe devant possder (ou hriter) une mthode concrte pour chaque mthode abstraite de linterface. Par exemple :
class Moto implements Vendable { private String marque, modele; private int prix, cylindree, poids, puissance; // mthodes servant impanter Vendable public int prix() { return prix; } public int rabais(int quantite) { if(quantite > 5) return prix/10; else return 0;} public void changerPrix(int prix) { this.prix = prix; } // autres mthodes Moto(String m, int p) {marque = m; prix = p; } void imprime() {System.out.println(marque + " prix: " + prix);} }

La notion dinterface pousse lextrme le dcouplage entre la spcification et limplantation dun type. Une interface dfinit un type de donnes qui peut servir typer des variables ou des paramtres de mthodes. On peut affecter une variable dclare dun type interface I tout objet dune classe qui implante I. Par exemple :
Vendable v; v = new Moto("Honda", 16678);

De mme, partout o un paramtre de type I est attendu, on peut passer un objet dune classe qui implante I.

21.4 Spcification dune classe


Lorsquon utilise une classe, on doit savoir non seulement quelles sont les mthodes appeler et leurs paramtres mais aussi ce que font prcisment ces mthodes. Or, la partie publique dune classe ne constitue pas une spcification suffisante du comportement des objets. On peut bien sr imaginer quune mthode retrait() dune classe CompteEnBanque ne va pas ajouter de largent sur le compte mais plutt en soustraire. Cependant, le seul nom dune mthode est bien insuffisant en tant que description de son fonctionnement. Ainsi, lopration positionner pour un rectangle a-t-elle pour effet de changer la forme du rectangle? Les deux nombres donns en paramtre dfinissent-ils la nouvelle position du coin suprieur gauche, du coin infrieur droit ou du centre?

Description textuelle
Une manire simple de dcrire leffet dune mthode consiste crire un texte en franais. Un tel texte prsente les avantages et inconvnients de la langue

Javabook Page 297 Lundi, 12. juillet 1999 3:58 15

Spcification dune classe

297

naturelle : dun ct, il est facilement lisible par un tre humain et peut sappuyer sur toutes sortes de connaissances implicites; dun autre ct, il peut prsenter des ambiguts telles que deux lecteurs pourront linterprter diffremment. La langue naturelle peut galement savrer trop lourde pour dcrire des faits qui sexpriment trs simplement dans un langage plus formel comme les mathmatiques. Cest pourquoi nous proposons dajouter une description plus formelle de chaque mthode et de chaque classe. Il existe pour cela de nombreux formalismes plus ou moins abstraits et plus ou moins simples manipuler; nous examinerons la technique des pr- et postconditions et des invariants.

Les prconditions
Une mthode travaille partir dun objet (this) et des paramtres qui lui sont fournis. Cependant, certaines valeurs de paramtres ou variables dinstance de lobjet peuvent ne pas avoir de sens pour la mthode. Par exemple, la mthode qui modifie la largeur dun rectangle ne peut rien faire dun paramtre ngatif, de mme une mthode calculant la moyenne des nombres contenus dans une liste na pas de sens pour une liste vide. Les prconditions fixent donc les conditions dans lesquelles une mthode peut sexcuter correctement. Elles dpendent de ltat de lobjet this (tat dfini par ses variables dinstance) et des paramtres. Exemples :
public void defLargeur(int lrg) { // PRE-CONDITION: lrg > 0 ... } public void deplace(int dh, int dv) { // PRE-CONDITION: this.gauche() + dh > 0 // et this.haut() + dv > 0 ... }

La condition ci-dessus garantit quon ne tente pas un dplacement qui amnerait le rectangle hors du systme de coordonnes (qui commence (0,0)). On remarque sur ce dernier cas, que la prcondition est exprime laide des mthodes publiques gauche() et haut() et non des variables prives gauche et haut. Cette expression est donc publique, ce qui signifie quon peut la tester depuis lextrieur de la classe Rectangle, par exemple avant dappeler la mthode.
Rectangle r; ... r = new Rectangle; ... if (r.gauche() + deplH > 0 & r.haut() + deplV > 0) { r.deplace(deplH, deplV); } else ...

Javabook Page 298 Lundi, 12. juillet 1999 3:58 15

298

Chapitre 21 Conception des classes

Alternativement, si la prcondition est teste dans la mthode et dclenche une exception, la mthode appelante saura, si elle capte lexception, que lexpression de prcondition est fausse. Une telle prcondition est indpendante de la reprsentation interne de lobjet, elle est donc compatible avec le principe dencapsulation et fournit une information sur le comportement dune mthode de la classe comprhensible indpendamment des dtails internes de la classe.

Les post-conditions
Si la prcondition garde la porte dentre dune mthode, la postcondition indique ce quest devenu lobjet aprs lexcution de la mthode, sil a t transform ou non, et quel est lventuel rsultat produit. Nous utiliserons deux pseudovariables : resultat qui reprsente le rsultat retourn par la mthode, sil y en a un, et this_post qui reprsente la valeur de lobjet this aprs lexcution de la mthode. Considrons tout dabord le cas dune mthode qui ne modifie pas lobjet mais fournit un rsultat de calcul.
public int surface() { // PRE-CONDITION: aucune // POST-CONDITION: resultat = this.hauteur() * this.largeur() ... }

La postcondition dtermine la valeur qui sera retourne comme rsultat en fonction de ltat de lobjet (ici sa largeur et sa hauteur). Il faut bien voir que la postcondition nest pas l pour dire comment le calcul est fait; le calcul dpend de la reprsentation interne de lobjet. Comme dans le cas des prconditions, on exprime les postconditions laide des paramtres, de lobjet this et des mthodes publiques de manire rendre cette condition lisible de lextrieur de la classe. Lorsque la mthode modifie lobjet, on peut exprimer ce changement soit par son effet sur les variables dinstance de lobjet, soit en disant ce qui se passe lorsquon applique des mthodes daccs sur lobjet transform. La deuxime technique est la meilleure car elle ne met pas en jeu la reprsentation interne de lobjet. Compltons ainsi nos dfinitions des mthodes defLargeur et deplacer de la classe Rectangle.
public void defLargeur(int l) { // PRE-CONDITION: l > 0 // POST-CONDITION: this_post.largeur() = l // (le nouveua rectangle a une largeur l)

Javabook Page 299 Lundi, 12. juillet 1999 3:58 15

Exceptions
... } public void deplace(int dh, int dv) { // PRE-CONDITION: this.gauche() + dh > 0 // et this.haut() + dv > 0 // POST-CONDITION: this.gauche() = this_pre.gauche() + dh // et this.haut() = this_pre.haut() + dv ... }

299

Les invariants
Les invariants sont des expressions logiques qui doivent rester vraies durant toute la vie dun objet. Un invariant ne dcrit pas ce que fait une mthode mais ce quest et doit rester un objet de cette classe. Dans notre classe Rectangle, on pourrait ajouter linvariant :
pour tout Rectangle r: r. hauteur() >= 0 et r.largeur() >= 0

pour prciser quen toute circonstance ni la largeur ni la hauteur dun rectangle ne peuvent devenir ngatives. Dans une classe RectanglePlat destine reprsenter des rectangles dont la largeur est suprieure la hauteur on aura linvariant :
pour tout RectanglePlat c: c.hauteur() <= c.largeur()

Les invariants induisent bien videmment lobligation pour toutes les mthodes de la classe de les maintenir vrai . Par exemple, dans le cas de notre classe RectanglePlat, la mthode defLargeur(int l) devra dune manire ou dune autre garantir que la largeur reste suprieure la hauteur.

21.5 Exceptions
Le mcanisme dexceptions offre un moyen lgant de structurer la gestion des erreurs ou des cas exceptionnels qui empchent le bon droulement des oprations. Dun point de vue purement syntaxique, le mcanisme dexceptions simplifie lcriture du code en remplaant : des cascades de if imbriqus; la transmission dindicateurs de succs ou dchec des mthodes. Dans le premier cas, un fragment de code de la forme :
if (erreur) traiterErreur(); else { ... if (erreur) traiterErreur(); else { ... if (erreur) traiterErreur();

Javabook Page 300 Lundi, 12. juillet 1999 3:58 15

300
else { ... etc. } } }

Chapitre 21 Conception des classes

devient :
try { if (erreur) throw new MonException(); ... if (erreur) throw new MonException(); ... if (erreur) throw new MonException(); ... etc. } catch (MonException me) traiterErreur();

Il ny a plus dimbrication de if et le traitement de lerreur nest spcifi quune seule fois, ce qui garantit quil est uniforme pour toutes les erreurs dun type donn. La propagation des exceptions aux mthodes appelantes remplace les codes de retour que la mthode appelante devrait tester pour sassurer que tout sest bien pass :
if (canal.lire(desBytes) != 0) traiterErreur(); else { ... if canal2.ecrire(desBytes) != 0) traiterErreur(); else { ... suite } }

devient :
try { canal.lire(desBytes); // il ny a plus de code tester ... canal2.ecrire(desBytes); ...} catch (ExceptionCanal ec) traiterErreur();

Malgr ces possibilits attrayantes, il ne faut pas abuser de lutilisation des exceptions. Le traitement dexceptions doit rester limit aux cas exceptionnels. La propagation et la capture des exceptions sont relativement coteuses en temps de calcul. Le try... catch ne doit donc pas servir de nouvelle structure de contrle, les if, switch, while et for tant amplement suffisants pour exprimer

Javabook Page 301 Lundi, 12. juillet 1999 3:58 15

Modliser avec les classes

301

les algorithmes et sexcutant beaucoup plus rapidement. Il ne faut pas non plus en faire un goto dguis. Dautre part, certains types dexceptions ne devraient pas tre capturs car ils reprsentent des erreurs profondes, souvent irrparables. Les capturer reviendrait poursuivre lexcution du programme dans un tat instable qui ne conduirait qu de nouvelles erreurs. La hirarchie des exceptions prdfinies en Java est ainsi subdivise en deux parties : les erreurs qui sont des sous-classes de Error; les exceptions qui sont des sous-classes de Exception.

21.6 Modliser avec les classes


Tout composant logiciel (application, applet, package, etc.) est construit partir de classes qui dterminent tous les types dobjets qui vont tre utiliss par le composant. Ces classes sont soit dfinies par le dveloppeur, soit prexistantes et choisies dans une bibliothque de composants. Lidentification des diffrents types dobjets et donc des classes qui vont intervenir dans la fabrication dun composant logiciel est une tche primordiale de conception qui dtermine larchitecture du logiciel.

Des classes pour les concepts


Une manire daborder le problme du choix ou de la conception des classes consiste considrer la structure de classes comme un modle de la ralit extrieure au programme. Chaque classe reprsente alors une catgorie dobjets concrets ou abstraits (un concept) du domaine dapplication. Dans un programme qui traite de facturation on pourra, par exemple, trouver des classes Commande, Facture, Rappel, Client, Marchandise, etc.; dans un systme de gestion dinterface graphique, comme java.awt, on trouvera des classes Fenetre, Bouton, Panneau, Menu, etc., qui correspondent aux divers lments dinterface utilisateur. Empressons-nous de prciser que tout concept du domaine dapplication ne doit pas forcment donner lieu une classe et que, rciproquement, toute classe ne correspond pas ncessairement un concept du domaine.

Les relations entre classes


Les concepts dun domaine dapplication ne sont en gnral pas isols car il existe toutes sortes de relations entre eux. Par exemple, une facture est adresse un client, elle correspond un ensemble de commandes. Une commande est passe par un client, elle porte sur une marchandise pour une quantit et un prix donns. Si nous considrons toujours quune structure de classe est un modle de la ralit, ce modle doit prendre en compte les relations entre concepts.

Javabook Page 302 Lundi, 12. juillet 1999 3:58 15

302

Chapitre 21 Conception des classes

Il est commode de reprsenter graphiquement les relations entre classes. De nombreux formalismes ont t dvelopps cet effet, du modle Entits-associations des annes 70 au modle unifi UML [http://www.rational.com/uml] qui tend devenir le standard actuel. Dans ce formalisme, on reprsentera les relations entre commandes, clients, marchandises et factures que nous avons nonces plus haut de la manire suivante :
1 facturation * Facture 1 concerne > Client 1 passage-commande * * Commande 1 Marchandise

porte sur >

Figure 21.4 Diagramme des relations entre classes

Les relations sont reprsentes par des lignes tiquetes par un nom. Les symboles 1 et * aux extrmits indiquent les cardinalits uniques ou multiples des relations. Par exemple, la relation passage-commande peut associer un client une ou plusieurs commande(s) mais chaque commande au plus un client. Le symbole > suivant un nom de relation indique simplement un sens de lecture ( une facture concerne une commande et non une commande concerne une facture )

Implantation des relations


La manire la plus directe de raliser une relation entre objets consiste utiliser des variables dinstance. La structure de classe esquisse ci-dessous implante les relations dcrites prcdemment.
class Client { String nom, adresse; ... } class Facture { Client client; // relation "facturation" avec le client Commande[] commandes; // relation "concerne" avec les commandes double montant(); ... } class Commande { Date date; Client client; // relation "passage-commande" Marchandise marchandise; int quantite; double prix; ... }

Javabook Page 303 Lundi, 12. juillet 1999 3:58 15

Modliser avec les classes


class Marchandise { ... }

303

Remarquons toutefois que la reprsentation par variables dinstance est sens unique. Dans notre exemple, on peut atteindre un client depuis une facture, grce la variable client, par contre on ne peut pas trouver partir dun client toutes les factures le concernant. Il faudrait pour cela ajouter une variable Facture [] factures dans la classe Client et sassurer quen tout temps, il y a cohrence entre client et factures. Sur un diagramme, on peut indiquer le ou les sens de parcours autoriss en ajoutant des pointes de flches aux extrmits des lignes figurant une relation. Il est galement possible de reprsenter certaines relations laide de mthodes. Par exemple, la relation facturation de Facture Client peut tre calcule par une mthode, en se basant sur lhypothse que le client facturer est celui qui a pass la premire commande faisant lobjet de la facture.
class Facture { Client client() { return commandes[0].client; } ...

Nous verrons dans le chapitre consacr aux structures de donnes quil existe dautres possibilits de raliser des relations en utilisant les classes collections. Parmi les relations entre concepts, la relation gnrique-spcifique ou est un (une chaise est un meuble, un ordinateur est une machine, etc.) joue un rle particulier que nous tudierons dans le cadre de lhritage entre classes. En rgle gnrale, on vitera de reprsenter cette relation par une variable ou une mthode.

Un exemple complet : le jeu du serpent


Nous prsentons ici un exemple complet dapplet o interviennent plusieurs classes. Il sagit de crer une applet permettant de jouer au jeu du serpent (voir figure 21.5). Lespace de lapplet sera divis en une grille sur laquelle volue le serpent. Cette grille est borde par un cadre. Le serpent se dplace dans les quatre directions (haut, bas, droite, gauche). La direction du dplacement est indique laide du clavier au moyen des flches. Le serpent a initialement la taille dune case. Sur le terrain se trouvent des appts que le joueur doit faire manger au serpent, en passant dessus. Le serpent grandit lorsquil a mang un appt. Il grandit en laissant immobile lextrmit de sa queue. En temps normal, le serpent se dplace de manire continue (en conservant sa longueur). Le but du jeu est de rendre le serpent le plus long possible. Le jeu se termine lorsque le serpent heurte le cadre ou lorsquil se mord lui-mme.

Javabook Page 304 Lundi, 12. juillet 1999 3:58 15

304

Chapitre 21 Conception des classes

Figure 21.5 Le jeu du serpent

Cette solution est base principalement sur quatre classes dobjets : Terrain, PointMobile, Serpent et Appat. Le diagramme ci-dessous dcrit les relations qui nous intressent entre ces classes.
JeuSerpent 1 se_joue_sur 1 Terrain 1 < sur 1 1 Figure 21.6 Structure des classes de lapplet JeuSerpent Serpent 1 position_tte 1 1 < sur * Appat * position 1 1 *

PointMobile

position_corps 1 position_queue

Un terrain est le lieu o se droule le jeu, il est compos dune surface de jeu dont les cases sont arranges en lignes et colonnes. Chaque case du terrain peut contenir rien, une partie du cadre, une partie du serpent ou un appt. Les oprations sur un terrain consistent essentiellement lire ou modifier le contenu dune case, et dessiner le terrain en entier ou juste une case. La classe dfinit un ensemble de constantes qui permettent dcrire du code plus lisible. La position du corps du serpent est reprsente par les cases du terrain qui contiennent lune des constantes DROITE, GAUCHE, BAS ou HAUT. Ces constantes indiquent la direction suivre pour arriver la case suivante du serpent. On peut donc dire que ces cases matrialisent la relation position_corps.
class Terrain { // constantes static final Color

Javabook Page 305 Lundi, 12. juillet 1999 3:58 15

Modliser avec les classes

305

COULEUR_VIDE = Color.lightGray, COULEUR_CADRE = Color.black, COULEUR_APPAT = Color.red, COULEUR_SERPENT = Color.yellow; static final char CADRE=C, VIDE =V, APPAT=A, DROITE=D, GAUCHE=G, HAUT=H, BAS=B; // representation du terrain par une matrice de caracteres private char t[][]; public int largeur,hauteur; public int tailleCase; // taille dune case en pixel private Graphics g; // la feuille de desin de lapplet Terrain(int l, int h, int tc, Graphics appletG){ g = appletG; largeur = l;hauteur = h;tailleCase = tc; t = new char [l+1][h+1]; // initialisation du terrain: cadre au bord et vide a linterieur for (int i = 0; i <= largeur; i++) for (int j = 0; j <= hauteur ; j++) { if ((i==0) | (i==largeur) | (j==0) | (j==hauteur)) t[i][j]= CADRE; else t[i][j]=VIDE; } } public int taille() { return (largeur+hauteur)/2;} public char contenuCase (PointMobile p) {return t[p.x][p.y];} public void modifCase (PointMobile p, char v) {t[p.x][p.y]=v;} public void redessine(){ PointMobile p = new PointMobile(0,0); for (int i = 0; i <= largeur; i++) for (int j = 0; j <= hauteur ; j++){ p.deplacer(i,j); dessineCase(p); } } // Modifie le contenu dune case et la redessine public void majCase(PointMobile p, char v) { modifCase(p, v); dessineCase(p); } // Dessine une case, la couleur indique le contenu public void dessineCase (PointMobile p) { switch (t[p.x][p.y]) { case APPAT: g.setColor(COULEUR_APPAT); break; case CADRE: g.setColor(COULEUR_CADRE); break; case VIDE: g.setColor(COULEUR_VIDE); break; default: g.setColor(COULEUR_SERPENT); }

Javabook Page 306 Lundi, 12. juillet 1999 3:58 15

306

Chapitre 21 Conception des classes


g.fillRect( p.x*tailleCase, p.y*tailleCase, tailleCase , tailleCase); }

Un pointMobile reprsente une position sur le terrain, il peut se dplacer dans les quatre directions droite, gauche, haut, bas.
class PointMobile { public int x, y; PointMobile(int initx, int inity){ x=initx;y=inity; } public void deplacer(int cx, int cy){ x=cx;y=cy; } public void avance(char direction){ switch (direction) { case Terrain.DROITE: x++;break; case Terrain.GAUCHE: x--;break; case Terrain.BAS: y++;break; case Terrain.HAUT: y--;break; } } }

Un serpent volue dans un terrain, on peut dfinir la direction dans laquelle le serpent doit avancer (defDirection) et faire avancer le serpent (avance). Le serpent fournit aussi un message qui indique son tat. La reprsentation interne du serpent est compose des deux variables de type PointMobile : pTete et pQueue, qui implantent les relations position_tte et position_queue du diagramme de classes. La variable terrain implante la relation sur entre Serpent et Terrain.
class Serpent { String PointMobile PointMobile int Terrain char char int msg; pTete = new PointMobile(3,3); // position tete pQueue = new PointMobile(3,3); // position queue longueur = 1; terrain; directionTete = Terrain.BAS; directionQueue; grandir = 0;

Serpent (Terrain t){ terrain=t; terrain.majCase(pTete,directionTete); } // Avance la tete du serpent dans la direction directionTete

Javabook Page 307 Lundi, 12. juillet 1999 3:58 15

Modliser avec les classes


public boolean avance(){ boolean fini=false; terrain.modifCase(pTete,directionTete); pTete.avance(directionTete); switch (terrain.contenuCase(pTete)) { case Terrain.CADRE: msg = " Boum Cadre!"; fini=true; break; case Terrain.HAUT: case Terrain.BAS: case Terrain.DROITE: case Terrain.GAUCHE: msg = " Queue mordue!"; fini=true; break; case Terrain.APPAT: grandir+=terrain.taille(); } terrain.majCase(pTete,directionTete); // Avance la queue du serpent si necessaire if (grandir==0) {// la queue doit avancer directionQueue = terrain.contenuCase(pQueue); terrain.majCase(pQueue,Terrain.VIDE); pQueue.avance(directionQueue); } else { // la queue doit rester fixe grandir--; longueur++; } return fini; } public void defDirection(char d){ directionTete=d; } }

307

Un appt occupe une case dun terrain. Un appt disparat au bout dun laps de temps pour rapparatre ailleurs. La variable terrain implante la relation sur entre Serpent et Terrain.
class Appat{ private PointMobile position = new PointMobile(0,0); private int vieAppat = 0; private Terrain terrain; Appat (Terrain t){ terrain = t; } public void vivre(){ if (vieAppat > 0) vieAppat--; if (vieAppat==0) { if (terrain.contenuCase(position)==Terrain.APPAT) // effacement dun appat non consomme terrain.majCase(position,Terrain.VIDE); // lappat mort reapparait sur une autre case vide do {

Javabook Page 308 Lundi, 12. juillet 1999 3:58 15

308

Chapitre 21 Conception des classes


position.x= (int)Math.floor(Math.random()*(terrain.largeur)); position.y= (int)Math.floor(Math.random()*(terrain.hauteur)); } while (terrain.contenuCase(position) != Terrain.VIDE); vieAppat=terrain.taille()*4; terrain.majCase(position, Terrain.APPAT); } }

Un jeu est compos dun terrain, dun serpent, de deux appts et dun processus danimation (runner) qui met jour rgulirement la position du serpent et des appts ainsi que le score. La variable terrain implante la relation se_joue_sur entre JeuSerpent et Terrain. Quant aux variables s, a1 et a2, elles permettent daccder directement au serpent et aux appts qui sont sur le terrain de jeu. Cest lapplet qui par son processus runner anime le jeu. La mthode run() met jour le serpent et les appts puis sendort un moment et recommence.
public class JeuSerpent extends java.applet.Applet implements Runnable, KeyListener, MouseListener{ Thread runner; Terrain t; Serpent s; Appat a1,a2; int tailleCase = 10; // taille en pixel dune case int vitesse = 50;// nb. de millisecondes entre chaque mouvement du serpent int hauteur = 100,largeur = 200; public void init() { String parametre; this.addKeyListener(this); this.addMouseListener(this); // lecture et initialisation parametres parametre = getParameter("vitesse"); if (parametre != null) vitesse = 1000 - Integer.parseInt(parametre); parametre = getParameter("hauteur"); if (parametre != null) hauteur = Integer.parseInt(parametre); parametre = getParameter("largeur"); if (parametre != null) largeur = Integer.parseInt(parametre); parametre = getParameter("grain"); if (parametre != null) tailleCase =

Javabook Page 309 Lundi, 12. juillet 1999 3:58 15

Modliser avec les classes


Integer.parseInt(parametre); resize(largeur, hauteur);

309

t = new Terrain((int)(this.getSize().width / tailleCase )-1, (int)(this.getSize(). height / tailleCase)-1, tailleCase,this.getGraphics()); setBackground(Terrain.COULEUR_VIDE); s = new Serpent (t); a1 = new Appat (t); a2 = new Appat (t); } public void start() { if (runner == null); { runner = new Thread(this); runner.start(); } } public void stop() { if (runner != null); { runner.stop(); runner = null; } } public void run() { int scoreMax = (t.largeur-1)*(t.hauteur-1); while (true) { if (s.avance()) { this.showStatus(s.msg+" Score="+s.longueur+ " maximum="+scoreMax); stop(); } a1.vivre(); a2.vivre(); try { Thread.sleep(vitesse);} catch (InterruptedException e) { } showStatus("Score="+s.longueur+" maximum="+scoreMax); } } public void paint(Graphics g) { t.redessine(); } /// implantation de KeyListener /// public void keyPressed(KeyEvent e) { int key = e.getKeyCode(); switch (key) { case KeyEvent.VK_DOWN: s.defDirection(Terrain.BAS); break; case KeyEvent.VK_UP:

Javabook Page 310 Lundi, 12. juillet 1999 3:58 15

310

Chapitre 21 Conception des classes


s.defDirection(Terrain.HAUT); break; case KeyEvent.VK_LEFT: s.defDirection(Terrain.GAUCHE); break; case KeyEvent.VK_RIGHT: s.defDirection(Terrain.DROITE); break; } } public void keyTyped(KeyEvent e) {} public void keyReleased(KeyEvent e) {} /// implantation de MouseListener /// public void mouseClicked(MouseEvent e) { int xm = e.getX(); int ym = e.getY();

if (Math.abs(xm - s.pTete.x*tailleCase) > Math.abs(ym s.pTete.y*tailleCase)) { // la distance horizontale (x) entre la tete et le click est // superieure a la distance verticale (y) if (xm>s.pTete.x*tailleCase) s.defDirection(Terrain.DROITE); else s.defDirection(Terrain.GAUCHE); } else { // la distance en y est plus grande if (ym>s.pTete.y*tailleCase) s.defDirection(Terrain.BAS); else s.defDirection(Terrain.HAUT); } } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public void mousePressed(MouseEvent e){ } public void mouseReleased(MouseEvent e){ } }

Applet 55 : Le jeu du serpent

Le choix des classes retenu pour cette applet nest bien entendu pas le seul possible; il correspond un choix de concepts du domaine (le terrain, les points, le serpent, les appts). Nous aurions pu en faire un autre o apparatraient les classes Bord, Trajectoire, Score, etc. Nanmoins, le fait que notre logiciel soit structur en classes tend amliorer sa maintenabilit et son volutivit. Ainsi, vous devriez tre capable de crer de nouvelles versions de lapplet qui rpondent de nouvelles spcifications telles que : le serpent change de couleur chaque fois quil mange un appt; par endroits, le serpent passe au-dessus du sol, ce qui lautorise se croiser lui-mme;

Javabook Page 311 Lundi, 12. juillet 1999 3:58 15

Modliser avec les classes

311

la surface de jeu est une sphre . Si le serpent sort gauche, il revient par la droite (il ny a plus de bords); les appts se dplacent et cherchent fuir le serpent; il y a deux serpents symtriques sur la surface de jeu! etc.

Javabook Page 312 Lundi, 12. juillet 1999 3:58 15

Javabook Page 313 Lundi, 12. juillet 1999 3:58 15

Chapitre 22

Mcanismes pour la rutilisation


Sil est bon de savoir dfinir de nouvelles classes, le dveloppement orient objet est galement bas sur la rutilisation de classes existantes. Dans la partie III, nous avons abondamment utilis les classes de lenvironnement Java, ce qui nous a vit de rcrire un gestionnaire dinterfaces, un gestionnaire dentres/sorties, un gestionnaire de communications, etc. Dans ce chapitre, nous commencerons par tudier en dtail le mcanisme dhritage qui permet de driver de nouvelles classes partir de classes existantes. Nous nous intresserons galement aux notions de polymorphisme et de gnricit qui sont dun grand intrt pour construire des composants rutilisables.

22.1 Hritage et sous-classes


Les langages objets possdent pratiquement tous un mcanisme dhritage servant driver une sous-classe partir dune ou plusieurs classes existantes. La sous-classe : hrite de toutes les caractristiques de son ou ses anctre(s) ; peut avoir des caractristiques propres; peut redfinir des caractristiques hrites. Si la notion dhritage est en elle-mme fort simple, elle est galement trs puissante et possde plusieurs usages fort diffrents, nous y reviendrons plus loin. Lhritage permet de rutiliser une classe existante (en particulier le code dj crit pour les mthodes) et de ltendre la fois structurellement et comporte-

Javabook Page 314 Lundi, 12. juillet 1999 3:58 15

314

Chapitre 22 Mcanismes pour la rutilisation

mentalement. On dispose de ce fait dune technique de rutilisation trs souple. Passons tout dabord en revue les principales caractristiques de lhritage en Java.

Hritage et redfinition en Java


La dfinition dune sous-classe en Java se fait par extension dune classe existante. Une sous-classe hrite des variables (la structure) et des mthodes (le comportement) de sa super-classe. La structure de la sous-classe est donc compose de ses propres variables et de celles provenant de sa super-classe, de mme pour les mthodes. Par exemple, si les classes Point et PointTopographique sont dfinies comme :
class Point { int x, y; Point(int px, int py) {x = px; y = py}; public double distanceOrigine() {...} public double distance(Point pt) {...} public void deplacer(int dx, int dy) {...} } class PointTopographique extends Point { int alt; PointTopographique(int px, int py, int a) {super(px, py); alt = a;} public int altitude() {...} public void ajusterAltitude(int a) {...} }

un objet de la classe PointTopographique possdera trois variables dinstance x, y et alt, et on pourra lui appliquer les mthodes : distanceOrigine, distance et deplacer (mthodes hrites); altitude, ajusterAltitude (mthodes propres).

Redfinition et liaison dynamique


Une mthode hrite peut galement tre redfinie dans la sous-classe. Il suffit pour cela de la rcrire en conservant la mme signature (mme nom et mmes paramtres). Par exemple, la classe PointTopographique peut redfinir la mthode distanceOrigine de manire ce que la distance ne soit plus la distance horizontale (calcule partir des coordonnes x, y), mais une distance dans lespace trois dimensions tenant compte de laltitude du point. La redfinition atteint toute sa puissance lorsquelle est combine avec la liaison dynamique. Rappelons tout dabord quune variable ou un paramtre dclar de classe C dsigne toujours un objet de la classe ou de lune des sous-classes de C. Le fragment de code ci-dessous est donc correct :

Javabook Page 315 Lundi, 12. juillet 1999 3:58 15

Hritage et sous-classes
Point p = new Point(3, 5); PointTopographique q = new PointTopographique(6, 4, 12); Point r = q; // r fait rfrence un PointTopographique

315

Le mcanisme de liaison dynamique fait que lorsque linstruction :


r.distanceOrigine()

sera excute, le systme dexcution choisira la bonne mthode distanceOrigine(), en fonction de la classe de lobjet dsign par r, indpendamment du type dclar de r. En loccurrence, ce sera la mthode distanceOrigine() de la classe PointTopographique qui sera choisie. La dclaration de r comme Point et le fait quon ne puisse affecter r que des objets de sous-classes de Point garantit que lobjet dsign par r possde forcment une mthode distanceOrigine, et quil ny aura pas derreur dexcution du genre cette mthode nexiste pas pour cet objet .

Redfinition et rutilisation de mthodes


De mme quune classe peut tendre sa super-classe, une mthode peut tendre le comportement dune mthode hrite plutt que de la redfinir compltement. La mthode m() dfinie dans une classe peut invoquer la mthode m() de sa super-classe (ou toute autre mthode redfinie de la super-classe) en employant la notation super.m(). Par exemple, si la classe Point possde une mthode dessiner(Graphics g), sa sous-classe PointTopographique peut tendre cette mthode en dfinissant :
void dessiner(Graphics g) { super.dessiner(g); // rutilisation g.drawString(...); // extension: affiche laltitude ct du point }

Redfinition et surcharge
Contrairement dautres langages, en Java, la redfinition dune mthode doit avoir strictement les mmes paramtres que loriginale, sinon il ny a pas redfinition mais surcharge. Si, dans la classe PointTopographique on dfinit une mthode :
public double distance(PointTopographique p) {...}

on ne redfinit pas la mthode distance() hrite de Point mais on la surcharge, cest--dire que notre classe possde dsormais deux mthodes distance :
public double distance(Point pt) {...} // hrite public double distance(PointTopographique p) {...} // nouvelle

lune sappliquant si le paramtre effectif p est un Point et lautre si le paramtre effectif est un PointTopographique.

Javabook Page 316 Lundi, 12. juillet 1999 3:58 15

316

Chapitre 22 Mcanismes pour la rutilisation

La rgle consiste choisir la mthode la plus spcifique, cest--dire celle dont les paramtres sont le plus bas dans la hirarchie des classes.
Point p1, p2; PointTopographique pt1, pt2; d=p1.distance(p2); // excute distance de Point car p1 est un Point d=p1.distance(pt1); // idem, un paramtre dune sous-classe est admis d=pt1.distance(p1); // excute la mthode distance(Point pt) hrite // car p1 est un Point d=pt1.distance(pt2);// excute distance(PointTopographique p) car // pt1 est un PointTopographique (liaison dynamique) // et pt2 est un PointTopographique

Cette rgle nexclut pas les ambiguts. Considrons deux mthodes m(Point p, PointTopographique pt) et m(PointTopographique pt, Point p) et p1, p2 et p3 qui sont PointTopographique. Linstruction p1.m(p2, p3) est alors ambigu car les deux mthodes sont applicables mais aucune nest plus spcifique que lautre. En Java, ces ambiguts provoquent une erreur la compilation.

Classes abstraites
Les classes abstraites sont des classes dont certaines mthodes, dites abstraites, sont dclares (nom et paramtres) mais ne possdent pas de corps dinstructions. Les diffrents types de classe et de mthode sont les suivants : une mthode est concrte si elle comporte un corps dinstructions (ventuellement vide {}); une mthode est abstraite si elle ne possde pas de corps dinstruction. Une telle mthode doit tre ncessairement implante dans une sousclasse dsire concrte; une classe est abstraite si elle dfinit une ou plusieurs signatures de mthodes abstraites; une classe est implicitement abstraite si elle ne dfinit aucune signature de mthode abstraite et si elle hrite de mthodes abstraites de ses super-classes directes ou non; une classe est concrte si toutes ces mthodes hrites ou non sont concrtes. Seules les classes concrtes sont instanciables. Le modificateur abstract doit prfixer la dfinition des classes et mthodes abstraites. Les classes abstraites ne sont pas instanciables, elles peuvent cependant servir typer des variables (ou des paramtres). Une telle variable fera toujours rfrence un objet dune sous-classe concrte.

22.2 Utilisations de lhritage


Dans lun de ses articles [7], B. Meyer, concepteur du langage orient objet

Javabook Page 317 Lundi, 12. juillet 1999 3:58 15

Utilisations de lhritage

317

Eiffel, distingue douze manires rellement diffrentes dutiliser lhritage en programmation oriente objet. Nous ne les expliciterons pas toutes mais mettrons en vidence quelques points qui nous semblent importants. Nous distinguerons essentiellement deux types dutilisation de lhritage : lhritage dimplantation et lhritage de modlisation.

Hritage dimplantation
Lintrt de lhritage tient videmment lconomie dcriture de code. On ne rinvente pas ce qui existe et qui nous satisfait dj partiellement. De plus, on peut complter ce qui est hrit, voire le redfinir, de manire raliser le comportement voulu. Lextension est donc une technique de rutilisation relativement souple qui se distingue du tout ou rien . Suppression du traitement des cas Du point de vue de larchitecture du logiciel, lhritage combin la liaison dynamique peuvent nettement simplifier lcriture des mthodes en vitant les traitements de cas particuliers. Considrons une classe Piece qui reprsente des pices fabriques par une usine et supposons que ces pices peuvent tre soit simples, soit composes dautres pices. Si lon ne dfinit quune seule classe pour reprsenter toutes les pices, on obtient une dfinition de la forme :
class Piece { String nom; boolean estComposee; // la pice est-elle compose ? int poids; int nbComposantes; Piece [] composantes; ... int poidsTotal() { if (estComposee) { int pt = 0; for (int i = 0; i < nbComposantes; i++) pt += composantes[i].poidsTotal(); return pt; } else return poids; } ...

Cette classe prsente deux problmes : premirement, certaines variables dinstance sont utilises seulement si la pice est simple (poids) et dautres seulement si elle est compose (nbComposantes et composantes); deuximement, la mthode poidsTotal doit tester le genre de la pice pour calculer son poids. Il en est de mme pour toutes les mthodes qui doivent se comporter diffremment suivant le genre de pice. Sil y avait encore dautres types de pices, on verrait prolifrer les instructions switch dans le corps des mthodes. Pour obtenir du code plus simple, et donc moins sujet erreur, introduisons une petite hirarchie de classes : la classe Piece contient tout ce qui est commun

Javabook Page 318 Lundi, 12. juillet 1999 3:58 15

318

Chapitre 22 Mcanismes pour la rutilisation

tous les genres de pice. Chaque sous-classe dfinit la structure et les traitements particuliers un type de pice. Piece est abstraite car les pices sont forcment soit simples soit composes, donc il ny a pas dinstance de Piece.
abstract class Piece { String nom; abstract int poidsTotal(); } class PieceSimple extends Piece { int poids; int poidsTotal() {return poids} } class PieceComposee extends Piece { int nbComposantes; Piece [] composantes; int poidsTotal() { int pt = 0; for (int i = 0; i < nbComposantes; i++) pt += composantes[i].poidsTotal(); return pt; } }

Nous obtenons un code beaucoup plus clair, qui ne comporte plus ni variables inutilises ni tests du genre de pice dans les mthodes. En fait, cest le mcanisme de liaison dynamique qui fait le travail de slection notre place. Une instruction :
p.poidsTotal()

appellera soit la mthode poidsTotal() de PieceSimple soit celle de PieceComposee, en fonction de la classe de lobjet dsign par p. Factorisation Lexemple ci-dessus illustre galement le processus de factorisation des proprits communes plusieurs classes. La variable nom existe pour toute pice, quelle soit simple ou compose, cest pourquoi elle est dfinie dans Piece. On peut galement factoriser des mthodes ou des parties de mthodes. Par exemple, la mthode affiche de Piece :
void affiche() { System.out.println("nom:" + nom + " poids: " + this.poidsTotal()); void affiche() { System.out.println("Pice simple "); super.affiche() // utilise la partie commune }

et la mthode affiche de PieceSimple :

Lintrt de la factorisation est de dfinir les parties communes plusieurs classes en un seul endroit. Ceci garantit automatiquement la cohrence des caract-

Javabook Page 319 Lundi, 12. juillet 1999 3:58 15

Utilisations de lhritage

319

ristiques communes car il ny a pas vrifier quelles sont bien dfinies de la mme manire pour tous les types de pices.

Hritage de modlisation
tre ou avoir? Si nous reprenons loptique selon laquelle les classes forment un modle du domaine dapplication, il est alors intressant de considrer la relation entre une sous-classe et une classe comme un lien est un entre des concepts du domaine. Par exemple, un technicien est un employ dune organisation, autrement dit, lensemble des techniciens est inclus dans lensemble des employs. Ainsi la classe Technicien devrait tre une sous-classe de Employe. Par contre, un employ fait partie dune organisation mais nest pas une organisation, on peut aussi dire quune organisation a des employs. Ds lors Employe ne devrait pas tre une sous-classe de Organisation et la relation entre ces classes (voir figure 22.1) correspond celle que nous avons vue au point 21.6.
Employe fait partie de Organisation

est un (sous-classe) Technicien Figure 22.1 Deux natures de liens entre classes

Cette vision de lhritage clarifie larchitecture du logiciel, car la hirarchie des classes correspond assez naturellement celle des concepts du domaine. Du reste, dans certaines disciplines scientifiques comme la botanique ou la zoologie, il existe dj des hirarchies compltes de classification des objets (appeles taxonomies). Modliser ou implanter? Il arrive parfois que la vision taxonomique soppose lhritage dimplantation qui, comme nous lavons vu, a pour objectif de rutiliser un maximum de code dj crit. Prenons lexemple des deux classes Carre et Rectangle. Si lon ne pense quen termes dimplantation, on dfinira tout dabord Carre avec trois variables : x, y (coordonnes du coin suprieur gauche) et cote (longueur des cts). Puis on dira que Rectangle hrite de Carre et on ajoutera une variable coteHorizontal pour reprsenter la longueur du ct horizontal alors que cote servira pour la longueur du ct vertical.
class Rectangle extends Carre { int coteHorizontal; ... }

Javabook Page 320 Lundi, 12. juillet 1999 3:58 15

320

Chapitre 22 Mcanismes pour la rutilisation

La hirarchie ainsi cre est exactement loppos de ce que nous connaissons en gomtrie o un carr est en fait un rectangle particulier dont les deux cts sont de mme longueur. Une solution plus proche du domaine de la gomtrie consisterait dfinir Carre comme une sous-classe de Rectangle. Dans ce cas, la sous-classe najoutera aucune proprit celles hrites mais dfinira la contrainte hauteur = largeur. Ngocier Il est trop strict dimposer le principe de lhritage bas sur le lien est un , car il existe bien des cas o ce lien nest pas vident. Dans notre exemple du point 22.1, la classe PointTopographique est une sous-classe de Point. Or, dun point de vue gomtrique, on ne peut pas dire que lensemble des points topographiques tel que nous lavons dfini (deux coordonnes plus une altitude) est un sous-ensemble de lensemble des points du plan (deux coordonnes). Malgr cela, on peut se dire quun point topographique est bien une sorte de point. En rsum, il est prfrable de rester le plus proche possible dune hirarchie correspondant au lien est un sans en faire un dogme absolu.

Hritage multiple
Java ne permet pas lhritage multiple dans la hirarchie des classes, par contre une classe peut la fois hriter dune autre et implanter une ou plusieurs interfaces. Cette situation correspond un cas frquent dutilisation de lhritage multiple dans les langages qui lautorisent. Une classe C hrite de A et de B mais nutilise que limplantation des mthodes de A et redfinit celles provenant de B. B nest l que pour apporter son interface. Par exemple, une classe PileParTableau qui hrite de Pile et de Tableau, utilisera limplantation de Tableau pour grer sa structure de donnes internes, et linterface de Pile dont elle redfinira les mthodes empiler, depiler, etc. Ce genre dhritage asymtrique correspond en Java une classe C qui hrite de A et implante linterface B. La situation que Java ne couvre pas est celle o limplantation des deux superclasses A et B serait rellement utilise.

22.3 Utilisation des classes abstraites


Comme leur nom lindique, ces classes reprsentent des abstractions, donc des concepts plus gnraux que les classes concrtes. On les utilisera principalement pour former le sommet dune hirarchie de classes qui reprsentent diffrentes variantes du concept le plus gnral. Dans notre exemple des pices du point 22.2, la classe abstraite Piece possde deux sous-classes : PieceSimple et PieceComposee. Ceci reprsente bien le fait quune pice concrte est soit simple soit compose, et ne peut pas tre dune autre nature. La classe abstraite est ici le

Javabook Page 321 Lundi, 12. juillet 1999 3:58 15

Polymorphisme

321

sommet dune taxonomie stricte o toute pice doit forcment tre classe dans lune des sous-classes. La classe Dictionary du package java.util nous offre un autre cas dutilisation dune classe abstraite. Dictionary dfinit ce quest un dictionnaire (une structure o lon peut stocker des paires clvaleur) mais nimpose aucune ralisation. La classe Hashtable est une sous-classe concrte de Dictionary qui, elle, dfinit une structure de stockage (une table de hachage) et redfinit concrtement les mthodes de stockage et de recherche de Dictionary. Lide est de fournir un cadre gnral et de laisser les dveloppeurs raliser des classes concrtes qui satisfont des besoins particuliers, par exemple implanter les classes ArbreBinaire ou B_Arbre comme autres sous-classes de Dictionary.

22.4 Polymorphisme
Hritage et polymorphisme
Daprs les rgles de typage de Java, si une variable est dclare de type C, on peut lui affecter un objet de C ou de nimporte quelle sous-classe de C. A fortiori, si la variable est de type Object, on peut lui affecter nimporte quel objet, car toute classe est sous-classe de Object. Cette proprit permet de crer des structures polymorphes composes dobjets provenant de diverses classes. Par exemple, la dclaration :
Piece[] composantes;

indique que le tableau tabPieces contiendra des objets de PieceSimple ou de PieceComposee. Par contre, il sera interdit dy mettre des objets de Point ou de Rectangle, qui ne sont pas des sous-classes de Piece. Le polymorphisme est ici contrl (limit) par la classe Piece. Le polymorphisme nous vite la cration dautant de structures quil y a de types dobjets stocker ou traiter. Sans polymorphisme, nous aurions d dfinir un tableau pour les pices simples et un autre pour les pices composes. Les deux classes Vector et Hashtable permettent de crer des structures de donnes polymorphes sans restriction car leurs mthodes acceptent des paramtres de type Object. On peut, par exemple, mettre dans un mme Vector : un Rectangle, une Applet et... un Vector.

Interfaces et polymorphisme
Les interfaces offrent une seconde manire de crer des structures polymorphes contrles indpendamment de la hirarchie dhritage. Si une variable est dclare dun type interface I, on peut lui affecter un objet de nimporte quelle classe qui implante I.

Javabook Page 322 Lundi, 12. juillet 1999 3:58 15

322

Chapitre 22 Mcanismes pour la rutilisation

Si les classes Moto, Montre et Casserole implantent toutes linterface Vendable, un tableau de type Vendable[6] pourra contenir deux motos, trois montres et une casserole, bien que leur classe respective nait aucune super-classe commune, mis part Object.

22.5 Gnricit et interface


Un composant est dit gnrique sil peut travailler sur diffrents types de donnes, par exemple une mthode de tri pourrait aussi bien trier des entiers que des chanes de caractres ou dautres types encore. La mthode ne peut cependant pas trier des objets pour lesquels aucune opration de comparaison nest disponible. Dans cet exemple, nous allons dfinir une mthode de tri qui sapplique nimporte quel tableau dobjets, pour autant que ceux-ci possdent une mthode plusPetitOuEgal(). Nous dfinissons donc une interface :
interface Comparable { public boolean plusPetitOuEgal(Object c); }

Dfinissons ensuite une classe Trieuse qui possde une mthode de classe tri() :
class Trieuse { public static void tri(Comparable[] x) { Comparable tmp; /* un simple tri par change */ for (int i = 0; i<x.length - 1; i++) for (int j = i+1; j<x.length; j++) if (x[j].plusPetitOuEgal(x[i])) { tmp = x[i]; x[i] = x[j]; x[j] = tmp; } } }

Nous voulons trier des motos selon leur prix, pour cela nous dfinissons une sous-classe de Moto qui implante linterface Comparable :
class MotoTriable extends Moto implements Comparable { public boolean plusPetitOuEgal(Object c) { return this.prix() <= ((Moto)c).prix(); } MotoTriable(String m, int p) {super(m,p); } }

Finalement, nous pouvons utiliser, par exemple dans un programme principal, notre mthode de tri :
public static void main(String[] args) { MotoTriable mt[] = {new MotoTriable("Honda", 16678), new MotoTriable("Kawasaki", 15099), new MotoTriable("Puch", 16000)}; Trieuse.tri(mt);

Javabook Page 323 Lundi, 12. juillet 1999 3:58 15

Gnricit et interface
for (int i = 0; i<mt.length; i++) mt[i].imprime(); }

323

Cet exemple montre une limite de la gnricit en Java. Dans linterface Comparable, nous avons dfini la mthode plusPetitOuEgal(Object c) dont le paramtre est de type Object, ce qui signifie quun objet est considr comme comparable seulement sil est comparable nimporte quel autre objet. En fait, il nous suffirait que lobjet soit comparable un autre objet de la mme classe. Or ceci nest pas exprimable en Java. De plus, dans la mthode tri(Comparable[] x), il nest pas possible de spcifier que le paramtre x doit contenir des objets qui sont tous des instances de la mme classe. On acceptera donc de trier des tableaux contenant la fois des motos, des vlos et des montgolfires. lheure actuelle, Java noffre donc pas de vritable mcanisme de gnricit indpendant du polymorphisme. De tels mcanismes existent depuis longtemps dans des langages comme Ada (packages, procdures, fonction gnriques), C++ (templates) ou Eiffel (classes gnriques).

Javabook Page 324 Lundi, 12. juillet 1999 3:58 15

Javabook Page 325 Lundi, 12. juillet 1999 3:58 15

Chapitre 23

Structures de donnes
Un objet est un module qui contient des donnes et des oprations daccs et de modification de celles-ci. Jusqu prsent, nous avons essentiellement rencontr des objets dont les donnes taient simples : soit des variables dun type de base; soit des rfrences dautres objets; ou encore des tableaux. Suivant le genre de problme que lon attaque, nous aurons besoin de donnes de structure beaucoup plus complexes, pensons par exemple un objet reprsentant en dtail lensemble de toutes les lignes ferroviaires dun pays. Ltude des structures de donnes sert prcisment raliser de tels objets complexes de manire systmatique et efficace. Nous verrons dans ce chapitre que lAPI Java peut venir notre secours dans ce domaine. Avant dexaminer les structures de donnes proprement dites, il est bon de se remmorer quelques notions relatives lidentit et lgalit des objets. Lune des difficults de la programmation par objets vient en particulier du fait que la distinction entre un objet et sa valeur reste souvent implicite. Pour les types de donnes primitifs, cette distinction na pas de raison dtre, on peut dire que lobjet 4 et la valeur 4 sont la mme entit. Par contre, pour les objets plus labors, il nen va pas de mme. Prenons par exemple trois rectangles construits de la manire suivante :
r1 = new Rectangle(10, 10, 8, 4); r2 = new Rectangle(10, 15, 7, 3); r3 = new Rectangle(10, 10, 8, 4);

Il sagit bien de trois objets diffrents (les tests r1 == r2, r1 == r3 et r2 == r3 donneraient chaque fois la valeur false), cependant r1 et r3 ont les mmes valeurs (si on les dessinait, ils seraient parfaitement superposs). Cest pourquoi il existe une mthode equals() qui teste non pas lidentit des objets, mais lgalit de

Javabook Page 326 Lundi, 12. juillet 1999 3:58 15

326

Chapitre 23 Structures de donnes

leur valeur. Ce test est bas sur le contenu des variables dinstance des objets. Dans lexemple ci-dessus, on aurait : r1.equals(r2) vaut false mais r1.equals(r3) vaut true.

23.1 Les chanes de caractres


La chane de caractres est lune des structures de donnes les plus simples et les plus utilises. Nanmoins, la manipulation de chanes requiert des prcautions.

Comparaisons
Bien que les chanes de caractres possdent en Java une reprsentation littrale sous forme dun texte entre guillemets, il est essentiel de se souvenir quil sagit dobjets et non de valeurs simples comme les boolens, entiers, flottants ou caractres. Cela signifie en particulier quil faut bien prendre garde distinguer lgalit et lidentit entre deux chanes. Par exemple, si lon crit :
String s1 = "Panoramix"; String s2 = "Pano" + "ramix";

rien ne garantit que (s1 == s2) donne comme rsultat true. En effet, s1 et s2 peuvent tre reprsents par deux objets diffrents qui ont tous deux la valeur "Panoramix", cela dpend de limplantation de la classe String. Par contre, il est certain que (s1.equals(s2)) donne true car equals() compare les deux objets caractre par caractre.

Reprsentation canonique
Lutilisation de equals() peut savrer coteuse en temps de calcul si lon doit comparer un grand nombre de fois des chanes de grande taille. Pour remdier cela, la classe String offre une reprsentation canonique des chanes grce la mthode intern(). Lexcution de s.intern() place la chane s dans un pool de chanes internes la classe String. Si le pool contient dj une chane t gale s, s.intern() retourne t comme rsultat, sinon s. Donc le pool ne contient jamais deux chanes de mme valeur, ce qui fait que si s1.equals(s2) vaut true alors s1.intern() == s2.intern() vaut aussi true, et rciproquement. Lorsquon travaille sur des chanes immuables que lon doit comparer trs souvent, cela vaut donc la peine de les remplacer par leur reprsentation canonique obtenue par intern(). On peut alors utiliser sans problme ==, qui est beaucoup plus rapide que equals() puisquil compare les identits dobjets et non les contenus.

Performances et StringBuffer
La reprsentation des chanes comme objets (instances de la classe String) peut galement avoir de fcheuses consquences sur les performances des program-

Javabook Page 327 Lundi, 12. juillet 1999 3:58 15

Les collections

327

mes si lon ny prend garde. Ceci est d au fait que les objets String sont immuables, ce qui signifie que toute modification dune variable String implique la cration dun nouvel objet String. Si lon excute le code suivant :
String allStars = "*"; for (int i = 1; i<10000; i++) allStars = allStars + "*";

chaque tour dans la boucle crera un nouvel objet. On se retrouvera la fin avec un objet String contenant la chane souhaite et 9999 objets inutiles contenant les valeurs "*", "**", "***", etc. Si lon tient compte des temps dallocation et de dsallocation de lespace mmoire occup par ces objets, la performance du programme sera nettement affaiblie par cet usage des Strings. Pour des programmes faisant un usage intensif de chanes de caractres dont la valeur change, il est fortement conseill dutiliser la classe StringBuffer. Cette dernire offre des chanes modifiables sans cration de nouvel objet et donc de bien meilleures performances. On crira par exemple :
StringBuffer allStarsB = new StringBuffer("*"); for (int i = 1; i<10000; i++) allStarsB.append("*"); String = allStarsB.toString();

23.2 Les collections


La thorie lmentaire des ensembles fournit des structures fondamentales telles que les ensembles, squences, multi-ensembles, fonctions, etc., qui forment des briques de base pour la construction du logiciel. Par rapport aux structures de donnes fournies par les langages (tableaux et classes en Java), ces structures permettent souvent dexprimer les algorithmes dune manire plus claire et plus naturelle. On peut galement sen servir, comme le proposent des mthodes telles que Z [10] ou VDM [5], pour modliser un domaine dapplication et obtenir une spcification formelle. Il existe en gnral, dans tous les environnements de dveloppement, des classes qui implantent ces structures directement ou non, mais sous des formes parfois difficiles reconnatre (pour une tude dtaille de ces structures, voir par exemple [2]). partir de la version 1.2 de lAPI, le package java.util offre des interfaces et classes correspondant aux collections de donnes fondamentales. Selon le bon principe de labstraction, il y a pour chaque type de collection une interface qui dfinit les oprations, et une ou plusieurs classes qui implante(nt) concrtement ce type. Le tableau ci-dessous rsume les diffrentes interfaces et implantations fournies dans le package java.util. Il existe plusieurs implantations car on ne connat pas de technique idale pour reprsenter les collections. Chacune possde des avantages et inconvnients en terme de vitesse dexcution et despace mmoire utilis. De plus, une implanta-

Javabook Page 328 Lundi, 12. juillet 1999 3:58 15

328

Chapitre 23 Structures de donnes

tion peut interdire certaines oprations. Par exemple, on pourrait crer une implantation ListeCroissante de List qui permet dajouter des lments mais interdit den retirer. Les interfaces Set, List et Map hritent de Collection. Dans chacun de ces trois types de collection, on retrouve des mthodes pour : ajouter un ou des lments; retirer un ou des lments; tester lappartenance dlments de la collection; obtenir des caractristiques de la collection (taille, vide/non vide, comparaison); effectuer des oprations propres ce type. Cest la smantique de ces oprations qui distingue ces types de collections entre eux. Examinons plus en dtail chaque type. Dun point de vue pratique, lutilisation dune collection consiste choisir le type de collection adapt au problme traiter, puis choisir limplantation qui convient le mieux en termes de performances. Dans un programme Java, on aura en gnral :
<InterfaceCollection> maCollection; maCollection = new <classe implantant InterfaceCollection>(...);

Par exemple :
Set motsCles; motsCles = new TreeSet(); ...etc...

Implantation Interface Set List Map SortedSet SortedMap

par table de hachage

tableau dynamique

arbre quilibr

cellules lies

HashSet ArrayList Vector HashMap Hashtable

TreeSet LinkedList TreeMap TreeSet TreeMap

Tableau 23.1 Interfaces et implantations des collections

Javabook Page 329 Lundi, 12. juillet 1999 3:58 15

Les collections

329

Ensembles (Set)
Un ensemble est une collection, ventuellement vide, dobjets qui ont tous des valeurs diffrentes. Donc si deux objets a et b sont dans le mme ensemble, a.equals(b) est forcment faux. De mme, le pseudo-objet null peut se trouver au plus un fois dans un ensemble. Il ny a pas dordre des lments dans un ensemble, on ne peut donc pas parler du premier ou du quatorzime lment dun ensemble. Les principales mthodes de linterface Set sont les suivantes.
Mthode
add(Object e)

Dfinition Ajoute llment e lensemble. Retourne vrai si e a effectivement t ajout, faux sinon (par exemple, sil y avait dj un lment de mme valeur). Retire e de lensemble, cest--dire retire tout lment gal e. Retourne vrai si lensemble a effectivement t modifi, faux sinon. Retourne vrai si lensemble contient un lment gal e, faux sinon. Vrai si lensemble est vide. Nombre dlments de lensemble. Retourne vrai seulement si o est un ensemble et tous les lments de o sont contenus dans cet ensemble et tous les lments de cet ensemble sont contenus dans o. Ajoute tous les lments de c cet ensemble. Retire de cet ensemble tous les lments qui sont aussi dans c. Retire tous les lments sauf ceux qui sont aussi dans c. Vrai si lensemble contient tous les lments de c.

remove(Object e)

contains(Object e) isEmpty() size() equals(Object o)

addAll(Collection c) removeAll(Collection c) retainAll(Collection c) containsAll(Collection c)

Tableau 23.2 Mthodes de linterface Set

Il ne faut pas ngliger les quatre dernires mthodes de la liste ci-dessus car elles permettent deffectuer les oprations ensemblistes classiques : s1.addAll(s2) revient faire lunion s1 = s1 # s2; s1.retainAll(s2) revient faire lintersection s1 = s1 $ s2; s1.removeAll(s2) revient faire la diffrence s1 = s1 \ s2;

Javabook Page 330 Lundi, 12. juillet 1999 3:58 15

330

Chapitre 23 Structures de donnes

b = s1.containsAll(s2) teste linclusion s1 = s2 % s1; Remarquons quun ensemble ne stocke que des objets (Objects). Pour y ranger des valeurs de types simples (char, int, double, etc.), il est ncessaire de les envelopper dans lune des classes prvues cet effet : Character, Integer, Double, etc. (voir point 6.10, p. 95). Les deux implantations des ensembles fournies par le package java.util diffrent par leurs performances et lordre de stockage des lments. HashSet : une implantation par table de hachage1, lajout et le test dappartenance sont trs rapides (temps quasi constant). TreeSet : les lments sont placs dans un arbre de recherche binaire quilibr, lajout et le test dappartenance prennent un temps proportionnel au logarithme du nombre dlments (cest encore rapide); de manire interne, les lments sont maintenus tris selon leur ordre naturel (dfini par la mthode compare()), ce qui permettra, par exemple, de parcourir facilement les lments par ordre croissant (voir point 23.3 Itrateurs). Un exemple : le compteur de mots La programme suivant compte le nombre de mots diffrents contenus dans un fichier de texte. La mthode est simple, il suffit dajouter chaque mot lu un ensemble. Si le mot y est dj, il nest pas ajout une seconde fois. la fin, la taille de lensemble donne le nombre de mots diffrents.
import java.io.*; import java.util.*; class CompteDiff { public static void main(String[] args) { try { // initialisation du lecteur de mots (voir chap. Entrees/ Sorties) Reader r=new FileReader(args[0]); StreamTokenizer st=new StreamTokenizer (r); st.whitespaceChars('.','.') ; // le '.' est un sparateur Set mots = new HashSet(); while (st.nextToken()!=st.TT_EOF) { if (st.ttype== st.TT_WORD) { mots.add(st.sval); // st.sval contient le mot lu

1.

Dans une table de hachage, un objet est stock une position donne par une fonction de hachage applique la valeur de lobjet et qui fournit un entier compris entre 0 et la taille de la table - 1. On utilise la mme fonction pour retrouver la place dune paire stocke. Si deux objets doivent occuper la mme position, lun des deux est dplac selon une rgle de rsolution de collision . Tant quil y a peu de collisions, laccs aux donnes est extrmement rapide.

Javabook Page 331 Lundi, 12. juillet 1999 3:58 15

Les collections

331

} } r.close(); System.out.println("Nb. de mots fifferents: "+mots.size()); } catch (FileNotFoundException e) {System.out.println("Fichier non trouve");} catch (IOException e) {System.out.println("Erreur de lecture");} }}

Squences (List)
Une squence est une collection ordonne dobjets. Chaque objet possde une position dans la squence et plusieurs objets de mmes valeurs peuvent apparatre dans une squence, On voit dans la table ci-dessous que les mthodes dajout, de suppression, etc., demandent comme paramtre la position laquelle doit seffectuer lopration.
Mthode
add(int i, Object e) add(Object e) remove(int i) remove(Object e) clear() set(int i, Object e) contains(Object e) indexOf(Object e) lastIndexOf(Object e) get(int i) size() isEmpty() equals(Object o) addAll(Collection c)

Description Ajoute e la position i. Ajoute e la fin de la squence. Retire llment se trouvant la position i. Retire la premire occurrence de e dans la squence. Vide la squence de tous ses lments. Remplace llment la position i par e. Vrai si cette squence contient e. Retourne la position (int) de la premire occurrence de e dans la squence ou 1 sil ny est pas. Position de la dernire occurrence de e. Retourne lobjet plac la position i. Nombre dlments dans la squence. Vrai si la squence est vide. Vrai si o est une liste qui contient des lments gaux des positions identiques. Ajoute c la fin de la squence (concatnation).

Tableau 23.3 Oprations de linterface List

Javabook Page 332 Lundi, 12. juillet 1999 3:58 15

332
Mthode
addAll(int i, Collection c) containsAll(Collection c) removeAll(Collection c) retainAll(Collection c) subList(int debut, int fin)

Chapitre 23 Structures de donnes


Description Insre c la position i. Vrai si la squence contient tous les lments de c. Retire de la squence les lments qui sont aussi dans c. Ne retient que les lments qui sont aussi dans c. Cre une liste qui est une vue de celle-ci entre debut et fin. La squence ainsi cre partage ses lments avec cette squence!

Tableau 23.3 Oprations de linterface List

Les trois implantations offertes pour les listes se distinguent par leurs performances. ArrayList : la liste est maintenue dans un tableau, laccs un lment par sa position est trs rapide, par contre linsertion au dbut prend un temps proportionnel la taille de la liste. Cest en rgle gnrale un bon choix. LinkedList : la liste est forme de cellules lies par des rfrences, linsertion est rapide, par contre laccs un lment par sa position prend un temps proportionnel la position. Intressante essentiellement si lon fait de frquentes insertions au dbut et de nombreux parcours avec suppressions. Vector : cest la classe originellement fournie avec les premires versions de lAPI Java, elle est similaire ArrayList. La liste est stocke dans un tableau dont on peut contrler les paramtres dallocation. Cette classe est employe dans de nombreux programmes Java dvelopps pour lAPI 1.0 et 1.1. Les mthodes sont synchronises : deux processus concurrents ne peuvent accder simultanment au mme Vector.

Fonctions (Map)
Une fonction dun ensemble S vers un ensemble D est un ensemble de liens s ! d o s est un lment de S et d un lment de D. un objet de la source S peut correspondre au plus un seul objet de la destination D. Par contre, un mme objet peut tre la destination de plusieurs liens. On peut donc avoir les liens s1 ! d et s2 ! d dans la mme fonction, mais pas s ! d1 et s ! d2. Dans un lien s ! d, on appelle s la cl et d la valeur et on parle donc de paire cl-valeur. Comme dans le cas des ensembles, on a une implantation par hachage (HashMap) et une implantation par arbre (TreeMap). Pour pouvoir parcourir les cls en ordre croissant, il faut choisir le TreeMap. Le HashMap est plus rapide.

Javabook Page 333 Lundi, 12. juillet 1999 3:58 15

Les collections
Mthode
put(Object cle, Object val)

333
Description Ajoute la fonction le lien cle ! val. Retourne lancienne valeur associe cle ou null si cle ntait pas associe. Retire le lien de cl c, sil existe. Retourne lancienne valeur associe cle. Vide la fonction. Vrai si la fonction associe la cl c une valeur. Vrai sil existe une ou plusieurs cl(s) associe(s) la valeur v. Retourne la valeur (Object) lie la cl c dans cette fonction, ou null sil ny en a pas. Teste lgalit entre deux fonctions (mmes paires cl-valeur). Vrai si la fonction est vide. Ajoute toutes les paires cl-valeur de t cette fonction. Retourne le nombre de paires cl-valeur de cette fonction. Fournit un Set contenant lensemble des cls de cette fonction. Attention, cet ensemble partage ses lments avec la fonction! Fournit une collection contenant les valeurs de cette fonction.

remove(Object c) clear() containsKey(Object c) containsValue(Object v) get(Object c) equals(Object o) isEmpty() putAll(Map t) size() keySet()

values()

Tableau 23.4 Oprations du type Map

la fin du paragraphe 23.3 sur les itrateurs, nous prsenterons un exemple complet utilisant les fonctions. Une remarque de modlisation : fonctions et encapsulation des liens Les fonctions permettent dtablir des liens entre objets sans briser lencapsulation, cest--dire sans toucher la structure interne des classes concernes. Supposons que lon dsire tablir des liens entre des objets de la classe Avion et de la classe Aroport pour indiquer laroport o seffectue lentretien de chaque avion. La premire manire de procder, que nous avons vue au point 21.6, consiste ajouter une variable dinstance entretien de type Aeroport dans la classe Avion. Ce qui nous oblige modifier la classe Avion.

Javabook Page 334 Lundi, 12. juillet 1999 3:58 15

334

Chapitre 23 Structures de donnes

Les fonctions nous offrent une autre solution qui consiste crer une fonction entretien sous forme dune Map pour stocker des liens (avion ! aroport). La classe Avion reste alors indpendante de la fonction entretien.
Map entretien = new HashMap(); Avion hb56 = ... ; Aeroport gva = ...; entretien.put(hb56, gva); // associe hb56 gva.

Fonctions et multiensembles Un multiensemble correspond un ensemble o un mme lment pourrait apparatre plusieurs fois; on parle alors du nombre doccurrences dun lment. En fait, un multiensemble est une fonction qui associe chaque cl un nombre entier qui reprsente son nombre doccurrences. On peut donc facilement raliser une classe MultiEnsemble laide de Map.

23.3 Itrateurs (Iterator)


Les itrateurs sont des objets permettant de parcourir les lments dune collection. On peut voir un itrateur comme une sorte de curseur qui se dplace le long dune collection en visitant successivement tous les lments. Les itrateurs sont ncessaires pour le parcours de collections dont les lments ne sont pas indics ou lorsque les valeurs des indices (cls) sont inconnues. Un itrateur tablit (et cest l son intrt majeur) une totale indpendance entre la structure de la collection et le code ncessaire pour la parcourir. En gnral, on cre un itrateur en invoquant la mthode iterator() de la collection parcourir. On effectue le parcours des lments de la collection laide des deux mthodes : hasNext() : retourne vrai sil y a encore des lments parcourir; next() : retourne lobjet suivant selon lordre de parcours fix par litrateur. On peut galement retirer de la collection llment sur lequel est positionn litrateur avec la mthode remove() de litrateur. Il faut absolument viter de retirer des lments pendant un parcours en utilisant la mthode remove() de la collection, car cela peut perturber le fonctionnement de litrateur. Le schma classique dutilisation des itrateurs est :
Iterator i = maCollection.iterator(); while (i.hasNext()) { objetCourant = i.next(); ... <traitement de objetCourant> ... <ventuellement> i.remove(); // jamais maCollection.remove(...) }

Javabook Page 335 Lundi, 12. juillet 1999 3:58 15

Itrateurs (Iterator)

335

Remarque Jusqu la version 1.1, lAPI Java offrait la classe Enumeration, munie des mthodes hasMoreElements() et nextElement() comme mcanismes ditration. Il est dsormais prfrable dutiliser Iterator qui permet de retirer des lments en cours de route. Un exemple : lindexation dun texte Ce petit programme lit un texte et cre un index qui contient, pour chaque mot, la liste des numros de lignes o il apparat.
import java.io.*; import java.util.*; class Indexeur { public static void main(String[] args) { try { Reader r=new FileReader(args[0]); StreamTokenizer st=new StreamTokenizer (r); st.whitespaceChars('.','.') ; st.eolIsSignificant(true); // reconnait les fins de ligne Map index = new TreeMap(); // fonctions avec cls ordonnes int noLigne = 1; while (st.nextToken()!=st.TT_EOF) { if (st.ttype == st.TT_EOL) noLigne++; // fin de ligne if (st.ttype== st.TT_WORD) { // mot List lignes = (List)index.get(st.sval); if (lignes == null) { // premiere fois qu'on trouve ce mot lignes = new ArrayList(); // une liste vide index.put(st.sval, lignes); // lui est associee } lignes.add(new Integer(noLigne)); } } // while r.close(); // Parcours de toutes les cles de la fonction Iterator i = index.keySet().iterator(); while (i.hasNext()) { Object mot = i.next(); System.out.print((String)mot); List lignes = (List)index.get(mot); // Parcours de la liste des nos de lignes Iterator j = lignes.iterator(); while (j.hasNext()) { int ligne = ( (Integer)j.next() ).intValue(); System.out.print(" " + ligne); }

Javabook Page 336 Lundi, 12. juillet 1999 3:58 15

336
System.out.println(); }

Chapitre 23 Structures de donnes

} catch (FileNotFoundException e) {System.out.println("Fichier non trouve");} catch (IOException e) {System.out.println("Erreur de lecture");} } }

Dans ce programme, on utilise une fonction (index) qui associe chaque mot lu une liste contenant les numros des lignes o apparat le mot. Cest donc une structure de collection deux niveaux. Pour imprimer lindex, on parcourt avec litrateur i lensemble des cls de la fonction (obtenu par keySet()) et, pour chaque cl, on parcourt avec litrateur j la liste qui lui est associe. Lexcution de ce programme avec son propre texte source comme fichier de donnes produit :
ArrayList 21 EOF 16 EOL 17 FileNotFoundException 46 FileReader 8 IOException 47 Indexeur 4 Integer 24 39 Iterator 30 37 List 19 19 34 34 Map 13 etc.

23.4 Copies et galits de surface et profondes


Nous avons dj mentionn la distinction entre galit et identit de deux objets, et la ncessit davoir une mthode qui teste lgalit de deux objets en se basant sur leur contenu. Dans le cas dune classe Rectangle simple, le test dgalit (equals) revient tester lgalit des quatre nombres entiers qui forment la valeur dun objet Rectangle (coordonne x, coordonne y, largeur et hauteur). Mais ce nest pas toujours aussi simple. Considrons une classe reprsentant des fractions de la forme (p/q) :
class Fraction { private int numerateur, denominateur;

Deux fractions sont gales si leur numrateur et leur dnominateur le sont, mais ce nest pas tout. Tout le monde sait que 1/2 = 2/4 = 3/6, etc. Deux fractions sont gales si les multiplications croises {numrateur de a * dnominateur de

Javabook Page 337 Lundi, 12. juillet 1999 3:58 15

Copies et galits de surface et profondes

337

b} et {numrateur de b * dnominateur de a} donnent le mme rsultat. Il faut donc crire une mthode equals() spcifique pour les fractions :
public boolean equals(Fraction f) { return (this.numerateur * f.denominateur == this.denominateur * f.numerateur); }

Dans le cas o les variables dinstance des objets comparer ne contiennent pas des valeurs primitives (int, long, float, etc.), la mthode equals doit en tenir compte et dcider dappliquer soit le test didentit (==), soit le test dgalit (equals) sur celles-ci. Prenons par exemple une classe ListeRect dont chaque objet a pour but de grer un ensemble de rectangles stocks dans un tableau :
class ListeRect { private Rectangle[] lesRectangles; private int nbRectangles;

Egalit de surface et galit profonde


On peut dfinir deux notions dgalit pour la classe ListeRect. Dans le premier cas, on dira que deux ListeRect a et b sont gales si elles contiennent les mmes rectangles, cest--dire que : a.lesRectangles[0] == b.lesRectangles[0] et a.lesRectangles[1] == b.lesRectangles[1] et etc. Ce type dgalit est souvent appel galit de surface. Dans le second cas, on dira que les deux ListeRect sont gales si elles contiennent des rectangles gaux, cest--dire que : a.lesRectangles[0].equals (b.lesRectangles[0]) et a.lesRectangles[1].equals (b.lesRectangles[1]) et etc. On parle dans ce cas d galit profonde car le test equals se propage en profondeur dans les composantes des objets tester. Ni lune ni lautre de ces deux notions nest la plus juste dans labsolu, cela dpend essentiellement de lusage quon fait de cette classe. Il est par contre essentiel de bien dcrire la notion dgalit utilise, afin dviter de mauvaises utilisations de la classe. De plus, lopration equals() se doit dtre : symtrique : a.equals(b) et b.equals(a) doivent toujours donner le mme rsultat; rflexive : a.equals(a) doit toujours donner true;

Javabook Page 338 Lundi, 12. juillet 1999 3:58 15

338

Chapitre 23 Structures de donnes

transitive : si a.equals(b) et b.equals(c) donnent true, alors a.equals(c) doit aussi donner true.

Copie dobjets
La copie dobjets soulve le mme genre de questions que lgalit. En effet, loprateur = neffectue aucune copie dobjet. Par exemple, si lon a :
r1 = new Rectangle(0, 0, 10, 15);

lopration : ne cre pas une nouvelle instance de Rectangle mais place dans r2 une rfrence lobjet rfrenc par r1. Aprs cette opration, r1 == r2 vaut true. Le but dune opration de copie est de crer un nouvel objet qui soit gal (au sens de equals()) lobjet de dpart. Dans le jargon Java, on parle dopration de clonage. On veut donc une opration clone() telle quaprs linstruction :
r2 = r1.clone() r2 = r1;

on ait r2 != r1 mais r2.equals(r1). De mme que pour lgalit, on peut dfinir des oprations de clonage de surface ou de clonage profond. Si lon reprend la classe ListeRect, une copie de surface de la ListeRect a consiste crer un nouvel objet b qui contient son propre tableau lesRectangles, et faire :
for (i=0; i<nbRectangles; i++) {b.lesRectangles[i] = a.lesRectangles[i]; }

On ne cre pas de nouveaux rectangles, la nouvelle liste fait rfrence aux rectangles de la prcdente liste. Pour une copie en profondeur, on crera au contraire un nouvel exemplaire de chaque rectangle :
for (i=0; i<nbRectangles; i++) {b.lesRectangles[i] = a.lesRectangles[i].clone(); }

Lopration de clonage doit tre trs clairement dcrite pour viter toute mauvaise interprtation par les futurs utilisateurs de la classe (ou par lauteur qui ne sait plus trs bien ce quil a fait il y a six mois). On notera en particulier que le clonage de surface introduit un partage dobjets, cest--dire que deux objets ListeRect font rfrence aux mmes objets Rectangle. Donc, si lon modifie lun de ces Rectangle, la modification apparat dans les deux ListeRect; nouveau, cela peut tre considr comme un avantage ou un inconvnient mais il faut en tre conscient.

Javabook Page 339 Lundi, 12. juillet 1999 3:58 15

Invitation explorer

339

23.5 Invitation explorer


Les interfaces Comparable et java.util.Comparator permettent de dfinir un ordre sur un type dobjets et de trier des listes ou de maintenir des ensembles tris. Explorez la classe java.util.Arrays qui offre toute sortes doprations de manipulation de tableaux, dont la transformation dun tableau en liste. Set et List ont aussi des mthodes pour produire des tableaux. Pour les squences, il existe un type ditrateur ListIterator qui permet davancer et de reculer, de modifier la liste en cours de route, etc. Lisez lexcellent tutoriel sur les collections de Joshua Bloch : http://java.sun.com/docs/books/tutorial/collections/index.html.

Javabook Page 340 Lundi, 12. juillet 1999 3:58 15

Javabook Page 341 Lundi, 12. juillet 1999 3:58 15

Chapitre 24

Composition du logiciel
Bien que la notion de classe permette de construire une application de manire modulaire, elle nest plus suffisante lorsquon se trouve face des applications de grande taille (ce que les anglophones nomment programming in the large). Cest pour cette raison que certains langages et mthodes orients objet proposent de regrouper les classes dans des structures de plus haut niveau. Le langage Java offre dans ce but la notion de package. Nous verrons galement dans ce chapitre comment dfinir laccessibilit aux objets dans des projets impliquant plusieurs packages. Si les packages constituent un outil de structuration du logiciel, les Java Beans ouvrent, quant eux, la possibilit de construire du logiciel par composition dobjets. Nous verrons pour terminer le mcanisme dintrospection ncessaire au dveloppement des Java Beans.

24.1 Les packages


Un package Java est simplement un groupe de classes. Pour dclarer quune classe appartient un package, il faut placer, au dbut du fichier source qui contient la dfinition de la classe, lnonc :
package <nom-du-package>;

Une classe ne peut appartenir qu un seul package. Certains environnements de dveloppement Java exigent que tous les fichiers de code source et de byte-code des classes dun package se trouvent dans le mme

Javabook Page 342 Lundi, 12. juillet 1999 3:58 15

342

Chapitre 24 Composition du logiciel

rpertoire du systme de fichier, ce rpertoire portant ncessairement le mme nom que le package. Les packages peuvent eux-mmes tre organiss hirarchiquement, il faut alors utiliser une notation pointe pour nommer chaque package. Un nom de la forme :
packA.packB

spcifie un sous-package de packA qui se nomme packA.packB. Les classes de ce package doivent alors tre places dans un sous-rpertoire de packA nomm packB. Si aucun package nest dclar en dbut de fichier, les classes dfinies dans ce fichier appartiennent un package anonyme. Ces classes ne sont importables dans aucun autre package. Il sagit dune facilit de test pour de petits programmes, qui doit tre abandonne ds quil faut aborder un dveloppement consquent.

Constitution des packages


Le design des packages, comme celui des classes, nest pas chose facile. Comment dcider quelle classe ira dans quel package? En principe, un package devrait regrouper des classes partageant des caractristiques communes. Une bonne pratique consiste fixer, pour chaque package, un critre qui permet de dcider si une classe doit appartenir ou non au package. Ce critre peut tre de diffrente nature, par exemple : critre fonctionnel : les classes du package concourent raliser une fonction du systme, par exemple la gestion de linteraction avec lutilisateur, la gestion du rseau de communications, etc; critre de domaine : les classes du package reprsentent des objets dun sous-domaine de lapplication comme, par exemple, des objets gomtriques (carrs, droites, cercles, points, surface, etc.), des units de mesure (poids, surfaces, dates, etc.); variantes dimplantation : les classes du package implantent le mme type abstrait de manires diffrentes. On pourrait avoir un package fonction contenant des classes fonctionSequence, fonctionArbre, fonctionHash, etc., qui sont autant de manires diffrentes dimplanter le type fonction.

Classes publiques et prives dun package


Chaque classe dun package peut tre dclare publique (public), auquel cas elle sera utilisable par des classes dautres packages, sinon son utilisation sera rserve aux autres classes de son package.

Javabook Page 343 Lundi, 12. juillet 1999 3:58 15

Rgles daccessibilit en Java

343

Une classe non publique est donc encapsule dans son package, ce qui permet de ne montrer lextrieur du package que les classes que lon dsire mettre disposition des autres. Les classes non publiques sont en gnral des classes auxiliaires qui ne prsentent pas dintrt pour lutilisateur du package, mais qui sont techniquement ncessaires sa ralisation. Le mot rserv public, plac devant la dfinition dune classe, indique que celleci est publique, sinon elle est usage interne du package. Pour utiliser une classe C dun package p depuis un autre package, il faut : soit prfixer son nom par celui du package (p.C) chaque rfrence; soit importer la classe (import p.C), ce qui permet de nutiliser que le nom C par la suite. Notons que lon peut importer dun coup toutes les classes dun package p en faisant import p.*

24.2 Rgles daccessibilit en Java


Dans la notion dencapsulation prsente au point 21.1, toute la partie structurelle dune classe (les variables) tait encapsule alors que toute la partie dynamique (les mthodes) tait visible de lextrieur. Dans un langage comme Java, la rgle ne peut tre aussi simple car il faut compter avec les notions de sous-classe et de package pour dfinir laccessibilit (galement appele visibilit). Le principe est de distinguer diffrents degrs daccessibilit entre classes suivant que lune est sous-classe de lautre ou que lune appartient au mme package que lautre. Un membre dune classe (variable ou mthode) est accessible depuis une autre classe dans les conditions suivantes : si le membre est dclar public (modificateur public plac avant la dclaration), il est accessible depuis nimporte quelle autre classe qui peut accder la classe de dclaration; sil est dclar priv (private), il nest accessible que depuis le code des mthodes de sa classe : sil ny a pas de dclaration particulire, il est accessible depuis les classes du mme package; sil est dclar protg (protected), il est accessible depuis les sousclasses de sa classe de dclaration, quelles soient ou non dans le mme package. La condition daccessibilit des membres protgs possde quelques raffinements supplmentaires, dont la principale consquence est la suivante : si m est une variable ou mthode protge dune classe C, une expression de la forme e.m qui apparat dans une sous-classe S de C nest correcte que si le type de e est

Javabook Page 344 Lundi, 12. juillet 1999 3:58 15

344

Chapitre 24 Composition du logiciel

S ou une sous-classe de S ou si e est la pseudovariable super. En dautres termes, S ne peut accder au membre m dobjets qui sont de type C mais pas de type S. Nous prsentons ci-dessous quelques cas dutilisation des modificateurs daccessibilit. Transparence des objets Un membre priv nest visible qu lintrieur de sa classe. Cela correspond lencapsulation la plus forte en Java. Notons cependant que les objets dune mme classe sont compltement transparents les uns par rapport aux autres. Une mthode peut donc accder aux membres privs de this mais aussi aux membres privs de tout objet de la mme classe que this (cette possibilit surprendra les habitus de Smalltalk) :
class Piece { private String type; boolean memeType(Piece p) { // accs une variable prive d'un autre objet Piece return p.type == this.type; } ... }

Hritage des variables prives Le modificateur private, plac devant une variable, rend celle-ci inaccessible dans les sous-classes, bien quelle soit hrite. Ainsi, lorsquune mthode dune sous-classe veut modifier une variable hrite mais inaccessible, elle doit forcment faire appel une mthode de modification de la super-classe, comme dans lexemple ci-dessous :
package p1; class Piece { private String type; int noSerie; void defType(String s) {type = s;} void defSerie(int i) {noSerie = i;} } class PieceSimple extends Piece{ void uneMethode() { // acces a la var. heritee travers une mthode de Piece: // this.type = "vis" causerait une erreur ! this.defType("vis"); // accs une variable hrite visible noSerie = 455848; } }

Javabook Page 345 Lundi, 12. juillet 1999 3:58 15

Rgles daccessibilit en Java

345

Modificateur protected Cet exemple illustre la rgle particulire demploi des variables protges :
package p1; public class Piece { protected int cout; ... } package p2; import p1.Piece; class PieceSimple extends Piece{ ... void uneMethode(Piece p) { PieceSimple ps = new PieceSimple(); this.cout = 345; // accs autoris // p.cout = 456; // accs interdit car p est de type Piece qui // pas une sous-classe de PieceSimple ps.cout = 765; // accs autoris } }

nest

Accessibilit et redfinition
Si une classe qui hrite dune mthode m() la redfinit, en donnant donc le mme nom et les mmes types de paramtres une nouvelle mthode, la mthode redfinie doit tre au moins aussi accessible que la mthode hrite. Cette rgle garantit quun objet dune sous-classe sait faire tout ce que sait faire un objet de sa super-classe. Si ce ntait pas le cas, on ne pourrait plus considrer quune sous-classe tend sa super-classe; on perdrait alors la proprit selon laquelle partout o un objet dune classe est requis, on peut le remplacer par un objet dune de ses sous-classes. Le compilateur ne pourrait plus faire de contrle statique des types des expressions, et des erreurs dexcution pourraient sensuivre.

Quelques conseils de design


Dfinir un niveau de visibilit est videmment une question de design qui ne possde pas de rponse toute faite. Le principe gnral reste daccorder une large visibilit aux mthodes et de restreindre la visibilit des variables. Rappelons quelques points qui peuvent aider choisir le niveau de visibilit adquat des variables :

Javabook Page 346 Lundi, 12. juillet 1999 3:58 15

346

Chapitre 24 Composition du logiciel

plus les variables dune classe sont caches, plus celle-ci est indpendante des autres et donc facile maintenir; plus le projet sur lequel on travaille est grand, plus les choix de visibilit portent consquence. LAPI Java constitue un exemple extrme car pratiquement tout programme Java crit quelque part dans le monde utilise les classes de lAPI; lextension de la visibilit dune variable peut parfois viter dcrire plusieurs mthodes qui ne servent qu accder aux variables des objets; si la visibilit est limite au package, on na pas craindre quun grand nombre de classes se mette accder la variable; il nest pas toujours vrai que laccs direct aux variables est plus rapide que le passage par une mthode daccs, car les compilateurs modernes peuvent trs bien optimiser ces mthodes (par exemple, par expansion directe du code). De plus, les compilateurs peuvent tenir compte du modificateur final qui empche la redfinition dune mthode, ce qui vite de passer par le mcanisme de liaison dynamique lors des appels. En ce qui concerne les mthodes, on peut noter deux cas o il parat judicieux de limiter la visibilit : il peut tre utile de cacher des mthodes auxiliaires qui ont un usage interne important mais noffrent pas de service intressant aux autres classes. De cette manire, on allge linterface de la classe et on en facilite la rutilisation par dautres concepteurs; dans le mme ordre dide, on vitera galement de rendre publiques des mthodes dont leffet peut savrer dsastreux si elles ne sont pas utilises selon des rgles bien prcises, en gnral connues du dveloppeur seul.

24.3 Les Java Beans


Java Beans est une architecture logicielle conue pour favoriser la cration dapplications par assemblage de composants. Il existe dj un certain nombre darchitectures allant dans ce sens. Parmi les plus intressantes, on peut citer : Les plug-ins Il sagit de composants additionnels qui enrichissent une application existante (butineur Web, traitement de texte, traitement dimages, etc.) de nouvelles fonctions. Les applets Java Cest une architecture base sur la mobilit du code stock sur un serveur et excut sur nimporte quelle machine cliente munie dune machine

Javabook Page 347 Lundi, 12. juillet 1999 3:58 15

Les Java Beans

347

virtuelle Java. Les applets sont fournies lutilisateur en fonction des tches quil veut effectuer. DCOM Larchitecture de composants distribus dfinie par MicroSoft permet dcrire des composants logiciels capables de communiquer avec dautres composants DCOM pour sintgrer dans un systme distribu. AppleScript Ce langage de haut niveau permet dinvoquer des services de diffrentes applications (tableurs, traitements de texte, bases de donnes, etc.) pour crire une macro-application . Des ensembles de services standards sont rpertoris dans des dictionnaires.

Anatomie et vie dun Java Bean


Techniquement, un Java Bean nest rien dautre quun objet Java dont la classe remplit certains critres de dnomination de ses mthodes qui peut tre srialis. Conceptuellement, un Bean est compos : de proprits (persistantes); dvnements reconnus; de mthodes de traitement des vnements. Un Bean possde deux vies. Il vit la premire lintrieur dun outil de gnie logiciel qui sert dvelopper des applications par composition de Beans. La vie du Bean commence au moment o loutil linstancie (new). Loutil sert ensuite configurer les proprits du Bean, par exemple dfinir la taille, la couleur et le texte dun Bean de type bouton. Il sert galement dfinir le comportement de la future application en configurant lenvoi dvnements entre Beans. On spcifie, par exemple, que le bouton efface envoie un vnement un champ de texte qui devra alors excuter la mthode effacement(). En gnral, loutil de dveloppement prsentera les Beans et leurs interactions sous forme graphique, comme esquiss sur la figure 24.1. Une fois tous les Beans configurs, ils sont srialiss, cest--dire sauvegards dans des fichiers archives (de type JAR) dans ltat o ils se trouvent. Notons encore quun Bean peut dfinir sa propre interface graphique de configuration. La seconde vie du Bean commence lorsque lapplication dont il fait partie dmarre. Une fois dsrialis, il se retrouve tel quon la configur et prt excuter les services (mthodes) quon lui demande au sein de lapplication. On peut reprsenter le cycle de vie dun Bean par le diagramme dtats/transitions de la figure 24.2.

Javabook Page 348 Lundi, 12. juillet 1999 3:58 15

348

Chapitre 24 Composition du logiciel

classes de Beans

application en construction proprits du Bean slectionn

x: 45 y: 123 couleur: red poids: 4560

connexion par envoi dvnements Bean = instance dune classe de Bean

Figure 24.1 Outil de dveloppement interactif avec des Beans

Les vnements
Le modle dvnements dcrit au chapitre 13 est une composante essentielle de larchitecture Java Beans, car cest le support de la communication entre Beans. Un Bean communique avec dautres Beans, qui se sont inscrits comme couteurs, en leur envoyant des vnements. Rappelons brivement comment fonctionne ce modle. Pour quun Bean puisse produire des vnements de type T il faut : dfinir une classe TEvent qui contiendra la mmoire de lvnement, cest--dire les donnes transmettre aux couteurs; dfinir une interface dcoute TListener qui spcifie quelles mthodes les couteurs doivent implanter. Ces mthodes ont en gnral un seul paramtre de type TEvent; dfinir dans la classe du Bean une mthode dinscription et une mthode de retrait dcouteurs : public void addTListener(TListener ecouteur) public void removeTListener(TListener ecouteur) ; ventuellement dfinir une classe dadaptateurs TAdapter qui implante TListener.

Javabook Page 349 Lundi, 12. juillet 1999 3:58 15

Les Java Beans

349

Pour transmettre un vnement, le Bean source parcourt la liste de tous les couteurs inscrits et invoque pour chacun deux lune des mthodes de linterface TListener.
Bean cr configuration - proprits - vnements Bean configur

instantiation srialisation Outil de dveloppement

Bean srialis

utilisation

Bean prt

dsrialisation

Application Figure 24.2 Cycle de vie dun Bean

Les proprits
Une proprit est un attribut dun Bean qui est identifie par un nom et possde une valeur dun type quelconque. Par exemple, un Bean reprsentant un vlo pourra avoir une proprit poids de type double. Pour quune proprit de nom P soit reconnue comme telle, le Bean doit possder une mthode daccs getP() et une mthode daffectation setP(). Notre vlo aura donc une mthode getPoids() qui retourne un double et une mthode setPoids(double valeur). Une proprit peut tre indexe, dans ce cas sa valeur est un tableau de valeurs. Les mthodes getP() et setP() ont alors un paramtre supplmentaire qui est lindice dans le tableau. Par exemple, si la proprit couleur est indexe on crira :
Couleur couleurPrincipale = monVelo.getCouleur(0); monVelo.setCouleur(1, couleurSecondaire);

Un Bean peut galement avoir des proprits lies, ce qui signifie que tout changement de valeur doit tre signal dautres objets. Lors dun changement de valeur, le Bean doit crer un vnement de type PropertyChangeEvent et le transmettre tous les objets inscrits en appelant leur mthode property-

Javabook Page 350 Lundi, 12. juillet 1999 3:58 15

350

Chapitre 24 Composition du logiciel

Change(). La classe PropertyChangeSupport aide grer les inscriptions et transmissions de tels vnements. Une proprit peut tre lie encore plus fortement dautres objets, on dit alors que la proprit est contrainte. Dans ce cas, le Bean signale aux abonns quil veut changer la valeur de la proprit et leur permet de sopposer au changement. En cas dopposition, un abonn lance une exception de type PropertyVetoException lorsque le bean appelle sa mthode vetoableChange(). Si le Bean reoit une telle exception, il doit renvoyer un vnement pour dfaire le changement, sinon il envoie un vnement de changement normal pour confirmer le changement tous les abonns. Il sagit donc dun protocole deux phases. Les conventions de dnomination stricte des mthodes lies aux proprits et aux vnement sont l pour permettre aux outils de dveloppement de reconnatre les proprits et vnements dun Bean. On remarquera que les classes de lAWT, de mme que celles de Swing respectent toutes les conventions dcriture des Beans. Les objets de ces classes sont donc des Beans, ce qui permet de les utiliser dans les outils de dveloppement dinterfaces graphiques.

24.4 Introspection
Mais comment un outil de dveloppement peut-il connatre les mthodes offertes par une classe sans lire le code source de celle-ci? Cest prcisment pour rpondre cette question qua t introduite lintrospection en Java. Lintrospection permet un systme de se regarder lui-mme pendant quil fonctionne. En Java, les objets de la classe Class reprsentent les classes du systme et les objets de la classe Method (dans le package java.lang.reflect) reprsentent les mthodes. Voici quelques exemples dintrospection : rechercher une classe daprs son nom
Class classeBouton = Class.forName("Bouton");

crer une nouvelle instance de cette classe


Object monBouton = classeBouton.newInstance();

rcuprer toutes les mthodes de cette classe


Method [] methodesBouton = classeBouton.getDeclaredMethods();

Sil existe dans la classe Bouton une mthode efface avec un paramtre de type Rectangle, on linvoque sur lobjet monBouton.
// cre le tableau des types de paramtres Class [] typesParam = { Class.forName("Rectangle") }

Javabook Page 351 Lundi, 12. juillet 1999 3:58 15

Introspection

351

// cre le tableau des types de paramtres Class [] typesParam = { Class.forName("java.awt.Rectangle") }; Method efface = classeBouton.getDeclaredMethod("efface", typesParam); // prpare les parametres effectifs Object[] valParam = {new Rectangle(1,1,100,191)}; efface.invoke(monBouton, valParam);

Ces exemples montrent quon peut non seulement connatre les mthodes dune classe et leurs paramtres, mais que lintrospection nous autorise crer des objets (newInstance()) et invoquer des mthodes (invoke()). Cest exactement ce que fait un outil de dveloppement interactif avec les Beans.

Javabook Page 352 Lundi, 12. juillet 1999 3:58 15

Javabook Page 353 Lundi, 12. juillet 1999 3:58 15

Chapitre 25

Processus et concurrence
La machine virtuelle Java permet lexcution concurrente de plusieurs processus dans un programme. Un processus Java est un objet auquel est associ un fil dexcution (thread) qui possde : un tat actif ou inactif, ltat actif tant subdivis en : prt lexcution, en excution, et en attente; un nom (une chane de caractres pas forcment unique); un contexte dexcution (instruction courante, pile de mmorisation des appels de mthodes, etc.). Les deux possibilits consistant crer des processus sont soit dfinir une sousclasse de Thread qui redfinit la mthode run(), soit crer un objet de Thread en donnant comme paramtre un objet de type Runnable (qui possde une mthode run()). La mthode start() initialise le processus et passe le contrle la mthode run() du processus ou de lobjet pass comme argument au constructeur du processus. Le processus sarrte lorsquil sort de la mthode run(). Diffrentes mthodes permettent de contrler et de synchroniser les processus : stop(), suspend(), resume(), sleep(), yield() (passe le contrle un autre processus en attente), join() (attend la fin dun processus). Par dfaut, une application Java ne contient quun seul processus qui est implicitement mis en marche au lancement de lapplication et qui appelle la mthode main().

Javabook Page 354 Lundi, 12. juillet 1999 3:58 15

354

Chapitre 25 Processus et concurrence

Une applet simple est contrle par un processus du butineur qui appelle les mthodes init(), start(), stop(), repaint(), etc., suivant les besoins.

Pourquoi utiliser plusieurs processus?


pour utiliser au mieux une machine multiprocesseur, un cas encore peu rpandu; pour effectuer des tches qui doivent se rpter intervalles rguliers et indpendamment des autres, par exemple redessiner une image anime toutes les cinquante millisecondes; pour simplifier le design des systmes qui fonctionnent en temps rel et ont des interactions asynchrones avec lextrieur (dans lexemple de lapplication de tldiscussion, un processus gre un client).

25.1 Problme de la concurrence daccs


En principe, tout processus peut accder tout objet de lapplication dont il fait partie. Les processus nont pas de mmoire prive, tout le monde travaille dans un espace commun. Lavantage de cette conception est quil ny a pas besoin de crer des canaux de communication entre processus; les changes entre processus peuvent passer par lintermdiaire dobjets. Par contre, laccs simultan au mme objet par deux processus peut causer dimportants problmes de cohrence. Par exemple, si un processus A excute linstruction :
if (a[1] != 0) { ...; c = b/a[1]; ... };

et quun processus B excute :


a[1] = 0;

aprs que A ait test a[1] != 0 mais avant quil ait eu le temps de faire b/a[1], alors une erreur de division par 0 se produira dans A, malgr le test qui prcde. Une manire dviter ce type de problme consiste garantir laccs exclusif un objet pendant lexcution dune ou plusieurs instructions.

25.2 La synchronisation en Java


La synchronisation en Java est base sur la technique des moniteurs de C.A.R. Hoare qui garantit laccs exclusif une ressource (en loccurrence un objet ou un tableau) pendant lexcution dune portion de code appele section critique. Chaque objet possde un moniteur daccs pour grer une file dattente des processus qui veulent avoir un accs exclusif lobjet. Une section critique est soit une mthode dont la dclaration est prcde du modificateur synchronized, soit une instruction prcde de synchronized(expression).

Javabook Page 355 Lundi, 12. juillet 1999 3:58 15

La synchronisation en Java

355

Pour que les instructions de lexemple prcdent fonctionnent correctement, il aurait fallu crire :
synchronized (a) if (a[1] != 0) { ...; c = b/a[1]; ... }

dans le processus A et :
synchronized (a) a[1] = 0;

dans B. La technique des moniteurs introduit un raffinement supplmentaire dans la synchronisation. Lorsquun processus possde laccs un objet, il peut appeler la mthode wait() de lobjet pour se mettre en attente et librer lobjet. Pour le sortir de cette attente, il faut quun autre processus excute un notify() sur cet objet et que lui-mme obtienne nouveau laccs exclusif lobjet. Les mthodes wait() et notify() existent pour tout objet (elles sont hrites de Object); elles ne peuvent tre appeles que lorsque le processus possde un accs exclusif lobjet. noter que lexcution de notify() ne libre pas lobjet. Lexemple suivant illustre leur utilisation; il sagit dun cas classique de producteur-consommateur. Un processus producteur produit des donnes (de simples entiers dans notre cas) et les place dans une file dattente. Un consommateur prend ce quil trouve dans la file. La file est ici limite un lment. Chaque objet de la classe Produit est une file dattente qui, pour simplifier, peut contenir 0 ou 1 lment entier (contenu). On peut ajouter ou retirer un lment et tester si la file est vide.
class Produit { int contenu; boolean vide; Produit() {vide = true;} void ajoute(int x) {contenu = x; vide = false;} int retire() {vide = true; return contenu;} boolean estVide() {return vide;} }

Lorsque la file est pleine, le processus producteur doit attendre que le processus consommateur la vide. Quand il a mis un nombre dans la file, il le signale afin de redmarrer le consommateur qui serait en attente.
class Producteur extends Thread { Produit produit; Producteur(Produit p) {this.produit = p;} public void run() { int ip; while (true) { ... synchronized (produit) { if (!produit.estVide()) { try produit.wait();

Javabook Page 356 Lundi, 12. juillet 1999 3:58 15

356

Chapitre 25 Processus et concurrence

catch (InterruptedException e); } ip = (int)(Math.random() * 1000); // produit un nb. alatoire produit.ajoute(ip); // signale quil y a qqch prendre produit.notify(); } } }}

Un consommateur prend ce quil y a dans la file de produits et laffiche; lorsquil ny a rien, il se met en attente. Lorsquil a vid la file, il le signale afin de dbloquer le processus producteur sil tait en attente.
class Consommateur extends Thread { Produit produit; Consommateur (Produit p) {this.produit = p;} public void run() { int jp; while (true) { synchronized (produit) { if (produit.estVide()) { try produit.wait(); catch (InterruptedException e); } jp = produit.retire(); produit.notify(); System.out.println(jp); } } }}

Le programme principal cre les deux processus et les dmarre :


public class ProdCons { public static void main(String[] argv) { Produit pp = new Produit(); Producteur pr = new Producteur(pp); Consommateur co = new Consommateur(pp); co.start(); pr.start(); }}

La figure 25.1 ci-aprs illustre le fonctionnement de synchronized, wait() et notify() dans le cas o le consommateur trouve la file vide. Cette solution fonctionne mais nest pas entirement satisfaisante du point de vue du design de lapplication. En effet, rien noblige passer par une instruction synchronized pour accder produit. Un processus sauvage dont le dveloppeur ne serait pas bien inform de la nature partage de produit pourrait y accder sans contrle et semer le trouble. Pour obtenir un mcanisme nettement plus sr, il faut se souvenir des principes de la programmation oriente objet et

Javabook Page 357 Lundi, 12. juillet 1999 3:58 15

La synchronisation en Java
consommateur synchronized (produit) synchronized (produit) wait producteur

357

notify sortie du synchronized sortie du synchronized

Lgende excution normale accs exclusif produit attente

Figure 25.1 Fonctionnement de la synchronisation

appliquer lencapsulation. Redfinissons ainsi notre classe Produit pour la rendre sre par rapport aux processus :
class Produit { int contenu; boolean vide; Produit() {vide = true;} synchronized void ajoute(int x) { while (!vide) { try wait(); catch (InterruptedException e);} contenu = x; vide = false; notify(); } synchronized int retire() { while (vide) { try wait(); catch (InterruptedException e);} vide = true; notify(); return contenu; } synchronized boolean estVide() {return vide;} }

Javabook Page 358 Lundi, 12. juillet 1999 3:58 15

358

Chapitre 25 Processus et concurrence

Dsormais, laccs un objet produit de la classe Produit passe obligatoirement par des mthodes synchronises, les mthodes utilisatrices de Produit nont plus se soucier de faire des synchronized. On peut rcrire le producteur beaucoup plus simplement :
class Producteur extends Thread { Produit produit; Producteur(Produit p) {this.produit = p;} public void run() { int ip; while (true) { try {sleep((int)(Math.random() * 1000));} catch (InterruptedException e) {}; ip = (int)(Math.random() * 1000); produit.ajoute(ip); } }}

25.3 .Interblocages
Laccs exclusif aux objets offre des garanties quant lintgrit des donnes et la consistance des traitements. Par contre, il introduit des dpendances entre processus du type : un processus A attend que B ait libr un objet O. Lorsque la chane des dpendances devient cyclique, il y a interblocage des processus. Par exemple, si A a obtenu laccs o1 et attend laccs o2 et B a obtenu laccs o2 et attend laccs o1. Les deux processus sont en attente : A attend sur B et B attend sur A, il y a interblocage. Seule une tude rigoureuse de la dynamique des processus, et en particulier des dpendances possibles, peut prvenir ce genre de problme. Il existe pour cela des techniques formelles comme la modlisation par rseaux de Petri.

Javabook Page 359 Lundi, 12. juillet 1999 3:58 15

Chapitre 26

Intgration des applets


Nous avons examin lutilisation de Java pour dvelopper des applications et des applets. Les applets que nous avons montres taient en fait de petits programmes qui sexcutaient sous la direction dun butineur ou dun visualiseur dapplet. Nous pouvons maintenant passer une autre vision des applets, en lien direct avec la notion de document et de document dynamique.

26.1 Documents et types de contenus


Les langages de balisage comme HTML, ou mieux SGML, ont pour fonction premire dindiquer le rle de chaque composante dun document. Dans HTML, les balises <Hn> et </Hn> dlimitent une partie du contenu de type entte de niveau n, les balises <UL>, <OL>, <DL> et </UL>, </OL> </DL> indiquent un contenu de type liste (ordonne, non ordonne, de dfinitions, etc.). On trouve galement des balises pour le type image, le type table, le type formulaire de saisie, et ainsi de suite. Cependant, les types de contenu admis par HTML sont et resteront certainement limits des types trs gnraux que lon retrouve dans la plupart des documents1. Cet tat de fait est parfois gnant pour des utilisateurs dun domaine particulier qui aimeraient bien avoir des types de contenus propres leur domaine.

1.

Par contre, le nombre de balises destines uniquement rgler lapparence des documents (fontes, centrage, bordures, etc.) va sans doute augmenter sous la pression des utilisateurs commerciaux du World-Wide Web.

Javabook Page 360 Lundi, 12. juillet 1999 3:58 15

360

Chapitre 26 Intgration des applets

26.2 Traiter de nouveaux types de contenu


Prenons le cas dun spcialiste du jeu dchecs qui souhaite rdiger des documents pdagogiques propos de ce jeu. Ses documents seront sans doute remplis de figures dcrivant des situations de jeu ou des enchanements de coups. Comme il nexiste pas de balise <ECHECS> en HTML, la seule solution consiste crer des images avec un logiciel de dessin et les incorporer au document laide dune balise <IMG>. Une autre solution consiste utiliser les applets! Supposons que notre spcialiste dcouvre quil existe sur le Web une applet Echec.class qui, partir dune situation donne par les valeurs des paramtres BLANCS et NOIRS, dessine un chiquier et les pices correspondant la situation. Il pourra alors insrer dans son document des balises de la forme :
<APPLET CODE="Echec.class" SOURCE="http://www.mon-club-echec.com/" WIDTH=500 HEIGHT=500> <PARAMETER NAME=BLANCS VALUE="Re1,Dd1,e2"> <PARAMETER NAME=NOIRS VALUE="Rb8,Ta7,b2"> </APPLET>

et le lecteur verra apparatre la situation sous forme de dessin. Mieux encore, il pourrait exister une applet AnimePartie.class capable de visualiser une partie coup par coup, davancer, de reculer, etc. Cette fois, le paramtre serait une chane de caractres dcrivant une partie selon lune des notations standard des checs. Lutilisation de cette applet ferait du document un document dynamique et interactif. Les applets Java nous permettent donc de grer des types de contenus qui ne sont pas prvus dans HTML (parties dchecs, molcules chimiques, pices mcaniques, etc.).

26.3 Dfinir une applet comme gestionnaire de contenu


Il y a deux points essentiels satisfaire pour quune applet devienne un gestionnaire de contenu valable : dfinir clairement le type de contenu que lapplet peut grer; dfinir en dtail la syntaxe des paramtres. Dans le cas de notre applet hypothtique AnimePartie, le type de contenu gr est nimporte quelle partie dchec et la syntaxe du paramtre est une partie dcrite selon la notation algbrique. Le document HTML devra contenir :
<H2>Gambit de la dame</H2> <APPLET CODE="AnimePartie.class" SOURCE="http://www.mon-club-echec.com/" WIDTH=500 HEIGHT=500> <PARAMETER NAME=PARTIE

Javabook Page 361 Lundi, 12. juillet 1999 3:58 15

Dfinir une applet comme gestionnaire de contenu

361

VALUE="1.d2-d4,d7-d5 2.c2-c4,e7-e6 3.Cb1-e3,Cg8-f6 4.Fc1-g5,Ff8e7"> </APPLET>

Parmi les applets de dmonstration fournies par Sun dans le JDK, se trouve une applet de dessin dynamique de graphe. Un graphe est dcrit par un paramtre edges, squence dartes de la forme nomNoeud1nomNoeud2 spares par des virgules. Ci-dessous se trouve lexemple dinclusion dun tel graphe dans un document :
<applet code="Graph.class" width=400 height=400> <param name=edges value="a1-a2,a2-a3,a3-a4,a4-a5,a5-a6,b1-b2,b2b3,b3-b4,b4-b5,b5-b6,c1-c2,c2-c3,c3-c4,c4-c5,c5-c6,x-a1,x-b1,xc1,x-a6,x-b6,x-c6"> </applet>

Figure 26.1 Applet paramtrable de graphe (Sun Microsystems)

N.B. Le livre que vous tes en train de lire ntant pas dynamique, nous avons d procder une copie dcran. Les outils fournis par Java pour traiter les paramtres Nous avons dj vu plusieurs reprises lutilisation de la mthode getParameter() de la classe Applet (voir lapplet du serpent, p. 303) qui fournit le String donn comme valeur dun paramtre dans une balise <APPLET>. Dautres mthodes et classes sont galement de premire utilit :

Javabook Page 362 Lundi, 12. juillet 1999 3:58 15

362

Chapitre 26 Intgration des applets

les mthodes de conversion de la classe String vers les types numriques que lon trouve dans les classes Float, Integer, Long et Double; la classe StringTokenizer qui analyse un String, unit syntaxique (token) par unit syntaxique. Cette dernire classe dfinit un itrateur qui parcourt la chane en fournissant un mot chaque appel la mthode nextToken().
String partie = getParameter("PARTIE"); StringTokenizer st = new StringTokenizer(partie, " "); while (st.hasMoreTokens()) { String unCoup = st.nextToken(); ... }

Le second paramtre du constructeur de StringTokenizer est une chane qui dtermine la liste des caractres utiliss comme sparateurs de mots, dans notre cas lespace.

Javabook Page 363 Lundi, 12. juillet 1999 3:58 15

Chapitre 27

Scurit en Java
Sun Microsystems a conu Java en y incorporant ds le dpart des critres de scurit. La scurit est un concept qui doit tre trait a priori et non a posteriori. Cette prise en compte de la scurit ds la conception est perceptible dans les diffrents choix qui ont t faits (absence de pointeur, vrification de types, gnration de byte-code, etc.). Ces choix amnent dautres aspects positifs : robustesse et portabilit des programmes, mais ils sont surtout ncessaires pour implanter le niveau de scurit vis. Nous avons dj expliqu pourquoi un tel niveau de scurit est requis. Rappelons quavec la gnralisation des butineurs ayant la capacit dexcuter du Java, il est possible de tlcharger des programmes depuis nimporte quel point du rseau Internet. Vous avez constat que la programmation en Java nest pas si complique et nous esprons que vous avez dj programm quelques applets, peuttre mme en avez-vous ajout une votre page personnelle. Si la scurit de Java nexistait pas, il vous serait possible dcrire une applet qui tablit une liste de tous les fichiers .EXE dun disque et qui la poste x@y.com, ou bien encore de vous procurer un virus connu ou inconnu pour linstaller sur un disque, etc. Sans la scurit de Java, personne ne voudrait prendre le risque de tlcharger et dexcuter des applets. Nous dveloppons ce chapitre sur la scurit pour contribuer, nous lesprons, une meilleure comprhension des mcanismes sous-jacents. Ceux-ci doivent tre publis (et comprhensibles), dune part pour quils soient crdibles et dautre part pour quils soient prouvs : sils sont vraiment srs, alors leurs concepteurs peuvent les publier sans crainte. Cette dmarche, utilise pour Java, a

Javabook Page 364 Lundi, 12. juillet 1999 3:58 15

364

Chapitre 27 Scurit en Java

dj permis de dcouvrir quelques faiblesses, non pas dans les principes mais dans le code de la machine virtuelle Java. Larchitecture Java comporte quatre niveaux de scurit : 1. Le langage et le compilateur. 2. Le vrificateur de byte-code. 3. Le chargeur de classes. 4. La protection des fichiers et des accs au rseau.

27.1 Le langage et le compilateur


Les risques majeurs lors de lexcution de code sont la manipulation involontaire de la mmoire abritant le code et les donnes (il sagit alors dune erreur), et la manipulation malintentionne de celle-ci en vue de : dtruire/modifier du matriel, du logiciel ou des informations sur la machine du client; publier des donnes considres comme confidentielles par le client 1 ; rendre la machine du client inutilisable en accaparant ses ressources. Les deux premiers points sont pris en charge par les concepts du langage et par le compilateur (le programme qui gnre du byte-code). Les points suivants liminent des risques de manipulation de la mmoire : labsence de pointeurs : le programmeur ne peut pas crer de fausses rfrences la mmoire, ni dtourner des mcanismes dassignation en vue de modifier le code du programme. Il ne peut pas explorer des zones de mmoire qui lui sont trangres (les variables private dautres objets); la vrification des bornes des vecteurs : le programmeur ne peut pas utiliser des indices en dehors des bornes comme moyen dexplorer ou de modifier la mmoire; la dsallocation automatique de la mmoire interdit, dune fa on subtile, quon dsalloue un objet tout en gardant une rfrence sur lui et que lon attribue cet emplacement un autre objet (dont le programmeur malintentionn aurait le contrle);

1.

Ce dernier point est assez difficile liminer. En effet, la nuisance est dans le comportement du programme, qui peut calculer sans interruption, tre bruyant, ouvrir des fentres, lancer des processus. Il existe la fois des programmes utiles et des programmes hostiles ayant un tel comportement. Nanmoins, de tels programmes hostiles ne peuvent que nuire temporairement, leurs auteurs risquant dtre rapidement ensevelis sous une avalanche de courrier lectronique.

Javabook Page 365 Lundi, 12. juillet 1999 3:58 15

Le vrificateur de byte-code

365

la vrification stricte des types nautorise pas la conversion implicite des types. Les droits daccs aux mthodes et aux variables sont vrifis la compilation pour dterminer sils sont en accord avec les spcifications de visibilit (protected, private, etc.). Les entiers ne peuvent pas tre convertis en objets et rciproquement. Le code Java de linterprteur et du compilateur sont disponibles, ainsi que la spcification du langage. Ainsi, chacun peut thoriquement vrifier que le code est bien conforme la spcification.

27.2 Le vrificateur de byte-code


Le passage ltape suivante repose sur le compilateur et sur la dfinition du byte-code. La machine virtuelle Java a t conue afin de rendre le code portable sur des plates-formes physiquement diffrentes. De plus, le byte-code a t enrichi dinformations et dinstructions qui ne sont pas fonctionnellement utiles lexcution du code mais qui ont des vises de scurit. Le compilateur gnre ainsi des lments de code qui sont structurellement vrifiables et qui possdent de bonnes proprits. Linterprteur de byte-code ne consommant pas directement le code gnr par le compilateur, est oblig de refaire la preuve des bonnes proprits du code quil doit excuter. En effet, on pourrait imaginer que quelquun tablisse un compilateur hostile ou modifie manuellement le fichier compil dune classe. La vrification est dpendante de la machine virtuelle, caractrise par : des types primitifs (six) : entiers 32 bits, entiers longs 64 bits, flottants 32 bits, doubles 64 bits, rfrences des objets, adresses de retour; des structures de vecteurs bases sur les types primitifs et tendues aux octets, aux entiers courts (short) et aux caractres Unicode. Ces structures contiennent des informations supplmentaires telles que le type dobjets accepts par le vecteur; une structure de pile, avec des registres de manipulation de la pile. Chaque mthode reoit une pile pour lvaluation et un ensemble de registres; le jeu dinstructions de la machine; il est partitionn en catgories : empiler des constantes; manipuler la valeur dun registre; accder aux valeurs dun vecteur; manipuler la pile (empiler, dpiler, changer, etc.); instructions arithmtiques, logiques, de conversion; instructions de transfert du contrle;

Javabook Page 366 Lundi, 12. juillet 1999 3:58 15

366

Chapitre 27 Scurit en Java

fonction de retour; manipulation des champs dun objet; invocation de mthode; cration dun objet; conversion de type (casting). Les instructions sont ventuellement suivies par des arguments sur leurs oprandes. Lespace mmoire de la machine est rparti en diffrentes zones : une zone mmoire o seront crs les objets; une zone de constantes htrognes (pool); une zone de description pour le byte-code; une zone dactivation pour chaque mthode comprenant une pile et des registres locaux.

Tester le format du fichier .class


La premire tche du vrificateur est de tester le format du fichier de byte-code quil est en train de charger. Le fichier de byte-code dune classe comprend : une constante magique; des informations propos des versions; des informations sur la classe (nom, super-classe, interface, etc.); des informations sur tous les champs et les mthodes de cette classe; des informations de mise au point (debugging); un raton laveur (mais oui, voyons); la description de la zone de constantes contenant : les valeurs des String; les chanes de caractres Unicode; les rfrences aux champs et aux mthodes; les noms des classes et des interfaces; pour chaque mthode, nous avons : le nom et la signature de la mthode; la taille maximum utilise sur la pile; le nombre maximum de registres locaux; une table des exceptions; les bytes-codes de la mthode.

Javabook Page 367 Lundi, 12. juillet 1999 3:58 15

Le vrificateur de byte-code

367

Le fichier lu, on vrifie son nombre magique (pour sassurer que la transmission est correcte), ensuite on vrifie le format du fichier (attribut et longueur des attributs). Le fichier doit tre complet, sans ajout ni limination. La structure de la zone de constantes doit tre correcte.

Tester la vraisemblance
La deuxime tape va tester la vraisemblance des structures et des rfrences dans la zone de constantes. Les vrifications suivantes sont effectues : la structure des classes finales nest pas tendue (idem pour les mthodes finales); toutes les classes ont une super-classe; toutes les rfrences des champs et des mthodes ont des noms bien forms et des signatures lgales dans la zone de constantes. Dans cette tape, on ne cherche pas savoir si les noms existent vraiment, mais seulement si la forme des noms est correcte.

Prouver la description
Cette tape est dcisive. Il sagit de vrifier pour chaque mthode que son modle dexcution est correct. Ce modle est le suivant : chaque point du programme, on peut associer un tat de la pile (longueur et type des lments); cet tat est indpendant des possibilits dexcution qui prcdent ce point; les registres locaux ne sont pas accds avant davoir reu une valeur (de type compatible); les mthodes sont invoques avec des arguments corrects; les champs des objets sont modifis avec des valeurs spcifies par leur type; les bytes-codes ont des arguments corrects (par rapport aux registres locaux, la pile et la zone de constantes). Concentrons-nous sur la premire contrainte : elle ncessite de construire un modle dexcution de la classe simulant les diffrentes possibilits, afin de vrifier que chaque chemin mnera bien au mme tat. On va ainsi transformer les bytes-codes en flux de donnes. Les bytes-codes vont tre regroups en squences dinstructions. Chaque instruction doit comporter un dbut et une fin; quitter linstruction au milieu est interdit, se brancher au milieu galement. Chaque instruction va tre vrifie (accs aux registres locaux, rfrences la zone des constantes). chaque instruction va tre associe une prcondition qui mmorise ltat de la pile et lutilisation des registres locaux en termes de types.

Javabook Page 368 Lundi, 12. juillet 1999 3:58 15

368

Chapitre 27 Scurit en Java

Les bytes-codes de la machine virtuelle sont conus de manire ce que ltat de la pile soit entirement dtermin par le type des oprandes et le code excuter. Ltat de la pile nest donc pas conditionn par les valeurs (mais seulement par les types). Lanalyse du flux de donnes ne prendra en compte que les types des objets. La premire instruction de la mthode est initialise avec une pile vide, les registres locaux contenant les types indiqus par la signature de la mthode. Cette instruction est marque vrifier. Lalgorithme de lanalyseur est conceptuellement le suivant : 1. Chercher une instruction marque vrifier . Sil ny en a plus, la mthode est vrifie. 2. Simuler leffet de linstruction sur la pile et sur les registres : a) en vrifiant quil ny a pas de dpassement des dimensions de la pile (underflow et overflow) par rapport la taille maximum indique pour la mthode; b) en vrifiant la conformit des types utiliss sur la pile; c) en vrifiant que les registres utiliss soient initialiss et accessibles la mthode (nombre maximum de registres). la fin du point 2, on a dtermin un nouvel tat de la pile et des registres. 3. Dterminer la prochaine instruction excuter, qui peut tre soit : a) la prochaine instruction; b) les branches dune instruction conditionnelle; c) un retour ou une mission dexception. 4. Dterminer ltat de la pile pour les instructions suivantes : a) si la nouvelle instruction est visite pour la premire fois, on initialise cet tat avec celui obtenu en 2); b) sil existe dj un tat, il faut fusionner les deux tats. Les piles doivent tre de taille gale. Les types doivent tre gaux. Dans le cas de conflit entre deux classes, on choisit lanctre commun le plus proche. Pour fusionner les registres, on vrifie la compatibilit des types; en cas dincompatibilit, le registre prend ltat indfini. Si la prcondition de linstruction suivante est modifie, elle est marque comme vrifier; la marque de linstruction examine est efface, on recommence au point 1. Toute anomalie survenant pendant la vrification provoque labandon de la vrification avec un statut ngatif.

Javabook Page 369 Lundi, 12. juillet 1999 3:58 15

Le vrificateur de byte-code

369

Nous prsentons des exemples qui montrent bien le principe de cette vrification (nous restons ici au niveau du compilateur qui utilise des mcanismes similaires). Soit deux classes O1 et O2 :
class O1 { int f1() {return 1;} } class O2 { int f2() {return 2;} }

Le programme suivant (Securite1) tente de construire un tat ambigu lissue de la premire condition : soit o1 est cr, soit o2 est cr. La deuxime condition risque dutiliser une variable non initialise. Le compilateur ne peut accepter cette ambigut et la signale.
// Classe refuse la compilation: class Securite1 { public static void main (String args[]) { int i=1; O1 o1; O2 o2; if (i==1) o1=new O1(); else o2=new O2(); if (i==1) System.out.println(o1.f1()); // variable o1 peut ne pas tre initialise else System.out.println(o2.f2()); // variable o2 peut ne pas tre initialise } }

On peut rcrire ce programme dune autre manire (Securite2). Le compilateur laccepte, car la vrification des conversions de type allant du gnral au particulier est repousse lexcution. Ces conversions doivent donc tre utilises avec prudence car elles peuvent tre source derreurs lexcution.
// Classe accepte la compilation pouvant gnrer une erreur // lexcution class Securite2 { public static void main (String args[]) { int i=1; Object o; if (i==1) o=new O1(); else o=new O2(); if (i==1) System.out.println(((O1)o).f1()); else System.out.println(((O2)o).f2()); } }

Javabook Page 370 Lundi, 12. juillet 1999 3:58 15

370

Chapitre 27 Scurit en Java

Pour ceux qui croient encore que lon peut sen passer, voici un dernier exemple de programme montrant que les vrifications statique et dynamique des types sont une affaire dordinateurs.
class O1 { int f1() {return 1;} O1 f(O2 o) {return new O2 f(O1 o) {return new } class O2 { int f2() {return 2;} O1 f(O2 o) {return new O2 f(O1 o) {return new } O1();} O2();}

O1();} O2();}

class Securite { public static void main (String args[]) { int i=1; O2 o2=new O2(); //oui lexpression est bien un O1! O1 o1=o2.f(o2).f(o2.f(o2)).f(o2).f(o2.f(o2).f(o2.f(o2)). f(o2)).f(o2.f(o2).f(o2.f(o2)).f(o2)).f(o2).f(o2.f(o2). f(o2.f(o2)).f(o2).f(o2.f(o2).f(o2.f(o2)).f(o2)). f(o2.f(o2).f(o2.f(o2)).f(o2)).f(o2)).f(o2.f(o2). f(o2.f(o2)).f(o2).f(o2.f(o2).f(o2.f(o2)).f(o2)). f(o2.f(o2).f(o2.f(o2)).f(o2)).f(o2)).f(o2); System.out.println(o1.f1()); } }

Optimiser lexcution
En cas de succs, le vrificateur effectue un dernier passage sur le code pour remplacer certaines instructions par leur version rapide (_quick). Par exemple, les codes new, invokestatic, anewarray, etc., sont remplacs par new_quick, invokestatic_quick, anewarray_quick, etc. partir de ce moment, pour excuter le byte-code, on peut utiliser : un simple interprteur de byte-code : les instructions sont interprtes chaque excution; un interprteur associ un compilateur la vole : les instructions sont compiles (code natif de la machine cliente) lors de leur premire excution et ce code est excut lors des excutions ultrieures; un compilateur de byte-code crant du code natif; et bientt sans doute un processeur Java (projet de Sun Microsystems) qui excutera directement le byte-code.

Javabook Page 371 Lundi, 12. juillet 1999 3:58 15

Le chargeur de classes

371

27.3 Le chargeur de classes


Lors de cette dernire tape, qui a lieu pendant lexcution du code, on charge les classes (non encore charges) invoques par linstruction en cours dexcution. On vrifie ce moment que cette instruction est autorise rfrencer la classe charge. De mme, on vrifie pour chaque accs un champ ou une mthode appartenant une classe charge dynamiquement que la mthode ou le champ rfrenc existe, que les signatures sont compatibles et les droits de visibilit respects. Chaque classe est charge dans un espace de noms qui lui est propre. Il est donc impossible quune des classes de base (java.lang, par exemple) soit remplace par une classe charge dynamiquement. Les classes gardent toujours la marque de leur provenance (le nom complet du package, qui indique le nom du serveur). Ces vrifications peuvent dtecter des changements de dfinitions dans les classes charges. lissue de la vrification, on a une assurance formelle sur la qualit du bytecode. Cela permettra dviter certains tests sur la compatibilit des types, sur lutilisation de la pile, etc. , car on a dj lassurance que ces contraintes sont respectes (linterprteur de byte-code sera donc plus performant).

27.4 La protection des fichiers et des accs au rseau


Lutilisateur peut dfinir des droits par rapport laccs aux fichiers locaux et aux ressources de communication. Le droit daccs aux fichiers locaux dfini par dfaut est demande lapprobation de lutilisateur1. Les droits de communication sont dtermins par la combinaison entre la source du byte-code et lemplacement de son excution.
Emplacement source Extrieur du mur pare-feu Intrieur du mur pare-feu Intrieur du mur pare-feu Emplacement excution Intrieur du mur pare-feu Extrieur du mur pare-feu Intrieur du mur pare-feu

Tableau 27.1 Table des droits de communication

1.

Le butineur actuel de Netscape quant lui ne prend aucun risque, il interdit lcriture et la lecture locales.

Javabook Page 372 Lundi, 12. juillet 1999 3:58 15

372

Chapitre 27 Scurit en Java

On peut ainsi adopter diffrentes politiques comme, par exemple, ne pas autoriser les applets extrieures communiquer lintrieur du mur pare-feu, ou autoriser lapplet communiquer uniquement avec sa source (le serveur do lon a charg la classe), etc. Ajoutons encore que ces mcanismes de scurit doivent tre modifis avec circonspection. Finalement, si la scurit doit tre adapte une situation particulire, la classe SecurityManager peut tre tendue, afin de supporter de nouveaux degrs de protection ou de nouveaux critres de protection.

Javabook Page 373 Lundi, 12. juillet 1999 3:58 15

Chapitre 28

Java et les bases de donnes


JDBC
La nature distribue de Java, sa portabilit et ses possibilits daccs des machines distantes le positionnent comme un langage de choix pour le dveloppement dapplications interagissant avec des systmes de gestion de bases de donnes (SGBD). De plus, les mcanismes de scurit propres Java limitent les possibilits daccs des donnes locales (fichiers). Dans ce contexte, les acteurs du monde des bases de donnes (vendeurs de SGBD, de middleware, doutils CASE) ont dvelopp des solutions propritaires, cest--dire spcialises dans linteraction entre Java et leur propre systme. Ainsi, une certaine pression sest exerce sur les concepteurs de Java afin quils ajoutent au langage des fonctionnalits daccs des bases de donnes. La raction se devait dtre rapide, la multiplication de solutions labores sans souci de standardisation tant contraire lesprit de Java et risquant de lui faire perdre lun de ses avantages principaux, savoir sa portabilit. Dans le cas de laccs des bases de donnes, la portabilit signifie une certaine indpendance vis--vis du SGBD et du protocole de connexion utiliss. Une telle indpendance ne peut tre ralise quen se basant sur un ensemble de classes et de mthodes communes, regroupes sous le terme dinterface de programmation dapplications (API, en anglais).

Javabook Page 374 Lundi, 12. juillet 1999 3:58 15

374

Chapitre 28 Java et les bases de donnes

La rponse des concepteurs de Java a t la publication dune proposition dAPI dfinissant linteraction entre un programme Java et une base de donnes (relationnelle dans un premier temps). Cette API, nomme JDBC (Java DataBase Connectivity), supporte les fonctionnalits de base de SQL (langage dinterrogation des SGBD relationnels). En ce sens, elle peut tre considre comme une API de bas niveau, simple et robuste ( limage de Java), lide tant de construire par la suite des niveaux suprieurs tels que systmes de transactions, diteurs de schmas, etc. JDBC est base sur les dfinitions de X/Open SQL CLI (Call Level Interface), tout comme ODBC, la solution de Microsoft pour laccs des bases de donnes. JDBC prsente ainsi de nombreuses similitudes avec ODBC et dfinit une interface Java pour les principaux concepts de X/Open CLI. La spcification complte de JDBC est disponible chez Sun [4]. Nous reviendrons au point 28.3 sur les objectifs de JDBC et sur ses relations avec ODBC, SQL et Java.

28.1 Architecture de JDBC


JDBC est compose de deux ensembles dinterfaces abstraites : JDBC API; JDBC Driver API.

JDBC API
LAPI JDBC est destine aux dveloppeurs de programmes Java (applets et applications) dsirant interagir avec un SGBD relationnel. Elle dfinit les structures ncessaires la connexion une base de donnes, lenvoi de requtes SQL et la rception de leurs rsultats. Les principales interfaces dfinies dans lAPI JDBC se trouve dans le tableau 28.1 .
Interface
java.sql.CallableStatement java.sql.Connection

Description

Gre linvocation de procdures stockes. Gre les connexions existantes, cre les requtes, gre les transactions. Gre les accs un SGBD travers un protocole. Gre le chargement des drivers et la cration des connexions TCP.

java.sql.Driver

java.sql.DriverManager

Tableau 28.1 Interfaces de lAPI JDBC

Javabook Page 375 Lundi, 12. juillet 1999 3:58 15

Principaux lments de JDBC


Interface
java.sql.PreparedStatement java.sql.ResultSet java.sql.Statement

375
Description

Reprsente une requte paramtre. Gre laccs aux tuples dun rsultat. Gre les requtes excuter, reoit les rsultats.

Tableau 28.1 Interfaces de lAPI JDBC

JDBC Driver API


Linterface java.sql.Driver est destine aux dveloppeurs de drivers (pilotes) dsirant interfacer un SGBD Java en utilisant JDBC. La programmation dun driver JDBC consiste implanter les lments dfinis dans les interfaces abstraites de lAPI JDBC.

28.2 Principaux lments de JDBC


Les points suivants dcrivent les principaux lments (interfaces, classes) composant JDBC. Outre le DriverManager, gestionnaire des diffrents drivers disponibles, les notions de Connection, Statement et ResultSet ralisent linteraction avec une base de donnes. Le choix de ces trois notions nest pas propre JDBC : en effet, dautres API bases sur un dcoupage identique ont t commercialises pour diffrents environnements de dveloppement. Parmi celles-ci on peut citer : DB Kit de NeXT, pour lenvironnement NEXTSTEP (Objective C); DataLens de ParcPlace, pour VisualWorks (Smalltalk); DBTools.h++ de Rogue Wave (C++).

DriverManager
Le DriverManager gre la liste des drivers JDBC chargs dans la machine virtuelle Java. Il sert galement mettre en correspondance les URL utiliss par les connexions avec les drivers disposition. Ainsi, le DriverManager dcortique les URL afin den extraire le sous-protocole et le service, puis recherche dans sa liste de drivers celui (ou ceux) capable(s) dtablir la connexion. Dans le cas o plusieurs drivers sont disponibles, le DriverManager peut consulter une proprit Java (sql.drivers) que lutilisateur a la possibilit de configurer; cette proprit regroupe une liste de noms de drivers. Le DriverManager parcourt alors cette liste dans lordre, choisissant le premier driver utilisable. Dans le cas o la proprit sql.drivers nest pas dfinie, cest lordre dans lequel les drivers ont t chargs qui sera considr.

Javabook Page 376 Lundi, 12. juillet 1999 3:58 15

376

Chapitre 28 Java et les bases de donnes

Prcisons encore que la proprit sql.drivers est utilise par le DriverManager au moment de son initialisation : il charge alors lensemble des drivers indiqus dans la liste, les plaant ainsi en tte des drivers disponibles.

Connection
Une Connection reprsente un canal de communication (une connexion) entre un programme Java et une base de donnes. La cration et la gestion des Connections sont prises en charge par le DriverManager. Une Connection est cre partir dun URL dcrivant le protocole et le service utiliser. Lors de la cration dune Connection, des arguments tels que le nom de lutilisateur et son mot de passe peuvent tre fournis sous la forme dobjets de la classe java.util.Properties. Une fois cre, une Connection va servir envoyer des requtes au SGBD et rcuprer les rsultats, ces deux tches tant effectues laide des interfaces Statement (requte) et ResultSet (ensemble rsultat). Prcisons encore quune Connection peut servir de multiples squences requte/rsultat et quil nest donc pas ncessaire de crer systmatiquement une nouvelle Connection pour chaque requte. Transactions Linterface Connection est capable de grer des transactions SQL. Par dfaut, une Connection est place en mode de commit (confirmation) automatique : chaque requte est excute dans une transaction SQL spare puis confirme automatiquement. Ce mode peut tre dsactiv (mthode setAutoCommit()) afin de regrouper lexcution de plusieurs requtes en une seule transaction. En mode non automatique, la Connection maintient ouverte une transaction courante, qui peut tre confirme (Connection.commit()) ou annule (Connection.rollback()) au moment voulu. La Connection libre alors cette transaction et en cre immdiatement une nouvelle.

Requtes SQL dans JDBC


Les requtes SQL sont reprsentes dans JDBC laide des interfaces Statement, PreparedStatement et CallableStatement. Chacune de ces interfaces est spcialise dans un type particulier de requtes, comme le montre le tableau 28.2 .
Interface
Statement

Description Requtes SQL statiques.

Tableau 28.2 Fonctions des interfaces pour les requtes SQL

Javabook Page 377 Lundi, 12. juillet 1999 3:58 15

Principaux lments de JDBC


Interface
PreparedStatement CallableStatement

377
Description Requtes SQL paramtres. Procdures stockes paramtres.

Tableau 28.2 Fonctions des interfaces pour les requtes SQL

Avant de dcrire ces diffrentes interfaces, prcisons quune requte doit tre obtenue auprs dune Connection existante avant de pouvoir tre prpare et excute. Le rsultat dune requte est obtenu auprs de la requte elle-mme.

Statement
Statement est destine aux requtes SQL simples, cest--dire celles dont lexpression SQL est prte lemploi, pouvant tre transmises telles quelles au SGBD. Une fois obtenue auprs dune Connection, une requte peut tre excute, son rsultat prenant la forme dun ResultSet (voir le point ResultSet) dans le cas dun SELECT. Ce rsultat peut alors tre vrifi (valeur NULL, ensemble vide, etc.) et parcouru ligne par ligne. Les ordres DELETE, INSERT, UPDATE quant eux retournent un entier. PreparedStatement (extension de Statement) PreparedStatement permet de crer une requte contenant des paramtres. Une telle requte est destine tre prpare et excute plusieurs fois de suite, avec des valeurs de paramtres diffrentes. Son code SQL contient des caractres ? indiquant lemplacement des paramtres, qui sont ensuite remplacs par des valeurs claires au moment de lenvoi de la requte la Connection associe. La mise jour des paramtres (binding) est ralise en invoquant les mthodes PreparedStatement.set...() adaptes aux types des paramtres. Le binding est effectu avant chaque excution, prparant ainsi la requte. noter quun paramtre, une fois mis jour, peut servir plusieurs excutions successives de la requte, la mthode clearParameters() permettant de vider lensemble des paramtres. CallableStatement (extension de Statement) CallableStatement est destine excuter des procdures stockes dans le SGBD. Les procdures de ce type acceptent gnralement des paramtres en entre (IN) et fournissent dautres paramtres (OUT) en sortie. Lassignation des paramtres IN seffectue laide des mthodes PreparedStatement.set...(). Les paramtres OUT doivent tre dclars (CallableStatement.registerOutParameter()) avant lexcution de la procdure : on invoque une fois cette mthode pour chaque paramtre OUT, en indiquant son type SQL.

Javabook Page 378 Lundi, 12. juillet 1999 3:58 15

378

Chapitre 28 Java et les bases de donnes

Aprs lexcution, les paramtres OUT peuvent tre rcuprs laide des mthodes CallableStatement.get...() adaptes leurs types.

ResultSet
Une requte SQL produit diffrents types de rsultats. Dans le cas dune insertion, dune mise jour ou dune suppression, le rsultat retourn par le SGBD est gnralement un nombre entier indiquant uniquement le nombre de tuples ayant t touchs par la modification. Au contraire, dans le cas dune slection (ordre SELECT), le rsultat, fourni sous la forme dun ensemble de tuples gr par un ResultSet, est beaucoup plus intressant. Nous allons donc commencer par dcrire le rsultat dune slection avant de mentionner celui des autres ordres SQL.

Rsultat dun ordre SELECT


La mthode executeQuery() excute une requte et retourne le rsultat sous forme dun ResultSet. Un ResultSet est un ensemble de lignes (chaque ligne reprsentant un tuple de la relation rsultat); chaque ligne comporte le mme nombre de colonnes (chaque colonne reprsentant un attribut de la relation rsultat). De nombreuses mthodes sont dfinies dans la classe ResultSet afin de pouvoir parcourir le rsultat ligne par ligne et daccder de diffrentes manires aux colonnes de la ligne courante. Au niveau du programme Java, une simple boucle while combine la mthode ResultSet.next() permet de rcuprer chaque ligne du rsultat, comme le montre lexemple suivant :
// // // // admettons quune Connection conn soit deja tablie nous allons slectionner certains tuples de la relation AMI dont les attributs sont: prenom (VARCHAR), age (INTEGER), remarque (VARCHAR)

java.sql.Statement requete = conn.createStatement(); ResultSet resultat = requete.executeQuery ("SELECT prenom, age FROM AMI WHERE age > 14"); // on sintresse aux personnes de plus de 14 ans while (resultat.next()) { // on rcupre le prnom et lge de chaque tuple int a = resultat.getInt ("age");// accs par le nom de colonne string p = resultat.getString (1);// accs par lindex de colonne System.out.println (p + " est age(e) de " + a + "ans"); }

Cet exemple illustre les deux manires de rfrencer une colonne : laide de son nom (ex. : "age"); laide de son index (ex. : 1 pour la premire colonne).

Javabook Page 379 Lundi, 12. juillet 1999 3:58 15

JDBC et les standards

379

Il existe ainsi deux versions de chaque mthode ResultSet.get...(), lune acceptant une chane de caractres, lautre un entier. La notion de curseur est ralise laide de la mthode getCursorName() qui retourne un curseur associ au ResultSet courant. JDBC ne fournit pour linstant quun support simpliste de la notion de curseur, qui sera certainement toff dans le futur. Une fois encore, labsence de standard dans ce domaine justifie ce choix minimaliste.

Rsultat dun ordre UPDATE, INSERT ou DELETE


Les ordres de mise jour ne retournent gnralement que des indications concernant le nombre de tuples touchs par lexcution ou concernant le statut de la requte (excute, refuse, etc.). Le code ci-dessous montre un exemple de mises jour effectues laide dune PreparedStatement. Le nombre de tuples touchs par chaque excution est rcupr dans la variable nbTuples.
java.sql.PreparedStatement requete = conn.prepareStatement("UPDATE AMI SET remarque = ? WHERE age = ?"); // le 1er paramtre est fix une fois pour toutes requete.setString(1, "fte une dizaine"); for (ans = 10; ans < 120; ans += 10) { requete.setInt(2, ans);// 2me paramtre: varie selon lexcution int nbTuples = requete.executeUpdate(); // nombre de tuples touchs }

28.3 JDBC et les standards


La dmarche des concepteurs de JDBC sattache faire accepter cette API par lensemble des acteurs concerns : dveloppeurs de SGBD, doutils CASE, denvironnements de programmation, etc. Leur choix sest donc port sur des lments (syntaxe, formats, structures) connus et dj utiliss dans le domaine, savoir ODBC et SQL. Ds lors, on peut se poser la question suivante : pourquoi ne pas avoir directement intgr ODBC dans Java plutt que de dvelopper une API spcifique? Les points suivants tentent dy rpondre en dcrivant tour tour les rapports entre JDBC, ODBC, SQL et... Java.

JDBC et ODBC
La rponse la question pose ci-dessus, savoir pourquoi ne pas avoir intgr ODBC dans Java, se rsume en quelques mots : ODBC est trs (trop) li au langage C.

Javabook Page 380 Lundi, 12. juillet 1999 3:58 15

380

Chapitre 28 Java et les bases de donnes

Ainsi, ODBC se base sur des lments propres au C tels que les types, les pointeurs ou lusage des (void *). Compte tenu des diffrences entre Java et C dans ce domaine (voir annexe A), une intgration dODBC dans Java naurait pu seffectuer que de manire force, mme si elle tait techniquement ralisable. Dautre part, ODBC passe pour tre un systme compliqu, difficile apprendre et mettre en uvre, y compris pour des utilisations simples. Enfin, la paramtrisation dODBC seffectue laide de fichiers de configuration stocks localement, ce qui va lencontre des principes de scurit de Java (du moins en ce qui concerne les applets). Ces diffrents aspects montrent que lintgration Java-ODBC scarte de la philosophie Java en matire de simplicit, duniformit et de robustesse. Ainsi, sans jamais remettre en question les qualits et les avantages du couple C-ODBC (disponibilit sur de nombreuses plates-formes, large diffusion, performance, etc.), les concepteurs de Java ont choisi de raliser dans un premier temps lAPI JDBC que lon peut situer au-dessus de la couche ODBC, celle-ci jouant le rle de sousprotocole et pouvant tre utilise laide de passerelles JDBC-ODBC. Un exemple complet en fin de chapitre, utilise cette passerelle.

JDBC et SQL
Le but de JDBC est de permettre un programme Java de transmettre des ordres SQL une base de donnes et de rcuprer les rsultats ventuels dans des structures Java (objets, tableaux, etc.) afin de les traiter. JDBC supporte les fonctionnalits de base de SQL, telles que dfinies dans la norme SQL2 Entry Level. Ce choix quelque peu restrictif se justifie par le fait quil reprsente le dnominateur commun en matire de SQL entre les principaux SGBD relationnels. Ici encore, lide des concepteurs de JDBC est doffrir rapidement un noyau de bas niveau commun et standardis, des fonctionnalits de plus haut niveau pouvant tre dfinies par la suite sous forme de nouvelles API ou doutils Java invoquant JDBC. cet effet, des mcanismes dextension de JDBC ont t prvus : lments de syntaxe, conversions de types. Les principes suivants ont t retenus : JDBC permet un programme Java de transmettre nimporte quelle requte un SGBD, autorisant ainsi lutilisation des fonctionnalits propres celui-ci. Cette possibilit risque nanmoins de compromettre srieusement la portabilit de ce programme sur un autre SGBD; un label de conformit JDBC Compliant a t dfini par Sun. Un driver JDBC dsirant obtenir ce label devra se soumettre des tests montrant quil supporte au minimum SQL2 Entry Level. Ds que ce label se sera impos comme LA rfrence en matire de driver JDBC,

Javabook Page 381 Lundi, 12. juillet 1999 3:58 15

Utilisation de JDBC

381

les programmes Java pourront utiliser cet ensemble dordres tout en restant portables. plus long terme, le but est de supporter la totalit de la norme SQL2, lorsque celle-ci aura vraiment t adopte et surtout lorsque les principaux SGBD la supporteront de manire complte.

JDBC et Java
JDBC, cest du Java! Cette exclamation reflte bien le souci des concepteurs de JDBC de conserver lesprit Java dans leur API. En effet, limmense succs de ce langage est trs li sa relative simplicit et llgance de bon nombre de ses concepts. Ds lors, JDBC, comme toutes les (futures) API Java, se doit dapparatre comme une extension naturelle du langage et non comme un empltre ajout de force. Influence de Java sur JDBC Les principes de base de Java se retrouvent dans lensemble de lAPI. Ainsi, lutilisation dexpressions fortement types est encourage, afin de maximiser les contrles derreurs la compilation (cet aspect du typage fort pose dailleurs quelques problmes). Nanmoins, la nature dynamique des rsultats de certaines requtes SQL est prise en compte par JDBC. De mme, lAPI est dfinie de manire relativement simple et cohrente, noffrant gnralement que peu dalternatives la ralisation dune tche. Enfin, JDBC, comme dautres librairies Java, utilise abondamment les principes de la programmation oriente objet, comme par exemple lhritage, le polymorphisme ou les interfaces. Un nombre relativement important de mthodes a ainsi t dfini, mthodes spcialises dans une tche prcise et facile comprendre.

28.4 Utilisation de JDBC


Les distinctions faites en matire de scurit entre une applet Java et une application Java restent valables dans le contexte de JDBC : pour une applet : le stockage local est interdit et les connexions travers un driver se limitent la machine do provient le driver; pour une application : dans ce cas, laccs aux ressources locales et au rseau peut tre considrablement tendu, permettant ainsi le stockage local de donnes ou laccs simultan plusieurs SGBD. Ces lments font pencher la balance en faveur des applications Java lorsquil sagit daccder diffrentes bases de donnes dissmines sur le rseau. De

Javabook Page 382 Lundi, 12. juillet 1999 3:58 15

382

Chapitre 28 Java et les bases de donnes

mme, la possibilit de stocker des donnes de manire locale peut paratre indispensable, tout au moins dans des cas dune certaine complexit. La solution de lapplet reste intressante dans les cas les plus simples (et ils sont nombreux !), lintgration de lapplet dans un document HTML restant son principal avantage.

28.5 JDBC et la scurit


Les problmes de scurit sont bien videmment traits de manire srieuse dans JDBC, ceci dautant plus que, par dfinition, les accs des bases de donnes seffectuent travers le rseau. ce niveau, les concepteurs de JDBC distinguent les trois cas suivants : scurit des applets; scurit des applications; scurit des drivers.

Scurit des applets


Dans le cas des applets contenant des appels JDBC, des rgles ont t tablies afin de garantir un niveau de scurit quivalent celui dune applet ninvoquant pas JDBC. Ainsi, un driver JDBC une fois tlcharg ne pourra effectuer de connexions quavec des bases de donnes situes sur la machine do il provient. Il servira alors de point de passage commun aux diffrentes connexions tablies par des classes provenant de cette machine. De mme, une applet Java ne pourra tablir de connexions quavec des bases de donnes situes sur la machine do elle est issue. Enfin, une applet ne devrait pas tre autorise accder dventuelles donnes locales. Si le conditionnel est parfois utilis dans ce texte, cest que certaines rgles proposes par les concepteurs de JDBC peuvent ne pas tre respectes par certains drivers, do lintrt du label mentionn au point JDBC et SQL, p. 380.

Scurit des applications


Une application Java, avec ou sans appels JDBC, est gnralement considre comme sre. Ds lors, les restrictions cites ci-dessus ne sont pas applicables. Nanmoins, un cas de figure reste dlicat : lorsquun driver est charg depuis une machine, alors ce driver ne devrait tre utilis que par du code provenant de cette mme machine.

Scurit des drivers


Les dveloppeurs de drivers doivent quant eux observer certaines rgles lmentaires de scurit afin de protger leur code contre des utilisations abusives,

Javabook Page 383 Lundi, 12. juillet 1999 3:58 15

Formats dURL et JDBC

383

aussi bien par des applets locales (attaque depuis lintrieur) que par du code tlcharg (attaque depuis lextrieur). En effet, le driver est un maillon sensible de la chane de connexion entre un client et un serveur. Les recommandations des concepteurs de JDBC concernent plus particulirement la phase douverture des connexions rseau (TCP/IP). Dans le cas le plus simple dune connexion non partage, les contrles effectus par le SecurityManager suffisent garantir la scurit dune connexion, cest--dire que lobjet Java demandant la connexion est bien autoris accder la machine en question. La diffrence apparat lorsquun driver dsire pouvoir partager une connexion TCP entre plusieurs Connections JDBC (par exemple, lorsque plusieurs processus interrogent la mme base de donnes en parallle). Dans ce cas, cest au driver de vrifier que les diffrents clients (threads, classes) sont tous bien autoriss accder la base de donnes dfinie dans la connexion TCP partage. L encore, lutilisation du SecurityManager est recommande afin de vrifier les droits daccs. Le dveloppeur dun driver doit galement veiller la scurit des accs aux ressources du systme local. Le comportement sera diffrent selon quil sagit daccs uniques ou partags. Pour conclure, prcisons encore que toutes les mthodes dun driver doivent supporter des accs concurrents (multithread, voir chapitre 25).

28.6 Formats dURL et JDBC


Le systme de nommage utilis dans JDBC pour dcrire une connexion (driver, protocole, machine, etc.) est directement inspir de la notion dURL (voir le point URL, p. 11). Contrairement ODBC, JDBC ne suppose pas lexistence de fichiers de configuration contenant les informations ncessaires une connexion. Ce principe typiquement Java place la gestion de ces informations au niveau des connexions elles-mmes. La syntaxe des URL recommande est la suivante :
jdbc:sous-protocole:service

la chane jdbc indique le protocole, au mme titre que http; le sous-protocole est le mcanisme de connectivit utilis (odbc par exemple); le service (subname en anglais) est une chane de caractres indiquant la machine, le port et la base de donnes utiliss. Exemple de service :
mycpu.unige.ch:9876:mybase

Le mcanisme des URL a t retenu comme format gnrique de description des connexions JDBC, en raison de son statut de standard en matire de nommage des ressources sur le Web. Nanmoins, la syntaxe pourra varier selon les

Javabook Page 384 Lundi, 12. juillet 1999 3:58 15

384

Chapitre 28 Java et les bases de donnes

environnements (drivers, sous-protocoles, SGBD). Dans le cas du sous-protocole odbc (en minuscules dans les URL), une syntaxe a dj t spcifie afin de pouvoir inclure des valeurs de paramtres dans le nom du service.

quivalences de types entre Java et SQL


De nombreuses quivalences ont t tablies entre les types de donnes, aussi bien dans le sens Java-SQL (envoi de paramtres) que dans le sens SQL-Java (rsultats et paramtres retourns). Ces quivalences se refltent galement dans les nombreuses mthodes de conversion disposition du programmeur JDBC.

28.7 Base de donnes et Java : un exemple complet


Lapplication ci-dessous illustre la cration de table, linsertion, la mise jour et la destruction de donnes. Elle contient galement des interrogations ainsi quun exemple de traitement derreur. Cette application est btie sur deux classes : SQLService et ExampleWithJDBCOracle. La classe SQLService traite les requtes dinterrogation et de manipulation des donnes ou du schma. Elle utilise quatre mthodes : ExecDML qui effectue les traitements sur les donnes ou le schma; ExecSelect qui interroge puis affiche les rsultats de la requte; PrintResult qui affiche les rsultats ; PrintSQLError qui explicite en dtail une erreur de traitement sur la base, erreur signale par une exception (SQLException).

import java.sql.*; class SQLService { // instance variables public static String query; public static Connection con; public static Statement stmt; public static ResultSet results; public static String ExecDML(String sqlText) { /* permet d'executer une commande de manipulation des donnees - insert, delete, update ou de manipulation du schema - create, drop, ...*/ int ResultCode; try {stmt = con.createStatement(); ResultCode = stmt.executeUpdate(sqlText); return ("OK ("+ResultCode+"): "+sqlText); }

Javabook Page 385 Lundi, 12. juillet 1999 3:58 15

Base de donnes et Java : un exemple complet


catch (Exception ex) {return ( "** Erreur dans : "+sqlText);} } public static String ExecSelect(String sqlText) { /* permet d'executer une selection - select ... from ... where ... et d'afficher le resultat */ try {stmt = con.createStatement(); results = stmt.executeQuery( sqlText ); PrintResults( results ); return ("OK: "+sqlText); } catch (Exception ex) {return ( "** Erreur dans : "+sqlText);} } public static void PrintResults( ResultSet results ) throws SQLException {int i; int nbLigne=0; // nbre de lignes du resultat int nbCol; // nbre de colonnes du resultat boolean pasfini= results.next (); // encore des donnes

385

// recupere le schema du resultat (nom des colonnes, type, ...) ResultSetMetaData resultSchema = results.getMetaData (); nbCol= resultSchema.getColumnCount (); //nbre de colonnes // affiche les entetes des colonnes System.out.println(); for (i=1; i<=nbCol; i++) {System.out.print(resultSchema.getColumnLabel(i)); System.out.print("|"); // sparateur de colonne } System.out.println(); // affiche les donnes ligne par ligne while (pasfini) { for (i=1; i<=nbCol; i++) // pour chaque colonne { System.out.print(results.getString(i)); System.out.print("|"); } System.out.println(""); nbLigne++; pasfini = results.next (); //prochaine ligne } System.out.println(nbLigne+" lignes trouvees par la requete"); } public static void PrintSQLError(SQLException ex) { System.out.println ("**ERREUR SQLException\n"); while (ex != null)

Javabook Page 386 Lundi, 12. juillet 1999 3:58 15

386

Chapitre 28 Java et les bases de donnes


{ System.out.println ("Etat : " +ex.getSQLState ()); System.out.println ("Message: " +ex.getMessage ()); System.out.println ("Fournis: " +ex.getErrorCode ()); ex = ex.getNextException (); System.out.println (); } }

La classe SQLService

Lapplication ci-dessous utilise la classe SQLService pour effectuer les manipulations suivantes : cration de la table; insertion des donnes; mise jour des donnes; suppression des donnes; interrogation chaque manipulation pour vrifier leffet; exemple de traitement derreur.
class ExampleWithJDBCOracle { static String DML="DML"; static String SEL="SEL"; public static void doIt(String typereq, String s){ if (typereq.equals("DML")) System.out.println(SQLService.ExecDML(s)); if (typereq.equals("SEL")) System.out.println(SQLService.ExecSelect(s)); } public static void main (String args[]) { try { // Charger le driver jdbc-odbc bridge Class.forName ("sun.jdbc.odbc.JdbcOdbcDriver"); // Connexion au driver //(fournir la source odbc, utilisateur, mot de passe) SQLService.con = DriverManager.getConnection ("jdbc:odbc:sgbdOracle", "javauser", "pwd"); // ici, on est connect, sinon on a gnr une exception // Crer la table BANQUE, on commence par dtruire la table! doIt(DML, "drop table BANQUE"); doIt(DML, "create table "+ "BANQUE(NOM_COMPTE CHAR(20), MONTANT Number)"); doIt(SEL, "Select * from BANQUE"); doIt(DML, "insert into BANQUE values ('PourMoi' , 100)");

Javabook Page 387 Lundi, 12. juillet 1999 3:58 15

Base de donnes et Java : un exemple complet

387

doIt(DML, "insert into BANQUE values ('PourToi' , 100)"); doIt(DML, "insert into BANQUE values ('PourLui' , 500)"); doIt(DML, "insert into BANQUE values ('PourElle', 300)"); doIt(SEL, "Select * from BANQUE"); doIt(DML, "update BANQUE "+ "set MONTANT= 200 where NOM_COMPTE='PourToi'"); doIt(SEL, "Select * from BANQUE"); doIt(DML, "delete from BANQUE where MONTANT> 250"); doIt(SEL, "Select * from BANQUE"); // Close the statement SQLService.stmt.close(); // Close the connection SQLService.con.close(); // Une nouvelle connection avec une erreur SQLService.con = DriverManager.getConnection ("jdbc:odbc:sgbdOracle", "javatest", "?"); } catch (SQLException e) {SQLService.PrintSQLError(e);} catch (Exception e ) {e.printStackTrace ();} } }

Application 15 : La classe ExampleWithJDBCOracle

Lexcution du programme donne le rsultat suivant :


OK (-1): drop table BANQUE OK (-1): create table BANQUE(NOM_COMPTE CHAR(20), MONTANT Number) NOM_COMPTE|MONTANT| 0 lignes trouvees par la requete OK: Select * from BANQUE OK (1): insert into BANQUE values OK (1): insert into BANQUE values OK (1): insert into BANQUE values OK (1): insert into BANQUE values

('PourMoi' , ('PourToi' , ('PourLui' , ('PourElle',

100) 100) 500) 300)

NOM_COMPTE|MONTANT| PourMoi |100.| PourToi |100.| PourLui |500.| PourElle |300.| 4 lignes trouvees par la requete OK: Select * from BANQUE OK (1): update BANQUE set MONTANT= 200 where NOM_COMPTE='PourToi' NOM_COMPTE|MONTANT|

Javabook Page 388 Lundi, 12. juillet 1999 3:58 15

388

Chapitre 28 Java et les bases de donnes

PourMoi |100.| PourToi |200.| PourLui |500.| PourElle |300.| 4 lignes trouvees par la requete OK: Select * from BANQUE OK (2): delete from BANQUE where MONTANT> 250 NOM_COMPTE|MONTANT| PourMoi |100.| PourToi |200.| 2 lignes trouvees par la requete OK: Select * from BANQUE **ERREUR SQLException Etat : 28000 Message: [Oracle][ODBC][Ora]ORA-01017: invalid username/password; logon denied Fournis: 1017

En modifiant une seule ligne de ce programme, il est possible de se connecter une autre source ODBC, dans notre cas MicroSoft Access (le nom de lutilisateur et le mot de passe ne sont pas ncessaires) :
SQLService.con = DriverManager.getConnection ("jdbc:odbc:sgbdOffice");

28.8 Invitation explorer


Ce chapitre vous a prsent les notions de base des interactions de Java avec les bases de donnes relationnelles via JDBC. De nombreux points nont t abords que de manire succincte et mriteraient de plus longues explications. De mme, certaines fonctionnalits nont pas t mentionnes afin de ne pas dborder du cadre de cet ouvrage. Parmi elles : les rsultats multiples; les extensions de SQL : types (DATE), fonctions ODBC; la gestion des erreurs; les mtadonnes. Les mtadonnes dcrivent le dictionnaire de donnes dun SGBD (catalogue des tables, des colonnes, etc.). Leur support dans JDBC a pour but den normaliser laccs, facilitant ainsi la programmation doutils de haut niveau (diteurs de schmas, de requtes, etc.).

Javabook Page 389 Lundi, 12. juillet 1999 3:58 15

Chapitre 29

Fabriquer des objets rpartis avec RMI


Le package RMI (Remote Method Invocation1) permet l'laboration de programmes utilisant des objets rpartis sur des machines diffrentes. Les principes de RMI sont trs proches de CORBA (Common Object Request Broker Architecture) qui dfinit une norme d'interoprabilit entre des objets.

29.1 Description du package


Le package RMI contient, outre ses propres interfaces, classes et exceptions, quatre sous-packages : java.rmi.dgc contient une interface et deux classes de gestion du ramasse-miettes distribu. Celui-ci piste les objets lors des transferts entre machines, et dtruit les objets lorsquils ne sont plus rfrencs; java.rmi.registry contient une classe et deux interfaces pour la gestion du rfrentiel dimplantation qui met en correspondance un nom avec son serveur dobjet; java.rmi.server contient les classes et interfaces pour grer toute la partie serveur des objets distribus; java.rmi.activation contient les classes, interfaces et exceptions pour activer des objets partir de leurs rfrences persistantes. Les objets sont alors activs effectivement pour tre utiliss.
1. Invocation de mthode distance.

Javabook Page 390 Lundi, 12. juillet 1999 3:58 15

390

Chapitre 29 Fabriquer des objets rpartis avec RMI

Dans le package rmi, linterface Remote et la classe Naming sont essentielles tout dveloppement et utilisation dobjets distribus. Les concepts de ce package tant parfois difficiles comprendre, il nous est apparu plus utile den dcrire les principes, puis den expliquer les composants travers un exemple complet.

29.2 Principes de fonctionnement


Considrons un programme client (une application ou une applet) qui vous permet d'accder votre compte en banque gr par un programme serveur. Toute l'interface utilisateur est programme dans le client, les traitements effectifs sur votre compte s'excutent sur le serveur. Pour que cela soit possible, il faut que le client puisse accder l'objet compte du serveur et ensuite lui appliquer les mthodes correspondant aux oprations financires classiques sur un compte. L'applet doit donc : savoir comment accder un compte particulier gr par un serveur; connatre les services (traitements) que peut effectuer un objet compte. Cette connaissance mutuelle des services repose videmment sur la notion d'interface Java, puisque celle-ci dfinit contractuellement les services que doit implanter une classe d'objets si celle-ci dclare implanter telle ou telle interface. Les programmes client et serveur ont donc connaissance de l'interface, le serveur parce qu'il implante les services de l'interface, le client parce qu'il les sollicite. Le courtier d'objet (request broker) a pour mission de faire circuler les demandes de service et les rsultats de leur excution entre les programmes client et serveur. Au niveau du client, la demande de service est un appel habituel de mthode. la diffrence prs que l'excution en local de la mthode ne ralise pas le service demand, mais transmet au courtier d'objet la demande de service qui, son tour, la transmet au travers du rseau au programme serveur appropri. Le code qui implante la demande de service relay par le courtier s'appelle une souche (stub). Le code qui reoit du courtier la demande de service et qui la transmet au serveur s'appelle le squelette (skeleton). Le squelette et la souche font galement le transfert des rsultats de l'excution du service du serveur vers le client, qui termine alors l'excution de la mthode pour ensuite passer l'instruction suivante. La seule question encore ouverte est comment disposer d'un mcanisme permettant au client d'identifier un objet rparti et de savoir si celui-ci est disponible ou activ. Pour a, lobjet serveur s'enregistre sur un rfrentiel d'implantation que va interroger le courtier pour trouver la machine sur laquelle le serveur est en cours d'excution.

Javabook Page 391 Lundi, 12. juillet 1999 3:58 15

Le dveloppement d'une application distribue avec RMI pas pas

391

client objet mthode

serveur

traitement

Souche

Squelette

Courtier dobjets RMI


Figure 29.1 Principes de fonctionnement de RMI

29.3 Le dveloppement d'une application distribue avec RMI pas pas


Nos allons dcrire, pas pas, limplantation rpartie de la gestion dun compte en banque telle quelle a t dcrite ci-dessus.

Dfinition de l'interface
public interface compteDistant extends java.rmi.Remote { // depot d'argent float depot(float amount) throws java.rmi.RemoteException; // retrait d'argent float retrait(float amount) throws java.rmi.RemoteException; // lecture du solde float litSolde() throws java.rmi.RemoteException; }

Implanter l'interface dans un objet serveur


Un objet serveur est une sous-classe de UnicastRemoteServer, qui implante l'interface dfinie ci-dessus.
public class CompteServeur extends UnicastRemoteObject implements compteDistant {

Les points cls sont les suivants : le constructeur de l'objet serveur doit appeler le constructeur de la classe dont il hrite; l'objet serveur implante toutes les mthodes de l'interface (le code des mthodes ne tient absolument pas compte du fait que les mthodes vont tre appeles par un objet distant);
public CompteServeur() throws java.rmi.RemoteException { super(); }

Javabook Page 392 Lundi, 12. juillet 1999 3:58 15

392

Chapitre 29 Fabriquer des objets rpartis avec RMI

le lancement du serveur requiert l'installation d'un gestionnaire de scurit et galement l'enregistrement de l'objet serveur sur un rfrentiel d'implantation.
public static void main(String args[]) { //installation d'un gestionnaire de scurit if (System.getSecurityManager()==null) { System.setSecurityManager(new RMISecurityManager()); } System.out.println("security manager install"); try { // cration d'un objet CompteServeur CompteServeur name = new CompteServeur(); // enregistrement de l'objet sur le referentiel d'implantation Naming.rebind("//site:host/gestionCompteDistant", name); } catch (Exception e) { System.out.println("Exception: " + e.getMessage()); } }

L'laboration des squelette et souche se fait aprs la compilation du programme serveur avec lutilitaire rmic du JDK :
>javac CompteServeur.java >rmic CompteServeur

rmic construit deux fichiers CompteServeur_stub.class et CompteServeur_Skel.class. Ceux-ci seront tlchargs avec lapplet sur le poste client. Le code complet de l'objet serveur est le suivant :
import java.rmi.* ; import java.rmi.server.UnicastRemoteObject; public class CompteServeur extends UnicastRemoteObject implements compteDistant { float solde = 0; // constructeur public CompteServeur() throws java.rmi.RemoteException { super(); } // depot montant et renvoie le nouveau solde public float depot(float montant) throws java.rmi.RemoteException { solde += montant; return solde; } // renvoie le solde courant public float litSolde() throws java.rmi.RemoteException { return solde; } // retrait montant et renvoie le nouveau solde public float retrait(float montant) throws java.rmi.RemoteException { solde -= montant;

Javabook Page 393 Lundi, 12. juillet 1999 3:58 15

Le dveloppement d'une application distribue avec RMI pas pas

393

return solde; } public static void main(String args[]) { //installation d'un gestionnaire de scurit if (System.getSecurityManager()==null) { System.setSecurityManager(new RMISecurityManager());} try { // cration d'un objet CompteServeur CompteServeur name = new CompteServeur(); // enregistrement de l'objet sur le referentiel d'implantation Naming.rebind("gestionCompteDistant", name); } catch (Exception e) { System.out.println("Exception: " + e.getMessage()); } } //main }

Lapplet dclare un identificateur sur linterface CompteDistant. Elle obtient ensuite une rfrence sur un objet dont elle connat le nom et qui implante cette interface; cest le rle de la mthode Naming.lookup. Lapplet peut ensuite appeler les diffrentes mthodes de cet objet.
import import import import import import java.awt.*; java.awt.event.*; java.rmi.*; java.net.MalformedURLException; java.net.UnknownHostException; java.applet.Applet;

public class AppletClient extends Applet implements ActionListener { // remote interface declaration private CompteDistant accesDistant; private Button Depot, Retrait; private Label Solde; private TextField saisieMontant; private float MontantSolde; //constructeur public AppletClient(){ connexionServeur(); demandeSolde(); creeInterfaceGraphique(); } public void connexionServeur(){ // recherche de nom dans les registres try { accesDistant=(CompteDistant) Naming.lookup ("//site:port/gestionCompteDistant"); } catch (Exception e) { System.out.println("Exeception "+ e.getMessage());

Javabook Page 394 Lundi, 12. juillet 1999 3:58 15

394

Chapitre 29 Fabriquer des objets rpartis avec RMI


} } public void demandeSolde(){ try { MontantSolde=accesDistant.litSolde(); } catch (RemoteException e) { System.out.println("Exception "+ e.getMessage()); } } public void creeInterfaceGraphique(){ setLayout( new BorderLayout()); Panel p=new Panel(); p.setLayout( new FlowLayout(FlowLayout.LEFT)); Solde=new Label(" Solde: "); Solde.setText(" Solde: CHF "+MontantSolde); add("North",Solde); p.add(new Label("montant : ")); saisieMontant=new TextField(3); p.add(saisieMontant); add("Center", p); p=new Panel(); Depot= new Button("Depot"); p.add(Depot); Depot.addActionListener(this); Retrait= new Button("Retrait"); p.add(Retrait); Retrait.addActionListener(this); add("South",p); }

public void actionPerformed(ActionEvent e) { String arg = e.getActionCommand(); float solde, montant; try { montant = (new Float(saisieMontant.getText()).floatValue()); } catch (NumberFormatException ex) { montant=0; } if ("Depot".equals(arg)) { try { solde= accesDistant.depot(montant); Solde.setText(" Solde: CHF "+solde); } catch (RemoteException re) { System.out.println("Exception "+ re.getMessage()); } }

Javabook Page 395 Lundi, 12. juillet 1999 3:58 15

Le dveloppement d'une application distribue avec RMI pas pas


else if ("Retrait".equals(arg)) { try { solde= accesDistant.retrait(montant); Solde.setText(" Solde: CHF "+solde); } catch (RemoteException re) { System.out.println("Exception "+ re.getMessage()); } } } public static void main(String args[]) { try { Frame f = new Frame("Compte Client"); AppletClient appletClient = new AppletClient(); appletClient.init(); appletClient.start(); f.add("Center", appletClient); f.setSize(300, 300); f.show(); } catch (Exception e) { System.out.println("Exception "+ e.getMessage()); } } }

395

Applet 56 : Une applet utilisant RMI

Le dploiement comporte trois phases : dmarrage du rfrentiel dimplantation (rmiregistry); lancement du programme serveur, linstance de CompteServeur va alors se dclarer auprs de ce rfrentiel; tlchargement et excution de lapplet.
machine utilisateur butineur web http : tlchargement de lapplet RMI : appel de mthode applet Java RMI : fin de mthode http : requte de lurl de lapplet machine serveur serveur www

serveur dobjets objet distant

Figure 29.2 Dploiement et fonctionnement de la gestion de compte bancaire distribue

Javabook Page 396 Lundi, 12. juillet 1999 3:58 15

396

Chapitre 29 Fabriquer des objets rpartis avec RMI

La figure ci-dessous montre un exemple dexcution de cette applet.

Figure 29.3 Lapplet de gestion de compte en banque distance

Lexemple que nous avons prsent nillustre quune partie des fonctionnalits de RMI. Une mthode distante accepte des paramtres et peut renvoyer des rsultats qui sont des objets et pas seulement des types simples. Le protocole de srialisation (vu au point 19.15, p. 261) est utilis pour lenvoi et la rception dobjet. On parle alors dobjet mobile, puisquil y a dplacement dobjet de machine en machine.

Javabook Page 397 Lundi, 12. juillet 1999 3:58 15

Chapitre 30

Fabriquer des objets rpartis avec CORBA


CORBA (Common Object Request Broker Architecture) est une proposition commune de courtiers de services objets manant de lOMG (Object Management Group, www.omg.org), correspondant au standard dun bus logiciel pour des objets rpartis. Ce bus dfinit les interfaces de base pour la communication entre des objets distribus et htrognes. La distribution des objets mne directement une architecture client/serveur ou, dans sa plus grande gnralisation, une architecture plusieurs rangs (multi-tiers en anglais). Lhtrognit relve, elle, de la possibilit de faire communiquer des programmes dvelopps dans des langages diffrents, sexcutant sur des systmes dexploitation diffrents et sur des rseaux diffrents. CORBA permet lintgration et la coopration de systmes patrimoines (legacy systems) entre eux et avec les nouveaux applicatifs dvelopps via des technologies plus rcentes. Cest mme son intrt principal. La version 2 de Java est livre avec des packages permettant de tter le dveloppement avec CORBA. Il est possible de construire des objets CORBA en y faisant rfrence statiquement travers des souches. Il est galement possible de construire un transient serveur et de rfrencer les objets dans un serveur de noms livr par Sun. Un compilateur IDL vers Java est aussi disponible. Sun appelle cet ensemble Java-IDL. Ce march du middleware est en pleine bullition et nous conseillons de bien observer les batailles qui sy livrent pour le dominer. Les produits Orbix de IONA technologies et VisiBroker de Inprise (ex-Borland et ex-Visigenic) se dis-

Javabook Page 398 Lundi, 12. juillet 1999 3:58 15

398

Chapitre 30 Fabriquer des objets rpartis avec CORBA

putent actuellement le march. partir de la version 4, Netscape Navigator est livr avec lORB (Object Request Broker) VisiBroker. Et il est donc possible pour une applet dutiliser les services de cet ORB pour accder des services CORBA. Pendant une priode, Sun a aussi essay de dvelopper un produit ORB (sous le nom de NEO). Actuellement, la stratgie de Sun est de pousser sa technologie de Enterprise Java Bean chez les dveloppeurs dORB. RMI est lquivalent de CORBA dans le monde Java. Leurs principes et leur fonctionnement sont similaires. Il est conseill de lire le chapitre sur RMI avant de poursuivre celui-ci.

30.1 CORBA en quelques mots


Lide de CORBA est de pouvoir distribuer les services dobjets, sans se proccuper de connatre le lieu dexcution ni la nature du code de ces objets. Il sagit donc de services distribus et htrognes. CORBA est une norme qui dfinit comment publier, accder, grer, retrouver ces objets. Cette norme, tablie par lOMG qui regroupe plus de 800 entreprises, est purement dfinitoire. Le composant principal de son architecture est lORB (Object Request Broker ou courtier de requtes objet), qui gre les changes entre objets (demandes de services, rsultats, passage des paramtres, types, etc.). La mtaphore de lORB est le bus lectronique de donnes que lon trouve dans les ordinateurs et qui permet par sa dfinition de spcifier et brancher diffrentes cartes lectroniques, le bus nayant pour fonction que la dfinition statique dun standard lectrique. Limplantation de lORB nest pas dfinie dans la norme, ce sont les vendeurs dORB qui la prennent en charge.

Le bus dobjets rpartis CORBA


La norme CORBA a pour objectif principal la spcification de ce bus qui se caractrise par les points suivants : IDL, un langage de dfinition dinterface : les services offerts par les objets rpartis sont dfinis avec ce langage. linstar des interfaces Java, une interface crite en IDL dfinit contractuellement un ensemble de services qui doivent tre implants par un programme. Ce programme peut tre crit dans la plupart des langages existants (C++, Smalltalk, Cobol, Ada, Java, etc.). Si des programmes dj existants correspondent ces services, ils pourront tre encapsuls pour les rendre interoprables avec dautres objets CORBA existants ou crer. Cette encapsulation des services autorise, par exemple, la publication dapplications COBOL sous forme dobjets. Il est ais de redonner une nouvelle vie une comptabilit ou une gestion de stocks, crites dans les annes 80 en COBOL avec des fichiers squentiels indexs, en

Javabook Page 399 Lundi, 12. juillet 1999 3:58 15

CORBA en quelques mots

399

publiant certains services sous forme dobjets CORBA et en crant des applets Java accdant ces services; la transparence des appels : une requte sur un objet distant (et donc potentiellement implante dans un langage diffrent) sexprime exactement comme une requte sur un objet local. La transmission et les conversions de reprsentation des paramtres sont entirement prises en charge par les souches et le courtier dobjets, le dveloppeur dapplications ne sen occupant pas; des appels statiques ou dynamiques : lappel statique, le plus simple utiliser (celui propos par le JDK 1.2), consiste appeler un service dun objet distant, objet que le programme appelant connat nommment. Lappel dynamique utilise, quant lui, un rfrentiel dinterfaces pour identifier un objet possdant un service que le programme appelant souhaite obtenir sans pour autant connatre a priori cet objet. La norme CORBA dfinit galement comment plusieurs ORB peuvent communiquer entre eux. Pour le protocole de rseau TCP/IP, cette spcification se nomme IIOP (Internet Inter ORB Protocol). Cette norme rend les objets CORBA disponibles sur le rseau Internet, comme le sont des pages dfinies en HTML.
CLIENT rfrentiel interface souche IDL ORB client interface IMPLANTATION OBJET (serveur) rfrentiel implantation

appel dynamique

squelette squelette statique dynamique

Adaptateur objet

Object Request Broker IIOP


ORB ORB

Figure 30.1 La structure de lORB

Les services et les commodits de CORBA


IDL est galement utilis dans CORBA pour dfinir diffrentes interfaces proposant des services utiles la gestion dobjets distribus. Nous avons, entre autres, les services suivants : service de nommage : permet la recherche de la rfrence dobjets sur le bus travers des annuaires;

Javabook Page 400 Lundi, 12. juillet 1999 3:58 15

400

Chapitre 30 Fabriquer des objets rpartis avec CORBA

service de persistance : dfinition dune interface pour grer la persistance des objets; service de contrle de la concurrence : dfinition dune interface pour grer la concurrence et autoriser le verrouillage des objets par les transactions; service transactionnel : interface pour dfinir les mcanismes transactionnels sur les objets; etc. Les commodits de CORBA dfinissent un ensemble de composants pour la gestion et la cration de systmes dinformation. Ils sont bien sr dfinis en IDL. Voici la liste des domaines ayant retenu lattention de lOMG : gestion des documents; gestion des informations; administration des systmes; gestion des tches.
Applications objets Commodits : Documents Informations etc.

Objet Request Broker (le bus objets)

Services : Nommage Persistance

Transaction etc.

Figure 30.2 OMA (Object Management Architecture) de LOMG

30.2 IDL
IDL (Interface Definition Language) est le langage pour dfinir les services devant tre rendus par les objets. Les requtes ces objets seront achemines par lORB du client vers le serveur. En retour, les rsultats de ces requtes seront achemins par lORB du serveur vers le client. LORB adapte les paramtres et transmet les requtes, tout en masquant sil y a lieu lhtrognit des systmes. Des clients et des serveurs programms dans des langages diffrents cohabitent ainsi grce CORBA. Cest la dimension interoprable de CORBA. Les services spcifis en IDL doivent tre implants dans le langage cible. Il faut disposer dun traducteur dIDL vers ce langage cible, qui est un langage de spcification purement dclaratif (il nest pas possible dexprimer limplantation dune mthode). On trouve des traducteurs pour C, C++, Smalltalk, COBOL, Ada, Java, etc.

Javabook Page 401 Lundi, 12. juillet 1999 3:58 15

IDL

401

La structure IDL est la suivante : un module contient des interfaces et ces dernires, des oprations. Cela correspond aux notions de packages, interfaces et mthodes de Java. En reprenant lexemple du chapitre sur RMI, on peut dfinir le comportement d'un compte bancaire avec la dclaration IDL suivante :
module LikeCompte { interface Compte { float litSolde(); float retrait (in float x); float depot (in float x); }; };

Le module IDL de compte en banque

Sans entrer dans les dtails de la syntaxe dIDL, on peut reconnatre les diffrentes mthodes de linterface CompteDistant du chapitre sur RMI. Idltojava est le compilateur qui permet de transcrire les concepts IDL en Java 1, en utilisant la commande suivante :
idltojava -fno-cpp Compte.idl

Cette commande va crer un dossier LikeCompte dans lequel on trouvera les rsultats de la traduction. Voici les fichiers gnrs : Compte.java : interface implanter; _CompteStub.java : fonctionnalits CORBA pour le client (la souche statique); _CompteImplBase.java : classe abstraite servant de guide pour lobjet implanter; CompteHolder.java et CompteHelper.java : classes de services pour la conversion de type (entre lORB et Java). En examinant Compte.java, on peut constater la traduction nonce plus haut.
package LikeCompte; public interface Compte extends org.omg.CORBA.Object { float litSolde(); float retrait(float x); float depot(float x); }

Le module IDL de compte en banque traduit en interface Java

1.

partir de cette dclaration IDL, nous aurions pu gnrer un programme C++ pour illustrer lhtrognit permise par CORBA. En restant dans Java, les diffrences entre des applications distribues avec RMI ou CORBA sont plus visibles.

Javabook Page 402 Lundi, 12. juillet 1999 3:58 15

402

Chapitre 30 Fabriquer des objets rpartis avec CORBA

La figure ci-dessous illustre le principe de dveloppement dobjets rpartis dans des langages diffrents. Jusqu prsent, nous navons dvelopp que la partie client (partie gauche de la figure).
Dfinir les interfaces en IDL compiler IDL vers C++ Souches (squelettes) compiler IDL vers Java Ajouter le code aux squelettes Compiler C++ Souches IDL client Squelettes serveur implantation des objets adaptateur des objets

instancier

rfrentiel dimplantation

Figure 30.3 Principes de dveloppement dobjets distribus CORBA

30.3 Un objet CORBA


La prochaine tape est donc de dvelopper une classe qui tende le comportement de la classe abstraite _CompteImplBase.java et implante linterface Compte. Sans surprise, nous obtenons le code suivant :
public class CompteImpl extends LikeCompte._CompteImplBase { private float v; public CompteImpl(java.lang.String name) { super(); System.out.println("Objet Compte disponible : "+name); } public float litSolde() { return v; } public float retrait(float x) { v-=x; return v; } public float depot(float x) { v+=x; return v; } }

La classe CompteImpl

Javabook Page 403 Lundi, 12. juillet 1999 3:58 15

Le Serveur CORBA

403

30.4 Le Serveur CORBA


Nous avons donc maintenant une classe CompteImpl permettant dinstancier des objets qui seront manipulables travers un ORB. Il nous reste deux choses faire. La premire est de dvelopper le serveur qui abritera les instances de ces objets et leur donnera des noms. La seconde est dadapter lapplet du chapitre sur RMI pour quelle utilise les objets communiquant via lORB. Comme nous allons utiliser les services de nommage, un annuaire qui associe un nom la rfrence dun objet, commenons par dcrire la dynamique de la situation : 1. Le serveur localise le service de nommage. 2. Le serveur cre lobjet et enregistre sa rfrence dans le rfrentiel dimplantation (qui est en fait un serveur de noms). 3. Le client localise le service de nommage. 4. Le client demande la rfrence de lobjet quil cherche, au rfrentiel dimplantation. 5. Le client utilise cette rfrence pour adresser ses requtes lobjet (en passant par son serveur).
Client Serveur

5
ORB ORB

Le rseau 1+2
ORB rfrentiel dimplantation

3+4

Figure 30.4 Dynamique des appels

Cette mdiation du service de nommage permet de rendre compltement indpendants client et serveur. Examinons le code source du programme du serveur.
import LikeCompte.*; // Le package contenant nos stubs import org.omg.CosNaming.*; // serveur de noms : le ref. dimplantation import org.omg.CosNaming.NamingContextPackage.*; import org.omg.CORBA.*; // Corba class SetOfCompteServer { public static void main(String args[]) {

Javabook Page 404 Lundi, 12. juillet 1999 3:58 15

404

Chapitre 30 Fabriquer des objets rpartis avec CORBA


try{ORB orb = ORB.init(args, null); CompteImpl CompteRef = new CompteImpl("PourToi"); orb.connect(CompteRef); org.omg.CORBA.Object nameS = orb.resolve_initial_references("NameService"); NamingContext ncRef = NamingContextHelper.narrow(nameS); NameComponent nc = new NameComponent("PourToi", " "); NameComponent path[] = {nc}; ncRef.rebind(path, CompteRef);

java.lang.Object sync = new java.lang.Object(); synchronized(sync){sync.wait();} } catch(Exception e) { System.err.println("ERROR: " + e);e.printStackTrace(System.out); } } }

La classe SetOfCompteServer

Commentons un peu le programme du serveur. Nous importons dabord les diffrents packages ncessaires l'utilisation de CORBA et du rfrentiel dimplantation.
import import import import LikeCompte.*; // Le package contenant nos stubs org.omg.CosNaming.*; // le serveur de noms org.omg.CosNaming.NamingContextPackage.*; org.omg.CORBA.*; // Corba

Ensuite, nous initialisons lORB et crons une rfrence orb qui servira enregistrer nos objets.
ORB orb = ORB.init(args, null);

Nous crons une instance de compte et lenregistrons dans lORB.


CompteImpl CompteRef = new CompteImpl("PourToi"); orb.connect(CompteRef);

Les objets que nous publions sont connus des clients par un nom, et associs une rfrence. Pour entretenir cette association entre les noms et les rfrences, nous utilisons le service de nommage de CORBA. Les noms sont spcifis de manire hirarchique. La premire tape consiste chercher la racine du contexte des noms (ncRef). La mthode narrow est utilise en gnral pour typer la rfrence CORBA avec le type utilis dans Java (quivalent dune conversion de type (casting) entre IDL et Java).
org.omg.CORBA.Object nameS =

Javabook Page 405 Lundi, 12. juillet 1999 3:58 15

Le client CORBA
orb.resolve_initial_references("NameService"); NamingContext ncRef = NamingContextHelper.narrow(nameS);

405

La deuxime tape consiste associer un nom la rfrence de lobjet et enregistrer cette association dans le rfrentiel dimplantation (PourToi est le nom du compte, le deuxime paramtre tant sa catgorie).
NameComponent nc = new NameComponent("PourToi", " "); NameComponent path[] = {nc}; ncRef.rebind(path, CompteRef);

La fin du programme traite les erreurs et on attend que les clients invoquent les objets activs par le serveur. Aprs avoir compil les diffrentes classes, nous pouvons dmarrer le serveur. Au pralable, il faut dmarrer le rfrentiel dimplantation de CORBA avec la commande suivante :
start tnameserv -ORBInitialPort 1050

Le rfrentiel dimplantation publie le contexte initial de la racine de la hirarchie de nommage (IOR pour Interoperable Object Reference). Le service est accessible sur le port 1050.
Initial Naming Context: IOR:000000000000002849444c3a6f6d672e6f72672f436f734e616d696e672f4e616d696e67436f 6e746578743a312e3000000000010000000000000030000100000000000a6e745f66696e5f323200 045900000018afabcafe0000000276b1268a000000080000000000000000 TransientNameServer: setting port for initial object references to: 1050

Le serveur doit donc tre activ avec le mme port :


start java SetOfCompteServer -ORBInitialPort 1050

Le serveur nest pas trs bavard mais lobjet, au moment de son instanciation, dclare quil est actif :
Objet Compte disponible : PourToi

30.5 Le client CORBA


Il nous reste modifier le client de lexemple RMI pour ladapter notre serveur. Nous avons mis en vidence les parties modifies. On importe les packages ncessaires lutilisation de CORBA et du rfrentiel dimplantation. On cre une variable Compte qui permettra de rcuprer la rfrence notre objet. Pour cela, on procde comme dans le serveur linitialisation de lORB et on recherche la racine du rfrentiel dimplantation. Ensuite, il faut construire le chemin du nom pour retrouver notre objet. Et enfin, on demande au rfrentiel dimplantation de nous donner la rfrence du compte. Seule cette dernire instruction diffre du programme serveur :
accesDistant = CompteHelper.narrow(ncRef.resolve(path));

Javabook Page 406 Lundi, 12. juillet 1999 3:58 15

406

Chapitre 30 Fabriquer des objets rpartis avec CORBA

Le programme client est le suivant :


import import import import import import import java.awt.*; java.awt.event.*; java.applet.Applet; LikeCompte.*; org.omg.CosNaming.*; // serveur de noms : ref dimplantation org.omg.CosNaming.NamingContextPackage.*; org.omg.CORBA.*; // Corba

public class AppletClient extends Applet implements ActionListener { private private private private private Compte accesDistant; // la rfrence du compte dans l'ORB Button Depot, Retrait; Label Solde; TextField saisieMontant; float MontantSolde;

public AppletClient(String args[]){ connexionServeur(args); demandeSolde(); creeInterfaceGraphique(); } public void connexionServeur(String args[]){ try {ORB orb = ORB.init(args, null); org.omg.CORBA.Object nameS = orb.resolve_initial_references("NameService"); NamingContext ncRef = NamingContextHelper.narrow(nameS); NameComponent nc = new NameComponent("PourToi", " "); NameComponent path[ ] = {nc}; accesDistant = CompteHelper.narrow(ncRef.resolve(path));

} catch (Exception e) {System.out.println(e);}

} public void demandeSolde(){ // idem exemple RMI } public void creeInterfaceGraphique(){ // idem exemple RMI } public void actionPerformed(ActionEvent e) { // idem exemple RMI } public static void main(String args[]) { try {Frame f = new Frame("Compte Client"); AppletClient appletClient = new AppletClient(args); appletClient.init(); appletClient.start(); f.add("Center", appletClient);

Javabook Page 407 Lundi, 12. juillet 1999 3:58 15

Persistance des donnes


f.setSize(300, 300); f.show();} catch (Exception e) { System.out.println("Exception "+ e.getMessage()); } }}

407

Applet 57 : Gestion de compte en banque avec CORBA

On remarquera que les invocations de mthodes sont effectues comme si lobjet tait local au programme, la dlocalisation du compte est donc entirement transparente pour le dveloppeur. Le lancement du programme doit, comme on sen doute, se faire avec le mme port que pour le rfrentiel dimplantation.
java AppletClient -ORBInitialPort 1050

30.6 Persistance des donnes


Pour clore ce chapitre sur CORBA, nous allons crer une autre implantation de lobjet Compte. Dans tous les exemples vus jusqu prsent, le montant du compte tait volatile, cest--dire perdu lorsquon arrte le serveur. En mmorisant le montant du compte dans une base de donnes, il est possible de rendre persistant ltat du compte. En modifiant uniquement limplantation de lobjet compte, il est possible de donner une nouvelle implantation au serveur. Le serveur sera donc recompiler avec cette nouvelle implantation sans quon ait en retoucher le code. La partie client nest pas recompiler, car elle nest lie lobjet compte qu travers la dfinition IDL, non modifie dans notre cas. On voit donc ici le gain d lindpendance du client et du serveur communiquant par des interfaces IDL.
import java.sql.*; import java.net.URL; public class CompteImpl extends LikeCompte._CompteImplBase { // on supprime la variable Float v !!! // le compte est entierement gere dans la BD String nomCompte; static String DML="DML"; static String SEL="SEL"; public CompteImpl(java.lang.String name) { nomCompte=name; System.out.println("Objet Compte disponible : "+name+ " = "+SQLService.getMontant(nomCompte));} public float litSolde() { return SQLService.getMontant(nomCompte);}

Javabook Page 408 Lundi, 12. juillet 1999 3:58 15

408

Chapitre 30 Fabriquer des objets rpartis avec CORBA

public float retrait(float x) { doIt(DML, "update BANQUE set MONTANT=MONTANT-"+x+ " WHERE NOM_COMPTE='"+nomCompte+"'" ); return SQLService.getMontant(nomCompte);} public float depot(float x) { doIt(DML, "update BANQUE set MONTANT=MONTANT+"+x+ " WHERE NOM_COMPTE='"+nomCompte+"'" ); return SQLService.getMontant(nomCompte);} private static void doIt(String typereq, String s){ if (typereq.equals("DML")) System.out.println(SQLService.ExecDML(s)); if (typereq.equals("SEL")) System.out.println(SQLService.ExecSelect(s)); } // initialisation de la classe static{ try { // Charger le driver jdbc-odbc bridge Class.forName ("sun.jdbc.odbc.JdbcOdbcDriver"); SQLService.con = DriverManager.getConnection ("jdbc:odbc:sgbdOracle", "javatest", "javapass"); // ici, on est connect, sinon on a gnr une exception doIt(SEL, "Select * from BANQUE"); } catch (SQLException e) {SQLService.PrintSQLError(e);} catch (Exception e ) {e.printStackTrace ();} } }

La classe CompteImpl avec persistance

Notre code rutilise la classe SQLService du chapitre concernant JDBC. Pour faciliter et rendre plus lgant le code de notre classe Compte, nous y avons ajout une mthode getMontant() qui nous retourne le montant enregistr dans la base de donnes pour un compte spcifique.
class SQLService { // . . . // nous avons ajout une mthode cette classe par rapport // lexemple du chapitre sur JDBC public static float getMontant(String nc) { try {stmt = con.createStatement(); results = stmt.executeQuery( "SELECT MONTANT FROM BANQUE "+ "WHERE NOM_COMPTE='"+nc+"'" ); if (results.next ()) {return results.getFloat(1); } else System.out.print("** pas de donne pour le compte: "+nc);

Javabook Page 409 Lundi, 12. juillet 1999 3:58 15

Persistance des donnes

409

return 0; } catch (Exception ex) {System.out.print("** Erreur dans la requete pour: "+nc); return 0;}

} // . . .

La classe SQLService tendue

La connexion la base de donnes se fait lors de la premire instanciation dun objet de cette classe; nous avons accroch le code dans la partie dinitialisation statique de la classe Compte. Laspect le plus surprenant de cette implantation est la disparition complte de la variable charge de mmoriser la valeur du compte. Le solde du compte est toujours manipul dans la base de donnes. Pour finir en beaut ce chapitre et ouvrir une polmique, nous poserons une question concernant lextension possible de cette implantation. Pour implanter un mcanisme transactionnel dans notre applet de manipulation de compte bancaire, quel niveau doit-on le faire : dans limplantation de lobjet compte en utilisant le mcanisme de synchronisation de Java? en utilisant les services transactionnels de CORBA? en utilisant les mcanismes transactionnels de la base de donnes qui mmorise notre objet?
ORB

CompteImpl. java

Transactions ?

Base de donnes Figure 30.5 O grer le mcanisme de transaction ?

Javabook Page 410 Lundi, 12. juillet 1999 3:58 15

Javabook Page 411 Lundi, 12. juillet 1999 3:58 15

Chapitre 31

Les autres API de Java


Les API (Application Programming Interfaces) sont le mcanisme dextension de services pour le langage Java. JDBC, la premire API propose par Sun, a tendu les services du langage la connexion des bases de donnes. Nous donnons la liste actuelle des API.
API Security API Servlet API Enterprise JavaBeans Components JavaBeans Components Java Telephony API (JTAPI) Java 2D API Java 3D API Advanced Imaging API Java Sound API Java Speech API Tableau 31.1 Fonctions des API Fonction Ensembles de classes pour la gestion de la cryptographie. Ensembles de classes pour dvelopper des serveurs sur le Web. Plate-forme de cration des applications rutilisables. Plate-forme neutre de composants rutilisables. Intgration des besoins en informatique et en tlphonie. Outils pour la gestion du graphisme en 2 dimensions. Outils pour la gestion du graphisme en 3 dimensions. Outils pour le traitement dimages. Gestion du son en trs haute qualit. Interfaces avec reconnaissance de la voix.

Javabook Page 412 Lundi, 12. juillet 1999 3:58 15

412
API Java Naming and Directory Interface (JNDI) Java IDL Java Remote Method Invocation (RMI) API Java Message Service API Java Transaction API (JTA) Java Transaction Service (JTS) Java Management API (JMAPI) JDBC Java Mail AP JavaHelp API Java Communications API Tableau 31.1 Fonctions des API Fonction

Chapitre 31 Les autres API de Java

Interfaces de gestion dannuaires. Interfaces pour le dveloppement avec CORBA. Interfaces pour la programmation distribue. Gestion dun systme de messages. Mcanisme pour la gestion transactionnelle. Services associs la gestion transactionnelle. Interfaces pour la gestion de la gestion... Gestion de la connexion avec les bases de donnes. Interface pour la gestion dune messagerie. Gestion de laide en ligne. Gestion des communications (du bureau).

La lecture de cette liste montre bien quel point Java est en plein dveloppement et les directions vers lesquelles il soriente : rseau, bases de donnes, multimdia, scurit, etc.

Javabook Page 413 Lundi, 12. juillet 1999 3:58 15

Partie V

Annexes
A. B. C. D. E. Du C++ Java Grammaire BNF de Java Les fichiers darchives .jar Rappel sur HTML JavaScript

Javabook Page 414 Lundi, 12. juillet 1999 3:58 15

Javabook Page 415 Lundi, 12. juillet 1999 3:58 15

Annexe A

Du C++ Java
Quelle est la diffrence entre Java et C++? Java est orient objet.

Ce chapitre prsente une revue des diffrences existant entre C++ et Java. Ces diffrences sont nombreuses et il convient den illustrer toutes les subtilits. Nous dbutons par les diffrences lies au dveloppement de projets puis abordons les diffrences entre les langages eux-mmes.

A.1 Dveloppement dune application en Java


Une application Java est organise en modules. Un module est spcifi par le mot cl package et contient un ou plusieurs fichiers de dfinition de classes. En Java, un fichier contient la dfinition complte dune classe. Le corps des mthodes (fonctions membres en C++) dune classe est dfini juste aprs leur dclaration. Contrairement au C++, il ny a donc pas de fichier den-tte (header file) dcrivant linterface dune classe, ni de fichier dimplantation des mthodes de la classe. En Java, un fichier contient une ou plusieurs dfinitions de classe dont une seule est publique. Le nom du fichier est ncessairement le nom de la classe publique, nom auquel sajoute le suffixe .java. Une classe ne peut tre dfinie lintrieur dune autre classe.

Javabook Page 416 Lundi, 12. juillet 1999 3:58 15

416

Annexe A Du C++ Java

Commenons par un programme simple pour illustrer les diffrences dans lorganisation du dveloppement dapplication. Nous prsentons une version C++ puis la version Java quivalente.
// C++ // fichier Temps.h // note pour les programmeurs avertis : on parle des #ifdef plus tard class Temps { private : unsigned heure, minute, seconde; public : Temps() {heure=0; minute=0; seconde=0;} Temps(unsigned h,unsigned m, unsigned s) {heure=h; minute=m; seconde=s;} int tempsValide(); void affiche(); };

Exemple C++ de fichier den-tte


//C++ // fichier Temps.cpp #include "Temps.h" #include <iostream.h> int Temps::tempsValide() { // retourne 1 ssi le temps est une heure correcte, 0 sinon if ((heure>=24) || (minute>=60) || (seconde>=60)) return 0; return 1; }; void Temps::affiche() {cout <<heure <<":" <<minute <<":" <<seconde <<'\n'; }

Exemple C++ de fichier dimplantation des mthodes

Le listing suivant est la dfinition correspondante en Java de la classe Temps. On notera que les deux versions de la classe Temps nutilisent pas les mmes types de donnes : en effet, le type unsigned (dfini en C++) nexiste pas en Java, le type boolean quant lui existe et remplace avantageusement le type int retourn par la mthode tempsValide.
// Java // fichier Temps.java import java.io.*;

Javabook Page 417 Lundi, 12. juillet 1999 3:58 15

Le programme principal : la fonction main


class Temps { private int heure, minute, seconde; public Temps() {heure=0; minute=0; seconde=0;} public Temps(int h,int m, int s) {heure=h; minute=m; seconde=s;} public boolean tempsValide() { // retourne true ssi le temps est une heure correcte, // false sinon if ((heure>=24) || (minute>=60) || (seconde>=60)) return false; return true;} public void affiche() {System.out.println(heure +":" +minute +":"+seconde);} };

417

Dfinition quivalente en Java de la classe Temps

A.2 Le programme principal : la fonction main


En Java, tout est objet (hormis les types simples), une application est une classe : le main est une mthode de classe.
//C++ // programme utilisant la classe Temps #include "Temps.h" void main() { Temps t; t.affiche(); }

Exemple C++ dutilisation de la classe Temps


import Temps; class Maintemps { static public void main(String argv[]) { Temps t=new Temps(); t.affiche();} }

Exemple Java dutilisation de la classe Temps

A.3 Elaboration du code excutable


Pour les langages compils, llaboration dun programme excutable comporte gnralement deux phases : la compilation puis ldition de liens. La compilation en Java produit un programme objet1 nomm avec le suffixe .class (voir

Javabook Page 418 Lundi, 12. juillet 1999 3:58 15

418

Annexe A Du C++ Java

point 3.2, p. 32). Il ny a pas ddition statique de liens dans Java : linterprteur charge, si ncessaire, les diffrentes classes dont lapplication a besoin au cours de son excution. Ldition de liens est donc dynamique. Le C++ requiert une phase ddition de liens statique. Celle-ci a pour but dassembler les diffrents programmes objet issus de la compilation pour fabriquer un programme excutable. En C++, les fichiers den-tte jouent un rle important : par la directive du prprocesseur #include, ils spcifient les modalits de rutilisation dune classe. Ces modalits sont des rfrences externes qui ne doivent tre dclares quune seule fois pour une application (constitue ainsi dun ensemble de fichiers). Ces dclarations multiples ne sont gnralement identifies qu ldition de liens. Une bonne pratique permet dliminer ce problme en utilisant des primitives du prprocesseur. Cette pratique (illustre dans lexemple suivant) est une ncessit lorsquune application est dveloppe par une quipe de programmeurs, sans que lon sache si Pierre ou Paul rutilisera telle ou telle classe.
#ifndef TEMPS_H #define TEMPS_H // en-tete de la classe Temps class Temps { private : unsigned heure, minute, seconde; public : Temps() {heure=0; minute=0; seconde=0;} Temps(unsigned h,unsigned m, unsigned s) {heure=h; minute=m; seconde=s;} int tempsValide(); void affiche(); }; #endif

Exemple den-tte C++ relevant dune bonne pratique

Lusage des fichiers den-tte et de la squence #ifndef...#endif illustre sur lexemple prcdent nest plus ncessaire en Java (il ny a dailleurs pas de prprocesseur). Cependant, ces fichiers taient frquemment utiliss par les dveloppeurs C++ pour commenter la classe, prciser les modalits dutilisation et/ ou le rle des membres dune classe afin den faciliter la rutilisation.

1.

Le mot objet ici nest pas pris au sens de orient objet . Un programme objet est le rsultat de la compilation dun programme source.

Javabook Page 419 Lundi, 12. juillet 1999 3:58 15

Mise jour dune application Java

419

En Java, il nest pas toujours facile de se faire une ide prcise de la faon de rutiliser telle ou telle classe. En effet, un fichier unique contient la dfinition complte de la classe, y compris le corps de toutes les mthodes. On ne dispose pas dune vue synthtique permettant dapprhender rapidement lintrt dune classe pour sa rutilisation. Les programmeurs Java doivent donc faire un effort particulier de documentation de leurs programmes, ventuellement dans un fichier spar ou, mieux encore, utiliser les commentaires spciaux pour lutilitaire JavaDoc. JavaDoc gnre ensuite la documentation de vos sources sous forme de documents HTML. Cette pratique est ncessaire pour favoriser la rutilisation, que lon distribue ou non le code source sur Internet ou lintrieur de son quipe de dveloppement.

A.4 Mise jour dune application Java


En C++, la modification dune classe entrane gnralement la recompilation des classes ou de lapplication la rutilisant. Votre environnement de dveloppement peut vous proposer de reconstruire une application car lun des fichiers qui la composent a t modifi. Si vous choisissez de la reconstruire, votre environnement de dveloppement ne recompilera que les parties ncessaires, puis fera une dition de liens. En Java, ce genre de gestion nexiste pas, et des erreurs peuvent se produire lexcution en raison de ldition dynamique de liens (voir p. 371). Le scnario suivant en est une illustration : 1. On dispose de deux versions excutables (une C++ et une Java) de lexemple plus haut. 2. On supprime le constructeur Temps(). On obtient les fichiers suivants :
// C++ // fichier Temps.h class Temps { private : unsigned heure, minute, seconde; public : Temps(unsigned h,unsigned m, unsigned s) {heure=h; minute=m; seconde=s;} int tempsValide(); void affiche(); };

En-tte C++ de la classe Temps sans constructeur Temps()

Javabook Page 420 Lundi, 12. juillet 1999 3:58 15

420

Annexe A Du C++ Java

Le fichier Temps.cpp dimplantation des mthodes reste identique.


// Java // fichier Temps.java import java.io.*; class Temps { private int heure, minute, seconde; public Temps(int h,int m, int s) {heure=h; minute=m; seconde=s;} public boolean tempsValide() { // retourne true si le temps est une heure correcte, // false sinon if ((heure>=24) || (minute>=60) || (seconde>=60)) return false; return true;} public void affiche() {System.out.println(heure +":" +minute +":"+seconde);} };

Classe Temps en Java, sans le constructeur Temps()

3. On recompile la classe Temps dans les deux environnements. 4. On teste les deux applications : a. la version C++ na pas t reconstruite et sexcute comme avant; b. la version Java produit lerreur suivante lexcution :
java.lang.NoSuchMethodError: Temps: method <init>()V not found

Ce scnario illustre le chargement dynamique par Java des mthodes dont une application a besoin pour son excution. Cependant, dans les deux cas, loubli par le dveloppeur de recompiler lapplication entrane des consquences dommageables : en C++ lutilisateur a toujours lancienne version, en Java lutilisateur a une application qui peut produire des bogues. Tous les problmes didentification des classes clientes recompiler ne sont pas entirement rsolus, mais un pas en avant a t fait relativement au C++ (mme si on utilise le make ). Nous avons vu dans les paragraphes prcdents que la gestion du dveloppement dune application est diffrente pour ces deux langages. Nous allons maintenant aborder les diffrences existant entre les deux langages proprement dits.

A.5 Les types prdfinis


En Java, et contrairement au C++, la taille des types est indpendante du systme dexploitation de lordinateur.

Javabook Page 421 Lundi, 12. juillet 1999 3:58 15

Dfinition de nouvelles structures

421

Les types numriques


Le type byte de Java remplace le type char du C++. Java ne permet pas de spcifier des valeurs entires non signes laide du qualificatif unsigned.
Type
byte short int long float double

Taille en bits 8 16 32 64 32 64

Tableau A.1 Les types numriques en Java

Le type caractre
Le type char de Java dfinit un caractre de 16 bits au format Unicode. Les caractres Unicode sont des valeurs entires de 16 bits non signes (cest--dire entre 0 et 65535).

Le type boolen
Contrairement au C++, Java possde un type boolen nomm boolean. Ses valeurs sont true et false pour vrai et faux respectivement. Le type boolean est un type distinct des types numriques : on ne peut pas convertir un type boolean en un type numrique quel quil soit.

La classe String
Java comporte une classe prdfinie String. Un objet de la classe String nest pas quivalent un tableau de char.

A.6 Dfinition de nouvelles structures


En C++, on peut construire des structures (struct), des unions (union), des numrations (enum), des types (typedef) et enfin des classes (class). lexception des classes, toutes ces structures sont des rmanences du langage C dont est driv le C++. Pour programmer objet proprement, la seule structure utiliser est celle de classe. Java favorise ainsi une programmation tout objet puisque cest la seule structure permise.

Javabook Page 422 Lundi, 12. juillet 1999 3:58 15

422

Annexe A Du C++ Java

A.7 Dclaration et initialisation des variables


En Java, une dclaration de variable ne rserve aucun espace mmoire : pour une variable dun type simple, une variable non initialise ne contient aucune valeur; pour une variable dfinissant une instance dune classe, une variable non initialise ne fait rfrence aucun objet. Lutilisation dune variable non initialise est dtecte la compilation et provoque une erreur, contrairement au C++ qui initialise par dfaut les variables. Java impose donc une plus grande rigueur et permet dviter des oublis qui peuvent tre dommageables. Lexemple suivant en est une illustration.
Java
import java.io.*; class demo { public static void main (String argv[]) {int c; System.out.println(c);} }

C++
#include <iostream.h> main() {int c; cout << c <<'\n'; }

Tableau A.2 Test de linitialisation de variables en Java et en C++

La version C++ sexcute normalement et affiche 0, la valeur initiale affecte par le compilateur la variable c. La version Java est refuse la compilation et ne peut donc tre excute.

A.8 Dclaration des constantes


En Java, et contrairement au C++, il nest pas possible de dclarer des instances constantes de classe dobjet. Linstruction suivante na pas dquivalent en Java :
//C++ const Temps midi(12,0,0);

A.9 Les tableaux


Les diffrences entre les deux langages portent sur la dclaration et linitialisation des tableaux. De plus, lexcution, Java vrifie les dbordements des indices.

Dclaration
Le tableau A.3 rcapitule les diffrences sur les dclarations de tableau. En Java, les instructions lgales de cette table ne sont que des dclarations de type, elles ne crent pas le tableau.

Javabook Page 423 Lundi, 12. juillet 1999 3:58 15

Les tableaux

423

En C++, la dclaration dun tableau en initialise les lments : la classe doit avoir
Exemple de dclaration dun tableau
int[] monTableau; int monTableau[]; Temps [] rendezVous[]; // 2 dimensions int monTableau[5]; int[5] monTableau;

En Java lgal lgal lgal illgal illgal

En C++ illgal illgal illgal lgal illgal

Tableau A.3 Dclaration de tableaux

un constructeur par dfaut, ce constructeur tant appel automatiquement lors de la dclaration du tableau (si au moins un des lments nest pas initialis explicitement). Dans lexemple suivant, le constructeur Temps() doit tre prsent.
//C++ #include "Temps.h" void main() { Temps intervalle[2]; for (int i=0;i<2;i++) intervalle[i].affiche(); }

Initialisation des tableaux unidimensionnels


Lexemple suivant initialise les valeurs des tableaux aux valeurs null pour les objets. Aucun objet nest cr.
//Java int[] monTableau=new int[5]; //initialise 0 les 5 lments du tableau Temps intervalle[]=new Temps[2]; //initialise null les 2 lments, aucun constructeur n'est appel

En Java, lallocation effective des objets lments du tableau requiert lappel explicite dun constructeur.
//Java import Temps; class demo { public static void main(String argv[]) {Temps intervalle[]=new Temps[2]; for (int i=0;i<2;i++) {intervalle[i]=new Temps(); intervalle[i].affiche();} } }

Javabook Page 424 Lundi, 12. juillet 1999 3:58 15

424

Annexe A Du C++ Java

Le tableau A.4 illustre la dclaration et linitialisation avec appel explicite du constructeur dsir.
Dclaration et initialisation de tableaux dobjets Java C++
Temps[] intervalle= { new Temps(),new Temps(12,15,30)}; Temps intervalle[2]= {Temps(),Temps(12,15,30)};

Tableau A.4 Initialisation de tableaux dobjets

Initialisation des tableaux multidimensionnels Contrairement au C++, en Java il ny a pas de tableaux multidimensionnels mais des tableaux de tableaux. Linitialisation de leurs dimensions se fait ainsi :
// Java int t[][]=new int[3][4]; int t[][]={{0,3,-2,5,-1,4},{0,3,-2,3,-1},{0,3,-2,4},{0,3,3}};

Il nexiste pas de contrainte sur les tailles : ainsi le tableau prcdent est triangulaire. Lattribut length permet dobtenir la longueur dun tableau. Lexemple cidessous montre lintrt dun tel attribut puisquil dcharge le programmeur de la gestion des longueurs de tableaux. De plus, Java contrle les valeurs des indices de tableaux, ce qui facilite grandement la mise au point des programmes.
//Java import java.io.*; class demo { public static void main(String argv[]) { int t[][]={{0,3,-2,5,-1,4},{0,3,-2,3,-1},{0,3,-2,4},{0,3,3}}; for (int i=0;i<t.length;i++) {for (int j=0;j<t[i].length;j++) System.out.print(" "+t[i][j]); System.out.println();} } }

Exemple dun tableau de tableaux de longueur diffrente

Son excution donne le rsultat suivant :


0 0 0 0 3 3 3 3 -2 5 -1 4 -2 3 -1 -2 4 3

A.10 Destruction des objets


En Java, il ny a pas de destruction explicite dobjets. Lorsquun objet nest plus rfrenc, lespace mmoire quil occupe pourra tre rcupr par le ramassemiettes (garbage collector). Le programmeur est donc libr de ce travail didentification des objets dtruire.

Javabook Page 425 Lundi, 12. juillet 1999 3:58 15

Linstruction for

425

En fin de bloc, sil existe des objets uniquement rfrencs par des variables locales ce bloc, lespace quils occupent sera rcupr ultrieurement par le ramasse-miettes. Le programmeur peut dfinir une mthode appele finalize(). Cette mthode, appele par le ramasse-miettes avant la destruction de linstance concerne, nest utile que pour la libration de ressources autres que la mmoire par exemple un fichier non ferm. Cette mthode joue le rle du destructeur C++.

A.11 Linstruction for


Le tableau A.5 ci-dessous montre les diffrences de linstruction for entre les deux langages. Ces diffrences sont dues ce que Java, contrairement au C++, considre le for comme un bloc (voir Pour_faire_ (for), p. 70).
Programme Java refus la compilation
//Java import java.io.*; class demo { public static void main (String argv[]) { int t[]=new int[5]; for (int i=0;i<5;i++) t[i]=i; // i est inconnu System.out.println(i); } }

Programme C++ valide


//C++ #include <iostream.h> void main() { int t[5]; for (int i=0;i<5;i++) t[i]=i; // i reste defini cout << i <<'\n'; }

Tableau A.5 Porte des variables dclares dans le for

Le tableau A.6 montre la transformation des boucles for pour passer dun langage lautre.
Java
... for (int i=0;i<5;i++) t[i]=i; ... ... int i; ... for (i=0;i<5;i++) t[i]=i; ...

C++
... {for (int i=0;i<5;i++) t[i]=i;} ... ... for (int i=0;i<5;i++) t[i]=i; ...

Tableau A.6 Instructions for en Java et en C++

Javabook Page 426 Lundi, 12. juillet 1999 3:58 15

426

Annexe A Du C++ Java

A.12 Linstruction continue


Linstruction continue du C est prsente en C++. Dans ces langages, elle fait dbuter litration suivante de la rptitive (for, while, do) dans laquelle elle se situe. Ainsi lexemple ci-dessous permet de nafficher que les nombres positifs ou nuls du tableau t.
Java
import java.io.*; class demo { public static void main(String argv[]) {int t[]={0,3,-2,5,-1}; for (int i=0;i<t.length;i++) {if (t[i]<0) continue; System.out.println(t[i]);} } }

C++
#include <iostream.h> void main() { int t[5]={0,3,-2,5,-1}; for (int i=0;i<5;i++) {if (t[i]<0) continue; cout << t[i] << endl;} }

Tableau A.7 Instruction continue en Java et en C++

En Java, linstruction continue (voir point 5.6, p. 73) peut comporter une tiquette de branchement facultative. Si cette tiquette est absente, linstruction a la mme signification quen C++. Ltiquette de branchement nquivaut pas un goto qui autorise aller nimporte o, mais permet dans le cas de rptitives imbriques de spcifier le niveau dimbrication partir duquel on veut continuer les itrations. Ltiquette est ncessairement dfinie dans un bloc englobant celui dans laquelle linstruction continue se trouve. Ainsi, le programme suivant recherche toutes les occurrences dune suite de nombres dans un tableau numrique deux dimensions. Le programme affiche : le tableau dans lequel se fait la recherche; la suite rechercher; les coordonnes des occurrences (sil y en a) de cette suite dans le tableau.
//Java import java.io.*; class demo { public static void main(String argv[]) {int t[][]={{0,3,-2,5,-1,4},{0,3,-2,3,-1,2},{0,3,-2,4,5,1},{0,3,3,-2,3,-1}}; System.out.println("tableau a parcourir :"); for (int i=0;i<t.length;i++) {for (int j=0;j<t[i].length;j++)

Javabook Page 427 Lundi, 12. juillet 1999 3:58 15

Linstruction continue
System.out.print(" "+t[i][j]); System.out.println(); }; int search[]={3,-2,3}; System.out.println("suite a chercher :"); for (int i=0;i<search.length;i++) System.out.print(" "+search[i]); System.out.println(); for (int i=0;i<t.length;i++) {debutRecherche: for (int k=0;k<t[i].length-search.length;k++) {for (int j=0;j<search.length;j++) if (t[i][k+j]!=search[j]) continue debutRecherche; System.out.println("trouve en "+i+","+k); } } } }

427

Exemple de programme avec linstruction continue

Le rsultat de lexcution est le suivant :


tableau a parcourir 0 3 -2 5 0 3 -2 3 0 3 -2 4 0 3 3 -2 suite a chercher : 3 -2 3 trouve en 1,1 trouve en 3,2 : -1 -1 5 3 4 2 -1 -1

Dans cet exemple, linstruction continue permet, en cas dchec de reconnaissance de la suite dans le tableau (mme si on en a trouv une partie), de continuer la recherche lindice k suivant. Un programme C++ quivalent contenant des tiquettes de branchement utilise donc le goto.
//C++ #include <iostream.h> void main() { int t[4][6]={{0,3,-2,5,-1,4}, {0,3,-2,3,-1,2}, {0,3,-2,4,5,-1}, {0,3,3,-2,3,-1}}; cout << "tableau a parcourir :"<< endl; for (int i=0;i<4;i++) {for (int j=0;j<6;j++) cout <<" " << t[i][j] ; cout << endl;} int search[]={3,-2,3}; cout << "suite a chercher :" << endl; for (i=0;i<3;i++) cout <<" " << search[i] ;

Javabook Page 428 Lundi, 12. juillet 1999 3:58 15

428

Annexe A Du C++ Java


cout << endl; for (i=0;i<4;i++) {for (int k=0;k<6-3;k++) {for (int j=0;j<3;j++) if (t[i][k+j]!=search[j]) goto debutRecherche; cout <<"trouve en " << i <<"," << k << endl; debutRecherche: ; } }

Programme C++ avec goto

A.13 Linstruction break


Linstruction break du C est encore prsente en C++. Dans ces langages, elle fait sortir du bloc (for, while, switch, do) dans lequel elle se situe. En Java, linstruction break (voir point 5.5, p. 72) peut comporter une tiquette de branchement qui lui permet de spcifier o doit continuer lexcution du programme. Ltiquette est ncessairement dfinie dans un bloc englobant celui dans lequel linstruction break se trouve. Lexemple suivant est le mme que celui illustrant linstruction continue, si ce nest que lon sarrte la premire occurrence trouve.
//Java import java.io.*; class demo { public static void main(String argv[]) {int t[][]={{0,3,-2,5,-1,4},{0,3,-2,3,-1,2}, {0,3,-2,4,5,-1},{0,3,3,-2,3,-1}}; System.out.println("tableau parcourir"); for (int i=0;i<t.length;i++) {for (int j=0;j<t[i].length;j++) System.out.print(" "+t[i][j]); System.out.println();}; int search[]={3,-2,3}; System.out.println("suite chercher"); for (int i=0;i<search.length;i++) System.out.print(" "+search[i]); System.out.println(); sortie: for (int i=0;i<t.length;i++) {debutRecherche: for (int k=0;k<t[i].length-search.length;k++) {for (int j=0;j<search.length;j++) if (t[i][k+j]!=search[j]) continue debutRecherche; System.out.println("trouve en "+i+","+k); break sortie;} } System.out.println("C'est fini!");} }

Exemple de programme avec un break tiquet

Javabook Page 429 Lundi, 12. juillet 1999 3:58 15

Linstruction goto

429

Un programme C++ quivalent contenant des tiquettes de branchement utilise donc le goto.
//C++ #include <iostream.h> void main() { int t[4][6]={{0,3,-2,5,-1,4}, {0,3,-2,3,-1,2}, {0,3,-2,4,5,-1}, {0,3,3,-2,3,-1}}; cout << "tableau parcourir :"<< endl; for (int i=0;i<4;i++) {for (int j=0;j<6;j++) cout <<" " << t[i][j] ; cout << endl;} int search[]={3,-2,3}; cout << "suite chercher :" << endl; for (i=0;i<3;i++) cout <<" " << search[i] ; cout << endl; for (i=0;i<4;i++) {for (int k=0;k<6-3;k++) {for (int j=0;j<3;j++) if (t[i][k+j]!=search[j]) goto debutRecherche; cout <<"trouve en " << i <<"," << k << endl; goto sortie; debutRecherche: ; } } sortie: cout <<"C'est fini!" << endl; }

Programme quivalent en C++

En dfinitive, contrairement au C++, Java permet dviter une programmation avec des branchements non orthodoxes. Dans les deux langages, les branchements intempestifs peuvent toujours tre vits par des variables boolennes qui permettent de sortir de rptitives imbriques.

A.14 Linstruction goto


Le goto est un mot cl rserv du langage Java, mais ne correspond actuellement aucun traitement dans ce langage. Chacun sait que lusage du goto est dlicat, le goto est cependant trs pratique pour sortir de rptitives imbriques sans avoir ajouter un boolen chaque test des rptitives imbriques. En Java, ce bon usage du goto peut se raliser laide de linstruction break suivie dune tiquette.

Javabook Page 430 Lundi, 12. juillet 1999 3:58 15

430

Annexe A Du C++ Java

A.15 Laffectation
En Java, toutes les variables dsignant les objets sont des rfrences ( lexception des objets de types numrique, caractre et boolen). C++ utilise les rfrences aux objets notamment pour le passage de paramtres dans les mthodes, fonctions ou procdures. Une rfrence en C++ est une sorte de pointeur pour lequel lutilisateur na pas spcifier les indirections permettant laccs la variable pointe. Les rfrences C++ ne sont cependant pas des pointeurs : en effet, lorsque lon affecte deux pointeurs, ils dsignent le mme objet, ce qui nest pas le cas des rfrences C++. De plus, contrairement aux pointeurs, aucune opration (++, --) nest possible sur les rfrences.

Affectation de rfrence en Java


Laffectation dune rfrence une autre en Java aboutit ce quelles dsignent le mme objet (voir point 6.9, p. 94). Le mme exemple sera repris en C++, mais le rsultat de laffectation sera diffrent. Lexemple considre une nouvelle dfinition de la classe Temps laquelle on a ajout une mthode plusUneHeure() augmentant lheure dune unit. Cette nouvelle mthode nous permettra de distinguer les effets de laffectation.
// Java public void plusUneHeure() {heure++;}

Le programme utilisant cette nouvelle dfinition est le suivant :


// Java import Temps; class mainTemps {static public void main(String argv[]) { Temps t=new Temps(12,0,0); Temps t2=new Temps(14,30,0); System.out.println("Valeurs initiales :"); t.affiche(); // t vaut 12:0:0 t2.affiche(); // t2 vaut 14:30:0 t=t2; // affectation des rfrences System.out.println("Apres affectation"); t.affiche(); // t vaut 14:30:0 t2.affiche();// t2 vaut 14:30:0 t.plusUneHeure(); System.out.println("Apres plusUneHeure"); t.affiche(); // t vaut 15:30:0 t2.affiche(); // t2 vaut 15:30:0 } }

Lapplication Java utilisant la classe Temps

Javabook Page 431 Lundi, 12. juillet 1999 3:58 15

Laffectation

431

Aprs laffectation, les valeurs des attributs sont bien videmment identiques. Lappel de la mthode plusUneHeure() sur la rfrence t augmente lheure dune unit pour lobjet rfrenc par t. Lappel de la mthode affiche() sur les deux rfrences nous montre quelles dsignent le mme objet.

Affectation de rfrence en C++


La version C++ du mme programme renvoie des rsultats diffrents :
// C++ a rajouter dans la partie publique de la classe Temps void plusUneHeure() {heure++;}

Le programme C++ utilisant cette nouvelle dfinition est le suivant :


//C++ // programme utilisant la classe Temps #include "Temps.h" #include <iostream.h> void main() { Temps &t=Temps(12,0,0); Temps &t2=Temps(14,30,0); cout << "Valeurs initiales :"<<'\n'; t.affiche(); // t vaut 12:0:0 t2.affiche();// t2 vaut 14:30:0 t=t2; cout << "Apres affectation"<<'\n'; t.affiche(); // t vaut 14:30:0 t2.affiche();// t2 vaut 14:30:0 t.plusUneHeure(); cout << "Apres plusUneHeure" <<'\n'; t.affiche(); // t vaut 15:30:0 t2.affiche();// t2 vaut 14:30:0 }

Lapplication C++ utilisant la classe Temps

Le tableau A.8 montre les traces dexcution des deux programmes.


Java
Valeurs initiales : 12:0:0 14:30:0 Apres affectation 14:30:0 14:30:0 Apres plusUneHeure 15:30:0 15:30:0

C++
Valeurs initiales : 12:0:0 14:30:0 Apres affectation 14:30:0 14:30:0 Apres plusUneHeure 15:30:0 14:30:0

Tableau A.8 Traces dexcution : gestion des rfrences

Javabook Page 432 Lundi, 12. juillet 1999 3:58 15

432

Annexe A Du C++ Java

Laffectation de rfrence en C++ est quivalente laffectation de deux objets dsigns par des variables simples : elle substitue le contenu du terme gauche par celui du terme droit. Les rfrences ne dsignent pas le mme objet. Lorsque lon augmente lheure dune unit pour lun, lobjet dsign par lautre rfrence reste inchang.

Rcapitulatif
En C++, il y a trois possibilits de dsignation des objets : un dsignateur simple (une variable); un pointeur; une rfrence. Les rfrences nexistaient pas en C, elles ont t introduites en C++ pour le passage des paramtres. En Java, il nexiste quun seul mode de dsignation des objets : la rfrence. Cette uniformit ne constitue pas un appauvrissement du langage (par rapport au C++) mais simplifie plutt la conception des programmes. Les rfrences de Java ne sont quivalentes ni aux pointeurs ni aux rfrences du C++.

A.16 La dfinition de classes


Malgr une syntaxe voisine entre les deux langages, de nombreuses diffrences mritent notre attention.

Dfinition des attributs


Les attributs dune classe sont les variables dinstance et les variables de classes. Les seules diffrences entre Java et C++ concernent leur initialisation. En C++, seules les constantes peuvent tre initialises. En Java (voir point 7.7, p. 102), les variables dinstance et de classes sont initialisables. Les exemples ci-dessous en illustrent les diffrents aspects :
//Java import Temps; class UneClasse {// variable de classe static int n=3; // variables d'instances int x=n+5,y; java.lang.String nom="toto"; float valeurs[]=new float [10]; Temps debut=new Temps(12,0,0); }

Les variables de classe sont initialises lors du chargement de la classe, dans lordre dapparition dans la dfinition de la classe : une rfrence en avant provo-

Javabook Page 433 Lundi, 12. juillet 1999 3:58 15

La dfinition de classes

433

que une erreur de compilation :


class ClasseErronee { static int i=j+1; // j: reference en avant, erreur de compilation static int j=3; }

En Java, lors de la cration dune instance, les variables dinstance sont initialises avant lappel au constructeur. Ainsi, lors de la cration dune instance de la classe ci-dessous, la variable dinstance demo aura la valeur 6.
// Java class UneClasse { int demo=3; UneClasse() {demo=6;} }

Classe avec variable dinstance initialise


//Java import UneClasse; import java.io.*; class Demo { public static void main(String argv[]) {UneClasse c=new UneClasse(); System.out.println(c.demo); } }

Programme illustrant la valeur de la variable dinstance demo

En C++, la norme ANSI interdit linitialisation dune variable dinstance (non constante) lors de sa dfinition. Il faut alors initialiser celle-ci laide dun constructeur.

Dfinition des mthodes


En Java, les mthodes (voir point 7.8, p. 102) se dfinissent comme en C++ aux restrictions suivantes prs : on ne peut pas spcifier quun paramtre est constant; Java manipule des rfrences sur des objets et non des pointeurs. Les rfrences ne sont pas modifiables par la mthode, les objets eux-mmes sont modifiables : on peut invoquer des mthodes sur ces objets et modifier leurs attributs accessibles. Le contenu de lobjet peut changer. Avant et aprs lexcution dune mthode, une rfrence passe en paramtre dsigne toujours le mme objet; un paramtre dune mthode ne peut avoir de valeur par dfaut; le corps dune mthode se trouve obligatoirement dans la dfinition de sa classe.

Javabook Page 434 Lundi, 12. juillet 1999 3:58 15

434

Annexe A Du C++ Java

Homonymie des mthodes et des attributs


En Java, une mthode et un attribut dfinis dans une classe peuvent avoir le mme nom. En effet, Java ne permettant pas de manipuler des pointeurs sur des mthodes, il ny a donc pas de confusion possible. Le C++ ne peut distinguer si lon dsigne ladresse de la fonction membre ou la donne membre : ce langage ne permet donc pas de spcifier des attributs et des mthodes de mme nom.

Qualification des attributs des mthodes


Spcification des domaines de protection Comme en C++, les attributs et les mthodes peuvent tre qualifis par les modificateurs public, private et protected pour spcifier les domaines de protection de la classe (voir tableau A.9).
Java
class UneClasse { UneClasse() {...} public int A1, A2; public char A3; public void m1() {//corps de la methode } protected float A4; protected double A5; protected void m2() {//corps de la methode } private float A6,A7; private void m3() {//corps de la methode } private void m4() {//corps de la methode } };

C++
class UneClasse { UneClasse() {...} public: int A1, A2; char A3; void m1(); protected: float A4; double A5; void m2(); private: float A6,A7; void m3(); void m4(); };

m1

m2

m3 m4

Tableau A.9 Spcification de la visibilit dans Java et C++

Cependant en C++, une spcification dun domaine de protection reste valable jusqu spcification dun autre domaine de protection. En Java, cette spcification doit tre mentionne pour chaque attribut et mthode. public et private ont la mme signification dans les deux langages, protected prsente une diffrence : en C++, la mthode ou la variable dinstance est accessible

Javabook Page 435 Lundi, 12. juillet 1999 3:58 15

La dfinition de classes

435

( moins quil y ait un masquage) par nimporte quelle sous-classe. En Java, laccs est tendu aux classes du mme package. En C++, labsence de spcification dun domaine dfinit implicitement le domaine private. En Java, cette absence ne correspond aucun des trois domaines. En effet, la variable ou la mthode est accessible par toutes les classes du mme package, mais non par les sous-classes dclares dans dautres packages. Spcification des variables et des mthodes de classe En Java comme en C++, les variables de classe et les mthodes de classe sont spcifies laide du prfixe static devant leur dclaration.
//Java class UneClasse { static int nombresDInstances=0; // variable de classe static void uneInstanceDePlus() // methode de classe {nombresDInstances++; }; UneClasse() // constructeur {uneInstanceDePlus(); } private String info; //variable d'instance void Information()//methode d'instance {System.out.println("l'instance " + info + " est une des "+ nombresDInstances + " instances de sa classe" ); } };

Exemple de dfinition de variable et de mthode de classe

En C++ et en Java, les mthodes de classe nont accs quaux variables et mthodes de classe. Les mthodes dinstance ont accs aux variables et mthodes de classe et dinstance. En Java, on le rappelle : linitialisation des variables dinstance et de classe peut se faire au moment de leur dclaration, dans la dfinition de la classe. En C++, une variable de classe est accessible depuis la classe ou lune des instances de la classe. Laccs depuis la classe requiert loprateur de rsolution de porte (::). En Java, laccs seffectue partir de linstance ou de la classe de manire uniforme laide de loprateur de slection (.) : la classe est un objet avec des donnes membres et des mthodes. Le tableau A.10 illustre laccs aux variables et mthodes de classe dans les deux langages. En Java, une mthode de classe ne peut tre redfinie dans une sous-classe. Une mthode static est donc implicitement final.

Javabook Page 436 Lundi, 12. juillet 1999 3:58 15

436
Java Dfinition de classe avec variable et mthode de classe
class UneClasse { public int x; public static int n; public static int valeur() {return n;}; UneClasse(){x=3;} }; //accs partir de la // classe int i=UneClasse.n; int j=UneClasse.valeur(); //accs partir d'une //instance UneClasse c=new UneClasse(); i+= c.n; j+= c.valeur();

Annexe A Du C++ Java


C++
class UneClasse { public: int x; static int n; static int valeur() {return n;}; UneClasse(){x=3;} }; //accs partir de la // classe int i=UneClasse::n; int j=UneClasse::valeur(); //accs partir d'une //instance UneClasse c; i+= c.n; j+= c.valeur();

Modes daccs

Tableau A.10 Accs aux variables et mthodes de classe

Autres qualifications des variables Une variable dinstance ou de classe peut tre constante. Un prfixe (const en C++, final en Java) donne cette spcification. Java permet de qualifier de volatile et transient des variables.
Java Dfinition de constantes
class UneClasse { final int version=3;}

C++
class UneClasse { const int version=3;}

Tableau A.11 Spcification dattributs constants

Autres qualifications des mthodes En Java, final quivaut const en C++ pour les variables dinstance ou de classe. En Java, une mthode qualifie de final nest pas une mthode retournant une valeur constante mais une mthode ne pouvant tre redfinie dans une classe drive. Une mthode prfixe par native nest pas implante par la machine virtuelle, mais par du code dpendant de la plate-forme utilise, par exemple du C ou de lassembleur. Ces mthodes nont pas de corps. Elles peuvent tre des mthodes de classe ou dinstance, hritables, masquables ou non.

Javabook Page 437 Lundi, 12. juillet 1999 3:58 15

Constructeurs

437

Une mthode prfixe par synchronized est une mthode qui sexcute via un moniteur qui en contrle les accs (voir point 25.2, p. 354). Le verrou est sur la classe pour une mthode de classe, sinon sur lobjet (mthode dinstance). En Java, une mthode qualifie de abstract ressemble une mthode virtuelle pure en C++, en ce sens quelle na pas de corps et requiert une dfinition explicite dans les sous-classes. Cependant, en Java, de telles mthodes sont dfinies dans une classe ncessairement abstraite elle aussi (voir point A.20, p. 439). final signifie en Java : pour une classe : pas de drivation de sous-classes; pour un attribut : attribut constant; pour une mthode : non redfinissable dans une sous-classe avec les mmes paramtres.

A.17 Constructeurs
Le principe de dfinition des constructeurs en Java est le mme quen C++. Les constructeurs portent le mme nom que la classe. Ils peuvent tre surchargs afin doffrir plusieurs manires dinitialiser des instances.
Construction dobjet par copie Java C++
Temps t=new Temps(12,0,0); Temps t2=t.clone() Temps t(12,0,0); Temps t2=t;

Tableau A.12 Clonage en Java

Il existe cependant quelques diffrences. En Java, il nexiste pas de constructeur par copie par dfaut, la mthode clone() de la classe Object le remplace (voir tableau A.12). Lordre dappel des constructeurs des super-classes est le mme pour Java et C++ : le constructeur de la classe de base est toujours excut avant celui de la classe drive. Une diffrence notable a trait aux constructeurs des objets composants. Contrairement au C++, aucun constructeur par dfaut dobjet composant nest appel en Java. Lexemple du tableau A.13 en est une illustration. La classe Cours est compose de deux variables dinstance de la classe Temps. En C++ seulement, le constructeur par dfaut de la classe Temps sera appel. Sil nexiste pas, la classe Temps devra tre redfinie pour en inclure un.

Javabook Page 438 Lundi, 12. juillet 1999 3:58 15

438
Java Modification du constructeur de la classe Temps pour afficher son nom
Temps() {heure=0; minute=0; seconde=0; System.out.println ("Temps()"); } import Temps; class Cours { public Temps debut,fin; public int numero; public Cours(int num) {numero=num;} }; Cours c=new Cours(12);

Annexe A Du C++ Java


C++
Temps() {heure=0; minute=0; seconde=0; cout << "Temps()"; cout << endl;} #include "Temps.h" class Cours { public : Temps debut,fin; int numero; Cours(int num) {numero=num;} }; Cours c(12); Temps() Temps()

Classe Cours compose de deux variables dinstance de la classe Temps

Dclaration et initialisation dun cours Effet de linstruction prcdente

Tableau A.13 Appel aux constructeurs des composantes

A.18 Destructeurs
Un destructeur en Java est une mthode spciale (non ncessaire) appele finalize() qui permet la libration de ressources systmes non automatiquement libres par le ramasse-miettes. Cette mthode ne joue pas tout fait le mme rle que les destructeurs en C++. Elle est appele par le ramasse-miettes qui, si ncessaire, libre lespace allou des objets qui ne sont plus rfrencs. En C++, lappel au destructeur de la super-classe seffectue automatiquement aprs le destructeur de la classe de linstance dtruire. En Java, le programmeur doit explicitement terminer le texte de sa mthode finalize() par lappel de celui de sa super-classe, soit super.finalize(). En Java, il nest pas utile (ni ncessaire) de programmer des destructeurs, sauf si la classe a acquis une ressource autre que la mmoire que le ramasse-miettes ne peut rcuprer comme, par exemple, un accs sur un fichier ou sur un socket.

A.19 Hritage
Hritage simple
Seul lhritage simple est permis. Le mot cl extends quivaut aux : du C++.

Javabook Page 439 Lundi, 12. juillet 1999 3:58 15

Classe abstraite
Spcification de lhritage Java
import classeDeBase; class classeDerivee extends classeDeBase { ... // attributs et mthodes de la classe drive }; #include "classeDeBase.h" class classeDerivee : classeDeBase { ... // attributs et mthodes de la classe drive };

439

C++

Tableau A.14 Spcification de lhritage en Java et en C++

Modes dhritage
En C++, trois modes dhritage dune classe sont permis : public, protected, private. En Java, il ny en a quun seul (implicite) : public. Ces diffrents modes ont des consquences sur les domaines de protection des membres (variables et mthodes) hrits. Pour les modes dhritage private et protected, le C++ permet de conserver dans la classe drive les domaines de protection des membres de la classe de base. En considrant galement lhritage multiple, on constate que le C++ permet dexprimer de manire fine les relations dhritage entre classes, au dtriment cependant de la simplicit de comprhension pour des schmas de classes consquents.
Mode dhritage prsent dans : C++ C++ C++ et Java Mode dhritage dans la classe drive
private protected public

Protection dun membre de la classe de base private inaccessible inaccessible inaccessible protected
private protected protected

public
private protected public

Tableau A.15 Modes dhritage en Java et en C++

A.20 Classe abstraite


En Java, une classe est abstraite si lune de ses mthodes lest. Le mot cl abstract nest pas un remplacement du mot virtual du C++. En C++, le prfixe virtual sur une mthode sert spcifier la liaison dynamique. De plus, si une mthode est ainsi prfixe, on peut la dfinir virtuelle pure en indiquant que son corps est vide. En Java, il y a toujours une liaison dynamique. Le prfixe abstract signifie virtuelle pure : les mthodes abstraites nont pas de corps.

Javabook Page 440 Lundi, 12. juillet 1999 3:58 15

440
Java Mthode avec liaison dynamique Mthode abstraite pure
void m(...) { // corps de m } abstract void m(...);

Annexe A Du C++ Java


C++
virtual void m(...) { // corps de m } virtual void m(...)=0;

Tableau A.16 Mthode virtuelle avec corps

Le mot cl abstract doit galement prfixer le nom de la classe si cette classe a au moins une mthode abstraite.
Spcification de mthode abstraite
abstract class UneClasse { abstract void uneMethode(...); // methode abstraite ... }; class UneClasse { virtual void uneMethode(...)=0; // methode virtuelle pure .... };

Java

C++

Tableau A.17 Spcification de classe abstraite (virtuelle)

A.21 Classe terminale


Java permet dinterdir la drivation dautres classes partir dune classe considre comme terminale. Le mot cl final prfixant la dfinition de la classe permet de spcifier cette interdiction.
final class classeTerminale extends ... { ... // attributs et mthodes de la classe };

Spcification de classe terminale en Java

A.22 Amiti entre classes et entre instances


En Java, lamiti autorise laccs de toutes les variables et mthodes sans qualificatif aux autres classes du mme package. Les membres non qualifis ne sont pas accessibles par les classes dun package diffrent. Les membres qualifis de private ne sont pas accessibles par les autres classes du mme package. Seules des instances de la mme classe peuvent accder leurs membres privs respec-

Javabook Page 441 Lundi, 12. juillet 1999 3:58 15

Gestion des exceptions

441

tifs. Cest donc lappartenance ou non dune classe un package qui dcide de ses relations damiti avec dautres classes. En C++, lamiti entre classes ncessite une dfinition explicite dans la classe autorisant les accs ses membres privs. Ce qui entrane de frquentes recompilations au fur et mesure que de nouvelles classes sont ajoutes et quelles doivent accder des membres privs dune classe particulire. En Java, de telles nouvelles classes sont simplement ajouter dans le package, ce qui ne requiert aucune compilation supplmentaire.

A.23 Gestion des exceptions


Java tend la gestion des exceptions de C++ par lajout de la clause optionnelle finally. Si cette clause est prsente, elle est excute mme sil ny a pas eu de leve dexception dans le bloc try {...} catch la prcdant. En Java (voir point 8.1, p. 105), toutes les classes dexception doivent tre sousclasses de Throwable.

Dclaration des exceptions leves par une mthode


Cette dclaration prsente des diffrences de syntaxe dans les deux langages (attention au s de throws en Java).
Dclaration des exceptions leves par une mthode Java
void uneMethode(...) throws A,B,C { //corps de la mthode } void uneMethode(...) throw (A,B,C) { //corps de la mthode }

C++

Tableau A.18 Dclaration des exceptions leves par une mthode

Leve des exceptions


La leve de lexception sexprime en Java et en C++ par linstruction throw qui est ncessairement suivie dune instance dexception. Si linstance doit tre cre, le procd est le mme que pour la construction de nimporte quelle instance en Java.

Propagation dune exception en cours de traitement


En C++, cette propagation se fait par linstruction throw seulement. En Java cette propagation requiert le nom de linstance dexception concerne.

Javabook Page 442 Lundi, 12. juillet 1999 3:58 15

442

Annexe A Du C++ Java


Propagation dune exception en cours de traitement
.... catch (IOException e) { ... throw e;} .... catch (IOException e) { ... throw ;}

Java

C++

Tableau A.19 Propagation dune exception en cours de traitement

A.24 Caractristiques de C++ absentes de Java


Outre celles que nous avons illustres dans ltude dtaille ci-dessus, il est noter quelques caractristiques du C++ non reprises dans Java. Java nautorise pas la surcharge des oprateurs. Loprateur +, par exemple, ne peut tre redfini pour des objets de la classe Matrice. Il faudra dfinir une mthode plus() permettant laddition matricielle. Java na pas la notion de pointeur, on ne peut avoir de pointeur sur des mthodes. De nombreux cas dutilisation des fonctions en paramtres peuvent tre rsolus avec la notion dinterface en Java. Java nincorpore pas la notion de classe gnrique (template).

A.25 Caractristiques de Java non supportes par C++


Java prsente de nombreuses qualits qui ont suscit un engouement assez large sur la plante. La portabilit, la scurit (voir chapitre 27), le fonctionnement multiprocessus (voir p. 107) des applications sont des points majeurs. En outre, Java contrle laccs aux ressources partages laide de moniteurs. Gageons que le programmeur familier du C++, motiv par les avantages de Java, apprendra vite ce langage, car il a t bien pens sur de nombreux aspects dont la pertinence apparat lorsque lon dveloppe des applications assez volumineuses.

Javabook Page 443 Lundi, 12. juillet 1999 3:58 15

Annexe B

Grammaire BNF de Java


Nous avons utilis les conventions suivantes pour les rgles de grammaire : [ nom ] : nom est rpt 0 ou 1 fois; < nom > : nom est rpt 0 ou n fois; a | b : soit a soit b; "chane" : chane terminale.

B.1 Niveau syntaxique


goal = compilationUnit. literal = integerLiteral | floatingPointLiteral | booleanLiteral

| characterLiteral | stringLiteral | "null".


type = primitiveType | referenceType. primitiveType = numericType | "boolean". numericType = integralType | floatingPointType. integralType = "byte" | "short" | "int" | "long" | "char". floatingPointType = "float" | "double". referenceType = classOrInterfaceType | arrayType. classOrInterfaceType = name.

Javabook Page 444 Lundi, 12. juillet 1999 3:58 15

444
classType = classOrInterfaceType. interfaceType = classOrInterfaceType. arrayType name

Annexe A Grammaire BNF de Java

= ( primitiveType | name ) "[" "]" < "[" "]" >.

= simpleName | qualifiedName. = identifier. = name "." identifier. importDeclaration >

simpleName

qualifiedName compilationUnit

= [ packageDeclaration ] < < typeDeclaration >. = "package" = "import" name ";".

packageDeclaration importDeclaration typeDeclaration modifier

name [ ".*" ] ";". interfaceDeclaration | ";".

= classDeclaration |

"public" | "protected" | "private" | "static" | "abstract" | "final" | "native" | "synchronized" | "transient" | "volatile". identifier

classDeclaration

= < modifier > "class" [ super ] [ interface ] classBody. = "extends" classType. = "implements"

super

interfaces classBody

interfaceType < ","

interfaceType >.

= "{" < classBodyDeclaration > "}".

classBodyDeclaration

= classMemberDeclaration | staticInitializer | constructorDeclaration. = fieldDeclaration | methodDeclaration.

classMemberDeclaration fieldDeclaration

= < modifier > type variableDeclarator < "," variableDeclarator > ";".

variableDeclarator

= variableDeclaratorId [ "=" variableInitializer ]. = = = identifier < "[" "]" >. expression | arrayInitializer. methodHeader methodBody.

variableDeclaratorId variableInitializer methodDeclaration

Javabook Page 445 Lundi, 12. juillet 1999 3:58 15

Niveau syntaxique
methodHeader

445

= < modifier > ( type | "void" ) methodDeclarator [ throws ].

methodDeclarator

= identifier "(" [ formalParameterList ] ") < "[" "]" >. = type formalParameter < "," variableDeclaratorId. formalParameter >.

formalParameterList formalParameter throws

= "throws" classTypeList. = classType < "," classType >.

classTypeList methodBody

= block | ";". = "static" block.

staticInitializer

constructorDeclaration

[ ")".

= < modifier > constructorDeclarator throws ] constructorBody. = simpleName "(" [ formalParameterList ]

constructorDeclarator

constructorBody

= "{" [ explicitConstructorInvocation ] [ blockStatements ] "}" .

explicitConstructorInvocation

= "this" "(" [ argumentList ] ")" ";" | "super" "(" [ argumentList ] ")" ";". identifier interfaceType

interfaceDeclaration

[ >.

= < modifier > "interface" extendsInterfaces ] interfaceBody. = "extends" interfaceType < ","

extendsInterfaces

interfaceBody

= "{" <

interfaceMemberDeclaration > "}".

interfaceMemberDeclaration

= constantDeclaration | asbstractMethodDeclaration. = fieldDeclaration. = methodHeader ";".

constantDeclaration

abstractMethodDeclaration arrayInitializer

< ","
block

= "{" [ variableInitializer variableInitializer > ] [ "," ] "}".

= "{" < blockStatement > "}". = localVariableDeclarationStatement | statement.

blockStatement

Javabook Page 446 Lundi, 12. juillet 1999 3:58 15

446
localVariableDeclarationStatement localVariableDeclaration

Annexe A Grammaire BNF de Java


= localVariableDeclaration ";".

< ","
statement

= type variableDeclarator variableDeclarator >.

= statementWithoutTrailingSubstatement | labeledStatement | ifThenStatement | ifThenElseStatement | whileStatement | forStatement. = statementWithoutTrailingSubstatement | labeledStatementNoShortIf | ifThenElseStatementNoShortIf | whileStatementNoShortIf | forStatementNoShortIf. = block | emptyStatement | expressionStatement | switchStatement | doStatement | breakStatement | continueStatement | returnStatement | synchronizedStatement | throwStatement | tryStatement.

statementNoShortIf

statementWithoutTrailingSubstatement

emptyStatement labeledStatement

= ";". = identifier ":" = statement. statementNoShortIf.

labeledStatementNoShortIf expressionStatement statementExpression

identifier ":"

statementExpression ";".

= assignment | preIncrementExpression | preDecrementExpression | postIncrementExpression | postDecrementExpression | methodInvocation | classInstanceCreationExpression. = "if" "(" expression ")" statement.

ifThenStatement

Javabook Page 447 Lundi, 12. juillet 1999 3:58 15

Niveau syntaxique
ifThenElseStatement

447

= "if" "(" expression ")" statementNoShortIf "else" statement. = "if" "(" expression ")" statementNoShortIf "else" statementNoShortIf. = "switch" "(" expression ")" switchBlock.

ifThenElseStatementNoShortIf

switchStatement switchBlock

[ <

= "{" [ switchBlockStatementGroups ] switchLabels ] "}". = switchBlockStatementGroup switchBlockStatementGroup >. = switchLabels < blockStatement >. switchLabel >. ":" | "default" ":". statement.

switchBlockStatementGroups

switchBlockStatementGroup switchLabels switchLabel

switchLabel <

= "case" constantExpression = while "("

whileStatement

expression ")"

whileStatementNoShortIf

= while "(" expression ")" statementNoShortIf. = "do" statement "while" "(" expression ")" ";" .

doStatement forStatement

= "for" "(" [ forInit ] ";" [ expression ] ";" [ forUpdate ] ")" statement. = "for" "(" [ forInit ] ";" [ expression ] ";" [ forUpdate ] ")" statementNoShortIf. = = statementExpressionList | statementExpressionList. statementExpression >. localVariableDeclaration.

forStatementNoShortIf

forInit forUpdate

statementExpressionList

= statementExpression < ","

Javabook Page 448 Lundi, 12. juillet 1999 3:58 15

448
breakStatement

Annexe A Grammaire BNF de Java


= "break" [ identifier ] ";". identifier ] ";".

continueStatement returnStatement throwStatement

= "continue" [ = "return" [

expression ] ";".

= "throw"

expression ";". expression ")" block. finally ).

synchronizedStatement tryStatement catches

= "synchronized" "("

= "try" block ( catches | [ catches ]

= catchClause < catchClause >. = "catch" "(" formalParameter ")" block.

catchClause finally primary

= "finally" block. = primaryNoNewArray | arrayCreationExpression.

primaryNoNewArray

= literal | this | "(" expression ")" | classInstanceCreationExpression | fieldAccess | methodInvocation | arrayAccess.

classInstanceCreationExpression

= "new" classType "(" [ argumentList ] ")". = expression < "," expression >.

argumentList

arrayCreationExpression

= "new" ( primitiveType | classOrInterfaceType ) "[" expression "]" < "[" expression "]" > < "[" "]" >.

fieldAccess

= primary "." identifier | "super" "." identifier.

methodInvocation

= name "(" [ argumentList ] ")" | primary "." identifier "(" [ argumentList ] ")" | "super" "." identifier "(" [ argumentList ] ")". = name "[" expression "]" | primaryNoNewArray "[" expression "]". =

arrayAccess

postfixExpression

Javabook Page 449 Lundi, 12. juillet 1999 3:58 15

Niveau syntaxique
primary | name | postIncrementExpression | postDecrementExpression.
postIncrementExpression postDecrementExpression unaryExpression

449

= =

postfixExpression "++". postfixExpression "--".

= preIncrementExpression | preDecrementExpression | "+" unaryExpression | "-" unaryExpression | unaryExpressionNotPlusMinus. = "++" unaryExpression. = "--" unaryExpression. =

preIncrementExpression preDecrementExpression

unaryExpressionNotPlusMinus

postfixExpression | "~" unaryExpression | "!" unaryExpression | castExpression.


castExpression

= "(" primitiveType < "[" "]" > ")" unaryExpression | "(" expression ")" unaryExpressionNotPlusMinus | "(" name "[" "]" < "[" "]" > ")" unaryExpressionNotPlusMinus. = unaryExpression | multiplicativeExpression "*" unaryExpression | multiplicativeExpression "/" unaryExpression | multiplicativeExpression "%" unaryExpression.

multiplicativeExpression

additiveExpression

= multiplicativeExpression | additiveExpression "+" | additiveExpression "-"

multiplicativeExpression multiplicativeExpression.

shiftExpression

= additiveExpression | shiftExpression "<<" additiveExpression | shiftExpression ">>" additiveExpression | shiftExpression ">>>" additiveExpression. = shiftExpression | relationalExpression "<"

relationalExpression

shiftExpression

Javabook Page 450 Lundi, 12. juillet 1999 3:58 15

450
| | | | relationalExpression relationalExpression relationalExpression relationalExpression

Annexe A Grammaire BNF de Java


">" shiftExpression "<=" shiftExpression ">=" shiftExpression "instanceof" referenceType.

equalityExpression

= relationalExpression | equalityExpression "==" | equalityExpression "!=" = equalityExpression | andExpression "&"

relationalExpression relationalExpression.

andExpression

equalityExpression.

exclusiveOrExpression

= andExpression | exclusiveOrExpression "^" andExpression. = exclusiveOrExpression | inclusiveOrExpression "|"

inclusiveOrExpression

exclusiveOrExpression.

conditionalAndExpression

= inclusiveOrExpression | conditionalAndExpression "&&"

inclusiveOrExpression.

conditionalOrExpression

= conditionalAndExpression | conditionalOrExpression "||" conditionalAndExpression.

= conditionalOrExpression | conditionalOrExpression "?" conditionalExpression.


conditionalExpression assignmentExpression assignment

expression ":"

= conditionalExpression | assignment.

= leftHandSide assignmentOperator assignmentExpression. = name | fieldAccess | arrayAccess.

leftHandSide

assignmentOperator

= "=" | "*=" | "/=" | "%=" | "+=" | "-=" | "<<=" | ">>=" | ">>>=" | "&=" | "^=" | "|=". = assignmentExpression. = expression.

expression

constantExpression

Javabook Page 451 Lundi, 12. juillet 1999 3:58 15

Niveau lexical

451

B.2 Niveau lexical


unicodeInputCharacter = unicodeEscape | rawInputCharacter. unicodeEscape = "\" unicodeMarker hexDigit hexDigit hexDigit

hexDigit.

unicodeMarker = "u" < "u" >. rawInputCharacter = "any Unicode character". lineTerminator = "LF" | "CR" | "CRLF". inputCharacter = unicodeInputCharacter "but not CR or LF". input = [ inputElements ] [ sub ]. inputElements = inputElement < inputElement >. inputElement = whiteSpace | comment | token. token = identifier | keyword | literal | separator | operator. sub = "the ASCII SUB character, also known as control-Z". whiteSpace = " " | "TAB" | "FF" | lineTerminator. comment = traditionalComment | endOfLineComment |

documentationComment.

traditionalComment = "/*" notStar commentTail. endOfLineComment = "//" < inputCharacter > lineTerminator. documentationComment = "/**" commentTailStar. commentTail = "*" commentTailStar | notStar commentTail. commentTailStar =

"/" | "*" commentTailStar | notStarNotSlash commentTail.


notStar = inputCharacter "but not *" | lineTerminator. notStarNotSlash = inputCharacter "but not * or /" | lineTerminator. identifier = identifierChars "but not" (keyword | booleanLiteral |

nullLiteral).

identifierChars = javaLetter | identifierChars javaLetterOrDigit.

Javabook Page 452 Lundi, 12. juillet 1999 3:58 15

452

Annexe A Grammaire BNF de Java

javaLetter = "any Unicode character that is a Java letter".

digit".

javaLetterOrDigit = "any Unicode character that is a Java letter-orkeyword =

"abstract" | "default" | "if" | "private" | "throw" | "boolean" | "do" | "implements" | "protected" | "throws" | "break" | "double" | "import" | "public" | "transient" | "byte" | "else" | "instanceof" | "return" | "try" | "case" | "extends" | "int" | "short" | "void" | "catch" | "final" | "interface" | "static" | "volatile" | "char" | "finally" | "long" | "super" | "while" | "class" | "float" | "native" | "switch" | "const" | "for" | "new" | "synchronized" | "continue" | "goto" | "package" | "this".
integerLiteral =

( decimalNumeral | hexNumeral | octalNumeral ) [ "l" | "L" ] .


decimalNumeral

= "0" | ( "1..9" < "0..9" > ).

digits = "0..9" < "0..9" >. hexNumeral = "0" ( "x" | "X" ) hexDigit < hexDigit >. hexDigit = "0..9" | "a..f" | "A..F". octalNumeral = "0" "0..7" < "0..7" >.

floatingPointLiteral =

( ( (digits "." [ digits ] | "." digits) [ exponentPart ] | digits exponentPart ) [ "f" | "F" | "d" | "D" ] ) | digits [ exponentPart ] ("f" | "F" | "d" | "D" ) .
exponentPart = ("e" | "E") [ "+" | "-" ] digits. booleanLiteral = "true" | "false". characterLiteral = "'" ( singleCharacter | escapeSequence ) "'". singleCharacter = inputCharacter "but not ' or \". stringLiteral = """ [ stringCharacters ] """. stringCharacters = stringCharacter < stringCharacter >. stringCharacter = inputCharacter "but not double quote or \" |

escapeSequence.

octalEscape ).

escapeSequence =

"\" ("b" | "t" | "n" | "r" | """

| "'" | "\" |

Javabook Page 453 Lundi, 12. juillet 1999 3:58 15

Niveau lexical
octalEscape =

453
"\" [ "0..3" ] [ "0..7" ] "0..7".

separator = "(" | ")" | "{" | "}" | "[" | "]" | ";" | "," | ".". operator = "=" | ">" | "<" | "!" | "~" | "?" | ":" | "==" | "<=" |">=" |"!=" | "&&" | "||" | "++" | "--" | "+" | "-" | "*" |"/" | "&" | "|" | "^" | "%" | "<<" | ">>" | ">>>" | "+=" |"-=" | "*=" | "/=" | "&=" | "|=" | "^=" | "%=" | "<<=" | ">>=" | ">>>=" .

Javabook Page 454 Lundi, 12. juillet 1999 3:58 15

Javabook Page 455 Lundi, 12. juillet 1999 3:58 15

Annexe C

Les fichiers darchives .jar


Une application Java peut tre constitue dun nombre important de classes et, par consquent, dautant de fichiers. Le transfert dune applet vers le butineur peut savrer relativement long, car le chargement se fait classe par classe. Pour acclrer le chargement, il est possible de construire un fichier unique compress comportant plusieurs fichiers. On parle alors dun .jar (pour java archive), quivalent des .tar dUnix ou des .zip du monde des PC. Les fichiers .jar ont lavantage dtre indpendants et portables.

C.1 Loption ARCHIVES


En spcifiant dans la balise <applet> dun fichier HTML loption ARCHIVES, on modifie le scnario de lexcution dune applet. Les classes contenues dans les fichiers .jar sont charges en une seule fois avant le dbut de lexcution de lapplet. Cela reprsente essentiellement une optimisation pour leur excution. Examinons un exemple. Le jeu du serpent prsent dans ce livre, contient (pour une certaine version) les classes suivantes (avec leur taille en bytes) :
876 3,021 2,008 1,590 222 Appat.class Jeu.class LeMonde.class Serpent.class appletcode.html

Javabook Page 456 Lundi, 12. juillet 1999 3:58 15

456

Annexe A Les fichiers darchives .jar

Le butineur WWW chargera donc la page appletcode.html suivante :


<title>jeux1</title> <hr> <applet code=Jeu.class width=500 height=300> <PARAM NAME=vitesse VALUE="20"> <PARAM NAME=hauteur VALUE="300"> <PARAM NAME=largeur VALUE="500"> <PARAM NAME=grain VALUE="10"> </applet>

Linterprtation de la balise <applet> entrane le chargement de la classe Jeu puis son excution. Lexcution de ce code contient une instruction pour instancier un objet de la classe LeMonde. Comme la machine virtuelle de Java fait du chargement dynamique, le chargement de cette classe sera effectu, puis lexcution reprendra. Et ainsi de suite. Finalement les cinq classes seront charges et le jeu continuera sans autres temps morts. En construisant un fichier .jar des classes charges par Jeu, on vite ces interruptions dans lexcution. On utilise loutil jar pour construire ce fichier. Dans notre cas, on peut excuter la commande suivante (la signification des paramtres cvf est explique en fin de chapitre) :
jar cvf Serpent.jar *.class

Loutil montre les classes quil inclut dans larchive ainsi que les gains obtenus grce la compression.
added manifest adding: Appat.class (in=876) (out=579) (deflated 33%) adding: Jeu.class (in=3021) (out=1683) (deflated 44%) adding: LeMonde.class (in=2008) (out=1163) (deflated 42%) adding: PointMobile.class (in=483) (out=336) (deflated 30%) adding: Serpent.class (in=1590) (out=900) (deflated 43%)

Dans un nouveau rpertoire, nous pouvons mettre les fichiers suivants, la page html et larchive .jar :
244 appletcodejar.html 3,797 Serpent.jar

Le butineur WWW chargera donc la page appletcodejar.html suivante :


<title>jeux1</title> <hr> <applet archives="Serpent.jar" code=Jeu.class width=500 height=300> <PARAM NAME=vitesse VALUE="20"> <PARAM NAME=hauteur VALUE="300"> <PARAM NAME=largeur VALUE="500"> <PARAM NAME=grain VALUE="10"> </applet>

Javabook Page 457 Lundi, 12. juillet 1999 3:58 15

Retour sur loutil jar

457

Et la premire chose sera de charger larchive Serpent.jar. Ensuite, le butineur cherchera dans les classes charges celle demande dans loption code (dans notre cas Jeu.class), si elle sy trouve. Il commence alors lexcution de celle-ci. Sinon, il la charge en utilisant ventuellement loption codebase. Il existe une autre possibilit pour dclarer une archive. Cette archive peut tre spcifie dans les paramtres de lapplet (la balise <param>) :
<applet code=Jeu.class width=500 height=300> <PARAM NAME=ARCHIVES VALUE="Serpent.jar"> . . . </applet>

Il est possible de spcifier plusieurs archives lors du chargement de lapplet. Il suffit de sparer les noms des fichiers par un signe +.
<applet archives="Serpent.jar+Autres.jar" code=Jeu.class width=500 height=300> . . . </applet>

Lutilisation des archives est intressante dans les cas suivants : vous dsirez diminuer le temps de chargement de vos applets; vous dsirez simplifier la distribution dune application ou dun package; vous dsirez certifier et authentifier votre code. Remarque: lutilisation des archives nest pas toujours une optimisation du temps de chargement. En effet, si votre applet contient beaucoup de classes, gnralement peu dentre elles sont effectivement charges lors dune excution. En utilisant une archive, elles seront toutes charges alors que beaucoup ne seront pas utilises. Il faut dont choisir entre une solution optimiste et une solution pessimiste.

C.2 Retour sur loutil jar


Loutil jar permet : darchiver un ensemble de fichiers (en mode cration et en mode de mise jour); de lister le contenu dune archive; dextraire des fichiers dune archive; de manipuler le fichier manifest associ larchive. Le fichier manifest associ larchive contient des mta-informations sur larchive. Sans mcanisme de scurit ou dauthentification, il contient galement des informations sur les check-sum des archives. Nous reproduisons, en la traduisant, laide de la commande jar afin den expliciter toutes les options :

Javabook Page 458 Lundi, 12. juillet 1999 3:58 15

458

Annexe A Les fichiers darchives .jar

>jar Usage: jar {ctxu}[vfm0M] [jar-file] [manifest-file] [-C dir] files ... Options: -c crer une nouvelle archive -t lister le contenu d'une archive -x extraire les fichiers nomms(ou all) de l'archive -u mettre jour une archive existante archive -v generer une sortie longue sur la sortie standard -f spficier le nom de l'archive -m inclure des informations manifestes d'un fichier manifest spcifi -0 stocker seulement; pas de compression ZIP -M ne pas crer de fichier manifest pour les entres -C changer de directoire et inclure les fichiers suivants

Lauthentification et la scurisation du code sont galement possibles, mais le lecteur doit tre bien inform sur les mcanismes de scurit (cl publique, signature, etc.). Nous le renvoyons la documentation de Sun pour cet aspect particulier. Le dernier point souligner est que loutil jar peut tre utilis pour la compression de nimporte quel fichier, et pas seulement des fichiers .class. Vous pouvez aussi lutiliser comme nimporte quel autre outil de compression avec lavantage de la portabilit. Il permet notamment dassocier des images, des sons ou dautres ressources qui pourraient tre ncessaires lapplet, et qui seront donc distribues avec elle.

Javabook Page 459 Lundi, 12. juillet 1999 3:58 15

Annexe D

Rappel sur HTML


Ce court rappel sur le langage HTML et ses principaux dlimiteurs (balises) est destin permettre une meilleure intgration des applets Java sur le Web. Le programmeur Java doit intgrer son applet dans une page HTML. Cette page constitue donc un emballage de lapplet. Le succs dun produit dpendant aussi de son emballage... vous voil averti.

D.1 SGML
HTML (Hyper Text Markup Language) est issu dun systme beaucoup plus puissant appel SGML (Standard General Markup Language). SGML est un standard international pour la reprsentation de textes sous une forme informatise indpendante du systme et des priphriques daffichage (imprimantes, crans, etc.). Il sagit dun mtalangage qui permet de dfinir dautres langages bass sur les dlimiteurs (markup en anglais). La description obtenue est une DTD (Document Type Definition). HTML est ainsi une DTD de SGML. SGML sera appel dans le futur jouer un rle de plus en plus important pour la gestion des documents lectroniques, car sa description indpendante des plates-formes permet de manipuler facilement le texte et de structurer fortement les documents.

Javabook Page 460 Lundi, 12. juillet 1999 3:58 15

460

Annexe A Rappel sur HTML

D.2 Dlimiteurs
Tags, balises, signets ou bornes sont autant de termes utiliss pour dsigner les dlimiteurs. Ceux-ci ont la forme gnrale suivante :
<Nom_Dlimituer> subit laction du dlimiteur </Nom_Dlimiteur>

Le nom du dlimiteur reprsente une action de structuration ou de mise en forme sur le texte qui le suit, jusqu lindication de la fin de laction </>. Certains dlimiteurs ne ncessitent pas de fin, comme par exemple <HR> qui indique une ligne horizontale. Il existe plusieurs standards HTML : les versions (1.0, 2.0 et maintenant 3.21) ainsi que les dialectes, soutenus par les acteurs du march du logiciel tels que Netscape ou Microsoft. Normalement, tous les butineurs actuels devraient supporter le HTML 2.0. Dans la suite de ce chapitre, nous signalons par lindication (*) les extensions propres au dialecte de Netscape, par ailleurs gnralement comprises par lInternet Explorer de Microsoft. Parmi ces extensions, les suivantes sont prises en compte dans la norme 3.2 : les tables; le dlimiteur APPLET; lcoulement du texte autour des images (ALIGN); les indices et les exposants (SUB, SUP).

Dlimiteurs de structuration
Les dlimiteurs suivants (voir tableau D.1) permettent dindiquer un minimum de structuration pour un document HTML.
Dlimiteur
<HTML>...</HTML> <!...> <HEAD>...</HEAD> <TITLE>...</TITLE> <BODY>...</BODY> <Hi>...<Hi>

Signification Type du document Commentaire En-tte du document (non affich) Titre du document (non affich) Corps du document Titres de niveau : i =1 6 Tableau D.1 HTML, dlimiteurs de structuration

1. Voir les annonces dans [14].

Javabook Page 461 Lundi, 12. juillet 1999 3:58 15

Dlimiteurs
Dlimiteur
<P>...</P> <BR> <HR>

461
Signification Paragraphe Rupture de ligne Ligne horizontale de sparation Tableau D.1 HTML, dlimiteurs de structuration

Exemple de document HTML structur (ex1.html) :


<HTML> <HEAD> <! le titre apparait dans les outils de navigation> <! et dans les indexeurs Yahoo, altavista> <TITLE> Titre du document visible </TITLE> </HEAD> <BODY> <H1>JAVA</H1> texte du document <H2>Une introduction</H2> Il etait une fois une ile .... qui etait au milieu de l'ocean ...<P> Cette ile ... <H2>Une ...</H2> texte du document <H2>Une conclusion</H2> Il cultivait un delicieux cafe ....<BR> qui se buvait en faisant des programmes ... </BODY> </HTML>

Figure D.1 Document HTML structur (ex1.html)

Javabook Page 462 Lundi, 12. juillet 1999 3:58 15

462

Annexe A Rappel sur HTML

Limage obtenue dans un butineur permet dobserver que les titres, les ruptures de lignes et les fins de paragraphes sont bien respects.

Dlimiteurs de listes
Les dlimiteurs suivants (tableau D.2) permettent de structurer des listes ayant diffrentes prsentations.
Dlimiteur
<UL> <LI> <LI> </UL> <OL> <LI> <LI> </OL> <DL> <DT> <DD> </DL> <UL TYPE=disc | circle | square> (*) <OL TYPE=a | A | i | I | 1 |> (*)

Signification UL - Unnumbered List LI - List Item Liste non numrote OL - Ordered List LI - List Item Liste numrote DL - Definition List DT - Definition Title DD - Definition Description Liste de dfinition Type de mise en vidence (disque, cercle, carr) Type de numrotation

Tableau D.2 HTML, dlimiteurs de listes

Exemple de listes (ex2.html) :


<HTML> <HEAD> <TITLE> liste ... </TITLE> </HEAD> <BODY> <H1>Les listes</H1> <OL> Liste ne pas oublier <LI> les nombres premiers <LI> les dcimales de pi </OL> mais avec en plus ... <OL TYPE=i> Liste des numrations gadgets <LI> i, ii, iii, <LI> a, b, c, <LI> 1, 2 , 3 </OL>

Javabook Page 463 Lundi, 12. juillet 1999 3:58 15

Dlimiteurs
et encore <UL>Listes OUX <LI>bijoux <LI>cailloux <LI>poux <LI>... </UL> et enfin <DL> Ici quelques dfinitions importantes <DT>Classe <DD>Une classe est une description .... <DT>Interface <DD>Une Interface est une description .... </DL> </BODY> </HTML>

463

Nous obtenons laffichage suivant (limage a t volontairement tronque) :

Figure D.2 Document HTML contenant des listes (ex2.html)

Dlimiteurs dattributs logiques textuels


Les dlimiteurs suivants permettent de dfinir le type dun texte, qui influence gnralement sa forme. Il est noter que ces types sont relativement limits et

Javabook Page 464 Lundi, 12. juillet 1999 3:58 15

464

Annexe A Rappel sur HTML

quils sont orients vers des documents de programmation. Exemple dattributs logiques (ex3.html) :
Dlimiteur
<EM>...</EM> <STRONG>...</STRONG> <CITE>...</CITE> <KDB>...</KDB> <SAMP>...</SAMP> <VAR>...</VAR>

Signification Mise en vidence (EMphase). Mise en vidence forte. Citation. Entre au clavier. Exemple. Variable.

Tableau D.3 HTML, dlimiteurs dattributs logiques textuels


<HTML> <HEAD> <TITLE> attributs logiques ... </TITLE> </HEAD> <BODY> <H1>attribut logique</H1> Texte "normal" sans attribut logique<p> <EM>Attention </EM><p> <STRONG>Important</STRONG><p> <CITE>"Sur un arbre perch maitre corbeau tenait un ..." La Fontaine</CITE><p> <KDB>La touche ESC permet de ...</KDB><p> <SAMP>Ici on trouve un exemple de multiplication</SAMP><p> <VAR>variable</VAR><p> </BODY> </HTML>

Nous obtenons limage de la figure D.3 : le choix dun type de caractres et de son style repose sur linterprteur HTML.

Figure D.3 Attributs logiques du texte en HTML (ex3.html)

Javabook Page 465 Lundi, 12. juillet 1999 3:58 15

Dlimiteurs

465

Dlimiteurs dattributs typographiques


Les dlimiteurs suivants permettent de dfinir directement les lments typographiques du texte.
Dlimiteur
<B>...</B> <I>...</I> <TT>...</TT> <SUP>...</SUP> <SUB>...</SUB> <FONT SIZE=n COLOR=#rrvvbb >

Signification Gras. Italique. (TeleType) fonte non proportionnelle (courrier) respecte les retours de ligne. Variable en exposant, au-dessus de la ligne de base. Variable en indice, en dessous de la ligne de base. Spcifie la taille de la fonte par rapport une chelle relative de 1 7 et la couleur en hexadcimal.

Tableau D.4 HTML, dlimiteurs dattributs typographiques

Exemple dattributs typographiques (ex4.html) :


<HTML> <HEAD> <TITLE> attribut typographiques ... </TITLE> </HEAD> <BODY> <H1>attribut typographique</H1> <B>en gras</B><P> <I>en italique</I><P> <TT>Comme sur une machine crire!</TT><p> Doit apparatre<SUP>en exposant</SUP><P> Doit apparatre<SUB>en indice</SUB><P> <FONT size=1 color=#FF0000>petit rouge</SUB><P> <FONT size=7 color=#0000FF>grand bleu</SUB><P> </BODY> </HTML>

Nous obtenons limage de la figure D.4 : le choix dun type de caractres et de son style repose sur les indications du concepteur de la page. Nanmoins, ces aspects esthtiques tant fortement dpendants des butineurs, il est conseill de les utiliser avec parcimonie.

Javabook Page 466 Lundi, 12. juillet 1999 3:58 15

466

Annexe A Rappel sur HTML

Figure D.4 Attributs typographiques en HTML (ex4.html)

Dlimiteurs de zones dcran


Netscape implante, laide du concept de frame, la possibilit de partager lespace de la fentre en plusieurs zones spares. Chaque zone pourra afficher un document indpendamment des autres ou tre remplie par un autre document. Le dlimiteur <FRAMESET> remplace le dlimiteur <BODY>.
Dlimiteur
<FRAMESET COLS="hauteur_liste" ROWS="largeur_liste"> ...</FRAMESET>

Signification Dfinit la rpartition de la zone en colonnes ou en ranges. La rpartition est : absolue (n) en points, en pourcentage (n%), relative (*,n*). Les FRAMESET peuvent tre imbriqus les uns dans les autres. Ce dlimiteur est contenu dans un FRAMESET, il donne un nom une zone et indique lURL pour charger son contenu; les autres paramtres concernent la taille des marges la sparant des autres zones, les ascenseurs de dfilement de la zone et la possibilit de la redimensionner (avec la souris, vous pouvez redimensionner une zone en vous positionnant sur lune de ses marges). Le texte mis entre ces deux dlimiteurs sera excut si le navigateur ne connat pas le concept de FRAME. Cela permet donc de donner aussi accs ces pages quelquun qui ne possde pas de navigateur adapt. Tableau D.5 HTML, dlimiteurs de zones dcran

<FRAME SRC="URL" NAME="Nom_Zone" MARGINWIDTH=n MARGINHEIGHT=n SCROLLING="yes|no|auto" NORESIZE> </FRAME>

<NOFRAME> ... </NOFRAME>

Javabook Page 467 Lundi, 12. juillet 1999 3:58 15

Dlimiteurs

467

Exemple de dlimiteurs de zones (ex5.html) :


<HTML> <HEAD><TITLE> dlimiteurs de zones... </TITLE></HEAD> <FRAMESET ROWS=*,*,3*> <FRAME SRC="ex5h.html" NAME="haut"> <FRAME SRC="ex5m.html" NAME="milieu"> <FRAMESET COLS=40%,60%> <FRAME SRC="ex5bd.html" NAME="basdroite"> <FRAMESET ROWS=*,*> <FRAME SRC="ex5bgh.html" NAME="basgauchehaut"> <FRAME SRC="ex5bgb.html" NAME="basgauchebas"> </FRAMESET> </FRAMESET> </FRAMESET> <NOFRAME> Cette page est mieux vue avec une version supportant les FRAME, suite du texte. </NOFRAME> </HTML>

La figure D.5 illustre lexcution avec un butineur connaissant le concept de FRAME, et avec un second qui ne le connat pas. Conserver une quivalence de navigation en programmant une double interprtation des pages HTML peut tre un exercice coteux.

Figure D.5 Dlimiteurs de zones en HTML (ex5.html)

Javabook Page 468 Lundi, 12. juillet 1999 3:58 15

468

Annexe A Rappel sur HTML

Dlimiteurs dancres et de liens


Les dlimiteurs suivants permettent de dfinir des liens entre les documents. Cest ici que se joue la partie hypertexte de HTML.
Dlimiteur
<A NAME="...">... </A>

Signification Dfinit une ancre lintrieur du document. La partie comprise entre les deux dlimiteurs est la zone rfrence. Lien vers un autre URL (document ou ventuellement intrieur du mme document). La partie comprise entre les deux dlimiteurs dfinit le texte du lien dans le document appelant (gnralement soulign). Lien vers un autre URL (document) afficher dans la sous-fentre dsire.

<A HREF="URL"> ... </A>

<A HREF="URL" TARGET="frame"> (*)

Tableau D.6 HTML, dlimiteurs dancres et de liens

Exemple dancres et de liens (ex6.html) :


<HTML> <HEAD><TITLE> fichier liens hypertextuels ... </TITLE></HEAD> <BODY> <H1>liens hypertextuels</H1> texte ...<p> attention <a href="ex6a.html"> ici </a> se trouve une liste de site important.<p> texte ...<p> </BODY> </HTML>

Exemple : ex6a.html
<HTML> <HEAD><TITLE>liste importante ex6a </TITLE></HEAD> <BODY> <A href="ex6.html">sommaire</A><P> <H1>liens hypertextuels</H1> <H2>liens hypertextuels</H2> item 1<P> item 2<P> <a href="#java">liens sur java</A><P> item n<p> ...<p> <A name="#java"><H2>JAVA</H2></A> ... <A href="http://java.sun.com/">sun et java</A><P> ... </BODY> </HTML>

Javabook Page 469 Lundi, 12. juillet 1999 3:58 15

Dlimiteurs

469

Nous obtenons limage suivante pour le document ex6.html. En cliquant sur ici, on charge le document ex6a.html. En cliquant sur sommaire, on retourne ex6.html. En cliquant sur liens sur java, on avance dans le document jusqu la zone de rfrence. En cliquant sur sun et java, on charge la home page du serveur Sun.

vers le serveur Web sur Sun et Java

Figure D.6 Liens hypertextuels en HTML (ex6.html)

Dlimiteurs de manipulation dimages


Les images sont charges depuis des fichiers (extension gif et jpg selon la compression utilise). Le dlimiteur permet de spcifier lalignement de limage).
Dlimiteur
<IMG SRC="URL" ALIGN=top | middle | bottom ALT="..." >

Signification Permet dinsrer une image dans le document en indiquant lURL dsignant limage. ALIGN permet de positionner limage par rapport la ligne de texte courante. ALT permet de donner un texte pour les navigateurs naffichant pas dimage.

Tableau D.7 HTML, dlimiteurs de manipulation dimages

Javabook Page 470 Lundi, 12. juillet 1999 3:58 15

470
Dlimiteur
<IMG SRC="URL" WIDTH=".." HEIGHT=".." VSPACE=".." HSPACE=".." ALIGN="right | left" BORDER="number"> <IMG SRC="URL" ISMAP>

Annexe A Rappel sur HTML


Signification Ces extensions permettent de dfinir la taille de limage (HEIGHT, WIDTH), lespace autour de limage (VSPACE, HSPACE), lcoulement du texte autour de limage (LEFT, RIGHT) et le cadre de limage (BORDER). Cette extension permet dindiquer que limage est aussi une zone sensible dclenchant des actions. Permet de choisir un fond dcran. Il doit tre petit en taille et ne pas gner la lecture.

<BODY BACKGROUND="image.gif">

Tableau D.7 HTML, dlimiteurs de manipulation dimages

Exemple dimages (ex7.html) :


<HTML> <HEAD> <TITLE>images ... </TITLE> </HEAD> <BODY> <H1>image</H1> texte <img src="image7.gif" align=top> haut <img src="image7.gif" align=middle> milieu <img src="image7.gif" align=bottom> bas <p> utilisation d'image pour les ancres<p> <a href="ex6.html"><img src="flechegauche.gif" align=middle></a> <a href="ex8.html"><img src="flechedroite.gif" align=middle></a><p> <img src="bigimg7.jpg" width="100" align=left> taille fixe, image jpeg, le texte s'coule autour de l'image gauche .... </BODY> </HTML>

Limage suivante (figure D.7) montre le rsultat obtenu. Il est aussi possible de dfinir des ancres avec des images en lieu et place du texte du lien.

Dlimiteurs dimages cliquables (cartes)


Les images dfinissent une zone qui peut tre dcoupe en plusieurs rgions auxquelles on associe une action. Le systme de coordonnes est identique celui de Java (voir point 11.1, p. 129). Deux possibilits sont offertes : dans la premire, la gestion des rgions est confie au serveur HTTP (on utilise alors loption ISMAP); dans la deuxime, la carte est gre par le butineur lui-mme.

Javabook Page 471 Lundi, 12. juillet 1999 3:58 15

Dlimiteurs

471

Figure D.7 Insertion dimages en HTML (ex7.html) Dlimiteur


<IMG SRC="URL" USEMAP=#... > <MAP NAME=" ... </MAP> ">

Signification Dfinit la source de la zone sensible et associe le nom de la dfinition de la carte. Dfinit la carte en lui associant plusieurs rgions dont les coordonnes sont relatives limage associe. Pour chaque zone sensible, on dfinit sa forme et les coordonnes de la zone : rect="x1,y1,x2,y2" circle="ox,oy,rx,ry" poly=" x1,y1, ..., xn,yn" HREF le lien activer NOHREF permet de dfinir des zones insensibles.

<AREA SHAPE="rect | poly | circle" COORDS= x1,y1, ..., xn,yn HREF="URL" NOHREF>

Tableau D.8 HTML, dlimiteurs dimages cliquables

Exemple dimage cliquable (ex8.html) :


<HTML> <HEAD> <TITLE>images ... </TITLE> </HEAD> <BODY> <H1>image avec zones sensibles</H1> <! une image de 100 x 100>

Javabook Page 472 Lundi, 12. juillet 1999 3:58 15

472

Annexe A Rappel sur HTML

carte d'accs<img src="image8.gif" usemap=#demo> <MAP NAME="demo"> <AREA SHAPE="circle" HREF="ex4.html" COORDS=25,25,35,35 > <AREA SHAPE="rect" HREF="ex5.html" COORDS=0,50,50,100 > <AREA SHAPE="rect" HREF="ex6.html" COORDS=50,0,100,50 > <AREA SHAPE="rect" HREF="ex7.html" COORDS=50,50,100,100 > </MAP> </BODY> </HTML>

La carte ci-dessous permet daccder quatre liens dfinis dans les zones.

Figure D.8 Images cliquables en HTML (ex8.html)

Dlimiteurs de gestion de formulaires


HTML permet de grer des formulaires comportant des champs, des boutons, des cases cocher, des menus, des listes droulantes, etc. Ces formulaires sont obligatoirement associs une application (un CGI) indpendante du serveur HTTP. Dans ce cas, le serveur sert dintermdiaire entre le client et cette application (par exemple, une base de donnes). Le contenu des diffrents champs et ltat des boutons du formulaire sont transmis lapplication.
Dlimiteur
<FORM METHOD="post | get" ACTION="URL de lapplication"> ... </FORM> <INPUT TYPE="submit" VALUE="Executer"> <INPUT TYPE="reset" VALUE="Effacer">

Signification Dfinit un formulaire, sa mthode dchange et lURL de lapplication destinataire (gnralement une extension .cgi). Entre les deux dlimiteurs, on trouve du texte et les objets de formulaire. Lattribut name sera le nom du paramtre envoy lapplication. Bouton dclenchant lexcution du formulaire (envoi des paramtres). Bouton rinitialisant le formulaire (vide les champs).

Tableau D.9 HTML, dlimiteurs de gestion de formulaires

Javabook Page 473 Lundi, 12. juillet 1999 3:58 15

Dlimiteurs
Dlimiteur
<INPUT TYPE="text" SIZE=... NAME="nom_champ" VALUE="val initiale"> <INPUT TYPE="password" SIZE=... NAME="nom_champ" VALUE="val initiale"> <INPUT TYPE="radio" NAME="nom_bouton" VALUE="valeur_retourne" CHECKED> <INPUT TYPE="checkbox" NAME="nom_du_groupe" VALUE="valeur_retourne" CHECKED> <SELECT NAME="nom_liste" SIZE=... MULTIPLE> ... </SELECT> <OPTION> text <TEXTAREA NAME="nom_zone" ROWS=n COLS=n >t exte initial </TEXTAREA>

473
Signification Champ permettant lentre de texte sur une ligne de taille dfinie.

Champ permettant lentre dun texte non affich sur lcran.

Affichage dun bouton radio (actif si CHECKED).

Affichage dune case cocher dans un groupe. La concatnation des valeurs des cases est retourne.

Permet dafficher des menus droulants si SIZE est absent, ou bien des listes ascenseurs de la taille SIZE. MULTIPLE indiquant dans ce cas si lon autorise des choix multiples. Entre les deux dlimiteurs, on donne les options afficher. lment de la liste. Ce dlimiteur permet de dfinir une zone de texte multilignes

Tableau D.9 HTML, dlimiteurs de gestion de formulaires

Exemple de formulaire en HTML (ex9.html) :


<HTML> <HEAD> <TITLE>Formulaire ... </TITLE> </HEAD> <body background="bg7.gif"> <H1>Formulaires ...</H1> <hr> <FORM METHOD="get" ACTION="application.cgi"> Remplissez ce formulaire pour recevoir de la documentation <INPUT TYPE="submit" VALUE="Executer"> <INPUT TYPE="reset" VALUE="Effacer"><p> nom......<INPUT TYPE="text" SIZE=20 NAME="nom" VALUE="entrez ici"><br> e-mail...<INPUT TYPE="text" SIZE=15 NAME="mail" VALUE=""><br> mot passe<INPUT TYPE="password" SIZE=8 NAME="pwd" VALUE="cach"> si dj abonn<p>

Javabook Page 474 Lundi, 12. juillet 1999 3:58 15

474

Annexe A Rappel sur HTML

Je m'intresse <INPUT TYPE="radio" NAME="int1" VALUE="java" CHECKED>Java <INPUT TYPE="radio" NAME="int2" VALUE="java-script" >Java script <INPUT TYPE="radio" NAME="int3" VALUE="html" >HTML<p> Je dsire l'information par: <INPUT TYPE="checkbox" NAME="media" VALUE="disk"> disquette <INPUT TYPE="checkbox" NAME="media" VALUE="email" CHECKED>e-mail <INPUT TYPE="checkbox" NAME="media" VALUE="cd"> CD-ROM<p> niveau d'information <SELECT NAME="niveau"> <OPTION> dbutant <OPTION> moyen <OPTION> avanc </SELECT> systme utilis <SELECT NAME="syst" SIZE=4 MULTIPLE> <OPTION> Mac-PowerPC <OPTION> SUN solaris 2.5 <OPTION> PC Linux <OPTION> PC Window 3.xx <OPTION> PC Window 95 <OPTION> PC Window NT <OPTION> dbutant </SELECT><p> Commentaires <TEXTAREA NAME="com" ROWS=3 COLS=40 >placer vos commentaires ici</TEXTAREA> <hr> </FORM> </BODY>

Nous obtenons le formulaire de la figure D.9. On notera lutilisation dune image de fond dcran. Lors de lactivation du bouton Executer, la chane suivante va tre envoye au serveur HTTP qui activera lapplication (cette dernire dcodera la liste des paramtres pour la traiter).
http://xx.xx.xx.xx/HD500/Desktop%20Folder/JAVA/javadoc/ Exemples%20HTML/ application.cgi?nom=Guyot+Jacques&mail=guyot@acm.org&pwd=cach%8E&i nt1=java&media=email&media=cd&%D3niveau%D3=moyen&%D3syst%D3=SUN+so laris+2.5&%D3com%22=placer+vos+commentaires+ici

Dlimiteurs de gestion de tableaux


HTML (version 3.2) permet de gnrer des tableaux qui peuvent contenir des textes, des listes, des images, des formulaires et des liens. Les tableaux se dfinissent range par range. Le tableau D.10 prsente les dlimiteurs de gestion de tableaux.

Javabook Page 475 Lundi, 12. juillet 1999 3:58 15

Dlimiteurs

475

Figure D.9 Un formulaire en HTML (ex9.html) Dlimiteur


<TABLE BORDER=n CELLPADDING= CELLSPACING= WIDTH=n%> ... </TABLE> <CAPTION ALIGN=top | bottom> ... titre du tableau </CAPTION> <TR VALIGN= top | middle | bottom ALIGN= left | center | right > ... les cellules </TR>

Signification Dfinit une table dont la taille (WIDTH) est spcifie en %. BORDER spcifie la largeur du bord. CELLPADDING spcifie lespacement entre le contenu de la cellule et son bord. CELLSPACING dfinit lespacement entre deux cellules. Les cellules sont dfinies entre les deux dlimiteurs. Associe un titre au tableau qui se place au-dessus ou en dessous de celui-ci.

Dfinit une ligne et les attributs par dfaut pour cette ligne tels que lalignement vertical ou horizontal.

Tableau D.10 HTML, dlimiteurs de gestion de tableaux

Javabook Page 476 Lundi, 12. juillet 1999 3:58 15

476
Dlimiteur
<TH VALIGN= top | middle | bottom ALIGN= left | center | bottom COLSPAN=n ROWSPAN=n NOWRAP> ... texte de lentte <TD VALIGN= top | middle | bottom ALIGN= left | center | bottom COLSPAN=n ROWSPAN=n NOWRAP> ... texte dune cellule

Annexe A Rappel sur HTML


Signification Dlimiteur permettant de dfinir le texte de lentte du tableau (avec un style prdfini). Lalignement vertical ou horizontal peut tre redfini. COLSPAN et ROWSPAN permettent dtendre une cellule sur plusieurs cases. NOWRAP indique que le texte doit tre affich sur une seule ligne. Dlimiteur permettant de dfinir le contenu dune cellule. Lalignement vertical ou horizontal peut tre redfini. COLSPAN et ROWSPAN permettent dtendre une cellule sur plusieurs cases. NOWRAP indique que le texte doit tre affich sur une seule ligne.

Tableau D.10 HTML, dlimiteurs de gestion de tableaux

Exemple de tableaux (ex10.html) :


<HTML> <HEAD><TITLE>Les tableaux ... </TITLE></HEAD> <BODY background="bg7.gif"> <H1>Tableaux ...</H1> <TABLE BORDER=5 CELLPADDING=2 CELLSPACING=3 WIDTH=100%> <CAPTION ALIGN=top> tableau des carrs </CAPTION> <TR> <TH> i <TH> i*i </TR> <TR> <TD> 1 <TD> 1</TR> <TR> <TD> 2 <TD> 4</TR> <TR> <TD> 3 <TD> 9</TR> </TABLE> <TABLE BORDER=5 CELLPADDING=2 CELLSPACING=3 WIDTH=100%> <CAPTION ALIGN=top> tableau de bric et de broc </CAPTION> <TR VALIGN= middle ALIGN= left > <TH COLSPAN=2 > sur deux case <TH> Nom <TH> e-mail </TR> <TR VALIGN= middle ALIGN= left > <TD> A <TD COLSPAN=2 ROWSPAN=2 > B attention <a href="ex6a.html"> ici </a> se trouve une liste de site important <TD> C </TR> <TR VALIGN= middle ALIGN= left > <TD> 1<TD> 2 </TR>

Javabook Page 477 Lundi, 12. juillet 1999 3:58 15

Dlimiteurs

477

<TR VALIGN= middle ALIGN= left > <TD> a <img src="image7.gif" align=middle><TD> b<TD> c<TD> d </TR> </TABLE> </BODY> </HTML>

La figure D.10 montre la construction de deux tableaux, lun trs simple, lautre un peu plus complexe.

Figure D.10 Tableaux en HTML (ex10.html)

Javabook Page 478 Lundi, 12. juillet 1999 3:58 15

Javabook Page 479 Lundi, 12. juillet 1999 3:58 15

Annexe E

JavaScript
JavaScript1 est un langage dvelopp par les socits Sun Microsystems et Netscape. JavaScript ressemble Java, mais il ne possde ni le typage statique ni la vrification des types. Les expressions et les instructions de contrle sont pratiquement identiques. JavaScript est entirement interprt, il ny a donc pas de phase de compilation comme dans Java. JavaScript est vu comme un complment de HTML; il permet dinclure du code directement dans un document HTML, alors que dans Java, on indique uniquement la source du code excuter. Le tableau E.1 ci-dessous souligne les principales diffrences entre les deux langages.
JavaScript Interprt directement par le client. Bas sur les objets, utilise et tend des objets prexistants, pas de classes ni dhritage. Code incorpor dans le document HTML. Java Compil puis charg depuis le serveur par le client. Langage orient objet, hritage, etc. Code spar mais rfrenc par le document HTML.

Tableau E.1 Principales diffrences entre JavaScript et Java

1.

Un document de rfrence du langage JavaScript peut tre obtenu ladresse : http://developer.netscape.com/docs/manuals/index.html.

Javabook Page 480 Lundi, 12. juillet 1999 3:58 15

480
JavaScript Pas de dclaration des variables. Application limite la taille du document HTML. Performance limite due linterprtation. Dveloppement ne ncessitant quun butineur interprtant JavaScript. Java

Annexe A JavaScript

Dclaration des variables et typage fort. Permet de grer des projets de taille importante. Performance limite par le processeur du poste client (si lon utilise la recompilation du byte-code en code natif). Dveloppement ncessitant le kit de dveloppement avec le compilateur.

Tableau E.1 Principales diffrences entre JavaScript et Java

Les objets manipuls par JavaScript sont ceux qui existent dans la page HTLM (les boutons, les champs, etc.). Le programme JavaScript est li ces objets afin de traiter les vnements qui en sont mis. Nous pensons quun programmeur Java peut sans peine programmer en JavaScript. Il lui faudra sinformer sur les diffrents gestionnaires dvnements construits autour des composants graphiques de HTML et sur les diffrentes librairies, Math par exemple. Nous donnons ci-dessous (voir figure E.1) un petit exemple de document HTML incluant du JavaScript pour confirmer notre propos : on remarquera labsence des points-virgules; en effet, une ligne est gale une instruction; le programme est structur en deux parties : dans la premire on dcrit la fonction calculF() qui vrifie la validit des caractres en entre, dans la seconde on spcifie le gestionnaire de lvnement onChange() attach au champ nombreATraiter.
<HEAD> <TITLE>Exemple en JavaScript</TITLE> <SCRIPT LANGUAGE="JavaScript"> <!---cach pour les butineurs ne connaissant pas JavaScript function calculF(s) { if (s == "") { alert("Entrez un nombre entier dans le champ SVP") return true } for (var i = 0; i < s.length; i++) { var ch = s.substring(i, i + 1) if (ch < "0" || ch > "9") { alert("Un nombre entier sans decimale") return true } }

Javabook Page 481 Lundi, 12. juillet 1999 3:58 15

Dlimiteurs
var val = parseInt(s, 10) racine=Math.sqrt(val) alert("racine carre de("+val+")="+racine) return false } // fin du code --> </SCRIPT> </HEAD> <BODY> <h1> Calcul de la racine carre</h1> <FORM NAME="ExempleJavaScript"> Entrez un nombre entier puis <RETOUR>: <INPUT NAME="nombreATraiter" onChange="if (calculF(this.value)) {this.focus();this.select();}"> </FORM> </BODY>

481

Figure E.1 Excution dun programme JavaScript

Javabook Page 482 Lundi, 12. juillet 1999 3:58 15

Javabook Page 483 Lundi, 12. juillet 1999 3:58 15

Glossaire
Adresse lectronique
Nom dutilisateur et de machine permettant une personne de recevoir du courrier lectronique (ex : dupont@moulinsart.be).

Adresse IP
Adresse affecte toute machine connecte lInternet, compose du numro du rseau et de machine (ex : 193.124.56.99). Les plages dadresses sont attribues par une organisation (InterNic Register).

API
(Application Programming Interface) Spcification de linterface de programmation dun systme, ensemble de classes et de mthodes dcrivant ses fonctionnalits.

Applet
Une applet est un petit programme crit en Java devant tre invoqu depuis une page HTML.

Archie
Outil permettant la recherche de fichiers sur un ensemble de sites FTP.

Archive
Ensemble de fichiers regroups et compresss pour la transmission (PC : fichiers .zip; Mac, Unix : fichiers .tar et .gz).

Butineur
Logiciel de navigation sur le Web, permet dinterprter les documents rdigs selon la syntaxe HTML et le code des programmes Java.

Javabook Page 484 Lundi, 12. juillet 1999 3:58 15

484

Glossaire

Byte-code
voir Pseudocode.

Champ
(Field) Variables et mthodes dune classe.

Classe
Unit de base dun programme Java. Linstanciation dune classe cre un objet ayant le comportement dfini dans la classe.

Client
Systme (gnralement un poste de travail) qui utilise les services dun autre systme (un serveur).

Code natif
Code que le processeur de la machine physique peut directement excuter, par opposition au pseudocode qui doit tre interprt par une machine virtuelle.

Compilateur
Logiciel permettant la compilation.

Compilation
Action transformant le code source dun programme Java en pseudocode pour la machine virtuelle Java.

Constructeur
Mthode permettant de crer une instance dune classe.

CORBA
(Common Object Request Broker Architecture) Norme qui dfinit linteroprabilit et la connection entre des objets rpartis.

E-mail
Courrier lectronique (adresse lectronique, logiciel client-serveur pour accder aux messages, SMPT).

Exception
Survenance dun vnement qui signale gnralement une anomalie lexcution. Par extension, code qui traite lanomalie.

FAQ
(Frequently Asked Questions) Document regroupant des questions de base sur un domaine particulier.

Javabook Page 485 Lundi, 12. juillet 1999 3:58 15

485

FTP
(File Transfer Protocol) Protocole de transmission de fichiers entre deux systmes connects Internet.

Garbage collection
voir Ramasse-miettes.

GUI
(Graphical User Interface) Ensemble de rgles et dobjets qui dfinissent la construction des interfaces utilisateur.

Hritage
Concept de la programmation objet qui permet de construire une nouvelle classe en tendant le comportement dune autre, sans en redfinir toutes les mthodes. La nouvelle (sous-) classe hrite le comportement de sa (super-) classe.

HotJava HTML

Le butineur de Sun Microsystems, premier butineur capable dexcuter du code Java. (Hyper Text Markup Language) Langage permettant de dcrire des hyperdocuments (dont le contenu est multimdia et inclut des liens hypertexte). Objet ayant le comportement de la classe dont il est linstance.

Instance dune classe Interface


Concept du langage Java qui permet de regrouper un ensemble de mthodes dfinissant un comportement qui sera implant par une ou plusieurs classes, quelle que soit leur position dans la hirarchie des classes.

Internet
Historiquement dfini comme le protocole de communication TCP/IP, mais devient de plus en plus synonyme de lensemble des services et des machines connects laide de ce protocole.

Interprtation
Action qui, pour chaque pseudocode, excute les oprations ncessaires (simule la machine virtuelle dfinie par le pseudocode).

Intranet
Utilisation des techniques lies lInternet pour une communaut restreinte (gnralement une entreprise).

Javabook Page 486 Lundi, 12. juillet 1999 3:58 15

486

Glossaire

Java
Langage de programmation orient objet qui permet dinvoquer des programmes depuis des documents HTML et dcrire des applications portables.

JavaScript
Langage de programmation orient objet permettant dinsrer des programmes dans des documents HTML (ici le code est inclus dans le document HTML, la diffrence de Java o seule linvocation est dans le document).

JDBC
(Java DataBase Connectivity) Ensemble dinterfaces Java permettant dinteragir avec des systmes de gestion de bases de donnes relationnelles.

JDK
(Java Development Kit) Kit de dveloppement Java, comprenant un compilateur, un interprteur, la Core API, un appletviewer, etc.

Machine virtuelle
La machine virtuelle de Java est linterprteur du pseudocode. Elle en assure la portabilit et la scurit.

Mthode
Unit de comportement dun objet (dfini dans sa classe).

Multiprocessus
Programme dont la description fait appel des activits concurrentes reprsentant chacune un processus.

Multithread
Voir Multiprocessus.

Navigateur
Voir Butineur.

NCSA
(National Center for Supercomputer Applications) Lorganisation qui a dvelopp le premier butineur grand public (Mosaic pour Macintosh et PC).

Objet
Possde diffrentes dfinitions selon le contexte : 1) instance de classe; 2) par extension, la classe elle-mme; 3) par extension,

Javabook Page 487 Lundi, 12. juillet 1999 3:58 15

487

utilis comme adjectif : programmation objet, dveloppement objet, base de donnes objet, etc.

ODMG
(Object Database Management Group) Consortium de vendeurs de systmes de gestion de bases de donnes orientes objet qui proposent des standards en matire de langage dinterrogation et de format des objets.

Package
En Java, regroupement de classes dun mme domaine fonctionnel.

Pointeur
Donne dont la valeur est une adresse (gnralement un entier pointant sur un emplacement mmoire).

Processus
Il faut distinguer entre : processus lourd, activit au sein dun systme dexploitation et processus lger, sous-activit dun processus lourd. Nous faisons toujours rfrence des processus lgers lorsque nous parlons de processus.

Pseudocode
Mthode pour reprsenter le jeu dinstructions dune machine virtuelle ; assure lindpendance vis--vis de la machine physique. Le compilateur Java gnre du pseudocode.

Ramasse-miettes
Programme permettant de rcuprer la mmoire occupe par des instances dobjets qui ne sont plus rfrences et de compacter la mmoire.

RMI
(Remote Method inovation) Modle de distribution dobjets de Java facilitant leur implantation sur des machines diffrentes.

Serveur
Systme qui fournit des services dautres systmes (voir Client).

SGBD
(Systme de Gestion de Bases de Donnes) Logiciel capable de grer une masse dinformations, den faciliter laccs et den garantir la cohrence et la persistance.

Javabook Page 488 Lundi, 12. juillet 1999 3:58 15

SGML
Langage de dfinition pour des langages comme HTML et VRML.

SMTP
(Simple Mail Transfert Protocol) Protocole dfinissant les services de base du courrier lectronique.

Sous-classe
Classe drive partir dune autre classe (super-classe).

Super-classe
Classe tendue par une autre classe (sous-classe).

Surcharge
Concept permettant dassocier plusieurs dfinitions au mme identificateur. En Java, seules les mthodes peuvent tre surcharges (mais pas les oprateurs).

Systme dexploitation (SE)


Programme de base grant les ressources de la machine physique (mmoire, disque, temps CPU). Il est vu comme un ensemble de services pour les applications. MS-DOS, Windows 3.11/95/NT, MacOS, Solaris, Linux, AIX sont autant de systmes dexploitation diffrents. La machine virtuelle de Java rend les applications indpendantes des diffrents SE.

TCP/IP
(Transmission Control Protocol/Internet Protocol) Protocole de transmission entre rseaux. Dfinition dInternet.

Tlcharger
(Download) Transfrer un fichier dun systme un autre (gnralement dun serveur vers un poste utilisateur).

Telnet
Protocole de connexion entre une machine client (en mode mulation de terminal) et une machine serveur.

Thread
Voir Processus.

Unicode
Jeu de caractres dfini sur 16 bits (norme ISO 10646).

Javabook Page 489 Lundi, 12. juillet 1999 3:58 15

489

URL
(Uniform Resource Locator) Chaque document du Web a une identit unique sur lInternet (forme gnrale : protocole:/hte/rpertoire/document.html?param). LURL permet didentifier dautres services Internet, comme FTP par exemple.

Vecteur
(Array) Ensemble dobjets dsigns par un indice entier.

Web
Voir WWW.

WWW
(World-Wide Web) Aussi appel W3 ou Web. La partie hypertextuelle dInternet (Butineur, HTML, HTTP, URL).

Javabook Page 490 Lundi, 12. juillet 1999 3:58 15

Javabook Page 491 Lundi, 12. juillet 1999 3:58 15

Rfrences
[1] [2] [3] [4] [5] [6] [7] [8] [9] Bergstra J. A, Heering J., Klint P. (eds.). Algebraic Specification, Addison Wesley, 1989. Booch. G. Software Components with Ada : Structures, Tools, and Subsystems, Benjamin/Cummings, 1987. CERN : Laboratoire europen pour la physique des particules, Genve. URL : http://www.cern.ch JDBC : A Java API, JavaSoft. URL : http://www.javasoft.com. Jones C. Systematic software development using VDM, Prentice Hall, 1986. Meyer B. Conception et programmation par objets : pour du logiciel de qualit, Interditions, 1991. Meyer B. The many faces of inheritance : A taxonomy of taxonomy, IEEE Computer, Vol. 29, No. 5, mai 1996. Network Wizards (statistiques propos dInternet). URL : http://www.nw.com. ODMG : Object Database Management Group. URL : http://www.odmg.org.

[10] Spivey J. M.. The Z notation : A reference manual : based on the work of J. R. Abrial, Prentice Hall, 1992. [11] Stroustrup B. The Design and Evolution of C++, Addison Wesley, 1994.

Javabook Page 492 Lundi, 12. juillet 1999 3:58 15

492

Rfrences

[12] Thomas P., Robinson H., Emms J. Abstract Data Types : Their Specification Representation and Use, Oxford Applied Mathematics and Computing Science Series, 1988. [13] The Unicode Consortium. URL : http://www.unicode.org [14] The W3 consortium. URL : http://www.w3.org Le lecteur intress par les aspects sociaux lis lintroduction de technologies telles que Java trouvera matire rflexion dans les livres ou documents lectroniques suivants : Terminal : technologies de linformation, culture et socit. Revue trimestrielle publie et diffuse par les ditions lHarmattan. http://terminal.ens-cachan.fr/Terminal/serveurText/index.html Le Monde diplomatique : publie rgulirement des articles sur la mondialisation, les enjeux conomiques, politiques et sociaux de lutilisation des nouvelles techniques. http://www.monde-diplomatique.fr/index.html Paul Virilio : dans Lart du moteur et Cybermonde, la politique du pire, il met en garde la socit contre les logiques sous-jacentes lacclration des techniques et lisolation des individus dans des socits trs ou trop informatises. Pierre Lvy : travers plusieurs livres dont Lintelligence collective, pour une anthropologie du cyberspace, il mne une rflexion sur lhomme, ses outils de cognition et la transformation des socits par la technologie. Philippe Queau : il dcrit dans Le Virtuel les risques et les bnfices des techniques bases sur la simulation. Jean Baudrillard : reconnu comme le thoricien du postmodernisme. Sherry Turkle : dans Life on the screen, elle tablit un rapport entre le postmodernisme, lindividu et les techniques lies Internet.

Javabook Page 493 Lundi, 12. juillet 1999 3:58 15

Liste des applets


1. Une applet minimum 3-121 2. Emplacements occups par une applet dans une page HTML 3-123 3. Cadre vide autour dune applet 3-124 4. Alignement dapplets dans une page HTML 3-125 5. Utilisation des paramtres dune applet 3-126 6. Dessiner une ligne 3-130 7. Dessiner une fonction (cosinus) 3-131 8. Dessiner des rectangles 3-131 9. Dessiner des rectangles aux coins arrondis 3-132 10. Dessiner des rectangles en relief 3-132 11. Dessiner des polygones 3-133 12. Dessiner des cercles et des ovales 3-133 13. Dessiner des arcs 3-133 14. Dessiner du texte en couleur 3-135 15. Dessiner des textes dans plusieurs fontes 3-137 16. Dessiner du texte centr 3-139 17. Reprsenter la 3e dimension laide de couleurs 3-141 18. Projeter une figure en 3D sur une surface 2D 3-142 19. Dessiner des rectangles alatoires 3-144 20. Dessiner un rectangle laide dovales 3-145 21. Certificat de la 1re applet 3-146 22. Animation : une horloge digitale 3-148 23. Animation, une horloge analogique (15h 56mn 7s) 3-154 24. Animation, un rectangle sur une diagonale 3-158 25. Animation, trois rectangles grs chacun par deux threads 3-160 26. Un pome gnr partir de la structure de R. Queneau 3-161 27. Afficher les coordonnes de la souris 3-166 28. Capter ltat du bouton de la souris 3-167

Javabook Page 494 Lundi, 12. juillet 1999 3:58 15

494

Liste des applets

29. Capter la position de la souris 3-168 30. Une applet de brouillon pour dessiner 3-170 31. Gestion du clavier 3-172 32. Affichage, les libells 3-181 33. Affichage, les boutons 3-182 34. Affichage, les botes cocher 3-185 35. Affichage, les botes cocher en mode exclusif 3-187 36. Affichage, les menus droulants (phase de slection) 3-188 37. Affichage, les listes de choix 3-190 38. Affichage, les champs de texte sur une ligne 3-193 39. Affichage, les champs de texte sur plusieurs lignes 3-194 40. Deux barres de dfilement dterminent les angles de vue 3-197 41. Dessiner et afficher les coordonnes dans un champ de texte 3-201 42. Gestion dun champ de texte dans une fentre spare 3-202 43. Applet lance deux fois par une application Java 3-204 44. Cration et utilisation de menus 3-206 45. Une alerte gre dans une fentre spare 3-208 46. Mise en pages glissante 3-211 47. Mise en pages glissante sadaptant la taille du conteneur 3-211 48. Mise en pages par spcification des bords 3-213 49. Mise en pages imbrique 3-214 50. Mise en pages laide dune grille 3-215 51. Contrainte de mise en pages dfinie laide dune mthode 3-218 52. Chargement de trois images 3-223 53. Travelling sur une image 3-225 54. Affichage laide dun double tampon 3-229 55. Le jeu du serpent 4-310 56. Une applet utilisant RMI 395 57. Gestion de compte en banque avec CORBA 407

Javabook Page 495 Lundi, 12. juillet 1999 3:58 15

Liste des applications


1. Composants Swing et look-and-feel modifiable 3-240 2. AfficheRpertoire 3-252 3. AfficheUnFichier 3-254 4. Copie de fichiers 3-256 5. Corriger la ponctuation dun fichier texte. 3-257 6. Utilisation des fichiers dentiers accs direct 3-259 7. Compteur de mots et de nombres dun fichier 3-260 8. Rendre un arbre persistant 3-262 9. Lecture dun objet arbre persistant 3-263 10. Identification du contenu dun URL 3-270 11. Affichage du contenu dun URL 3-272 12. Vrificateur dURL 3-273 13. Client 3-277 14. Client de la tldiscussion 3-284 15. La classe ExampleWithJDBCOracle 387

Javabook Page 496 Lundi, 12. juillet 1999 3:58 15

Javabook Page 497 Lundi, 12. juillet 1999 3:58 15

Liste des tableaux


1. Typologie de la rpartition des activits 1-26 2. Styles de commentaires 2-42 3. Liste des mots rservs en Java 2-43 4. Choix des identificateurs 2-44 5. Caractres de contrle 2-46 6. Exemples de Strings 2-47 7. Les types dentiers 2-49 8. Les types de flottants 2-50 9. Prcdence des oprateurs 2-52 10. Oprateurs numriques unaires 2-54 11. Oprateurs numriques binaires 2-54 12. Oprateurs relationnels 2-56 13. Table de vrit des oprateurs logiques 2-57 14. Les oprateurs logiques 2-58 15. Oprateurs de concatnation 2-59 16. Oprateurs de manipulation binaire 2-60 17. Correspondances entre oprateurs binaires et arithmtiques 2-60 18. Conversions entre types 2-63 19. Les packages de lAPI Java 2 3-111 20. Variables dinstances de la classe Rectangle 3-114 21. Constructeurs de la classe Rectangle 3-114 22. Mthodes de la classe Rectangle 3-115 23. Couleurs prdfinies dans la classe Color 3-134 24. Mthodes de la classe Font 3-137 25. Mthodes de la classe FontMetrics 3-138 26. Constantes associes aux principales touches 3-170 27. Modificateurs pour une souris trois boutons 3-172 28. Actions et vnements gnrs 3-177

Javabook Page 498 Lundi, 12. juillet 1999 3:58 15

498

Liste des tableaux

29. Mthodes de la classe Label 3-181 30. Mthodes de la classe Button 3-182 31. Mthode de la classe ActionEvent 3-183 32. Mthodes de la classe Checkbox 3-185 33. Mthodes de la classe Checkbox utilisant la notion de groupe 3-187 34. Mthodes de la classe CheckboxGroup 3-187 35. Mthodes de la classe Choice 3-188 36. Mthodes de la classe List 3-190 37. Mthodes de la classe TextComponent 3-191 38. Mthodes de la classe TextField 3-193 39. Mthodes de la classe TextArea 3-194 40. Mthodes de linterface LayoutManager 3-210 41. Constructeurs de la classe FlowLayout 3-212 42. Constructeurs de la classe BorderLayout 3-212 43. Constructeurs de la classe GridLayout 3-216 44. Constructeurs de la classe CardLayout 3-216 45. Variables dinstance de la classe GridBagConstraints 3-217 46. Mthodes de chargement dune image (classe Applet) 3-222 47. Mthodes de la classe Applet pour jouer un son 3-229 48. Mthodes de linterface AudioClip 3-230 49. Diffrences principales en AWT et Swing 3-233 50. Nouveaux composants introduits dans Swing 3-235 51. Interfaces et implantations des collections 4-328 52. Mthodes de linterface Set 4-329 53. Oprations de linterface List 4-331 54. Oprations du type Map 4-333 55. Table des droits de communication 4-371 56. Interfaces de lAPI JDBC 374 57. Fonctions des interfaces pour les requtes SQL 376 58. Fonctions des API 411 59. Les types numriques en Java 421 60. Test de linitialisation de variables en Java et en C++ 422 61. Dclaration de tableaux 423 62. Initialisation de tableaux dobjets 424 63. Porte des variables dclares dans le for 425 64. Instructions for en Java et en C++ 425 65. Instruction continue en Java et en C++ 426 66. Traces dexcution : gestion des rfrences 431 67. Spcification de la visibilit dans Java et C++ 434 68. Accs aux variables et mthodes de classe 436 69. Spcification dattributs constants 436 70. Clonage en Java 437

Javabook Page 499 Lundi, 12. juillet 1999 3:58 15

499

71. Appel aux constructeurs des composantes 438 72. Modes dhritage en Java et en C++ 439 73. Spcification de lhritage en Java et en C++ 439 74. Mthode virtuelle avec corps 440 75. Spcification de classe abstraite (virtuelle) 440 76. Dclaration des exceptions leves par une mthode 441 77. Propagation dune exception en cours de traitement 442 78. HTML, dlimiteurs de structuration 460 79. HTML, dlimiteurs de listes 462 80. HTML, dlimiteurs dattributs logiques textuels 464 81. HTML, dlimiteurs dattributs typographiques 465 82. HTML, dlimiteurs de zones dcran 466 83. HTML, dlimiteurs dancres et de liens 468 84. HTML, dlimiteurs de manipulation dimages 469 85. HTML, dlimiteurs dimages cliquables 471 86. HTML, dlimiteurs de gestion de formulaires 472 87. HTML, dlimiteurs de gestion de tableaux 475 88. Principales diffrences entre JavaScript et Java 479

Javabook Page 500 Lundi, 12. juillet 1999 3:58 15

Javabook Page 501 Lundi, 12. juillet 1999 3:58 15

Index
! 58 - 53 != 56 $ 43 & 58 && 57 (3 */ 41 ++ 53 .class 97 .java 97 /* 41 /** 42 // 42 < 56 <- 56 = 53 == 56, 325 > 56 >- 56 [ ] 102 ^ 58 _ 43 {} 66 | 58 || 57 ~ 53 2D 141 3D 139

abstract (modificateur dinterface) 01 abstract (modificateur de classe) 101 accept() 246, 267 accs exclusif 107, 355 accessibilit, rgles 343 actif 353 ActionEvent (vnement) 181 ActionListener (vnement) 181 add() 143, 179, 199 AddItem() 190, 191 addLayoutComponent() 210 addMouseMotionListener() 173 addSeparator() 205 AdjustmentEvent (vnement) 195 AdjustmentListener (vnement) 195 adresse Internet 266 IP 5, 11 affectation 87 Affichage 271 algorithmes en Java 73 alignement du texte 180 allocation 60 allowMultipleSelection() 190 AltaVista 36 analyse lexicale 259 syntaxique 259 ancre, dhypertexte 7

Javabook Page 502 Lundi, 12. juillet 1999 3:58 15

502

Index

animation 227 API 373 Java 111 JDBC 374 appendText() 194 applet 11, 31, 33, 119, 203, 381 cration 120 cycle de vie 126 dans une application 202 gestionnaire de contenu 360 intgration 359 invocation 119 paramtrable 361 Applet (classe) 221 application 33, 119, 203, 381 client-serveur 265 arc, dessiner 133 architecture 301 portable 24 argument 80 ArrayIndexOutOfBounds (classe) 106 assignation 53, 86 attente 355 AudioClip (classe) 229 available() 247 avoir, hritage 319

BorderLayout (classe) 212 BorderLayout() 212 boucle 69, 73 bouton 181 de navigation 216 break 68, 71, 72 BufferedInputStream (classe) 242 BufferedReader (classe) 242 BufferedWriter (classe) 242 butineur 8, 11, 33, 119 Button (classe) 181 Button() 182 byte-code 22, 363

balise 9, 359, 459 barre de dfilement 195 de menus 205 base de donnes 29, 373 bean 347 proprit 349 bloc dinstructions 66, 78 imbriqu 51 bote cocher 184 exclusive 186 Boolean (classe) 95 boolen 44, 49

C 16 pointeur 380 type 380 void * 380 C++ 16, 415 #ifndef...#endif 418 #include 418 affectation 430 de rfrence 431 boolean 416 break 428 char 421 class 421 const 436 constante 422 constructeur 437 continue 426 dfinition de classe 432 des attributs 432 des mthodes 433 dsignateur 432 destructeur 425 do 426 enum 421 fonctions membres 415 for 425

Javabook Page 503 Lundi, 12. juillet 1999 3:58 15

503

goto 427 header file 415, 418 hritage 438 int 416 main 417 mthode virtuelle 437 oprateur de rsolution de porte 435 private 434, 435, 439 protected 439 public 434, 439 qualification des attributs 434 rfrence 430 static 435 struct 421 union 421 unsigned 416, 421 variable 422 dinstance 432 de classe 432 virtual 439 while 426 CallableStatement, JDBC 377 Canvas (classe) 197 caractre 46, 50 de contrle 46 CardLayout (classe) 216 CardLayout() 216 cas (instruction switch) 67 cas, traitement 317 case 67 catch 105, 149 cercle, dessiner 132 chane de caractres 47, 59, 135 comparaison 94 champ (membre) 102 champ de texte sur plusieurs lignes 193 sur une ligne 191 Character (classe) 95 chargement du code 22 charWidth() 138

Checkbox (classe) 184 Checkbox() 185, 187 CheckboxGroup (classe) 186 CheckboxGroup() 187 CheckboxMenuItem (classe) 205 chemin, mcanisme dimportation 98 Choice (classe) 187 classe 19, 77, 100, 292 abstraite 89, 91, 101, 316 anonyme 91, 174 comme objet 293 conception 289 enveloppe 95 et concept 301 et modlisation 301 et package 341 finale 89, 101 interne 90 publique 342 spcification 294, 296 clavier, gestion 176 clearParameters() 377 clearRect() 133 client universel 28 client WWW 11 client-serveur 13, 26 ralisation avec java.net 274 tl-discussion avec java.net 278 clipRect() 227 clonage de surface 338 profond 338 clone() 94 Cloneable (interface) 216 code interprt 22 mobile 25, 29 robuste 23 collection (structure de donnes) 331 Color (classe) 134 commentaire 41 commit() 376

Javabook Page 504 Lundi, 12. juillet 1999 3:58 15

504

Index

compatibilit de type 48 compilation 97, 120 Component (classe) 165 comportement 19, 21, 77 composant AWT 233 Swing 233 composant graphique 147, 179 lger 231 concatnation 58 concept, implmenter 301 conception 289, 301 concurrence daccs 354 Connection (interface JDBC) 376 consommateur (processus) 356 constante 48 constructeur 79, 80, 81 Container (classe) 199 conteneurs 199 Swing 232 ContentHandler (classe) 266 ContentHandlerFactory (interface) 269 continuation (instruction) 73 continue (mot-cl) 73 contrainte, mise en pages 216 controlDown() 171 conversion de type 20, 61 copie dobjet 94, 338 copyArea() 133 cosinus 130 couleur du dessin 135 du fond 134 palette 134 countComponent() 199 courrier lectronique 6 createImage() 224 CropImageFilter (classe) 224 curseur, JDBC 379 cycle de dveloppement 32

cycle de vie dun Thread 150 dune applet 147

DatagramPacket (classe) 266 DataInputStream (classe) 243 DataOutputStream (classe) 243 Date (classe) 145 dcalage binaire 59 dclaration dune interface 101 de classe 100 default 68 DELETE (ordre JDBC) 379 dlimiteur APPLET 119, 121 dlimiteur HTML 9, 459 delItem() 190 deselect() 190 destroy() 127 Dialog (classe) 199, 206 Dictionary (classe) 321 Dimension (classe) 129 dispose() 201 distribution des logiciels 14 do 69, 72, 73 do...while 69 document 359 contenu 359 dynamique 27, 360 HTML 119 domaine, importation 98 Double (classe) 95 double prcision 46 draw3DRect() 132 drawArc() 133 drawImage() 222 drawLine() 130 drawOval() 133 drawPolygon() 132 drawRoundRect() 131 drawString() 135

Javabook Page 505 Lundi, 12. juillet 1999 3:58 15

505

driver JDBC 382 DriverManager, JDBC 375

chec, jeu 360 echoCharIsSet() 193 effet de bord 53 galit 94 de surface 337 entre objets 337 profonde 337 else 66 encapsulation 289, 333, 343, 357 encodage des caractres 22 ensemble (structure de donnes) 329 entier 45, 49 entre-sortie 241 affichage sur cran (out) 247 exceptions 246 saisie de caractres (in) 247 environnement de dveloppement 31 de programmation 111 EOFException (classe) 246 equals() 94, 326 proprits 337 Error (classe) 106 est un (lien) 319 et (oprateur) 58 vnement adaptateur 174 clavier 176, 197 couteur 172 et Java Beans 348 gestion 172 modle 172 slection dans un menu 206 source 172 souris 173, 197 type 168, 177 vnement (1.0) clavier 170

gestion 168 modle 165 souris 167, 172 Event (classe) 165, 170 exception 105, 299 hirarchie 301 propagation 300 executeQuery() 378 excution conditionnelle 66 itrative 69 Exite 36 expression valuation 53 numrique 54 extends (mot-cl) 85

factorisation 318 false 44 fentre 199, 201 fichier accs direct 257 afficher le contenu 253 byte-code 32 copie 255 entre dun rpertoire 252 fentre de dialogue 260 filtrage des noms 261 filtre 252 rpertoire 250 sparateur de rpertoire 248 source 32 Fichier (classe) 248 fichier dentre 246 constructeurs 246 FichierEcriture (classe) 249 FichierLecture (classe) 249 fil dexcution 353 File (classe) 244, 248 FileDescriptor (classe) 244 FileDialog (classe) 200, 260

Javabook Page 506 Lundi, 12. juillet 1999 3:58 15

506

Index

FileInputStream (classe) 243 FileNameFilter (interface) 252, 253 FileNotFoundException (classe) 246 FileOutputStream (classe) 243 FileReader (classe) 243 FileWriter (classe) 243 fill3DRect() 132 fillArc() 133 fillOval() 133 fillPolygon() 132 fillRoundRect() 131 FilteredImageSource (classe) 224 final (modificateur de classe) 101 finalize() 82 finally 105 first() 216 float 46 Float (classe) 95 flottant 45, 50 FlowLayout() 212 fonction (structure de donnes) 332 fond 197 Font (classe) 136 fonte, Voir police for 70, 72, 73 Frame (classe) 199, 201 FTP (File Transfer Protocol) 4

garbage collector, Voir ramasse-miettes gnrer des exceptions 106 gnricit 322 gestion de la mmoire 20, 364 getAlignment() 181 getAscent() 138 getAudioClip() 229, 230 getBackground() 134 getCodeBase() 222 getColor() 135 getColumns() 193, 195 getComponent() 199

getContent() 267 getCurrent() 187 getCursorName() 379 getDescent() 138 getDirectory() 261 getEchoChar() 193 getFile() 261 getFontMetrics() 138 getGraphics() 169 getHeight() 138 getHours() 154 getImage() 222 getInputStream() 267, 276 getItem() 190 getLabel() 183, 185, 188 getLayout() 199 getLeading() 138 getMessage() 106 getMinutes() 154 getName() 137 getOutputStream() 267, 276 getParameter() 125, 204 getRows() 195 getSeconds() 154 getSelectedIndex() 191 getSelectedIndexes() 191 getSelectedItem() 191 getSelectedItems() 191 getSelectedText() 191 getSelectionEnd() 191 getSelectionStart() 191 getSize() 137 getSource() 224 getState() 185 getStyle() 137 getText() 181, 191 goto 301 graphe 361 Graphics (classe) 131, 222 GridBagConstraints (classe) 216 GridLayout (classe) 214 GUI (Graphical User Interface) 179

Javabook Page 507 Lundi, 12. juillet 1999 3:58 15

507

hachage 330 handleEvent() 168, 170 HashTable (classe) 321 hritage 85, 313, 316 dimplantation 317 et modlisation 319 multiple 21 hirarchie 92 HTML 9, 359 gnration de documents 12 HTTP 11 hypertexte 7, 29

identificateur 42 IEEE 754 22 if 66 image 221 chargement 221 double tampon 227 filtre 224 gestionnaire 222 scintillement 227 zoom 222 ImageFilter (classe) 224 ImageObserver (classe) 222 ImageProducer (interface) 224 implantation 91 import (mot-cl) 99 importation 98 inactif, processus 353 indexation du Web 12 InetAddress (classe) 266, 267 init() 127 initialisation complexe 84 initialiseur statique 102 InputEvent (classe) 176 InputStream (classe) 247, 268 InputStreamReader (classe) 243 INSERT (ordre JDBC) 379 insertText() 194

instance 19, 77 cration 80 instanciation 292 instruction 65 Integer (classe) 95 interblocage, processus 358 interface 21, 91, 100, 295, 320, 322 corps 101 dun module 290 interface de programmation dapplications 111 interface de programmation dapplications, Voir API Internet 3, 12, 23 interprteur Java 32 InterruptedException (classe) 106 InterruptedIOException (classe) 246 intranet 25 introspection 350 invariant 299 io (package) 241 IOException (classe) 106, 246 isBold() 137 isEditable() 191 isItalic() 137 isPlain() 137 item 187 ItemEvent (vnement) 184, 185, 189 ItemListener (classe) 184 itrateur 362 itrateur (structure de donnes) 334

jar (archive) 347 Java Beans 346 Java, BD et Web 27, 29 java.awt (package) 179 java.lang.reflect (package) 350 java.net (package) classes 265 exceptions 269 interfaces 269

Javabook Page 508 Lundi, 12. juillet 1999 3:58 15

508

Index

JavaScript 27, 119 JComponent (classe) 233 JDBC 373, 455 JDK (kit de dveloppement Java) 33 jeu du serpent 303 join() 150

keyDown() 170 KeyEvent (classe) 176

label 71, 72 Label (classe) 180 langage de programmation 15 last() 216 layout() 199 LayoutManager (interface) 210 length() 132 liaison dynamique 86, 314 libell 180 lien entre objets 333 lien hypertextuel 8 List 190 List (classe) 190 list() 246, 247, 253 littral 44 logiciel modulaire 290 Long (classe) 95 look-and-feel 237 Lycos 36

machine virtuelle 22, 24 MacOS 240 main() 35 MalformedURLException (classe) 269 masque de saisie 192 matrice 61, 161 membre 102

menu 204, 205 droulant 187 MenuBar (classe) 204 MenuContainer (interface) 200, 204 MenuItem (classe) 205 message 19, 77 dalerte 206 mtadonne 388 metaDown() 171 Metal 240 mthode 19, 77, 287 abstraite 89 corps 78 dinstance 78 de classe 84, 293 de travail 112 dclaration 102 invocation 80 surcharge 82 middleware 373 MIME (Multipurpose Internet Mail Extensions) 265 mise en pages 209 cartes 216 contrainte 216 glissante 210 grille 214 imbrique 213 quadrillage 216 spcification des bords 212 modle 301, 327 modle-vue-contrleur 236 modlisation 301 modliser 319 modularit 289 module 16, 289, 292 mot de passe 192 Motif 240 mouseDown() 166 mouseDrag() 167 mouseDragged() 173 mouseEnter() 167

Javabook Page 509 Lundi, 12. juillet 1999 3:58 15

509

MouseEvent (vnement) 175 mouseExit() 167 MouseListener (interface) 175 MouseMotion (vnement) 173 MouseMotionAdapter() 175 MouseMotionListener (interface) 173, 175 MouseMove() 165 mouseMoved() 173 mouseUp() 167 multiprocessus 21, 150 MVC (modle-vue-contrleur) 236

binaire 59 de conversion 61 logique 57 prcdence 52 rgle dvaluation 55 relationnel 56 oprateur de slection 435 ou 58 exclusif 58 outil CASE 373 OutputStream (classe) 247 OutputStreamWriter (classe) 243 ovale, dessiner 132

ngation 58 new 20, 60, 80, 89 next() 216, 378 nextToken() 260 NNTP (Network News Transfer Protocol) 5 nom complet, importation 98 nombre premier 74 nombres amicaux 75 notify() 108, 355 null 278

Object (classe) 241 ObjectInputStream (classe) 245 Objective-C 21 ObjectOutputStream (classe) 245 objet 77, 292 copie 94, 338 cration 20, 80, 103 destruction 82 galit 94 rfrence 94 srialisable 245 ODBC 13, 379 openConnection() 268, 270 openStream() 268 oprateur 52

package 99, 341, 342 critre dappartenance 342 java.awt 179 java.lang.reflect 350 java.net 265 paint() 147 pane (surface daffichage) 232 Panel (classe) 179, 199 paramtre 78, 80, 83 fourni lapplet 121 reu dans lapplet 125 Pascal UCSD 22 priphrique 241 persistance 241 pi 80 PipedInputStream (classe) 243 PipedOutputStream (classe) 243 PipedReader (classe) 243 PipedWriter (classe) 243 PL/SQL 13 play() 230 Point (classe) 129 pointeur 20, 363 police de caractres 136 polygone, dessiner 132 polymorphisme 21, 92, 321 portabilit 14, 23

Javabook Page 510 Lundi, 12. juillet 1999 3:58 15

510

Index

porte 51 post-condition 298 pr-condition 297 prfrence daffichage 197 premire applet 35 premire application 34 PreparedStatement, JDBC 377 previous() 216 PrintStream (classe) 243 PrintWriter (classe) 243 private 102, 343, 344 private protected 102 processus 107, 353 producteur 355 producteur-consommateur 356 Produit (classe) 357 programmation distribue sur Internet 286 oriente objet 15, 289 Properties (classe) 247 protected 102, 343, 345 protocole 11 de connexion 373 IP 3 ProtocolException (classe) 269 pseudo-code 22 public (modificateur dinterface) 101 public (modificateur de classe) 101 public (modificateur de mthode) 102 public, accessibilit 343

Rectangle (classe) 114 redfinition de mthodes 314 et accessibilit 345 rfrence, un objet 94 registerOutParameter() 377 relation 301 cardinalit 302 repaint() 147 rpertoire 98 courant 248 de fichier 200 Repertoire (classe) 250 RepertoireEcriture (classe) 251 replaceText() 194 requte SQL 376 rseau de Petri 358 resize() 125 ResultSet (classe) 378 resume() 353 retour de chariot 192 return 79 rutilisation 313 de mthodes 315 RGBImageFilter (classe) 224 rollback() 376 run() 107, 353 Runnable 107, 150 RuntimeException (classe) 106 rupture 72

Q R

Queneau, Raymond 160 ramasse-miettes 21 random() 142 RandomAccessFile (classe) 257 readLine() 278 receive() 266 rechercher linformation sur le Web 36

schma dobjet 292 Scrollbar (classe) 195 section critique 354 scurit 24, 120, 382 SecurityManager, JDBC 383 SELECT (ordre) 378 select() 191 selectAll() 192 send() 266 squence (structure de donnes) 331

Javabook Page 511 Lundi, 12. juillet 1999 3:58 15

511

SequenceInputStream (classe) 243 srialisation 245 Serializable (interface) 246 serpent, jeu du 303 ServerSocket (classe) 267 serveur de donnes 13 serveur HTTP 11, 32, 266 setAlignment() 181 setAutoCommit() 376 setBackground() 134 setCheckboxGroup() 187 setDirectory() 261 setEchoChar() 193 setFile() 261 setFileNameFilter() 261 setFont() 136 setForeground() 135 setLabel() 183, 185, 188 setMenuBar() 205 setState() 185 setText() 181, 192 SGBD relationnel 374 SGML (Standard Generalized Markup Language) 9 shiftDown() 171 show() 216 si alors sinon 58 signature 79 Simula-67 16 site miroir 4 site Web 11 sleep() 150, 353 Smalltalk 16, 344 SMTP (Simple Mail Transfer Protocol) 5 SNMP (Simple Network Management Protocol) 5 Socket (classe) 267, 276 SocketException (classe) 269 SocketImpl (classe) 267 SocketImplFactory (classe) 269

son 221, 229 charger 229 format .au 229 souris 173 coordonnes 175, 200 vnements 173 vnements (1.0) 172 mouvement 173 mouvement (1.0) 166 sous-classe 85, 313 constructeur 88 spcification 296 SQL 380 sql.drivers 375 standards, utilisation dans Java 22 start() 107, 127, 353 Statement, JDBC 377 static 83, 293 stop() 127, 201 StreamTokenizer (classe) 259 String 161, 243 StringBuffer (classe) 243 StringReader (classe) 243 StringTokenizer (classe) 259, 362 stringWidth() 138 StringWriter (classe) 243 structure de contrle 65 super (pseudovariable) 86 super() 88 super-classe 100, 314 super-interface 101 surcharge 82, 315 surface daffichage 232 suspend() 353 Swing (composants) 231 architecture MVC 236 conversion depuis AWT 233 switch 67 synchronisation 21, 107, 354 synchronized 108, 278, 354 syntaxe 22 System (classe) 247

Javabook Page 512 Lundi, 12. juillet 1999 3:58 15

512

Index

System.out 84 systmes de gestion de bases de donnes 373

tableau 20, 50, 61 cration 103 initialisation 50 TCP/IP 4 Telnet (Terminal Protocol) 5 TextArea (classe) 193, 200 TextArea() 194 TextComponent (classe) 191, 194 TextEvent (vnement) 192 TextField (classe) 192 TextField() 193 then 66 this 79, 80 this() 82, 88 thread 21, 149, 353 Thread (classe) 107, 353 throw 105, 300 toString() 145 traitement dexceptions 105 true 44 try 105, 149 try ... catch 300 typage fort 20 type 48, 101 compos 49 dclaration 100 simple 48, 95 type abstrait 290 et classe 294 spcification 291

UnknownServiceException (classe) 269 UPDATE (ordre JDBC) 379 update() 147, 227 URL 11, 254, 265, 383 affichage dun contenu 271 identification dun contenu 270 tlchargement 267 vrification des liens 272 URLConnection (classe) 268 URLEncoder (classes) 268 URLStreamHandler (classe) 266 URLStreamHandlerFactory (interface) 269

ValiditeURLConnexion (classe) 272 variable denvironnement 247 dinstance 78, 302, 333 de classe 83, 293 dclaration 48 VDM, mthode 327 vecteur 50, 103 initialisation 50 Vector (classe) 95, 321 virus 119, 363 visibilit des variables 83 design 345 et redfinition 345 rgles 98 void 78, 102

UML, diagramme 304 Unicode 22, 43 unit de compilation 97 UnknownHostException (classe) 269

wait() 108 Web 3 while 69, 70, 72, 73 Window (classe) 199 World Wide Web, Voir WWW WWW 3, 7, 23

Javabook Page 513 Lundi, 12. juillet 1999 3:58 15

513

yield() 353

X/Open SQL CLI 374 X11 13

Z, mthode 327

Yahoo 36

Javabook Page 514 Lundi, 12. juillet 1999 3:58 15

514

Index

Javabook Page 515 Lundi, 12. juillet 1999 3:58 15

Le CD-ROM du livre
Le CD-ROM qui accompagne de ce livre contient les lments suivants :

Les sources
Les fichiers sources de toutes les applets et applications du livre (sauf lapplet n 26, base sur louvrage Cent mille milliards de pomes de Raymond Queneau, pour des raisons de droits dauteur).

Les diagrammes syntaxiques


Une applet de dessin des diagrammes syntaxiques pour explorer graphiquement la syntaxe de Java.

La syntaxe commente
Toute la syntaxe de Java, en format BNF et en diagrammes syntaxiques. Chaque lment syntaxique est comment. Les rgles sont connectes entre elles par des liens hypertextes.

Les concepts
Les concepts du langage Java et de son environnement de programmation expliqus et prsents dans des exemples.

Les notes de cours :


Les copies de transparents utiliss lors de plusieurs cours Java (environ 250 pages, en format PDF). Ces documents sont galement disponibles sur le site Web : http://cuiwww.unige.ch/java.

Javabook Page 516 Lundi, 12. juillet 1999 3:58 15

516

Le CD-ROM du livre

Lenvironnement de dveloppement intgr CodeWarrior for Java de Metrowerks (Windows et Macintosh)


Code Warrior est un atelier intgr de dveloppement de logiciel. Il contient les outils de base tels qu'un compilateur, un dbogueur, un diteur de texte, etc. Ces outils sont intgrs, c'est--dire qu'ils interagissent entre eux de manire cohrente. Par exemple, lorsque le compilateur dtecte une erreur de syntaxe, un simple clic souris sur le texte de l'erreur permet d'afficher, dans l'diteur, la portion de code concerne. Il en va de mme entre le dbogueur et l'diteur, etc. noter que le compilateur est nettement plus rapide que le standard fourni avec le JDK de Sun. Le cur de l'environnement de dveloppement est le gestionnaire de projets. Un projet est compos de fichiers sources Java, mais galement des fichiers d'images, de son, de code HTML ncessaires l'application ou l'applet dvelopper. La configuration d'un projet peut s'avrer un peu fastidieuse car il faut tout dfinir : les fichiers utiliser, le type de fichiers produire (.class, .jar, etc.), les paramtres de compilation et de dboguage, etc. Cependant, une fois cette phase effectue, Code Warrior se charge de tout. Lors d'une modification de code source, par exemple, il recompile tout ce qu'il faut, regnre les fichiers de code machine, les archives jar, etc. et relance l'excution de l'application ou de l'applet. Il s'agit donc d'un outil professionnel qui peut faire gagner du temps dans le dveloppement et la mise au point de projets. Le dveloppeur Java dbutant aura donc tout intrt matriser rapidement l'utilisation de ce genre d'outils avant de s'attaquer de plus gros projets.

Un projet port dans CodeWarrior for Java


Lapplet du jeu du serpent (voir p. 303) a t porte dans CodeWarrior for Java, au sein des environnements Windows NT et Macintosh.

Lditeur de texte UltraEdit (Windows)


UltraEdit-32 est un diteur de texte susceptible de remplacer avantageusement Notepad. Il propose de nombreuses fonctionnalits : support de laccs FTP, vrificateur orthographique multilangue, glisser/dposer de texte, numrotage des lignes, tris, macros, etc. Le clavier et la barre doutils sont configurables. Les fichiers peuvent tre dits en mode texte ou hexadcimal/binaire, pour des tailles allant jusqu 2 Go. Pour les programmeurs, le surlignage de syntaxe est pr-configur pour les langages HTML, Java, C/C++, VisualBasic et Perl. UltraEdit-32 est disponible en tlchargement (shareware, versions anglaise, franaise et allemande) http://www.imdcomp.com/

Javabook Page 517 Lundi, 12. juillet 1999 3:58 15

517

downloads/index.html index.html.

ou

http://www.ultraedit.com/downloads/

Le compilateur Java peut tre lanc partir dUltraEdit-32.

Le Java Development Kit de Sun

Javabook Page 518 Lundi, 12. juillet 1999 3:58 15

Javabook Page 519 Lundi, 12. juillet 1999 3:58 15

Vous tes sur le point de dvelopper en Java ?


La puissance de CodeWarrior travers son environnement de dveloppement intgr, amlior pendant des annes autour des langages C, C++ et Pascal, vous fournit dsormais tous les outils dont vous avez besoin pour utiliser les fonctionnalits uniques de Java.

Dbarrassez vous des soucis de plateformes


Aucun soucis de compatibilit, l'IDE de CodeWarrior comprend les Virtual Machines pour Windows 95/NT (Sun VM ou Microsoft VM) et MacOS (Metrowerks VM avec JIT, MRJ Apple). Son format de Portable Project vous permet de passer librement de Macintosh PC, mais aussi sur BeOS avec le CodeWarrior Java Tools et prochainement sous Sun Solaris

Dveloppez plus vite


Conu autour d'outils graphiques uniques, l'IDE de CodeWarrior vous permet d'un seul coup d'il d'apprcier la totalit de vos projets. Agrment d'un des compilateurs les plus efficaces et les plus rapides du march, paul d'une aide en ligne complte, vous ne pouvez allez que plus vite.

Capitalisez vos efforts


Comme aucun langage ne peut proposer de rponses universelles aux problmes de programmation, les outils de CodeWarrior, identiques pour C, C++, Pascal et Java, sur Mac, PC et toutes les autres plateformes supportes, vous vitent les apprentissages longs et fastidieux et vous permettent ainsi de capitaliser vos efforts et de valoriser vos investissements. Vous tes intress par CodeWarrior pour Java, contactez Aware pour plus d'information sur le produit et pour connatre la liste rcente des prix. Aware est le reprsentant et le distributeur exclusif des produits Metrowerks en France
Aware : www.aware.fr Tl. : 01 43 56 57 58 Fax : 01 43 56 66 77

Vous aimerez peut-être aussi