• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Introduction àJava
 

Introduction àJava

on

  • 7,051 views

Cours d'introduction à Java dispensé en 2ème année de l'ISAIP de 2004 à 2006.

Cours d'introduction à Java dispensé en 2ème année de l'ISAIP de 2004 à 2006.
26/12/2008 : Une petite correction sur un schéma p122.

Statistics

Views

Total Views
7,051
Views on SlideShare
7,006
Embed Views
45

Actions

Likes
1
Downloads
475
Comments
1

5 Embeds 45

http://thegeekintheshell.blogspot.com 22
http://www.slideshare.net 15
http://thegeekintheshell.blogspot.fr 5
http://forum.trouvez-services.com 2
http://thegeekintheshell.blogspot.be 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel

11 of 1 previous next

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
  • bonjour
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Introduction àJava Introduction àJava Presentation Transcript

    • Les bases de la programmation en Java Christophe Vaudry mél : thegeekintheshell@gmail.com blog : thegeekintheshell.blogspot.com site Web : cvaudry.developpez.com
    • Historique de ce document – Cecours de Java a été conçu sur la base de transparents que m'avait fourni à l'époque une collègue ■ Il a été utilisé à partir de 1999/2000 jusqu'en 2005/2006 et enrichi au fur et à mesure depuis. ■ Il m'a servi de support de cours à l'Ecole des Mines d'Alès, à l'IUT de Nîmes et à l'ISAIP. ■ Il ne tient pas compte des caractéristiques de Java au-delà de la version 1.5. 2
    • Présentation générale
    • Les origines de Java Algol Simula SmallTalk Pascal C C ++ Objective C Modula Ada Pascal Object Eiffel Ada 95 Java C# Adapté d'après Java – La Maîtrise de J. Bougeault 4
    • Historique de Java (1) – Un projet : ■ ‘ The Green Project ’ en 1991 chez Sun ■ Préparation de la convergence de l’électronique grand public et de l’informatique – Des acteurs : ■ Patrick Naughton ■ Mike Sheridan ■ James Gosling – Des besoins : ■ Initialement prévu d’utiliser le C++ ... ■ … mais problèmes avec le C++, d’où création d’un nouvel environnement de programmation 5
    • Historique de Java (2) 1991 : Oak ■ James Gosling développe un nouveau langage, Oak (chêne) ■ Raison : pallier aux faiblesses constatées de C++ – 1992 : Une première cible ■ La télévision digitale … ■ … création du *7 (StarSeven) et de Duke … ■ … mais un secteur encore trop jeune. 6
    • Historique de Java (3) – 1993 : Deux constats pour un nouveau débouché ■ Essor de l’Internet ■ La technologie développée avec Oak est adaptée à ce type de réseau – 1994 : De Oak à Java ■ Ecriture d'un navigateur Web en Oak, WebRunner qui deviendra bientôt HotJava – 1995 : Premières versions de Java rendues publiques 7
    • Les différentes versions de Java (1) – Trois versions de Java depuis 1995 ■ Java 1.0 en 1995 ■ Java 1.1 en 1996 – 1997 □ Apparition des Java Beans (composants) ■ Java 1.2 en 1999 (« Java 2 », version 1.2) □ Apparition de Swing, J2SE, J2ME et J2EE ■ Java 1.3 (Java 2, version 1.3) en 2001 - 2002 ■ Java 1.4 à partir de 2002, Java 1.4.2 en 2003-2004 ■ ... Java 1.5 ... ■ Java 1.6 actuellement, Java 1.7 dans les cartons... □ L’édition standard est disponible sur le site de Sun, http://java.sun.com/ , le J2SE (Java 2 platform, Standard Edition) 8
    • Les différentes versions de Java (2) – Evolution très rapide et succès du langage ■ Un langage vivant □ Qui ne cesse d’évoluer □ Qui est soutenu par une communauté de développeurs. □ Un succès certain dans le « monde universitaire », dans la recherche et l'enseignement – Une certaine maturité atteinte avec Java 2 – Des problèmes de compatibilité existent (ont existé!) ■ entre les versions 1.1 et 1.2/1.3/1.4/1.5 ■ avec certains « vieux » navigateurs non équipés de JVM correct ■ depuis la version 1.2 il y a une bonne compatibilité « ascendante » mais il peut exister encore quelques problèmes. 9
    • Que penser de Java? (1) – Les plus : ■ Il a su bénéficier de l’essor d’Internet mais aussi s’imposer dans de nombreux domaines ■ Un environnement gratuit (mais pas OpenSource!) ■ De nombreux outils disponibles dus notamment à une large communauté très active qui en fait un langage vivant. ■ Des API (Application Programming Interface) nombreuses et variées en standard, des API spécifiques disponibles gratuitement en option (3D, Multimédia, etc.) ■ Un langage généraliste qui a démontré sa souplesse et son élégance □ Utilisation dans l’industrie et dans le secteur académique □ Très utilisé comme langage d’apprentissage ■ La multitude des plateformes matérielles le supportant (portabilité) 10
    • Que penser de Java? (2) – Les moins : ■ Trop ‘médiatisé’? ■ Problèmes de compatibilité □ Avec les premières versions □ Avec certains navigateurs (les navigateurs ne sont pas écrits par Sun) ■ Problèmes de vitesse □ Existence de solutions pour y pallier (compilateur natif, compilation du bytecode à la volée) □ Grande amélioration de la vitesse avec la plateforme actuelle. ▪ Reste un point faible même si de moins en moins rédhibitoire. ■ Un langage pérenne : une concurrence redoutable (C# et la plateforme .NET) 11
    • Que penser de Java? (3) – Un bon langage ■ Un langage adapté aux besoins de développements actuels … ■ … qui a su se baser sur les acquis du passé. – Audelà de l’effet de mode, un succès mérité qui ne devrait pas se démentir dans le futur ■ Support de Sun ■ Importante communauté de développeurs ■ La portabilité du langage, les plateformes logicielles et matérielles supportées ■ Le nombre et la qualité des projets utilisant Java ■ Le développement des technologies autour de Java ■ Accord Sun-Microsoft : « convergence » de leur palteforme ? 12
    • Caractéristiques du langage Java
    • Caractéristiques du langage Java (1) – Simple ■ Apprentissage facile □ faible nombre de mots-clés □ simplifications aux fonctionnalités essentielles ■ Développeurs opérationnels rapidement □ Proche syntaxe C/C++ ... □ ...sans les dangers du C/C++ ▪ Plus d'arithmétiques sur les pointeurs, pas d'héritage multiple contrairement au C++, pas de surcharge des types primitifs et des opérateurs. 14
    • Caractéristiques du langage Java (2) – Orienté objet ■ Java ne permet d'utiliser que des objets (hors les types de base) ■ Java est un langage objet de la famille des langages de classe comme C++ ou SmallTalk ■ Les grandes idées reprises sont : encapsulation, dualité classe /instance, attribut, méthode / message, visibilité, dualité interface/implémentation, héritage simple, redéfinition de méthodes, polymorphisme – Familier ■ Syntaxe proche de celle de C/C++ 15
    • Caractéristiques du langage Java (3) – Sûr ■ Indispensable sur les réseaux (protection contre les virus, modification des fichiers, lecture de données confidentielles, etc.) Pour plus d’informations sur le thème de la sécurité sur les réseaux voir http://www.cs.princeton.edu/sip/ ▪ Une preuve : il n’existe pour l’instant aucun virus fait en Java (une grande peur lors des débuts de ce langage) alors que c'est assez courant dans des technologies concurrentes □ Notion de « bac à sable », police de sécurité, API destinés au cryptage, à la gestion de l'authentification, des certificats, ... 16
    • Caractéristiques du langage Java (4) – Fiable ■ Gestion automatique de la mémoire (ramasse-miette ou quot;garbage collectorquot;) ■ Gestion des exceptions ■ Sources d'erreurs limitées □ typage fort, □ pas d'héritage multiple, □ pas de manipulations de pointeurs, etc. ■ Vérifications faites par le compilateur facilitant une plus grande rigueur du code 17
    • Java, un langage de programmation – Applications Java ■ programmes autonomes, quot;stand-alonequot; – Applets (mini-programmes ou appliquettes) ■ Programmes exécutables uniquement par l'intermédiaire d'une autre application □ navigateur web : Netscape, Internet explorer, etc. □ application spécifique : Appletviewer (livré avec le kit de développement) ■ Java a longtemps été considéré comme étant uniquement un langage pour écrire des applets □ Cependant c'est avant tout un langage de programmation généraliste 18
    • Java, un langage indépendant? (1) – Java est un langage interprété ■ La compilation d'un programme Java crée du pseudo-code portable □ le quot;byte-codequot; ■ Sur n'importe quelle plate-forme, une machine virtuelle Java peut interpréter le pseudo-code afin qu'il soit exécuté – Les machines virtuelles Java peuvent être : ■ des interpréteurs de byte-code indépendants (pour exécuter les programmes Java) ■ contenues au sein d'un navigateur (pour exécuter des applets Java) 19
    • Java, un langage indépendant? (2) – Avantages : ■ Portabilité □ Des machines virtuelles Java existent pour de nombreuses plates- formes dont : Solaris, Windows, MacOS ■ Développement plus rapide □ courte étape de compilation pour obtenir le byte-code, □ pas d'édition de liens, □ débogagge plus aisé, ■ Le byte-code est plus compact que les exécutables classiques □ pour voyager sur les réseaux. 20
    • Java, un langage indépendant? (3) – Inconvénients : ■ L'interprétation du code ralentit l'exécution □ Il y a quelques années c’était de l'ordre de quelques dizaines de fois plus lent que C++ □ Maintenant cela dépend du type d’application □ Ce qu’il faut surtout voir c’est le rapport gain sur le temps de développement / vitesse du logiciel par rapport aux besoins de l’utilisateur. ■ Les applications ne bénéficient que du dénominateur commun des différentes plate-formes □ limitation, par exemple, des interfaces graphiques : AWT □ Dans le cas des interfaces graphiques, avec Swing ou des équivalents ce n’est plus vrai. 21
    • Langage compilé Etapes qui ont lieu avant l'exécution pour un langage compilé comme C++ Fichier de Librairies code Programme Compilation Code objet Edition de liens exécutable Autres code objet Fichier d'entête 22
    • Langage interprété (1) Cas de Java Avant exécution Exécution Autres byte code Fichier de code Byte code Machine virtuelle Compilation Java (JVM) Java javac MaClasse.class java MaClasse.java 23
    • Langage interprété (2) Librairies des Fichier source Java Class Loader Classes Java Interpréteur Compilateur JIT Compilateur Java Java (Just In Time) Système d'Exécution Fichier « Classe » Java Système d'Exploitation D'après Java – La Maîtrise de J. Bougeault 24
    • Java et Compilation – Il existe déjà au moins un vrai compilateur Java ■ Java devient bien plus rapide ... ■ ... mais perd quelques qualités (portabilité, etc.) – Autre technologie (celle préconisée par Sun): ■ La compilation à la volée : quot;Just In Time (JIT) compilersquot; ■ Le code est compilé au fur et à mesure de sa première exécution et stocké dans un cache pour être ensuite réutilisé tel quel. 25
    • L’API de Java (1) – Javafournit de nombreuses librairies de classes remplissant des fonctionnalités très diverses : c'est l'API Java ■ API (Application Program(ming) Interface /Interface pour la programmation d'applications) : Ensemble de bibliothèques permettant une programmation plus aisée car les fonctions deviennent indépendantes du matériel. ■ Ces classes sont regroupées, par catégories, en paquetages (ou quot;packagesquot;). 26
    • L’API de Java (2) – Les principaux paquetages ■ java.applet : les applets sur le web ■ java.awt : interfaces graphiques, images et dessins ■ java.beans : relatif aux JavaBeans ■ java.io : entrées / sorties ■ java.lang : chaînes de caractères, interaction avec l'OS, threads ■ java.net : sockets, URL ■ java.util : structures de données classiques ■ javax.swing : package récent proposant des composants « légers » pour la création d’interfaces graphiques ■ java.rmi : Remote Method Invocation ■ java.sql : fournit le package JDBC 27
    • L’API de Java (3) – La documentation de Java est standard, que ce soit pour les classes de l'API ou pour les classes utilisateur ■ possibilité de génération automatique avec l’outil Javadoc. – Elle est au format HTML. ■ intérêt de l'hypertexte pour naviguer dans la documentation 28
    • L’API de Java (4) – Pour chaque classe, il y a une page HTML contenant : ■ la hiérarchie d'héritage de la classe, ■ une description de la classe et son but général, ■ la liste des attributs de la classe (locaux et hérités), ■ la liste des constructeurs de la classe (locaux et hérités), ■ la liste des méthodes de la classe (locaux et hérités), ■ puis, chacune de ces trois dernières listes, avec la description détaillée de chaque élément. 29
    • L’API de Java (5) – Où trouver les informations sur les classes de l’API ■ sous le répertoire j2sdkx.x.x/docs/api dans le SDK □ les documentations de l’API se téléchargent et s’installent en général dans le répertoire dans lequel on installe java. ▪ Ces docs sont à placer à votre convenance, mais il est toujours utile de les avoir sous la main ! ■ Sur le site de Sun, on peut la retrouver à http://java.sun.com/docs/index.html 30
    • L’API de Java (6) 31
    • Le multithreading (1) – Un processus ? ■ Un processus est l’entité dynamique qui représente l’exécution d’un programme sur un processeur – Un thread (processus léger) ■ C'est une entité d'exécution qui peut se dérouler en parallèle à d'autres threads, c'est-à-dire concurremment, au sein d'une même application. □ On découpe le programme principal en un ensemble de sous- programmes qui s’exécutent indépendamment les uns des autres. – Javapermet de lancer plusieurs threads en même temps, sans bloquer les autres. 32
    • Le multithreading (2) – Exemple de threads ■ le ramasse-miettes (GC) est un thread quot;systèmequot; ■ la gestion de l'interface graphique qui peut être parallélisée avec l'accès à l'imprimante et l'envoi de données sur le réseau. – La programmation des threads est considérée comme complexe en général… – … mais relativement aisée en Java ; c’est un des avantages de ce langage. ■ Néanmoins, même si Java propose un bon support des Threads, leur programmation restent complexes quoiqu’il arrive et demandent une bonne maîtrise des algorithmes de synchronisation des processus. 33
    • Outil de développement : le SDK de Sun – Environnement de développement fourni par Sun ■ Il se nommait le JDK (Java Development Kit : Kit de développement Java). ■ On parle aussi ou on a parlé du SDK, de J2SDK (System Development Kit : Kit de développement) ou de J2SE (Java 2 Standard Edition) – Il contient : ■ les classes de base de l'API java (plusieurs centaines), ■ la documentation au format HTML ■ le compilateur : javac ■ la JVM (machine virtuelle) : java ■ le visualiseur d'applets : appletviewer ■ le générateur de documentation : javadoc ■ etc. 34
    • Java, un langage novateur? – Java n'est pas un langage novateur : ■ il a puisé ses concepts dans d'autres langages existants (Smalltalk par exemple) et sa syntaxe s’inspire de celle du C/C++. – Cette philosophie permet à Java ■ De ne pas dérouter ses utilisateurs en faisant quot;presque comme ... mais pas tout à faitquot; ■ D'utiliser des idées, concepts et techniques qui ont fait leurs preuves et que les programmeurs savent utiliser – Java a su faire une synthèse efficace de bonnes idées issues de sources d'inspiration variées ■ Smalltalk, C++, Ada, Lisp, etc. ■ Ce n'est pas pour rien que C# s'inspire d'un certain nombre de techniques mises en oeuvre en Java 35
    • Java et les objets – Java est un langage purement « objet » ■ Contrairement à des langages comme C, C++, PERL, PHP, par exemple qui ne sont pas purement objet ■ Et comme Smalltalk , Ruby, etc. ■ Java est ce qu’on nomme un langage de classe, un type particulier de langage dit à objet □ Les langages de classes sont certainement, à l’heure actuelle, le type de « langage objet » le plus répandu. ▪ Héritage de Simula et Smalltalk □ Il existe également des langages dit objet basées sur la notion de prototype (JavaScript, Self), ou des langages dit de Frame (repéresentation des connaissances) et des langages « hybrides ». 36
    • Syntaxe du langage Java : les bases
    • Les commentaires – /* commentaire sur une ou plusieurs lignes */ ■ Identiques à ceux existant dans le langage C – // commentaire de fin de ligne ■ Identiques à ceux existant en C++ – /** commentaire d'explication */ ■ Les commentaires d'explication se placent généralement juste avant une déclaration (d'attribut ou de méthode) ■ Ils sont récupérés par l'utilitaire javadoc et inclus dans la documentation ainsi générée. 38
    • Exemple (1) La classe est l’unité de Fichier Bonjour.java base de nos programmes. Le mot clé en Java pour définir une classe est public class Bonjour class { //Accolade débutant la classe MaClasse public static void main(String args[]) { //Accolade débutant la méthode main /* Pour l’instant juste une instruction */ System.out.println(“bonjour”); } //Accolade fermant la méthode main } //Accolade fermant la classe MaClasse 39
    • Instructions, blocs et blancs – Les instructions Java se terminent par un ; – Les blocs sont délimités par : { pour le début de bloc } pour la fin du bloc Un bloc permet de définir un regroupement d’instructions. La définition d’une classe ou d’une méthode se fait dans un bloc. – Lesespaces, tabulations, sauts de ligne sont autorisés. Cela permet de présenter un code plus lisible. 40
    • Exemple (2) Fichier Bonjour.java Accolades délimitant le début et la fin de la définition de la class Bonjour public class Bonjour { public static void main(String args[]) { Accolades délimitant le début System.out.println(“bonjour”); et la fin de la méthode main } } Les instructions se terminent par des ; 41
    • Exemple (3) Fichier Bonjour.java Une méthode peut recevoir des paramètres. Ici la méthode public class Bonjour main reçoit le paramètre args qui est un tableau de chaîne de caractères. { public static void main(String args[]) { System.out.println(“bonjour”); } } 42
    • Compilation et exécution (1) Le nom du fichier est nécessairement Fichier Bonjour.java celui de la classe avec l’extension .java en plus. Java est sensible à la casse des lettres. Compilation en bytecode java dans une console DOS: javac Bonjour.java Génère un fichier Bonjour.class public class Bonjour Exécution du programme (toujours depuis la console { DOS ou un terminal sous Unix) sur la JVM : public static void main(String[] args) java Bonjour Affichage de « bonjour » dans { la console System.out.println(“bonjour”); } } 43
    • Compilation et exécution (2) 44
    • Compilation et exécution (3) 45
    • Compilation et exécution (4) – On utilise généralement un IDE ■ IDE = Integrated Development Environment, c’est-à-dire un Environnement de Développement Intégré (EDI) ■ Un IDE facilite la tâche du développeur, particulièrement quand il y a beaucoup de classes à créer pour une même application □ On a vu que grosso modo on avait une classe par fichier. □ Pour chaque type d’objet on va quasiment avoir une classe □ Dans un projet un peu gros, il y a plusieurs types d’objets, donc plusieurs fichiers contenant des classes □ L’IDE permet d’assurer la compilation et le lien entre les différents fichiers à la place du développeur 46
    • Compilation et exécution (5) Compilation Exécution 47
    • Compilation et exécution (3) – Les IDE recommandés ■ JCreator (cf copie d’écran précédente) : www.jcreator.com ■ Eclipse : www.eclipse.org ■ BlueJ : http://www.bluej.org/ ■ NetBeans : http://www.netbeans.org/ – Les IDE ne sont pas une obligation … ■ Pour développer en Java, un éditeur de texte tout simple et le kit de développement de la plateforme standard suffisent. – …néanmoins pour des développements sérieux et conséquent ils sont indispensables ■ L’IDE permet de simplifier et d’automatiser certaines tâches ■ Les IDE évolués (Eclipse, NetBeans) permettent l’intégration d’outils complémentaires (Ant, CVS, BeanShell, ArgoUML, etc.) 48
    • Compilation et exécution (4) – Les IDE ne sont pas une obligation … ■ Pour développer en Java, un éditeur de texte tout simple et le kit de développement de la plateforme standard suffisent. – …néanmoins pour des développements sérieux et conséquent ils sont indispensables ■ L’IDE permet de simplifier et d’automatiser certaines tâches ■ Les IDE évolués (Eclipse, NetBeans) permettent l’intégration d’outils complémentaires (Ant, CVS, BeanShell, ArgoUML, etc.) 49
    • Compilation et exécution (5) – Pourrésumer, dans un terminal, si j’ai un fichier Bonjour.java pour la classe Bonjour : ■ javac Bonjour.java □ Compilation en bytecode java □ Indication des erreurs de syntaxe éventuelles □ Génération d’un fichier Bonjour.class si pas d’erreurs ■ java MaClasse □ Java est la machine virtuelle □ Exécution du bytecode □ Nécessité d’avoir une (et une seule) méthode main, qui est le point d’entrée dans le programme 50
    • Le cas d’une applet – Une applet n’est pas un programme indépendant ■ Elle est incorporée dans une page HTML et exécutée dans un navigateur ■ HTML dispose d'un quot;tagquot; <applet> </applet> destiné à intégrer des applets dans une page web. Entre ces tags j’indique le nom d’une classe java compilé en bytecode (un fichier « .class »). ■ Exemple : maPage.html ■ Ma classe MonApplet.java n’a pas besoin de contenir une méthode main…nous reviendrons sur les applets plus tard. <html><head><title>MonApplet</title></head> <body> <applet code=MonApplet.class width=100 height=100> </applet> </body> </html> 51
    • Compilation et exécution : l’applet – Dans un terminal : ■ javac MonApplet.java □ Compilation en bytecode java □ Indication des erreurs de syntaxe éventuelles □ Génération d’un fichier MonApplet.class si pas d’erreurs ■ appletviewer maPage.html (depuis le terminal) par exemple ou ouverture de la page HTML maPage.html depuis Nestcape Navigator ou Internet Explorer. □ Il faut que le chemin indiqué dans la paramètre code de la balise applet et permettant d’accéder au fichier « .class » soit valide ▪ Analogue à l’utilisation de liens ou de fichier de style : le fichier HTML « pointe » sur le fichier « .class » 52
    • Identificateurs (1) – On a besoin de nommer les classes, les variables, les constantes, etc. ; on parle d’identificateur. – Les identificateurs commencent par une lettre, _ ou $ ■ Attention : Java distingue les majuscules des minuscules – Conventions sur les identificateurs : ■ Si plusieurs mots sont accolés, mettre une majuscule à chacun des mots sauf le premier. □ exemple : uneVariableEntiere ■ La première lettre est majuscule pour les classes et les interfaces □ exemples : MaClasse, UneJolieFenetre 53
    • Identificateurs (2) – Conventions sur les identificateurs : ■ La première lettre est minuscule pour les méthodes, les attributs et les variables □ exemples : setLongueur, i, uneFenetre ■ Les constantes sont entièrement en majuscules □ exemple : LONGUEUR_MAX 54
    • Les mots réservés de Java abstract default if private throw assert do implements protected throws boolean double import public transient break else instanceof return true byte extends int short try case false interface static void catch final long strictfp volatile char finally native super while class float new switch throw continue for null synchronized const goto package this 55
    • Les types de base et les opérateurs
    • Les types de bases (1) – En Java, tout est objet sauf les types de base. – Il y a huit types de base : – 1 type booléen □ pour représenter les variables ne pouvant prendre que 2 valeurs (vrai et faux, 0 ou 1, etc.) : □ le type boolean avec les valeurs associées true et false – 1 type pour représenter les caractères □ char – 4 types pour représenter les entiers de divers taille □ byte, short, int et long – 2 types pour représenter les réelles □ float et double 57
    • Les types de bases (2) – Lataille nécessaire au stockage de ces types est indépendante de la machine. ■ Dans des langages comme C/C++, la taille nécessaire au stockage d’un type (le codage de ce type) dépend de la machine. – L’indépendance du codage des types de base entraîne ■ des avantages □ portabilité ■ des inconvénients □ quot;conversionsquot; coûteuses d’un type à l’autre. C’est le système logiciel (JVM) qui gère complètement le codage des types. 58
    • Les entiers (1) – Les entiers (avec signe ) ■ byte : codé sur 8 bits, peuvent représenter des entiers allant de -27 à 27 –1 (-128 à +127) ■ short : codé sur 16 bits, peuvent représenter des entiers allant de -215 à 215 –1 ■ int : codé sur 32 bits, peuvent représenter des entiers allant de -231 à 231 –1 ■ long : codé sur 64 bits, peuvent représenter des entiers allant de -263 à 263 –1 59
    • Les entiers (2) – Notation ■ 2 : entier normal en base décimal ■ 2L :entier au format long en base décimal ■ 010 : entier en valeur octale (base 8) ■ 0xF : entier en valeur hexadécimale (base 16) – Opérations sur les entiers ■ opérateurs arithmétiques +, -, * ■ / :division entière si les 2 arguments sont des entiers ■ % : reste de la division entière □ exemples : ▪ 15 / 4 donne 3 ▪ 15 % 2 donne 1 60
    • Les entiers (3) ExempleCM2.java class ExempleCM2 { public static void main(String args[]) { System.out.println(quot;Starting ExempleCM2...quot;); int i,j,k; long l; i = 2; l = 2L; j = 010; k = 0xF; System.out.println(quot;i = quot; + i + quot; et l = quot; +l); System.out.println(quot;j = quot; + j); System.out.println(quot;k = quot; + k); } } 61
    • Les entiers (4) – Opérations sur les entiers (suite) ■ les opérateurs d’incrémentation et de décrémentation ++ et -- □ ajoute ou retranche 1 à une variable int n = 12; n ++; //Maintenant n vaut 13 □ n++; « équivalent à » n = n+1; / n--; « équivalent à » n = n-1; □ 8++; est une instruction illégale □ peut s’utiliser de manière suffixée : ++n. La différence avec la version préfixée se voit quand on les utilisent dans les expressions. En version suffixée la (dé/inc)rémentation s’effectue en premier int m=7; int n=7; int a=2 * ++m; //a vaut 16, m vaut 8 int b=2 * n++; //b vaut 14, n vaut 8 62
    • Les réels (1) – Les réels ■ float : codé sur 32 bits, peuvent représenter des nombres allant de -1035 à + 1035 ■ double : codé sur 64 bits, peuvent représenter des nombres allant de -10400 à +10400 – Notation ■ 4.55 ou 4.55D réel double précision ■ 4.55f réel simple précision 63
    • les réels (2) – Les opérateurs ■ opérateurs classiques +, -, *, / ■ attention pour la division : ▪ 15 / 4 donne 3 ▪ 15 % 2 donne 1 ▪ 11.0 / 4 donne 2.75 (si l’un des termes de la division est un réel, la division retournera un réel). ■ puissance utilisation de la méthode pow de la classe Math. ▪ double y = Math.pow(x, a) équivalent à x^a, x et a étant de type double 64
    • les réels (3) ExempleOpEntier.java class ExempleOpEntier { public static void main(String args[]) { System.out.println(quot;Starting ExempleOpEntier...quot;); int i,j; float unReel; i = 10 ; j = 2; unReel = 2.0f; System.out.println(quot;i / j = quot; + i/j); System.out.println(quot;i / unReel = quot; + i/unReel); } } 65
    • Les booléens (1) – Les booléens ■ boolean : ■ Un booléen peut contenir 2 valeurs □ soit vrai : true (mot réservé) □ soit faux : false (mot réservé) – Les opérateurs logiques de comparaisons ■ Egalité : opérateur == ■ Différence : opérateur != ■ supérieur et inférieur strictement à : opérateurs > et < ■ supérieur et inférieur ou égal : opérateurs >= et <= ■ L’évaluation d’une expression avec un opérateur de comparaison renvoie un booléen 66
    • les booléens (2) – Notation boolean x; x= true; x= false; x= (5==5); // l ’expression (5==5) est évaluée et la valeur est affectée à x qui vaut alors vrai x= (5!=4); // x vaut vrai, ici on obtient vrai si 5 est différent de 4 x= (5>5); // x vaut faux, 5 n'est pas supérieur strictement à 5 x= (5<=5); // x vaut vrai, 5 est bien inférieur ou égal à 5 67
    • les booléens (3) – L’opérateur de comparaison ternaire ■ Un opérateur parfois intéressant qui vient du C manipuler ■ « ? : » int res,i,j; …. res = (i==0)? 0 : j/i; /* res contient 0 si i==0 et sinon il contient j/i */ int max = (x > y) ? x : y; String name = (name != null) ? name : quot;unkownquot; 68
    • Les booléens (4) – Les opérateurs logiques ■ et logique : && ■ ou logique : || ■ non logique : ! ■ Exemples : si a et b sont 2 variables booléennes boolean a,b, c; a= true; b= false; c= (a && b); // c vaut false c= (a || b); // c vaut true c= !(a && b); // c vaut true c=!a; // c vaut false 69
    • Les booléens (5) ExempleBooleen.java public class ExempleBooleen { public static void main (String args[]) { System.out.println(quot;Starting ExempleBooleen...quot;); boolean test1, test2, test3; int res; int i,j,k; i=0; j=2; k=3; test1 = (i == j); //false test2 = (i != k); //true test3 = (j <= k); //true res = (i==0)? 0 : j/i; if (test3) { System.out.println(quot;Nous sommes dans le ifquot;); System.out.println(quot;test3 = quot; + test3); } System.out.println(quot;test1 = quot; + test1); System.out.println(quot;test2 = quot; + test2); System.out.println(quot;res = quot; + res); }} 70
    • Les caractères (1) – Les caractères ■ char : contient une seule lettre ■ le type char désigne des caractères en représentation Unicode □ Codage sur 2 octets contrairement à ASCII/ANSI codé sur 1 octet. Le codage ASCII/ANSI est un sous-ensemble d’Unicode □ Notation hexadécimale des caractères Unicode de ‘ u0000 ’ à ‘ uFFFF ’. □ Plus d’information sur Unicode à : www.unicode.org 71
    • Les caractères (2) – Notation char a,b,c; // a,b et c sont des variables du type char a='a'; // a contient la lettre 'a' b= 'u0022' //b contient le caractère guillemet : quot; c=97; // x contient le caractère de rang 97 : 'a' 72
    • Les caractères (3) ExempleChar.java public class ExempleChar { public static void main (String args[]) { System.out.println(quot;Starting ExempleChar...quot;); char a,b,c; a='a'; b='u0022'; c=97; System.out.println(quot;a = quot; + a); System.out.println(quot;b = quot; + b); System.out.println(quot;c = quot; + c); } } 73
    • Initialisation des variables (1) – Java exige que toutes les variables soient définies et initialisées. ■ Le compilateur sait déterminer si une variable est susceptible d'être utilisée avant initialisation et produit une erreur de compilation. ■ Donc, le compilateur force l’initialisation de toutes variables avant son utilisation □ C’est une sécurité mais oblige à faire attention à ce point pour éviter une erreur de compilation ■ Erreur de compilation du type □ Z:TravailJavaexosExempleInit.java:8: variable a might not have been initialized 74
    • Initialisation des variables (2) ExempleChar.java public class ExempleInit { public static void main (String args[]) { System.out.println(quot;Starting ExempleInit...quot;); int a,b,c; b = 10; c = b + a; } } Z:TravailIUTEnseignements2003-2004SRC2AJavaexosExempleInit.java:8: variable a might not have been initialized 75
    • Opérateurs : mémo Ce sont, à peu d'exceptions près, les mêmes que ceux de C ou C++. Le tableau suivant en donne les règles d'associativité de gauche à droite ou de droite à gauche. Les plus Droite à Gauche .[]() prioritaires DàG ++ - - + - ~ ! (cast_operator) GàD */% GàD +- GàD << >> >>> GàD < > <= >= instanceof GàD = = != GàD & GàD ^ GàD && GàD ³ DàG ?: DàG = *= /= %= += -= <<= >>= >>>= &= ^= = Les moins prioritaires 76
    • Méthodes
    • Méthodes et paramètres (1) – La notion de méthodes dans les langages objets ■ Proches de la notion de procédure ou de fonction dans les langages procéduraux. □ La méthode c’est avant tout le regroupement d’un ensemble d’instructions suffisamment générique pour pouvoir être réutilisées □ Comme pour les procédures ou les fonctions (au sens mathématiques) on peut passer des paramètres aux méthodes et ces dernières peuvent renvoyer des valeurs (grâce au mot clé return). 78
    • Méthodes et paramètres (2) – Méthodes de classe et méthode d’instances ■ En java on a 2 grands types de méthodes les méthodes de classe (défini avec le mot clé static comme pour la méthode main) et les méthodes d’instance : □ Une méthode est un message que l’on envoie ▪ à une classe : méthode de classe ou ▪ à un objet : méthode d’instance (ou méthode) □ La méthode main est toujours une méthode de classe ▪ Pour utiliser une méthode d’instance, il faut d’abord créer un objet qui peut « recevoir » cette méthode ▪ La méthode main est le point d’entrée dans le programme et est la première méthode lancée, avant la création du premier objet. Il est donc nécessaire que cela soit une méthode de classe. 79
    • Méthodes et paramètres (3) – Opérateurs d’accès à un membre d’un objet ou d’une classe ■ En java nous avons l’opérateur « . » qui permet d’accéder à un attribut ou une méthode d’un objet ou d’une classe ■ On précise le nom de l’objet ou de la classe, suivi du point, suivi du nom de l’attribut ou du nom de la méthode. readint est une méthode de la classe (méthode static) BasicIO. Pour l’utiliser on écrit : Basic.readint(quot;Entrer un entier:quot;); La méthode indexOf est une méthode d’instance de String Si on a un objet String nommé « s » et initialisé avec une valeur, on pourra appeler la méthode indexOf de la manière suivante : s = new String(quot;Bonjourquot;); int index_j = s.indexOf(quot;jquot; ); Attention : BasicIO ne fait pas partie des classes fournies en standard en Java ; c'est une classe utilisée dans le cadre de ce cours pour faciliter la saisie des données. 80
    • Méthodes et paramètres (4) exemple : public, type de la valeur couples d'un type et d'un static renvoyée ou void identificateur séparés par des « , » <modificateur> <type-retour> <nom> (<liste-param>) {<bloc>} public double add (double number1, double number2) { Notre méthode retourne ici une return (number1 +number2); valeur } Définition d’une méthode en Java 81
    • Méthodes et paramètres (5) AdditionEntier.java readint() est une méthode de classe. Elle est défini comme public class AdditionEntier static dans la classe BasicIO. { C’est un message que l’on public static void main(String args[]) envoie à la classe BasicIO { int nb1, nb2, result; nb1 = BasicIO.readint(quot;Entrer un entier:quot;); nb2 = BasicIO.readint(quot;Entrer un entier:quot;); result = nb1 + nb2; méthode println() System.out.println(quot;Somme = quot; + result); est une méthode d’instance } c’est un message que l’on } envoie à l’objet System.out qui est un objet particulier représentant la sortie standard 82
    • Portée des variables (1) – Lesvariables sont connues et ne sont connues qu’à l’intérieur du bloc dans lequel elles sont déclarées public class Bidule { int i, j, k; public void truc(int z) { int j,r; Ce sont 2 variables différentes r = z; } public void machin() k est connu au niveau de la méthode { machin() car déclaré dans le bloc de la k = r; classe. Par contre r n’est pas défini pour } machin(). On obtient une erreur à la } compilation 83
    • Portée des variables (2) – Encas de conflit de nom entre des variables locales et des variables globales, ■ c’est toujours la variable la plus locale qui est considérée comme étant la variable désignée par cette partie du programme □ Attention par conséquent à ce type de conflit quand on manipule des variables globales. public class Bidule { int i, k, j; public void truc(int z) { int j,r; C’est le j défini en local j = z; qui est utilisé dans } la méthode truc() } 84
    • La classe Math (1) – Les fonctions mathématiques les plus connues sont regroupées dans la classe Math qui appartient au package java.lang ■ les fonctions trigonométriques ■ les fonctions d’arrondi, de valeur absolue, ... ■ la racine carrée, la puissance, l’exponentiel, le logarithme, etc. – Ce sont des méthodes de classe (static) double calcul = Math.sqrt (Math.pow(5,2) + Math.pow(7,2)); double sqrt(double x) : racine carrée de x double pow(double x, double y) : x puissance y 85
    • La classe Math (2) public class ExerciceAlgo2 { public static void main (String args[]) { System.out.println(quot;ExerciceAlgo2...quot;); double val = BasicIO.readdouble(quot;Entrer un nombrequot;); double val_abs; val_abs = Math.abs(val); System.out.println(quot;La valeur absolue de votre nombre est : quot;+ val_abs); } } 86
    • Les structures de contrôle (I)
    • Présentation générale – Les structures de contrôle classiques existent en Java : ■ if, else ■ switch, case, default, break ■ for ■ while ■ do, while –A utiliser avec parcimonie ■ <étiquette> : suivie d'une boucle for, while ou do ■ break <étiquette> ou break; ■ continue <étiquette> ou continue; 88
    • if / else (1) – Instructions conditionnelles ■ On veut effectuer une ou plusieurs instructions seulement si une certaine condition est vraie if (condition) instruction; et plus généralement : if (condition) { bloc d’instructions} condition doit être un booléen ou renvoyer une valeur booléenne ■ On veut effectuer une ou plusieurs instructions si une certaine condition est vérifiée sinon effectuer d’autres instructions if (condition) instruction1; else instruction2; et plus généralement if (condition) { 1er bloc d’instructions} else {2ème bloc d’instruction} ■ La structure if() {…} else if() {…} else if (){…} else {}est possible en Java 89
    • if / else (2) fausse (sinon) condition Série 2 d’actions vraie (alors) Série 1 d’actions 90
    • if / else (3) Max.java public class Max { public static void main(String args[]) { int nb1, nb2; nb1 = BasicIO.readint(quot;Entrer un entier:quot;); nb2 = BasicIO.readint(quot;Entrer un entier:quot;); if (nb1 > nb2) System.out.println(quot;l’entier le plus grand est quot;, nb1); else System.out.println(quot;l’entier le plus grand est quot;, nb2); } } 91
    • while (1) – Boucles indéterminées ■ On veut répéter une ou plusieurs instructions un nombre indéterminés de fois : on répète l’instruction ou le bloc d’instruction tant que une certaine condition reste vraie ■ nous avons en Java une première boucle while (tant que) □ while (condition) {bloc d’instructions} □ les instructions dans le bloc sont répétées tant que la condition reste vraie. □ On ne rentre jamais dans la boucle si la condition est fausse dès le départ 92
    • while (2) – Boucles indéterminées ■ un autre type de boucle avec le while: □ do {bloc d’instructions} while (condition) □ les instructions dans le bloc sont répétées tant que la condition reste vraie. □ On rentre toujours au moins une fois dans la boucle : la condition est testée en fin de boucle. 93
    • while (3) fausse while () { ...} condition vraie Instructions 94
    • while (4) Instructions do { ...}while (); vraie condition fausse 95
    • while (5) Facto1.java public class Facto1 { public static void main(String args[]) { int n, result,i; n = BasicIO.readint(quot;Entrer une valeur pour nquot;); result = 1; i = n; while (i > 1) { result = result * i; i--; } System.out.println( quot;la factorielle de quot; + n + quot; vaut quot; + result); } } 96
    • for (1) – Boucles déterminées ■ On veut répéter une ou plusieurs instructions un nombre déterminés de fois : on répète l’instruction ou le bloc d’instructions pour un certain nombre de pas. ■ La boucle for for (int i = 1; i <= 10; i++) System.out.println(i); //affichage des nombres de 1 à 10 ■ une boucle for est en fait équivalente à une boucle while for (instruction1; expression1; expression2) {bloc} … est équivalent à … instruction 1; while (expression1) {bloc; expression2} 97
    • for (2) Facto2.java public class Facto2 { public static void main(String args[]) { int n, result,i; n = BasicIO.readint(quot;Entrer une valeur pour nquot;); result = 1; for(i =n; i > 1; i--) { result = result * i; } System.out.println( quot;la factorielle de quot; + n + quot; vaut quot; + result); } } 98
    • Exermple – Somme des N premiers entiers public class SommeNEntiers { public static void main(String args[]) { int n; n = BasicIO.readint(quot;Entrer un entierquot;); System.out.println(quot;La somme vaut quot; + SommeNEntiers.somme(n)); } public static int somme(int n) { int res = 0; while (n > 0) { res = res + n; n--; } return res; } } 99
    • switch (1) – Sélection multiples ■ l’utilisation de if / else peut s’avérer lourde quand on doit traiter plusieurs sélections et de multiples alternatives ■ pour cela existe en Java le switch / case assez identique à celui de C/ C++ ■ La valeur sur laquelle on teste doit être un char ou un entier (à l’exclusion d’un long). ■ En règle général l’exécution des instructions correspondant à une alternative commence au niveau du case correspondant et se termine à la rencontre d’une instruction break ou arrivée à la fin du switch 100
    • switch (2) Alternative.java public class Alternative Variable contenant la valeur { que l’on veut tester. public static void main(String args[]) { int nb = ESBasique.litInt(quot;Entrer un entier:quot;); switch(nb) Première alternative : { on affiche 1 et on sort case 1: du bloc du switch au break; System.out.println(quot;1quot;); break; case 2: Deuxième alternative : System.out.println(quot;2quot;); break; on affiche 2 et on sort default: du bloc du switch au break; System.out.println(quot;Autre nombrequot;); break; } } Alternative par défaut: } on réalise une action par défaut. 101
    • break – Interruption et interruption étiquetée ■ l’instruction break permet de sortir d ’une boucle □ on sort du bloc d’instructions dans lequel on est pour remonter dans le bloc contenant ■ On peut aussi utilisée un étiquetage pour quitter un ensemble de boucles imbriquées □ l’étiquette doit précéder la plus externe des boucles que l ’on veut quitter. □ <étiquette> : suivie d'une boucle □ break <étiquette> ou break; □ continue <étiquette> ou continue; 102
    • continue – continue ■ l’instruction continue permet de sauter une itération dans une boucle sans pour autant sortir de la boucle □ à l’arrivée sur l’instruction continue on passe à l’itération suivante de la boucle sans aller jusqu’à la fin de la boucle. □ continue <étiquette> ou continue; 103
    • La récursivité (rappel)
    • Récursivité (1) – On définit la factorielle d’un nombre entier positif n, n! par ■ n! = n * n-1 * …* 1 sachant que par convention la 0! = 1 ■ Définir une classe Java qui calcule la factorielle par récurrence ■ On rappelle que □ n! = n* n-1 * … *1 = n * (n-1* n-2 * …*1) = n *(n-1)! 105
    • Récursivité (2) public class Facto3 { public static void main(String args[]) { int n, res; n = BasicIO.readint(quot;Entrer un nombre entier positifquot;); if (n >=0) { res = facto_recur(n);} else { res = 0;} System.out.println(quot;La factorielle de quot; + n + quot; vaut : quot; + res); } public static int facto_recur(int n) { if ((n == 1) || (n ==0)) {return 1;} else {return (n*facto_recur(n-1));} } } 106
    • Récursivité (3) – Récursivité ■ Pour résoudre un problème on fait appel à la résolution du même problème mais dans un cas plus « simple » ■ Schéma de résolution identique mais à un niveau inférieur □ Classiquement la résolution du problème au niveau « n » fait intervenir la résolution du problème au niveau « n-1 » ▪ La factorielle ▪ La puissance □ En mathématique on a des suites définies selon une équation de récurrence ▪ Un = q * Un-1 + r □ Problème classique des tours de Hanoi… 107
    • Les chaînes de caractères
    • La classe String (1) – Attention ce n’est pas un type de base. Il s'agit d'une classe défini dans l’API Java (Dans le package java.lang) String s=quot;aaaquot;; // s contient la chaîne quot;aaaquot; mais String s=new String(quot;aaaquot;); // identique à la ligne précédente – La concaténation ■ l’opérateur + entre 2 « String » les concatène : String str1 = quot;Bonjour ! quot;; String str2 = null; str2 = quot;Comment vas-tu ?quot;; String str3 = str1 + str2; / * Concaténation de chaînes : str3 contient quot; Bonjour ! Comment vas-tu ?quot; 109
    • Différences entre objets et types de base (1) Mémoire 3 int x=3,y=3; x == y est vrai 3 0x768 0x852 String s1=quot;abcquot;,s2=quot;abcquot;; Abc s1 == s2 est faux... .... Quand on compare 2 variables d’un type de base on compare leur valeur. Quand on compare 2 objet Abc avec les opérateurs on compare leur référence (leur .... adresse en mémoire). Introduction de la méthode equals() pour les objets : s1.equals(s2) est vrai 110
    • Différences entre objets et types de base (2) public class ExempleString { public static void main(String args[]) { String s1=new String(quot;abcquot;); String s2=new String(quot;abcquot;); String s_abc1 = quot;abcquot;; String s_abc2 = quot;abcquot;; int x = 3, y =3; System.out.println(quot;x = quot; + x + quot; y = quot; + y + quot; et x == y vaut quot; + (x == y)); System.out.println(quot;s1 = new String(quot;abcquot;); --> quot; + s1); System.out.println(quot;s2 = new String(quot;abcquot;); --> quot; + s2); System.out.println(quot;s1 == s2 vaut quot; + (s1 == s2)); System.out.println(quot;s1.equals(s2) vaut quot; + (s1.equals(s2))); System.out.println(quot;s_abc1 = quot;abcquot;; --> quot; + s_abc1); System.out.println(quot;s_abc2 = quot;abcquot;; --> quot; + s_abc2); System.out.println(quot;s_abc1 == s_abc2 vaut quot; + (s_abc1 == s_abc2)); System.out.println(quot;s_abc1.equals(s_abc2) vaut quot; + (s_abc1.equals(s_abc2))); } } 111
    • La classe String (2) – Longueur d’un objet String : ■ méthode int length() : renvoie la longueur de la chaîne String str1 = quot;bonjourquot;; int n = str1.length(); // n vaut 7 – Sous-chaînes ■ méthode String substring(int debut, int fin) ■ extraction de la sous-chaine depuis la position debut jusqu’à la position fin non-comprise. String str2 = str1.substring(0,3); // str2 contient la valeur quot;bonquot; ■ le premier caractère d’une chaîne occupe la position 0 ■ le deuxième paramètre de substring indique la position du premier caractère que l’on ne souhaite pas copier 112
    • La classe String (3) – Récupération d’un caractère dans une chaîne ■ méthode char charAt(int pos) : renvoie le caractère situé à la position pos dans la chaîne de caractère à laquelle on envoie se message String str1 = quot;bonjourquot;; char unJ = str1.charAt(3); // unJ contient le caractère 'j' 113
    • La classe String (4) – Modification des objets String ■ Les String sont inaltérables en Java : on ne peut modifier individuellement les caractères d’une chaîne. ■ Par contre il est possible de modifier le contenu de la variable contenant la chaîne (la variable ne référence plus la même chaîne). str1 = str1.substring(0,3) + quot; soirquot;; /* str1 contient maintenant la chaîne quot;bonsoirquot; */ ■ Quand on a besoin de manipuler directement les chaînes de caractères il existe la classe StringBuffer (cf. TP) 114
    • La classe String (5) – Les chaînes de caractères sont des objets : ■ pour tester si 2 chaînes sont égales il faut utiliser la méthode boolean equals(String str) et non == ■ pour tester si 2 chaînes sont égales à la casse près il faut utiliser la méthode boolean equalsIgnoreCase(String str) String str1 = quot;BonJourquot;; String str2 = quot;bonjourquot;; String str3 = quot;bonjourquot;; boolean a, b, c, d; a = str1.equals(quot;BonJourquot;); //a contient la valeur true b = (str2 == str3); //b contient la valeur false c = str1.equalsIgnoreCase(str2);//c contient la valeur true d = quot;bonjourquot;.equals(str2); //d contient la valeur true 115
    • La classe String (6) – Quelques autres méthodes utiles ■ boolean startsWith(String str) : pour tester si une chaine de caractère commence par la chaine de caractère str ■ boolean endsWith(String str) : pour tester si une chaîne de caractère se termine par la chaine de caractère str String str1 = quot;bonjour quot;; boolean a = str1.startsWith(quot;bonquot;);//a vaut true boolean b = str1.endsWith(quot;jourquot;);//b vaut true 116
    • La classe String (7) Plus d’informations dans les documentations de l’API dans le package java.lang 117
    • La classe String (8) public class ExempleString2 { public static void main(String args[]) { String str1 = quot;bonjourquot;; System.out.println(quot;Il y a quot; + str1.length() + quot; caractères dans str1quot;); String str2 = str1.substring(0,3); System.out.println(quot;str2 contient la chaine : quot; + str2); char unJ = str1.charAt(3); System.out.println(quot;Le 3eme caractère de str1 est : quot; + unJ); String str3 = quot;BonJourquot;; System.out.println(quot;str1.equals(quot;BonJourquot;); vaut : quot; + str1.equals(quot;BonJourquot;)); System.out.println(quot;str1.equalsIgnoreCase(str3); vaut quot; + str1.equalsIgnoreCase(str3)); System.out.println(quot;quot;bonjourquot;.equals(str1); vaut quot; + quot;bonjourquot;.equals(str1)); System.out.println(quot;str1.startsWith(quot;bonquot;); vaut quot; + str1.startsWith(quot;bonquot;)); System.out.println(quot;str1.endsWith(quot;Jourquot;); vaut quot; + str1.endsWith(quot;jourquot;)); } } 118
    • Objet et référence
    • Objets, tableaux, types de base – Lorsqu'une variable est d'un type objet ou tableau : ■ ce n'est pas l'objet ou le tableau lui-même qui est stocké dans la variable mais une référence vers cet objet ou ce tableau (on retrouve la notion d’adresse mémoire ou du pointeur en C). – Lorsqu'une variable est d'un type de base : ■ La variable contient la valeur. – Lorsqu’unevariable est d’un type « complexe » (Chaine, Tableau, Objet quelconque) ■ La variable contient la valeur de l’adresse à laquelle se trouve l’objet 120
    • Références – La référence en Java correspond à la notion de pointeur ■ La référence est, en quelque sorte, un pointeur pour lequel le langage assure une manipulation transparente (pour l’utilisateur), comme si c'était une valeur □ pas de déréférencement : on manipule toujours l’objet et jamais directement le « pointeur ». Contrairement au C/C++, il n’y a pas d’arithmétique sur les pointeurs – Attention ■ La référence n’étant pas une valeur, c'est au programmeur de prévoir l'allocation mémoire nécessaire pour stocker effectivement l'objet □ utilisation de l’opérateur new 121
    • Différences entre objets et types de base Mémoire 3 int x=3,y=3; x == y est vrai 3 0x768 0x852 String s1=new String(quot;abcquot;),s2=new String(quot;abcquot;); Abc s1 == s2 est faux... .... Quand on compare 2 variables d’un type de base on compare leur valeur. Quand on compare 2 objet Abc avec les opérateurs on compare leur référence (leur .... adresse en mémoire). Introduction de la méthode equals() pour les objets : s1.equals(s2) est vrai 122
    • Les tableaux
    • Les tableaux (1) – Les tableaux permettent de stocker plusieurs valeurs de même type dans une variable. ■ Les valeurs contenues dans la variable sont repérées par un indice ■ En langage Java, les tableaux sont des objets – Déclaration ■ type_elt_tableau nom_var_tab [ ]; □ int tab [ ]; String chaines [ ]; – Création d'un tableau ■ nom_var_tab = new type_elt_tableau [taille_tableau]; □ tab = new int [20]; //tableau de 20 entiers de type int □ chaines = new String [100]; //tableau de 100 chaînes 124
    • Les tableaux (2) – Le nombre d'éléments du tableau est stocké. ■ Java peut ainsi détecter à l'exécution le dépassement d'indice et générer une exception. ■ Mot clé length □ Le nombre d’éléments (la taille) est récupérable par nomTableau.length tab = new int [20]; int taille = tab.length; //taille vaut 20 – Comme en C/C++ ou en JavaScript, les indices d’un tableau commencent à ‘ 0 ’. ■ Donc un tableau de taille 100 aura ses indices qui iront de 0 à 99. 125
    • Les tableaux (3) – Initialisation tab[0]=1; tab[1]=2; //etc. noms[0] = new String( quot;Boulequot;); noms[1] = new String( quot;Billquot;);//etc – Création et initialisation simultanées String noms [ ] = {quot;Boulequot;,quot;Billquot;}; Point pts[ ] = { new Point (0, 0), new Point (10, -1)}; 126
    • Les tableaux (4) – Il est possible de créer des tableaux quot;rectangulairesquot; et des tableaux quot;non rectangulairesquot;. ■ Des tableaux à 2 dimensions : notion de matrices ■ on parle plus généralement de tableau multidimensionnel. – Exemples : int matrice [ ] [ ] = new int [4] [3]; int tab [ ] [ ] = new int [4] [ ]; tab [0] = new int [5]; tab [1] = new int [8]; tab [2] = new int [3]; tab [3] = new int [10]; 127
    • Les tableaux (5) – Quelques méthodes utiles ■ Dans la classe java.lang.System □ static void arraycopy(Object src, int src_position, Object dst, int dst_position, int length) qui copie le tableau src à partir de l’indice src_position dans le tableau dst, en le remplissant à partir de dst_position et en copiant length élément(s). 128
    • Les tableaux (6) – Quelques méthodes utiles ■ Dans la classe java.util.Arrays □ static int binarySearch ( type[ ] tab, type elt_a_chercher) qui recherche de elt_a_chercher. Renvoie l’indice si trouver, une valeur négative sinon. Dans ce dernier cas, (-r +1) désigne la position à laquelle il faudrait insérer elt_a_chercher pour que tab reste trié. □ static boolean equals(type[ ] tab1, type[ ] tab2) pour comparer 2 tableaux de même type. □ static void fill(type[ ] tab, type elt_de_remplissage) pour remplir un tableau avec un même élément. □ static void sort(type[ ] tab) qui réalise un quickSort ascendant sur les éléments de tab. 129
    • Les tableaux (7) Tab1.java public class Tab1 { public static void main (String args[]) Pour déclarer une variable tableau { on indique le type des éléments du int tab[ ] ; tableau et le nom de la variable tableau tab = new int[4]; suivi de [ ] tab[0]=5; tab[1]=3; tab[2]=7; on utilise new <type> [taille]; tab[3]=tab[0]+tab[1]; pour initialiser le tableau } } On peut ensuite affecter des valeurs au différentes cases du tableau : Les indices vont toujours de <nom_tableau>[indice] 0 à (taille-1) 130
    • Les tableaux (8) Tab1.java Mémoire public class Tab1 { public static void main (String args[]) { int tab[ ] ; 0x0000 0x258 tab = new int[4]; tab[0]=5; 0 tab[1]=3; 0 tab[2]=7; tab[3]=tab[0]+tab[1]; 0 } 0 } 131
    • Les tableaux (9) Tab1.java Mémoire public class Tab1 { public static void main (String args[]) { 0x258 int tab[ ] ; tab = new int[4]; tab[0]=5; 0 5 tab[1]=3; 0 3 tab[2]=7; tab[3]=tab[0]+tab[1]; 0 7 } 0 8 } 132
    • Les tableaux (10) Tab2.java Mémoire public class Tab2 { 0x0258 public static void main (String args[]) { String tab[ ] ; 0x0106 0x0000 tab = new String[4]; 0x0115 0x0000 tab[0]=new String(quot;Pierrequot;); 0x0234 0x0000 tab[1]=new String(quot;Paulquot;); tab[2]=new String(quot;Jacquesquot;); 0x0599 0x0000 tab[3]=new String(quot;Philippequot;); } } quot;Pierrequot; 133
    • Les tableaux (11) Tab2.java Modification du programme pour afficher le contenu public class Tab2 du tableau. { public static void main (String args[]) { String tab[ ] ; tab = new String[4]; tab[0]=new String(quot;Pierrequot;); tab[1]=new String(quot;Paulquot;); tab[2]=new String(quot;Jacquesquot;); tab[3]=new String(quot;Philippequot;); for (int i=0;i<tab.length;i++) { System.out.println(quot;Prénom Numero : quot; + i + tab[i]); }} } 134
    • Les bases de la programmation objet en Java
    • Accès aux attributs d’un objet (1) Personne.java Personne nom : String prenom : String public class Personne age : Integer { public String nom; getNom() public String prenom; setNom() public int age; public void setNom(String unNom) { nom = unNom; } public String getNom() { return (nom); } } 136
    • Accès aux attributs d’un objet (2) Application.java public class Application { public static void main(String args[]) { Personne jean = new Personne(); jean.nom = quot;Jeanquot; ; jean.prenom = quot;Pierrequot; ; } } Remarque : Contrairement aux variables, les attributs d'une classe, s'ils ne sont pas initialisés, se voient affecter automatiquement une valeur par défaut. Cette valeur vaut : 0 pour les variables numériques, false pour les booléens, et null pour les références. 137
    • Accès aux méthodes d’un objet (1) Personne.java Personne nom : String prenom : String public class Personne age : Integer { public String nom; getNom() public String prenom; setNom() public int age; public void setNom(String unNom) { nom = unNom; } public String getNom() { return (nom); } } 138
    • Accès aux méthodes d’un objet (2) Application.java public class Application { public static void main(String args[]) { Personne jean = new Personne(); jean.setNom(quot;Jeanquot;) ; } } 139
    • Les constructeurs (1) – L'appel de new pour créer un nouvel objet déclenche, dans l'ordre : ■ L'allocation mémoire nécessaire au stockage de ce nouvel objet et l'initialisation par défaut de ces attributs, ■ L'initialisation explicite des attributs, s'il y a lieu, ■ L'exécution d'un constructeur. – Un constructeur est une méthode d'initialisation. public class Application { Le constructeur est ici celui public static void main(String args[]) par défaut (pas de { constructeur défini dans Personne jean = new Personne(); la classe Personne) jean.setNom(quot;Jeanquot;) ; } } 140
    • Les constructeurs (2) – Lorsque l'initialisation explicite n'est pas possible ■ par exemple lorsque la valeur initiale d'un attribut est demandée dynamiquement à l'utilisateur, il est possible de réaliser l'initialisation au travers d'un constructeur. – Le constructeur est une méthode : ■ de même nom que la classe, ■ sans type de retour. – Toute classe possède au moins un constructeur ■ Si le programmeur ne l'écrit pas, il en existe un par défaut, sans paramètres, de code vide. 141
    • Les constructeurs (3) Personne.java Définition d’un Constructeur. Le public class Personne constructeur par défaut { (Personne() )n’existe plus. public String nom; Le code précédent occasionnera public String prenom; une erreur public int age; public Personne(String unNom, String unPrenom, int unAge) { nom=unNom; public class Application prenom=unPrenom; { age = unAge; public static void main(String args[]) } { } Personne jean = new Personne(); jean.setNom(quot;Jeanquot;) ; } } Va donner une erreur à la compilation 142
    • Les constructeurs (4) – Pour une même classe, il peut y avoir plusieurs constructeurs, de signatures différentes (surcharge). – L'appel de ces constructeurs est réalisé avec le new auquel on fait passer les paramètres. – p1 = new Personne(quot;Pierrequot;, quot;Richardquot;, 56); – Déclenchement du quot;bonquot; constructeur ■ Il se fait en fonction des paramètres passés lors de l'appel (nombre et types). C'est le mécanisme de quot;lookupquot;. – Attention ■ Si le programmeur crée un constructeur (même si c'est un constructeur avec paramètres), le constructeur par défaut n'est plus disponible. Attention aux erreurs de compilation ! 143
    • Les constructeurs (5) Personne.java Redéfinition d’un public class Personne Constructeur sans paramètres { public String nom; public String prenom; public int age; public Personne() { nom=null; prenom=null; On définit plusieurs constructeurs age = 0; qui se différencient uniquement } par leurs paramètres (on parle public Personne(String unNom, de leur signature) String unPrenom, int unAge) { nom=unNom; prenom=unPrenom; age = unAge; } } 144
    • Destruction d’objets (1) – Java n'a pas repris à son compte la notion de destructeur telle qu’elle existe en C++ par exemple. ■ C'est le ramasse-miettes (ou Garbage Collector - GC en anglais) qui s'occupe de collecter les objets qui ne sont plus référencés. ■ Le ramasse-miettes fonctionne en permanence dans un thread de faible priorité (en « tâche de fond »). □ Il est basé sur le principe du compteur de références. ■ Il faut faire attention certains bibliothèques graphiques (SWT) exigent du programmeur qu’il gère lui-même la libération des la mémoire par les objets inutilisés. □ Cependant ce n’est pas le cas général en Java. 145
    • Destruction d’objets (2) – Leprogrammeur n’a plus à gérer directement la destruction des objets, ■ c’était une importante source d'erreurs □ on parlait de fuite de mémoire ou « memory leak » en anglais – Désactivation du GC ■ Le ramasse-miettes peut être quot;désactivéquot; en lançant l'interpréteur java avec l'option -noasyncgc. – Activation du gc ■ le ramasse-miettes peut être lancé explicitement par une application avec l'appel System.gc(); 146
    • Destruction d’objets (3) – Il est possible au programmeur d'indiquer ce qu'il faut faire juste avant de détruire un objet. ■ C'est le but de la méthode finalize() de l'objet. ■ Cette méthode est utile, par exemple, pour : □ fermer une base de données, □ fermer un fichier, □ couper une connexion réseau, □ etc. 147
    • méthodes (rappel) exemple : public, type de la valeur couples d'un type et d'un static renvoyée ou void identificateur séparés par des « , » <modificateur> <type-retour> <nom> (<liste-param>) {<bloc>} public double add (double number1, double number2) { Notre méthode retourne ici une return (number1 +number2); valeur } 148
    • Mode de passage des paramètres (1) – Java n'implémente qu'un seul mode de passage des paramètres à une méthode : ■ le passage par valeur (comme le C) – Conséquences : ■ l'argument passé à une méthode ne peut être modifié, ■ si l'argument est un objet, c'est sa référence qui est passée par valeur. □ Ainsi, le contenu de l'objet peut être modifié, mais pas la référence elle-même. 149
    • Mode de passage des paramètres (2) public class Personne { public String nom; public String prenom; public int age; public Personne() { nom=null; prenom=null; age = 0; } public Personne(String nom, String prenom, int age) { this.nom=nom; this.prenom=prenom; this.age=age; } public void affiche_personne() { System.out.println(this.prenom + quot; quot; + this.nom + quot; quot; + this.age);} } 150
    • Mode de passage des paramètres (3) public class exemplePassageParam { public static void main(String args[]) { int nombre = 5; System.out.println(nombre); modification_nombre(nombre); System.out.println(nombre); Personne etudiant = new Personne(quot;Terieurquot;,quot;Alexquot;, 20); etudiant.affiche_personne(); modification_personne(etudiant); etudiant.affiche_personne(); } public static void modification_personne (Personne p) { p.nom = quot;Terieurquot;; p.prenom = quot;Alainquot;; p.age = 21; } public static void modification_nombre (int unNombre) { unNombre = 16; } } 151
    • Contrôle d’accès (1) – Chaque attribut et chaque méthode d'une classe peut être : ■ visible depuis les instances de toutes les classes d'une application. En d'autres termes, son nom peut être utilisé dans l'écriture d'une méthode de ces classes. Il est alors public. ■ visible uniquement depuis les instances de sa classe. En d'autres termes, son nom peut être utilisé uniquement dans l'écriture d'une méthode de sa classe. Il est alors privé. – Les mots réservés sont : – public – private 152
    • Contrôle d’accès (2) – En toute rigueur, il faudrait toujours que : ■ les attributs ne soient pas visibles, □ Les attributs ne devraient pouvoir être lus ou modifiés que par l'intermédiaire de méthodes prenant en charge les vérifications et effets de bord éventuels. ■ les méthodes quot;utilitairesquot; ne soient pas visibles, ■ seules les fonctionnalités de l'objet, destinées à être utilisées par d'autres objets soient visibles. ■ C’est la notion d’encapsulation ■ Nous verrons dans la suite que l’on peut encore affiner le contrôle d’accès . 153
    • Contrôle d’accès (3) public class Parallelogramme { private int longueur = 0; // déclaration + initialisation explicite private int largeur = 0; // déclaration + initialisation explicite public int profondeur = 0; // déclaration + initialisation explicite public void affiche ( ) {System.out.println(quot;Longueur= quot; + longueur + quot; Largeur = quot; + largeur + quot; Profondeur = quot; + profondeur); }} public class ProgPpal { public static void main(String args[]) { Parallelogramme p1 = new Parallelogramme(); p1.longueur = 5; // Invalide car l'attribut est privé p1.profondeur = 4; // OK p1.affiche( ); // OK }} 154
    • Contrôle d’accès évolué (1) – Outre private et public, Java définit deux niveaux de contrôle d'accès supplémentaires. – S'il n'y a pas de modificateur explicite dans la déclaration d'un attribut ou d'une méthode, celui-ci est visible depuis toute méthode d'une classe quelconque du même paquetage. ■ On l'appelle accès friendly. ■ Pas de mot réservé. 155
    • Contrôle d’accès évolué (2) – Un attribut ou une méthode protégé est visible depuis : ■ Toute méthode d'une classe quelconque appartenant au même paquetage, ■ Toute méthode d'une sous-classe. ■ Mot réservé : protected. – Une classe ou une interface peut être ■ publique (c'est-à-dire accessible partout où son paquetage l'est) ■ friendly (c'est-à-dire accessible seulement dans son paquetage). 156
    • Contrôle d’accès évolué (3) – Pour résumer ■ private : visible uniquement par la classe ■ public : visible par toutes mes classes ■ protected : visible par les sous-classes et par le package □ attention, la signification de protected en Java est différente de sa signification en C++ où il définit une visibilité uniquement pour les sous-classes. ■ Visibilité par défaut (quand aucun modificateur n’est spécifié) : visibilité par le package (paquetage) 157
    • L’héritage avec Java (1) – Java implémente le mécanisme d'héritage simple ■ L’héritage permet de quot;factoriserquot; de l'information dans le cas où deux classes sont reliées par une relation de généralisation / spécialisation. ■ L'héritage multiple n'existe pas en Java. □ Une classe ne peut hériter que d’une seule autre classe □ L’implémentation d’interface permet de compenser cette limitation – Pour le programmeur, il s'agit d'indiquer, dans la sous- classe, le nom de la superclasse dont elle hérite. ■ Par défaut toute classe Java hérite de la classe Object – Mot réservé : extends 158
    • L’héritage avec Java (2) class Personne Personne { nom : String date_naissance : Date private String nom; private Date date_naissance; // ... } class Employe extends Personne { Employe private float salaire; salaire : Double // ... } class Etudiant extends Personne { private int numero_carte_etudiant; // ... Etudiant } numero_carte_etudiant : Integer 159
    • L’héritage en Java (3) – Constructeurs et héritage ■ par défaut le constructeur d’une sous-classe appelle le constructeur quot;par défautquot; (celui qui ne reçoit pas de paramètres) de la superclasse. Attention donc dans ce cas que le constructeur sans paramètre existe toujours dans la superclasse... ■ Pour forcer l'appel d'un constructeur précis, on utilisera le mot réservé super. Cet appel devra être la première instruction du constructeur. 160
    • L’héritage en Java (4) public class Employe extends Personne { public Employe () {} public Employe (String nom, String prenom, int anNaissance) { super(nom, prenom, anNaissance); } } Pour forcer l'appel d'un constructeur précis, on utilise le mot réservé super. Cet appel doit alors être la première instruction du constructeur. 161
    • L’héritage en Java (5) public class Employe extends Personne { public class Personne public Employe () {} { public Employe (String nom, public String nom, prenom; String prenom, public int anNaissance; int anNaissance) public Personne() { { super(nom, prenom, anNaissance); nom=quot;quot;; prenom=quot;quot;; } } } public Personne(String nom, String prenom, int anNaissance) { this.nom=nom; Appel explicite à ce constructeur this.prenom=prenom; avec le mot clé super this.anNaissance=anNaissance; } } 162
    • L’héritage en Java (6) public class Personne public class Object { { public String nom, prenom; public Object() public int anNaissance; { public Personne() … / ... { } nom=quot;quot;; prenom=quot;quot;; } } public Personne(String nom, String prenom, int anNaissance) Appel par défaut dans le constructeur { de Personne au constructeur this.nom=nom; par défaut de la superclasse de this.prenom=prenom; Personne, qui est Object this.anNaissance=anNaissance; } } 163
    • Redéfinition de méthodes – Une sous-classe peut redéfinir des méthodes existant dans une de ses superclasses (directe ou indirectes), à des fins de spécialisation. ■ Le terme anglophone est quot;overridingquot;. On parle aussi de masquage. ■ La méthode redéfinie doit avoir la même signature. class Employe extends Personne class Cadre extends Employe { { private float salaire; redéfinition public calculePrime() public calculePrime( ) { { // ... // ... } } // ... } } 164
    • Recherche dynamique des méthodes (1) – Le polymorphisme ■ Capacité pour une entité de prendre plusieurs formes. ■ En Java, toute variable désignant un objet est potentiellement polymorphe, à cause de l'héritage. ■ Polymorphisme dit « d’héritage » – le mécanisme de quot;lookupquot; dynamique : ■ déclenchement de la méthode la plus spécifique d’un objet, c'est-à- dire celle correspondant au type réel de l'objet, déterminé à l'exécution uniquement (et non le type de la référence, seul type connu à la compilation, qui peut être plus générique). ■ Cette dynamicité permet d'écrire du code plus générique. 165
    • Recherche dynamique des méthodes (2) Employe jean = new Employe(); jean.calculePrime(); Employe salaire : Double calculePrime() Employe jean = new Cadre(); jean.calculePrime(); Cadre calculPrime() 166
    • Surdéfinition de méthodes (1) – Dans une même classe, plusieurs méthodes peuvent posséder le même nom, pourvu qu'elles diffèrent en nombre et/ou type de paramètres. ■ On parle de surdéfinition ou surcharge, on encore en anglais d’overloading en anglais. ■ Le choix de la méthode à utiliser est fonction des paramètres passés à l'appel. □ Ce choix est réalisé de façon statique (c'est-à-dire à la compilation). ■ Très souvent les constructeurs sont surchargés (plusieurs constructeurs prenant des paramètres différents et initialisant de manières différentes les objets) 167
    • Surdéfinition de méthodes (2) – Quelques précisions cependant : ■ le type de retour seul, ne suffit pas à distinguer deux méthodes de signatures identiques par ailleurs, ■ les types des paramètres doivent être quot;suffisammentquot; différents pour qu'il n'y ait pas d'ambiguïtés, en particulier avec les conversions de types automatiques (exemple : promotion d'un float en double). – Nepas confondre surcharge et redéfinition (même si très proche) ■ on redéfinit dans une classes des méthodes héritées de sa superclasse. ■ On surcharge quand plusieurs méthodes dans une même classe ont le même nom mais des paramètres différents. 168
    • Variables de classe (1) – Ilpeut s'avérer nécessaire de définir un attribut dont la valeur soit partagée par toutes les instances d'une classe. On parle de variable de classe. – Ces variables sont, de plus, stockées une seule fois, pour toutes les instances d'une classe. – Mot réservé : static – Accès : ■ depuis une méthode de la classe comme pour tout autre attribut, ■ via une instance de la classe, ■ à l'aide du nom de la classe. 169
    • Variables de classe (2) Variable de classe public class UneClasse { public static int compteur = 0; public UneClasse () { Utilisation de la variable de classe compteur++; compteur dans le constructeur de } la classe } public class AutreClasse { public void uneMethode() Utilisation de la variable de classe { compteur dans une autre classe int i = UneClasse.compteur; } } 170
    • Méthodes de classe (1) – Ilpeut être nécessaire de disposer d'une méthode qui puisse être appelée sans instance de la classe. C'est une méthode de classe. – On utilise là aussi le mot réservé static – Puisqu'une méthode de classe peut être appelée sans même qu'il n'existe d'instance, une méthode de classe ne peut pas accéder à des attributs non statiques. Elle ne peut accéder qu'à ses propres variables et à des variables de classe. 171
    • Méthodes de classe (2) public class UneClasse La méthode main est une { méthode de classe donc elle public int unAttribut; public static void main(String args[]) ne peut accéder à un attribut { non lui-même attribut de unAttribut = 5; // Erreur de compilation classe } } Autres exemples de méthodes de classe courantes int Integer.parseInt (String); String String.valueOf (i); taille = Integer.valueOf(getParameter(quot;taillequot;)).intValue(); Math.sin(x); 172
    • Opérateur instanceof – L'opérateur instanceof confère aux instances une capacité d'introspection : il permet de savoir si une instance est instance d'une classe donnée. ■ Renvoie une valeur booléenne if ( ... ) Personne jean = new Etudiant(); else Personne jean = new Employe(); //... if (jean instanceof Employe) // discuter affaires else // proposer un stage 173
    • Forçage de type / transtypage (1) – Lorsqu'une référence du type d'une classe contient une instance d'une sous-classe, il est nécessaire de forcer le type de la référence pour accéder aux attributs spécifiques à la sous-classe. – Si ce n'est pas fait, le compilateur ne peut déterminer le type réel de l'instance, ce qui provoque une erreur de compilation. – On utilise également le terme de transtypage – Similaire au « cast » en C 174
    • Forçage de type / transtypage (2) class Personne A ce niveau pour le { compilateur dans la private String nom; variable « jean » c’est private Date date_naissance; un objet de la classe // ... Personne, donc qui } n’a pas d’attribut « salaire » class Employe extends Personne { public float salaire; // ... } On « force » le type de la variable « jean » Personne jean = new Employe (); pour pouvoir accéder float i = jean.salaire; // Erreur de compilation à l’attribut « salaire ». float j = ( (Employe) jean ).salaire; // OK On peut le faire car c’est bien un objet Employe qui est dans cette variable 175
    • L’autoréférence : this (1) – Le mot réservé this, utilisé dans une méthode, désigne la référence de l'instance à laquelle le message a été envoyée (donc celle sur laquelle la méthode est « exécutée »). – Il est utilisé principalement : ■ lorsqu'une référence à l'instance courante doit être passée en paramètre à une méthode, ■ pour lever une ambiguïté, ■ dans un constructeur, pour appeler un autre constructeur de la même classe. 176
    • L’autoréférence : this (2) class Personne { public String nom; Pour lever l’ambiguïté sur le mot « nom » Personne (String nom) et déterminer si c’est le nom du paramètre { ou de l’attribut this.nom=nom; } } public MaClasse(int a, int b) {...} Appelle le constructeur public MaClasse (int c) MaClasse(int a, int b) { this(c,0); } public MaClasse () Appelle le constructeur { MaClasse(int c) this(10); } 177
    • Référence à la superclasse – Lemot réservé super permet de faire référence au constructeur de la superclasse directe mais aussi à d’autres informations provenant de cette superclasse. class Employe extends Personne { Appel à la méthode calculPrime() private float salaire; de la superclasse de Cadre public float calculePrime() { return (salaire * 0,05); } // ... } class Cadre extends Employe { public calculePrime() { return (super.calculePrime() / 2); } // ... } 178
    • Le mot réservé final – Uneclasse est déclarée finale lorsqu'on ne souhaite pas qu'elle puisse être sous-classée. ■ Exemple public final class Integer extends Number { ... } – Uneméthode est déclarée finale lorsqu'on ne souhaite pas qu'elle puisse être redéfinie. ■ Exemple public final String getWarningString() { ... } – Une variable déclarée finale est une constante. ■ Exemple public static final Color white=new Color(255, 255, 255); 179
    • Paquetages (1) – Unpaquetage regroupe des classes et des interfaces apportant une même catégorie de fonctionnalités. ■ Par exemple java.net qui regroupe tout ce qui concerne les sockets, URL, etc. ■ Les noms de paquetages sont construits de manière hiérarchique en utilisant le point comme séparateur □ Les composants du nom de paquetage fournissent au compilateur et systèmes d’exécution un chemin d’accès unique aux fichiers. ▪ Attention il n’existe pas réellement de notion de sous-paquetage. 180
    • Paquetages (2) – Pourutiliser une classe située dans un paquetage, il y a deux possibilités : ■ Indiquer le nom du paquetage avant celui de la classe, ■ Utiliser le raccourci lexical import. Précision : import ne réalise pas le chargement du paquetage. – Siaucun paquetage n'est précisé pour une classe, celle-ci est intégré dans le paquetage anonyme (unnamed). 181
    • Paquetages (3) import java.util.Vector; // en début de fichier // ... Vector unVecteur; équivaut à : java.util.Vector unVecteur; La ligne suivante permet d'utiliser toutes les classes du paquetage java.util import java.util.*; // en début de fichier 182
    • Paquetages (4) – Pourindiquer qu'une classe MaClasse doit être placée dans un paquetage mon_paquetage, il faut ajouter en première ligne du fichier MaClasse.java la ligne : – package mon_paquetage; – Il faut, en outre, indiquer le chemin au compilateur : – Spécification du chemin au compilateur □ javac –classpath $HOME/mon_paquetage MaClasse.java ■ Spécification du chemin dans la variable d’environnement CLASSPATH 183
    • Classes abstraites (1) – Ilpeut être nécessaire au programmeur de créer une classe déclarant une méthode sans la définir (c'est-à-dire sans en donner le code). La définition du code est dans ce cas laissée aux sous-classes. – Une telle classe est appelée classe abstraite. – Elle doit être marquée avec le mot réservé abstract. – Toutes les méthodes de cette classe qui ne sont pas définies doivent elles aussi être marquées par le mot réservé abstract. – Une classe abstraite ne peut pas être instanciée. 184
    • Classes abstraites (2) – Par contre, il est possible de déclarer et d'utiliser des variables du type de la classe abstraite. – Si une sous-classe d'une classe abstraite ne définit pas toutes les méthodes abstraites de ses superclasses, elle est abstraite elle aussi. public abstract class Polygone { private int nombreCotes = 3; public abstract void dessine (); // methode non définie public int getNombreCotes() { return(nombreCotes); } } 185
    • Interfaces (1) – Sile programmeur veut s'assurer qu'une certaine catégorie de classes (pas forcément reliées par des relations de généralisation / spécialisation) implémente un ensemble de méthodes, il peut regrouper les déclarations de ces méthodes dans une interface. ■ De telles classes pourront ainsi être manipulées de manière identique. 186
    • Interfaces (2) – Lesclasses désirant appartenir à la catégorie ainsi définie : ■ déclareront qu'elles implémentent cette interface, ■ fourniront le code des méthodes déclarées dans cette interface. – Cela peut être vu comme un contrat entre la classe et l’interface ■ la classe s’engage à implémenter les méthodes définies dans l’interface – Mots réservés : interface et implements. 187
    • Interfaces (3) interface Conduisible { class TondeuseGazon void demarrerMoteur(); implements Conduisible void couperMoteur(); { void tourner(float angle); // ... } void demarrerMoteur(); {...} void couperMoteur() {...} void tourner(float angle){...} } class Voiture implements Conduisible { // ... void demarrerMoteur(); {...} void couperMoteur() {...} void tourner(float angle){...} } 188
    • Interfaces (4) // … Voiture maVoiture = new Voiture(); TondeuseGazon maTondeuse = new TondeuseGazon(); Conduisible vehicule; Boolean weekEnd; // … if(weekEnd == true) vehicule = maTondeuse; else vehicule = maVoiture; vehicule.demarrerMoteur(); vehicule.tourner(90.0F); vehicule.couperMoteur(); // … 189
    • Interfaces (5) – Toutes les méthodes d'une interface sont abstraites. – Le modificateur abstract est facultatif. – Une classe peut implémentée plusieurs interfaces différentes 190
    • Classes internes et classes anonymes (1) – Java permet de définir des classes imbriquées dans une autre classe. Ces classes, appelées classes internes, n'ont pas d'existence en dehors de la classe dans laquelle elles sont imbriquées. – Il est aussi possible de définir une sous-classe d'une classe en réalisant, avec une seule expression la déclaration de la classe et la création d'une instance. On parle de classe anonyme. ■ Nous verrons un cas d’utilisation de classe anonyme dans la programmation des interfaces graphiques. – Néanmoins, l'usage de ces notions est marginal... 191
    • Classes internes et classes anonymes (2) Exemple de classe anonyme « souvent » utilisé new WindowAdapter() { public void windowClosing(WindowEvent e) { dispose(); System.exit(0); } } 192
    • Les exceptions
    • Définition (1) – Une exception ■ C'est un signal qui indique que quelque chose « d'exceptionnel » est survenu en cours d'exécution. ■ On a alors 2 solutions : □ laisser le programme se terminer avec une erreur, □ essayer, malgré l'exception, de continuer l'exécution normale. ■ Lancer une exception consiste à signaler quelque chose d'exceptionnel. ■ Capturer l'exception consiste à signaler qu'on va la traiter. 194
    • Définition (2) Java ne sait pas calculer cette int i= 5 / 0; division mais elle génère une int j=i+10; exception qu’il est possible for (int k=0;k<j;k++) de récupérer. Après un System.out.println(k); éventuel traitement, on poursuit l'exécution du programme. Dans ce cas précis c’est une exception ArithmeticException qui est produite. Si aucun code n'est prévu pour traiter l'exception, le programme s'arrêtera et l ’exception s'affichera sur la console. 195
    • Quelques exceptions prédéfinies – Il existe de nombreuses exceptions prédéfinies ■ Elles sont réparties dans les différents package ■ Division par zéro pour les entiers : ArithmeticException ■ Déréférencement d'une référence nulle : NullPointerException ■ Tentative de forçage de type illégale : ClassCastException ■ Tentative de création d'un tableau de taille négative :NegativeArraySizeException ■ Dépassement de limite d'un tableau : ArrayIndexOutOfBoundsException ■ URL mal formée : MalformedURLException 196
    • Utilisation des exceptions (1) – Une obligation de traitement des exception ■ Java exige qu'une méthode susceptible de lever une exception (hormis les Error et les RuntimeException) indique quelle doit être l'action à réaliser. ■ Sinon, il y a erreur de compilation. – Le programmeur a le choix entre : ■ écrire un bloc try / catch pour traiter l'exception, ■ laisser remonter l'exception au bloc appelant grâce à un throws. ■ C'est ce qu'on appelle : quot;Déclarer ou traiterquot;. 197
    • Utilisation des exceptions (2) try { ... } catch (<une-exception>) { Autant de blocs catch que nécessaire. ... } catch (<une_autre_exception>) { ... } ... finally { Le bloc finally est facultatif. ... } 198
    • Utilisation des exceptions (3) – Le bloc try ■ Toute instruction susceptible de provoquer une exception doit être contenu dans un bloc d'instructions de type try. ■ Ce bloc d'instructions peut contenir autant d'instructions que nécessaires, susceptibles ou non de lever des exceptions ■ Le bloc try est exécuté… □ … jusqu'à ce qu'il se termine avec succès □ … ou bien qu'une exception soit levée 199
    • Utilisation des exceptions (4) – Si une exception est levée dans un bloc try ■ Les clauses catch contiennent les différents traitement à effectuer pour chaque exceptions levées □ On a autant de bloc catch que de types d'exceptions □ Chaque exception est un objet, transmis par l'instruction qui l'a générée □ On distingue les différents types des exceptions en fonction des classes auxquelles elles appartiennent 200
    • Utilisation des exceptions (5) – Si une exception est levée dans un bloc try ■ Un bloc catch reçoit en argument un objet qui représente l'exception □ Cet objet contient des informations exploitables pour traiter l'erreur ■ Quand le bloc catch a été trouvé et les instructions correspondantes exécutées, l'exécution du programme reprend son cours. 201
    • Utilisation des exceptions (6) – Faire attention au fait que ■ les clauses catch sont examinées l'une après l'autre dans le but d'en trouver une qui traite cette classe d'exceptions ou qui traite une « superclasse » de cette exception. ■ Donc □ Les clauses catch doivent traiter les exceptions de la plus spécifique à la plus générale. □ La présence d'une clause catch qui intercepte une classe d'exceptions avant une clause qui intercepte une sous-classe d'exceptions déclenche une erreur de compilation. 202
    • Utilisation des exceptions (7) – Si elles ne sont pas immédiatement capturées par un bloc catch ■ les exceptions se propagent en remontant la pile d'appels des méthodes, jusqu'à être traitées. □ Ce cas se produit si on utilise throws ou si c'est une exception de type « Error » que l'on ne traite pas. – Si une exception n'est jamais capturée ■ elle se propage jusqu'à la méthode main(), ce qui pousse l'interpréteur Java à afficher un message d'erreur et à s'arrêter. – L'interpréteur Java affiche un message identifiant : ■ l'exception, ■ la méthode qui l'a causée, ■ la ligne correspondante dans le fichier. 203
    • Utilisation des exceptions (8) – Capturer les exceptions est une obligation ■ Si une méthode indique qu'elle peut lancer une exception, il faut nécessairement l'intercepter □ dans le pire cas il faut au moins faire « remonter » l'exception avec throws ▪ Cependant cela ne fait en général que décaler le problème, il faudra à un moment ou à un autre traiter l'exception. ■ Dans le cas courant tout appel d'une méthode susceptible de renvoyer une exception doit être inclus dans un bloc try. □ Et toutes les exceptions susceptibles d'être levées dans ce bloc try doivent être capturées. □ Sinon erreur de compilation ▪ XXXXException must be caught, or it must be declared in the throws clause of this method 204
    • Utilisation des exceptions (9) int i= 5 / 0; int j=i+10; for (int k=0;k<j;k++) System.out.println(k); Maintenant on décide de gérer l’exception try { Quand une ArithmeticException est int i= 5 / 0; levée, les instructions en dessous int j=i+10; sont ignorées. Le programme for (int k=0;k<j;k++) continue au niveau du bloc System.out.println(k); de traitement catch de l'exception. } catch (ArithmeticException e) { System.out.println(quot;exception, quot; +e); } Après exécution du bloc //Suite du programme de traitement, le programme se poursuit 205
    • Utilisation des exceptions (10) – Le bloc finally ■ il permet au programmeur de définir un ensemble d'instructions qui est toujours exécuté, que l'exception soit □ levée ou non, □ capturée ou non. ■ Il sert principalement à remettre en état la cohérence du traitement en cas d'exception. □ Par exemple refermer des fichiers utilisés lors des traitements dans le try. 206
    • Utilisation des exceptions (11) – Le bloc finally s'exécute même si ■ le bloc en cours d'exécution (try ou catch selon les cas) contient un return, un break ou un continue. □ Dans ce cas, le bloc finally est exécuté juste avant le branchement effectué par l'une de ces instructions. ■ La seule instruction qui peut faire qu'un bloc finally ne soit pas exécuté est « System.exit() ». 207
    • Utilisation des exceptions (12) try { int i= 5 / 0; int j=i+10; for (int k=0;k<j;k++) System.out.println(k); } catch (ArithmeticException e) { Quoiqu’il arrive, le System.out.println(quot;exception, quot; +e); System.out.println(quot;Boucle } terminéequot;); situé dans le finally bloc finally sera exécutée { System.out.println(quot;Boucle terminéequot;); } // suite du programme 208
    • Utilisation des exceptions (13) public static void main (String args[]) { String s = quot;environ 1423quot;; int i; Peut provoquer une exception try NumberFormatException { i = Integer.parseInt(s); } catch (NumberFormatException e) { System.out.println(e.toString()); i = 0; } System.out.println(quot;i= quot; +i); } 209
    • Utilisation des exceptions (14) – La gestion des exceptions en Java comporte 3 éléments ■ Le générateur de l'exception □ invocation d'une méthode d'un objet qui, au cours de son exécution, décide de s'arrêter pour signaler à l'appelant qu'un problème bloquant est apparu. ■ L'exception □ Un objet Java qui représente le problème rencontré. □ Objet créé et renseigné (description du problème) par le générateur et transmis à l'appelant ■ L'appelant □ i.e. le code appelant la méthode susceptible de transmettre une exception, enfermé dans un bloc try (bloc d'essai) auquel sont associées des blocs catch (bloc de récupération) 210
    • Utilisation des exceptions (15) – Avantages ■ Séparation de la gestion des erreurs du code normal de l'application □ la gestion des exceptions se fait dans un bloc d'instructions séparé ■ Propagation possible des erreurs dans la pile des appels □ Une méthode qui ne veut pas gérer une exception peut la renvoyer (la « faire remonter ») ■ Analyse plus fine des erreurs □ La gestion des exceptions se fait par type d'exception. 211
    • Hiérarchie des Exceptions (1) java.lang.Object java.lang.Throwable java.lang.Exception java.lang.Error Toutes les exceptions devant java.lang.RuntimeException être capturées : AWTException IOException ArithmeticException SQLException ClassCastException Exceptions métiers, ... IndexOutOfBoundsException NullPointerException SecurityException ... 212
    • Hiérarchie des Exceptions (2) – DansJava, il existe deux grands « types » d'exceptions, représentées par deux classes de l'API Java ■ java.lang.Error ■ java.lang.Exception 213
    • Hiérarchie des Exceptions (3) java.lang.Object java.lang.Throwable java.lang.Exception java.lang.Error Les exceptions contiennent celles Les erreurs sont graves et Java prédéfinies par Java ... et les vôtres. recommande de ne pas les corriger. 214
    • Hiérarchie des Exceptions (4) – La classe Throwable ■ La racine de la hiérarchie des Exceptions ■ elle définit un message de type String qui est hérité par toutes les classes d’Exception. ■ ce champ est utilisé pour stocker le message décrivant l’Exception. ■ Il est positionné en passant un argument au constructeur. ■ Ce message peut être récupéré par la méthode getMessage() public class MonException extends Exception { public MonException() { super(); } public MonException(String s) {super(s);} } 215
    • Hiérarchie des Exceptions (5) – La classe Throwable : détail (1) ■ Les objets Throwable sont les seuls types d'objets qui peuvent être envoyé par une instruction d'erreur et capturé par un catch ■ 4 constructeurs □ Throwable(); □ Throwable(String message); □ Throwable(Throwable cause); □ Throwable(String message, Throwable cause); ▪ Le paramètre message contient le message de l'incident exploitable ▪ Le paramètre cause permet le chaînage des interruptions (nouveauté de la 1.4) 216
    • Hiérarchie des Exceptions (6) – La classe Throwable : détail (2) ■ Les méthodes d'instances les plus importantes ■ String toString() □ « traduit » l'objet en chaine de caractères ; en général le type de l'exception suivi du message de l'exception ■ String getMessage() □ Retourne le message de l'exception ■ Void printStackTrace() □ Affiche la pile de la « trace ». ■ Throwable initCause(Throwable) et Throwable getCause() pour le chaînage des exceptions. 217
    • Hiérarchie des Exceptions (7) – La classe Error ■ Elle définit des conditions d'erreur graves □ Problèmes liés au fonctionnement de la machine virtuelle, à l'environnement natif de la machine virtuelle □ Théoriquement, l'application n'a pas à traiter ces exceptions. 218
    • Hiérarchie des Exceptions (8) – La classe Exception ■ Elle définit des conditions d'erreur que les programmes sont susceptibles de rencontrer. □ Au lieu de laisser le programme se terminer, on traite l’exception et l'exécution du programme peut-être éventuellement poursuivie. ■ La classe Exception ne comporte pas de nouveaux constructeurs ou de nouvelles méthodes par rapport à Throwable dont elle hérite. □ C'est la super classe de toutes les Exceptions à gérer dans une application et des classes d'Exception utilisateurs ou métiers 219
    • Hiérarchie des Exceptions (9) try { int i= 5 / 0; On indique dans le catch que int j=i+10; l’on capture les exceptions for (int k=0;k<j;k++) de la classe Exception et de ses System.out.println(k); sous-classes. Donc toutes les } exceptions seront capturées catch (Exception e) { System.out.println(quot; Exception:quot;+e); } // suite du programme java.lang.Object java.lang.Throwable java.lang.Error java.lang.Exception java.lang.RuntimeException 220
    • Hiérarchie des Exceptions (10) – Attention ■ Lorsque l'on traite plusieurs types d'exceptions dans un bloc try, l'ordre des clauses catch à de l'importance □ Il faut impérativement mettre en premier les catch sur les exceptions les plus spécialisées et en fin les exceptions les plus générales. □ Ainsi si par exemple le premier catch se fait sur la classe Exception, quelle soit la nature exacte de l'exception, le programme entrera systématiquement dans ce catch ▪ Toute exception est construite à partir de la classe Exception 221
    • Hiérarchie des Exceptions (11) – La classe RuntimeException ■ Cette classe hérite de la classe Exception □ Elle doit être utilisée pour indiquer un problème de conception ou d'implémentation. □ Les RuntimeExceptions et les exceptions qui en héritent n'ont pas obligatoirement à être traitées. ▪ En effet elles représentent des problèmes qui seront plus généralement traités par l'environnement d'exécution. ▪ Néanmoins, si on le souhaite on peut intercepter dans un catch une RuntimeException avec un catch. ▫ Si on ne le fait pas, elle sera gérée par la machine Java qui affichera l'Exception au niveau du Shell 222
    • Hiérarchie des Exceptions (12) – Exemple de RuntimeException ■ ArithmeticException □ Par exemple lors d'une division par zéro ■ ClassCastException □ Lors d'une tentative de transtypage impossible ■ IndexOutOfBoundsException □ Pour les tableaux, accès à une cellule au-delà de ses limites ■ NullPointerException □ Lorsque l'on cherche à accèder à un membre d'un objet qui n'a pas encore été créé ■ SecurityException □ Lorsqu'on effectue une opération en violation avec la politique de sécurité 223
    • Hiérarchie des Exceptions (13) – Exercice ■ Implémenter une classe TableauObjets qui représente une collection d'objets □ Cette classe comportera un attribut tableau de 100 « Object » □ Elle possède une méthode recupereObjet(int index) ▪ qui renvoie l'objet en position « index ». ▪ Si « index » correspond à une valeur dépassant les limites du tableau, recupereObjet renvoie la valeur null. 224
    • Manipulation des exceptions (1) – Le programmeur peut lever ses propres exceptions ■ utilisation du mot réservé throw. – throw prend en paramètre un objet instance de Throwable ou d'une de ses sous-classes. ■ les objets exception sont le plus souvent alloués dans l'instruction même qui assure leur lancement. throw new MonException(quot;Mon exception s'est produite !!!quot;); 225
    • Manipulation des exceptions (2) – Leprogrammeur peut définir des méthodes levant des exceptions ■ parce qu'il ne veut pas traiter une exception générée dans la méthode ; il l'a fait alors « rmeonter » ■ parce que il a définit ses propres exceptions correspondant aux besoins de son application (« exceptions métiers ») ■ Dans tous les cas utilisation du mot réservé throws dans la déclaration de la méthode dans laquelle l'exception est susceptible de se manifester. □ La classe de l'exception indiquée peut être une super-classe de l'exception effectivement générée. □ Une même méthode peut quot;laisser remonterquot; plusieurs types d'exceptions (séparés par des ,). 226
    • Manipulation des exceptions (3) public void uneMethode() throws IOException { // ne traite pas l'exception IOException // mais est susceptible de la générer } public void debit(double montant) throws SoldeInsuffisantException { if (montant > this.solde) throw new SoldeInsuffisantException(quot;Compte non suffisament pourvuquot;); else this.solde = this.solde - montant; } public class SoldeInsuffisantException extends Exception { public SoldeInsuffisantException (String message) { super(message); } } 227
    • Manipulation des exceptions (4) – Intérêt ■ Les programmeurs qui utilisent une méthode connaissent ainsi les exceptions qu'elle peut lever. – Attention ■ Une méthode doit traiter ou quot;laisser remonterquot; toutes les exceptions qui peuvent être générées dans les méthodes qu'elle appelle (et ceci récursivement). public calcul() throws Exception Ici, on choisit de laisser remonter { les exceptions : la méthode int i= 5 / 0; qui appellera calcul() sera tenue int j=i+10; de traiter les Exception ou elle for (int k=0;k<j;k++) aussi indiquer qu’elle les fait System.out.println(k); remonter. } 228
    • Manipulation des exceptions (5) – Les exceptions métiers ■ i.e les exceptions que le programmeur définit par rapport aux besoins particuliers du domaine pour lequel il réalise son application □ Business exception en anglais ■ Elles héritent de la classe Exception □ Elles doivent redéfinir au moins le constructeur qui prend un message en argument □ On redéfinit également généralement getMessage() et toString □ On peut bien sûr ajouter des propriétés (statiques ou dynamiques) propres à cette exception métier ■ Il est possible de définir des exceptions en sous classant RuntimeException 229
    • Chainage des exceptions – Stratégie de gestion des exceptions ■ En cas de problème dans le try, les codes des catch doivent remettre le système dans son état initial ■ Remontées des exceptions □ Les exceptions de « bas niveau » sont renvoyées sous la forme d'exceptions de plus « haut niveau » (éventuellement) ▪ Cela permet de cacher l'implémentation de de bas niveau, qui est susceptible de changer, sans pour autant remettre en question les traitements de haut niveau 230
    • Cause d'une exception – Support de la cause d'une exception depuis Java 1.4 ■ 2 nouveaux constructeurs pour Throwable □ Throwable(Throwable cause); □ Throwable(String message, Throwable cause); ■ Une nouvelle méthode □ Throwable getCause(); ▪ Permet, à la réception d'une exception de récupérer son Exception cause. Si elle n'existe pas , la méthode rtourne null. 231
    • Les applets
    • Présentation (1) – Une applet Java est une « mini-application » qui s'exécute dans l’environnement d’un navigateur Web. – L'exécution des applets se fait sur la machine cliente. ■ Avantages : □ plus rapide pour le client, □ moins coûteux pour le serveur. – Il faut que le navigateur intégre une JVM – On parle parfois « d'appliquette » en Français 233
    • Présentation (2) – Une applet n'est pas lancée directement par l'intermédiaire d'une commande, comme le serait un programme quot;usuelquot;. ■ Une applet est lancée par l'intermédiaire d'un fichier HTML indiquant au navigateur l'applet à exécuter. ■ Lors de la lecture de la page HTML par le navigateur, en local ou grâce à son URL, l'applet est lancée. – Une applet est essentiellement une application « graphique » 234
    • Conteneurs et composants (1) – Une interface graphique en Java est un assemblage de conteneurs (Container) et de composants (Component). – Un composant est une partie quot;visiblequot; de l'interface utilisateur Java. ■ C’est une sous-classes de la classe abstraite java.awt.Component. ■ Exemple : les boutons, les zones de textes ou de dessin, etc. – Un conteneur est un espace dans lequel on peut positionner plusieurs composants. ■ Sous-classe de la classe java.awt.Container ■ La classe Container est elle-même une sous-classe de la classe Component □ Par exemple les fenêtres, les panels, les applets, etc. 235
    • Conteneurs et composants (2) Object Hiérarchie d’héritage Button (from la ng) des principaux éléments des interfaces graphiques en Java (limité ici aux classe de l'AWT) Canvas Component Checkbox Container Choice Label Panel Window Scrollbar List Dialog Frame Applet TextComponent (from applet) FileDialog TextArea TextField 236
    • Conteneurs et composants (3) – Les deux conteneurs « graphiques » les plus courants en Java sont le Frame et le Panel. ■ La classe java.applet.Applet hérite de la classe java.awt.Panel ■ La classe javax.swing.JApplet hérite de la classe java.applet.Applet □ Elle implémente quelques méthodes supplémentaires □ Elle peut-être vue comme une amélioration de la classe Applet, un peu comme les composants Swing peuvent-être vus comme une amélioration des composants de l'AWT ▪ L'amélioration doit être considéré en terme de rendu et de fonctionnalités, pas nécessairement en terme de performance ▪ Tout ce qui est valable pour une Applet et valable pour une Japplet (mais l'inverse n'est pas vrai !) 237
    • Conteneurs et composants (4) – Un Panel n'a pas une apparence propre et ne peut pas être utilisé comme fenêtre autonome. ■ Un Panel est doté d'un FlowLayout par défaut. □ Ce FlowLayout est un « LayoutManager », i.e. un gestionnaire de disposition □ Nous verrons tout cela plus en détail dans le chapitre suivant, traitant des interfaces graphiques. 238
    • Conteneurs et composants (5) – Onajoute un composant dans un conteneur, avec la méthode add() : Panel p = new Panel(); Button b = new Button(); p.add(b); – Demanière similaire, un composant est retirer de son conteneur par la méthode remove() : p.remove(b); – Un composant a (notamment) : ■ une taille préférée que l’on obtient avec getPreferredSize() ■ une taille minimum que l’on obtient avec getMinimunSize() ■ une taille maximum que l’on obtient avec getMaximunSize() 239
    • Utilisation d’une applet (1) – HTML dispose d'un quot;tagquot; <applet> </applet> destiné à intégrer des applets dans une page web. ■ Exemple : <applet code=quot;HelloWorld.classquot; width=quot;100quot; height=quot;100quot;></applet> ■ Si Java n'est pas supporté, le tag <applet> est ignoré. Sinon, c'est le code HTML quot;régulierquot; qui est entre <applet> et </applet> qui est ignoré. 240
    • Utilisation d’une applet (2) Nom du fichier <applet code = quot;Fichier.classquot; width = quot;pixelsquot; height = quot;pixelsquot; compilé (bytecode) [codebase = quot;codebase URLquot;] correspondant au [alt = quot;alternateTextquot;] programme de mon [name = quot;appletInstanceNamequot;] applet [align = quot;alignementquot;] [vspace = quot;pixelsquot;] [hspace = quot;pixelsquot;]> [<param name = quot;appletAttribute1quot; value = quot;valuequot;>] [<param name = quot;appletAttribute2quot; value = quot;valuequot;>] ... [alternateHTML] </applet> Largeur et hauteur réservé pour mon applet Java dans la page HTML 241
    • Utilisation d’une applet (3) – Description : ■ code : nom du fichier contenant l'applet compilée. ■ width et height : largeur et la hauteur initiales de la zone d'affichage de l'applet. ■ codebase : URL de base de l'applet. Par défaut, c'est l'URL du document HTML lu. ■ alt : texte à afficher si le navigateur comprend le paramètre applet mais ne réussit pas à exécuter les applets Java. ■ name : nom pour l'instance de l'applet. ■ align : alignement de l'applet (mot-clé left, top, middle, etc.) ■ vspace et hspace : espace au-dessus et en dessous (vspace) et de chaque côté de l'applet (hspace). 242
    • Utilisation d’une applet (4) – Une applet est une classe Java : ■ sous-classe java.applet.Applet ou de javax.swing.JApplet ■ Publique ■ Stockée dans un fichier de même nom que la classe suivi de l'extension .java import java.awt.*; <HTML> import java.applet.*; <HEAD> public class EssaiApplet extends Applet </HEAD> { <BODY BGCOLOR=quot;000000quot;> public void init() <CENTER> {} <APPLET public void paint(Graphics g) code= quot;EssaiApplet.classquot; { width= quot;500quot; height= quot;300quot;> g.drawString(quot;Bonjourquot;, 50, 60 ); </APPLET></CENTER> }} </BODY></HTML> 243
    • Squelette d'une applet public class MonApplet extends Applet { public void init () {...} public void start () {...} public void stop () {...} public void destroy () {...} public void paint() {...} } 244
    • méthodes d’une applet – Dans une application Java, l'exécution du programme commence par l'exécution de la méthode main – Dans le cas d'une applet, après le déclenchement de son constructeur par défaut, des méthodes prédéfinies se déclenchent : – init() – start() – paint() – stop() – destroy() 245
    • init – Cette méthode est appelée une seule fois après l'instanciation de l'applet pour effectuer : ■ les initialisations, ■ l'analyse des paramètres, ■ la construction de l'interface utilisateur, ■ le chargement des ressources. – C'est habituellement le rôle du constructeur. ■ Pour une applet, le constructeur est appelé avant que l'applet ait accès à certaines ressources, comme les informations relatives à l'environnement. ■ Une applet ne fournit donc généralement pas de constructeur autre que celui par défaut de la classe Applet. 246
    • start – Cetteméthode est appelée à chaque fois que l'applet devient visible. ■ lorsque l'applet est affichée pour la première fois, ■ lorsque l'applet apparaît lors du défilement d'une fenêtre, ■ lorsque le navigateur est restauré après avoir été iconisé ■ lorsque le navigateur revient dans la page contenant l'applet après être passé dans une autre URL. – La méthode start() indique à l'applet qu'elle est active. ■ L'applet peut donc utiliser cette méthode pour démarrer une animation ou jouer des sons. 247
    • stop – Cetteméthode est appelée lorsque l'applet devient invisible. Cette situation se produit : ■ lorsque le navigateur est icônisé, ■ lorsque l'applet est déplacée à l'extérieur de l'écran, ■ lorsque le navigateur change de page. – Laméthode stop() est utilisée pour indiquer à l'applet qu'elle doit se mettre en veille. ■ L'applet peut utiliser cette méthode pour arrêter une animation ou un son. – Les méthodes start() et stop() forment une paire. ■ start() peut servir à déclencher un comportement et stop() à arrêter ce comportement. 248
    • destroy – Cetteméthode est appelée juste avant que l'applet ne soit détruite. ■ En ce sens, cela correspond un peu la méthode finalize() pour les objets. 249
    • Dessiner dans une applet (1) – Les applets sont essentiellement graphiques par nature. ■ Il est possible de dessiner sur l'affichage d'une applet grâce à la méthode paint() ■ La méthode paint() est appelée par le navigateur chaque fois que l'affichage a besoin d'être régénéré, par exemple, lorsque la fenêtre du navigateur est affichée après avoir été iconisée. ■ L'affichage est contrôlé par l'environnement et non par le programme. Il s'effectue donc de manière asynchrone. ■ On peut dessiner directement dans le « panel » de l'applet 250
    • Dessiner dans une applet (2) – Laméthode paint() prend en argument une instance java.awt.Graphics : le contexte graphique de l'applet. ■ Cela correspond à la zone de l'écran que l'applet peut utiliser pour dessiner ou écrire du texte. import java.awt. *; import.java.applet.*; public class HelloWorld extends Applet { public void paint (Graphics g) { g.drawString (quot;Hello World!quot;, 25, 25); } } Coordonnées de la base du texte (baseline) 251
    • Dessiner dans une applet (3) – La classe Applet fait partie du paquetage awt. ■ En particulier, Applet est une sous-classe de Component. – La mise à jour de l'affichage d'une applet ■ elle est effectuée de façon asynchrone par un thread qui peut être appelé pour gérer deux situations liées à la mise à jour de l'affichage □ L'exposition : une partie de l'affichage a été endommagée et doit être remplacée. □ L'affichage d'un nouveau contenu avec suppression de l'ancienne image dans un premier temps. 252
    • Dessiner dans une applet (4) – Letraitement de l'exposition est automatique et déclenche la méthode paint(). ■ Une fonction de la classe Graphics appelée clipRect() sert à limiter l'affichage à la zone endommagée. 253
    • Paramétrer une applet (1) – Il peut être utile d'écrire une applet qui prenne des paramètres. ■ nom des sons à jouer, nom des images à afficher, etc. – Ainsi, la même applet pourra être réutilisée d'un contexte à un autre. – Les paramètres de lancement d'une applet paramétrée sont fixés par le fichier HTML qui lance l'applet. 254
    • Paramétrer une applet (2) import java.applet.*; import java.awt.*; public class MonAppletParam extends Applet { String leMessage; public void init() {leMessage = getParameter (quot;messagequot;);} public void paint (Graphics gc) {gc.drawString (leMessage, 125, 95);} } <applet code=MonAppletParam.class width=300 heigth=200> <param name=quot;messagequot; value=quot;Hello World !quot;> </applet> nom du paramètre, repris comme valeur du paramètre argument du getParameter() 255
    • Accès aux ressources (1) – La classe Applet définit les méthodes suivantes : ■ public URL getDocumentBase() : retourne l'URL de base du document où se trouve l'applet. ■ public URL getCodeBase() : retourne l'URL du fichier de la classe applet. ■ Ces méthodes peuvent être utilisées par l'applet pour construire des URL relatives à partir desquelles elle peut charger d'autres ressources comme des données, des images ou des sons. □ Remarque : Pour des raisons de sécurité, on ne peut que descendre dans les arborescences de fichiers (jamais remonter quot;plus hautquot; que l'adresse de la page servie). 256
    • Accès aux ressources (2) – La classe Applet définit les méthodes suivantes (suite) : ■ Méthode getImage(URL url [, String name]) : permet de récupérer une image ■ Méthode getAudioClip(URL url [, String name]) : permet de récupérer un son ■ Remarque : URL est une classe du package java.net 257
    • Accès aux ressources (3) // Extension de HelloWorld pour afficher une image // Suppose l'existence de quot;Duke1.gifquot; import.java.awt.*; import.java.applet.Applet; public class AfficheImage extends Applet { Image duke; public void init () { duke = getImage (getDocumentBase (), quot;Duke1.gifquot;); } public void paint (Graphics g) { g.drawImage (duke, 25, 25, this); } } 258
    • Accès aux ressources (4) – Lesarguments utilisés avec la méthode drawImage () sont : ■ L'objet Image à dessiner, ■ L'abscisse, ■ L'ordonnée, ■ L'observateur d'image. □ Un observateur d'image correspond à la classe qui doit être référencée, ici l’applet elle-même, d’où le this. 259
    • Accès aux ressources (5) – Laméthode getImage() ne fait que créer une référence sur l'image à charger. ■ L'image est chargée par drawImage(). – Lechemin de l'image est indiqué relativement à la valeur retournée par getDocumentBase(). 260
    • Accès aux ressources (6) – La façon la plus simple d'écouter un clip audio consiste à utiliser la méthode d'applet play() : ■ play (URL soundDirectory, String soundfile); ■ ou plus simplement : play (URL soundURL); ■ Si le fichier son est situé dans le même répertoire que le fichier HTML, on peut utiliser getDocumentBase() : □ play (getDocumentBase(), quot;bark.auquot;); 261
    • Accès aux ressources (7) // Extension de HelloWorld pour restituer un son audio // Suppose l'existence du fichier quot;sounds/cuckoo.auquot; import java.awt.Graphics; import java.applet.Applet ; public class TestAudio extends Applet { public void paint (Graphics g) { g.drawString (quot;Audio Testquot;, 25, 25); play (getDocumentBase(), quot;sounds/cuckoo.auquot;); } } 262
    • Accès aux ressources (7) – Chargement d'un clip audio AudioClip sound; //AudioClip est une interface du package java.applet sound = getAudioClip(getDocumentBase(),quot;bark.auquot;); – Exécution d'un clip audio ■ Pour jouer le clip audio chargé : sound.play (); ■ Pour démarrer l'écoute du clip et l'écouter en boucle : sound.loop(); – Arrêt d'un clip audio ■ Pour arrêter un clip audio en cours d'écoute : sound.stop (); 263
    • Accès aux ressources (8) // Extension de HelloWorld pour générer une boucle d'une // piste audio - Suppose l'existence de quot;sounds/cuckoo.auquot; import java.awt.Graphics; import java.applet.*; public class SonEnBoucle extends Applet { AudioClip sound; public void init () { sound =getAudioClip(getDocumentBase(),quot;sounds/cuckoo.auquot;); } public void paint (Graphics g) { g.drawString (quot;Audio Testquot;, 25, 25); } public void start () {sound.loop (); } public void stop () {sound.stop (); } } 264
    • Interface graphique et dessin avec la plateforme Java
    • Préambule – Ce cours constitue une introduction à la programmation des IHM graphiques en Java – Des compléments d'informations pourront être trouvés sur le site de Sun, notamment sur leur tutoriaux ■ Swing □ http://java.sun.com/docs/books/tutorial/uiswing/index.html ■ AWT □ http://java.sun.com/docs/books/tutorial/information/download.html#O LDui 266
    • Conteneurs et composants (1) – Une GUI en Java est un assemblage de conteneurs et de composants ■ Conteneurs : java.awt.Container et javax.swing.JComponent ■ Composants : java.awt.Component et javax.swing.JComponent – Un composant est une partie quot;visiblequot; de l'interface graphique. ■ En général une sous-classe de Component (AWT) ou de JComponent (Swing) ■ Exemples : boutons, zones de textes ou de dessin, etc. – Un conteneur est un composants dans lequel on peut positionner plusieurs autres composants. ■ En général une sous-classe de Container (AWT) ou de JComponent (Swing) ■ La classe Container est elle-même une sous-classe de la classe Component ■ Exemples : fenêtres, applets, panels, etc. 267
    • Conteneurs et composants (2) La hiérarchie (simplifiée) des classes relatives aux GUI en Java Voir l'image 268
    • Conteneurs et composants (3) – Les deux conteneurs les plus courants sont le Frame/JFrame et le Panel/JPanel. – Un Frame/JFrame représente une fenêtre de haut niveau avec un titre, une bordure et des angles de redimensionnement. ■ Un Frame/JFrame est doté d'un BorderLayout par défaut. ■ La plupart des applications utilisent au moins une fenêtre comme point de départ de leur interface graphique. 269
    • Conteneurs et composants (4) – UnPanel/JPanel n'a pas une apparence propre et ne peut pas être utilisé comme fenêtre autonome. ■ Un Panel/JPanel est doté d'un FlowLayout par défaut. ■ Les Panel/JPanel sont créés et ajoutés aux autres conteneurs de la même façon que les composants tels que les boutons. □ Les Panel/JPanel peuvent ensuite redéfinir une présentation qui leur soit propre pour contenir eux-mêmes d'autres composants. 270
    • Conteneurs et composants (5) – Onajoute un composant dans un conteneur, avec la méthode add() : Panel p = new Panel(); Button b = new Button(); p.add(b); – Demanière similaire, un composant est retirer de son conteneur par la méthode remove() : p.remove(b); – Un composant a (notamment) : ■ une taille préférée que l’on obtient avec getPreferredSize() ■ une taille minimum que l’on obtient avec getMinimunSize() ■ une taille maximum que l’on obtient avec getMaximunSize() 271
    • Conteneurs et composants (6) Création d’une fenêtre (un objet de la classe Frame) avec un titre Création du bouton import java.awt.*; ayant pour label « clic» import java.awt.event.*; import javax.swing.*; Ajout du bouton au centre public class ExempleSimpleGUI de la fenêtre { public static void main(String[] args) { Appel à un objet externe Frame f =new Frame(quot;Une première fenêtre AWTquot;); pour gérer les Button b= new Button(quot;clickquot;); événements fenêtre f.add(BorderLayout.CENTER,b); f.addWindowListener(new Terminator()); f.pack(); f.setVisible(true); On demande à la fenêtre de choisir la taille minimum JFrame jf = new JFrame(quot;Une première fenêtre Swingquot;); avec pack() et de se rendre JButton jb = new JButton(quot;clickquot;); visible avec setVisible(true) jf.getContentPane().add(BorderLayout.CENTER,jb); jf.addWindowListener(new Terminator()); jf.pack(); jf.setVisible(true); Une JFrame possède un } « panel interne » auquel on } peut accéder avec getContentPane() 272
    • Conteneurs et composants (7) import java.awt.*; import java.awt.event.*; import javax.swing.*; public class SimpleGuiSwing extends JFrame { private JButton b; public SimpleGuiSwing() { super(quot;Ma première fenêtrequot;); b= new JButton(quot;Clicker Moi!quot;); this.getContentPane().add(BorderLayout.CENTER,b); this.addWindowListener(new Terminator()); this.pack(); this.setVisible(true); } } 273
    • Gestionnaire de présentation (1) –A chaque conteneur est associé un gestionnaire de présentation (layout manager) – Le gestionnaire de présentation gère le positionnement et le (re)dimensionnement des composants d’un conteneur. – Le ré-agencement des composants dans un conteneur a lieu lors de : ■ la modification de sa taille, ■ le changement de la taille ou le déplacement d'un des composants. ■ l'ajout, l'affichage, la suppression ou le masquage d'un composant. 274
    • Gestionnaire de présentation (2) – Lesprincipaux gestionnaire de présentation de l'AWT et de Swing sont : – FlowLayout – BorderLayout – GridLayout – CardLayout – GridBagLayout – On trouve également (avec Swing uniquement) – BoxLayout – SpringLayout 275
    • Gestionnaire de présentation (3) – Toutconteneur possède un gestionnaire de présentation par défaut. ■ Tout instance de Container référence une instance de LayoutManager. ■ Il est possible d'en changer grâce à la méthode setLayout(). – Les gestionnaires de présentation par défaut sont : ■ Le BorderLayout pour Window et ses descendants (Frame, Dialog, etc.) ■ Le FlowLayout pour Panel et ses descendants (Applet, etc.) 276
    • Gestionnaire de présentation (4) – Remarque ■ Une fois installé, un gestionnaire fonctionne quot;tout seulquot; en interagissant avec le conteneur. ■ Il est donc généralement inutile de garder une référence sur un gestionnaire de présentation □ d’où les setLayout(new FlowLayout() ); par exemple □ exception pour CardLayout et GridBagLayout 277
    • Gestionnaire de présentation (5) import java.awt.*; public class ExempleIHM extends Frame { private Button b1; private Button b2; public static void main (String args []) { ExempleIHM that = new ExempleIHM (); that.pack (); //change taille du Frame pour englober boutons that.setVisible (true) ; } public ExempleIHM() { super(quot;Notre exemple d'IHMquot;);//lance le constructeur de la super classe setLayout (new FlowLayout ());//nouveau gestionnaire pres. b1 = new Button (quot;Appuyerquot;); b2 = new Button (quot;Ne pas appuyerquot;); add (b1); add (b2);}} 278
    • Gestionnaire de présentation (6) import java.awt.*; public class AutreIHM { public Frame f; private Button b1, b2; public static void main (String args []) { AutreIHM that = new AutreIHM (); that.f.pack(); that.f.setVisible (true) ; } public AutreIHM() { f = new Frame(quot;Un exemple d'IHMquot;); f.setLayout(new FlowLayout()); b1 = new Button (quot;Appuyerquot;); b2 = new Button (quot;Ne pas appuyerquot;); f.add(b1); f.add(b2); } } 279
    • FlowLayout (1) – LeFlowLayout est le plus simple des managers de l'AWT – Gestionnaire de présentation utilisé par défaut dans les Panel si aucun LayoutManager n'est spécifié. – Un FlowLayout peut spécifier : ■ une justification à gauche, à droite ou centrée, ■ un espacement horizontal ou vertical entre deux composants. ■ Par défaut, les composants sont centrés à l'intérieur de la zone qui leur est allouée. 280
    • FlowLayout (2) – Lastratégie de disposition du FlowLayout est la suivante : ■ Respecter la taille préférée de tous les composants contenus. ■ Disposer autant de composants que l'on peut en faire tenir horizontalement à l'intérieur de l'objet Container. ■ Commencer une nouvelle rangée de composants si on ne peut pas les faire tenir sur une seule rangée. ■ Si tous les composants ne peuvent pas tenir dans l'objet Container, ce n'est pas géré (c'est-à-dire que les composants peuvent ne pas apparaître). 281
    • FlowLayout (3) OK Ouvrir Redimensionnement Ouvrir Fermer OK Fermer plus visible OK Ouvrir Redimensionnement OK Ouvrir Fermer Fermer 282
    • FlowLayout (4) Redimensionnement Redimensionnement 283
    • FlowLayout (5) Redimensionnement Redimensionnement 284
    • FlowLayout (6) – Ne pas utiliser un objet Container géré par un FlowLayout à l'intérieur d'un container dont le gestionnaire de présentation respecte la hauteur préférée. – Le FlowLayout cache réellement et effectivement les composants qui ne rentrent pas dans le cadre. – Le FlowLayout n'a d'intérêt que quand il y a peu de composants. 285
    • FlowLayout (7) – L'équivalent vertical du FlowLayout n'existe pas, il faut ou l'écrire soit même, ou utiliser le gestionnaire de disposition BoxLayout de javax.swing – Cacul de la taille préférée d'un objet Container utilisant un FlowLayout : ■ largeur préférée = Somme de la largeur de tous les composants ■ hauteur préférée = La plus grande hauteur préférée de ses composants 286
    • FlowLayout (8) – La présentation FlowLayout positionne les composants ligne par ligne. ■ Chaque fois qu'une ligne est remplie, une nouvelle ligne est commencée. – Legestionnaire FlowLayout n'impose pas la taille des composants mais leur permet d'avoir la taille qu'ils préfèrent. 287
    • BorderLayout (1) – BorderLayout divise son espace de travail en cinq zones géographiques : North, South, East, West et Center. – Les composants sont ajoutés par nom à ces zones (un seul composant par zone). ■ Exemple add(quot;Northquot;, new Button(quot;Le bouton nord !quot;)); ■ Si une des zones de bordure ne contient rien, sa taille est 0. 288
    • BorderLayout (2) – Division de l’espace avec le BorderLayout NO RTH W EST CENTER EAST SO UTH 289
    • BorderLayout (3) import java.awt.*; public class AppliBorderLayout extends Frame { private Button b1,b2,b3,b4, b5; public static void main (String args []) { AppliBorderLayout that = new AppliBorderLayout(); that.pack (); that.setVisible(true) ; } public AppliBorderLayout() { super(quot;AppliBorderLayoutquot;); setLayout(new BorderLayout()); b1 = new Button (quot;NORTHquot;); b2 = new Button (quot;SOUTHquot;); b3 = new Button (quot;EASTquot;); b4 = new Button (quot;WESTquot;); b5 = new Button (quot;CENTERquot;); this.add(b1, BorderLayout.NORTH); this.add(quot;Southquot;,b2); this.add(b3, BorderLayout.EAST); this.add(b4, BorderLayout.WEST); this.add(b5, BorderLayout.CENTER); }} 290
    • BorderLayout (4) – Stratégie de disposition du BorderLayout ■ S'il y a un composant dans la partie placée dans la partie NORTH, il récupère sa taille préférée, respecte sa hauteur préférée si possible et fixe sa largeur à la totalité de la largeur disponible de l'objet Container. ■ S'il y a un composant dans la partie placée dans la partie SOUTH, il fait pareil que dans le cas de la partie NORTH. 291
    • BorderLayout (5) – Stratégie de disposition du BorderLayout (suite) ■ S'il y a un composant dans la partie placée dans la partie EAST, il récupère sa taille préférée, respecte sa largeur préférée si possible et fixe sa hauteur à la totalité de la hauteur encore disponible. ■ S'il y a un composant dans la partie placée dans la partie WEST, il fait pareil que dans le cas de la partie EAST. ■ S'il y a un composant dans la partie CENTER, il lui donne la place qui reste, s'il en reste encore. 292
    • BorderLayout (6) – Lorsdu redimensionnement, le composant est lui-même redimensionné en fonction de la taille de la zone, c-à-d : ■ les zones nord et sud sont éventuellement élargies mais pas allongées. ■ les zones est et ouest sont éventuellement allongées mais pas élargies, ■ la zone centrale est étirée dans les deux sens. 293
    • BorderLayout (7) N N Redimensionnement O C E O C E S S 294
    • BorderLayout (8) Redimensionnement Redimensionnement 295
    • BorderLayout (9) – Calcul de la taille préférée d’un objet Container utilisant un BorderLayout : ■ largeur préférée = La plus grande valeur parmi : □ largeur préférée du « NORTH » □ largeur préférée du « SOUTH » □ (largeur préférée du « WEST ») + (largeur préféré du « CENTER ») + (largeur préférée du « EAST ») + (quot;Horizontal Gapquot;) 296
    • BorderLayout (10) – Calcul de la taille préférée d’un objet Container utilisant un BorderLayout (suite): ■ hauteur préférée = (quot;Vertical Gapquot;) + (hauteur préférée du « NORTH ») + (hauteur préférée du « SOUTH ») + MaximumEntre( hauteur préférée du « WEST », la hauteur préférée de « CENTER », la hauteur préférée du « EAST ») 297
    • GridLayout (1) – Le GridLayout dispose les composants dans une grille. ■ Découpage de la zone d'affichage en lignes et en colonnes qui définissent des cellules de dimensions égales. ■ Chaque composant à la même taille □ quand ils sont ajoutés dans les cellules le remplissage s ’effectue de gauche à droite et de haut en bas. ■ Les 2 paramètres importants sont les rangées et les colonnes. □ Seul l'un des deux est utilisé, l'autre est calculé en fonction du premier et du nombre de composants. ■ Construction d'un GridLayout : new GridLayout(3,2); nombre de lignes nombre de colonnes 298
    • GridLayout (2) – La taille préférée d'un GridLayout se calcule en prenant la plus grande hauteur et la plus grande largeur dans les tailles préférées des composants. Il met tous les composants à cette hauteur et à cette largeur. Donc la taille préférée vaut : ■ hauteur préférée = ( plus grande taille préférée des composants * nbre de colonnes ) + ( quot;Horizontal Gapquot; * (nbre de colonnes + 1 )) ■ largeur préféré = ( plus grande largeur préférée des composants * nbre de rangées ) + ( quot;Vertical Gapquot; * (nbre de rangées + 1 )) 299
    • GridLayout (3) import java.awt.*; public class AppliGridLayout extends Frame { public static void main(String args[]) { AppliGridLayout appli = new AppliGridLayout(); } public AppliGridLayout() { super(quot;AppliGridLayoutquot;); setLayout(new GridLayout(3,2)); for (int i = 1; i < 7; i++) add(new Button(Integer.toString(i))); this.pack(); this.show(); } } 300
    • GridLayout (4) – Lorsd’un redimensionnement les composants changent tous de taille mais leurs positions relatives ne changent pas. 1 2 1 2 Redimensionnement 3 4 4 3 5 6 5 6 301
    • GridLayout (5) Redimensionnement 302
    • CardLayout (1) – Le CardLayout n'affiche qu'un composant à la fois : ■ les composants sont considérées comme empilées, à la façon d'un tas de cartes. ■ La taille préférée d'un Container utilisant un CardLayout sera la taille préférée du plus grand de ces composants. – La présentation CardLayout permet à plusieurs composants de partager le même espace d'affichage de telle sorte que seul l'un d'entre eux soit visible à la fois. 303
    • CardLayout (2) – Pour ajouter un composant à un conteneur utilisant un CardLayout il faut utiliser add(String cle, Component monComposant) – Voir l’exemple commenté AppliCardLayout.java Application « multifenêtrée » 304
    • GridBagLayout (1) – Legestionnaire GridBagLayout fournit des fonctions de présentation complexes ■ basées sur une grille dont les lignes et les colonnes sont de taille variables. ■ permet à des composants simples de prendre leur taille préférée au sein d'une cellule, au lieu de remplir toute la cellule. ■ permet aussi l'extension d'un même composant sur plusieurs cellules. – Le GridBagLayout est compliqué à gérer. ■ Dans la plupart des cas, il est possible d’éviter de l’utiliser en associant des objets Container utilisant des gestionnaires différents. 305
    • GridBagLayout (2) – Legestionnaire GridBagLayout est associé à un objet GridBagConstraints ■ l’objet GridBagConstraints définit des contraintes de positionnement, d’alignements, de taille, etc. d’un composant dans un conteneur géré par un GridBagLayout. ■ On associe chaque composant que l’on place dans le GridBagLayout avec un objet GridBagConstraints □ Un même objet GridBagConstraints peut-être associé à plusieurs composants. □ Comme nous le verrons rentrer construire les objets GridBagConstraints en spécifiant les différents paramètres est assez fastidieux... 306
    • GridBagConstraints (1) – Paramètres gridx, gridy, gridwidth, gridheight des GridBagConstraints ■ Ces 4 paramètres déterminent la position et la taille d’un composant dans la grille du GridBagLayout ■ gridx : N° de colonne du coin supérieur gauche du composant □ pour la cellule la plus à gauche gridx = 0 ■ gridy : N° de ligne du coin supérieur gauche du composant □ pour la cellule la plus en haut gridy = 0 ■ gridwidth : nombre de colonnes du composant en largeur ■ gridheight : nombre de colonnes du composant en hauteur 307
    • GridBagConstraints (2) – Paramètres weightx et weighty ■ ces 2 paramètres définissent des champs de poids pour chaque zone dans un GridBagLayout □ weightx indique comment l’espace disponible supplémentaire doit être utilisé horizontalement □ weighty comment l’espace disponible supplémentaire doit être utilisé verticalement □ si l’un de ces 2 paramètres est 0, la zone n’aura pas d’espace supplémentaire dans cette direction. 308
    • GridBagConstraints (3) – Paramètre fill ■ fill permet d’indiquer si un composant doit s’étirer et remplir toute une zone ou non. Il y a 4 valeurs (constantes) valides possibles pour ce paramètre □ GridBagConstraints.NONE : ne remplit pas toutes la zone □ GridBagConstraints.HORIZONTAL : la remplit horizontalement □ GridBagConstraints.VERTICAL : la remplit verticalement □ GridBagConstraints.BOTH : la remplit verticalement et horizontalement 309
    • GridBagConstraints (4) – Paramètre anchor ■ anchor permet d’indiquer la position que doit occuper un composant s ’il ne remplit pas toute la zone. Il y a 9 valeurs (constantes) valides possibles pour ce paramètre □ GridBagConstraints.CENTER □ GridBagConstraints.NORTH □ GridBagConstraints.NORTHEAST □ … etc. 310
    • GridBagConstraints (5) – Paramètres insets ■ insets permet de définir une zone vide autour du composant. ■ C’est lui même un objet ayant 4 attributs (left, top, right, bottom) que l’on affecte avec les valeurs d’espaces que l’on veut associer au composant. – Paramètres ipadx et ipady ■ ces 2 valeurs sont ajoutés aux largeur et hauteur minimale du composant, garantissant que l’on ne puisse le réduire jusqu’à sa taille normale. 311
    • GridBagConstraints (6) – Lesparamètres gridx et gridy peuvent se voir affecter une valeur spéciale ■ GridBagConstraint.RELATIVE : en théorie elle indique au GridBagLayout de placer les éléments relativement les uns par rapport aux autres – Lesparamètres gridwidth et gridheight peuvent également se voir affecter une valeur spéciale ■ GridBagConstraint.REMAINDER : en théorie cette valeur indique que le composant s’étend jusqu’à la dernière ligne ou colonne. – Enpratique donne des résultats parfois étranges ou inattendus... 312
    • GridBagLayout (3) – Utilisation du GridBagLayout (1) ■ Esquissez la mise en forme de votre interface sur papier (c’est d’ailleurs valable quelque soit le gestionnaire de disposition que vous utilisez. ■ Essayer de trouver une grille de telle sorte que les petits composants soient chacun contenues dans une cellule et que les grands puissent en utiliser plusieurs. ■ Numéroter les lignes et les colonnes (en partant de 0) : cela permet de relever les valeurs pour gridx, gridy, gridwith et gridheight ■ Déterminer pour chacun de vos composants comment il doit remplir les cellules qu’il occupe (verticalement ou horizontalement ou les 2 ) et comment il doit être aligné : cela donne les valeurs pour fill et anchor 313
    • GridBagLayout (4) – Stratégie d’utilisation d’un GridBagLayout (2) ■ définir tous les poids à 100 par défaut. □ Si on souhaite néanmoins qu’une colonne ou qu’une ligne particulière reste toujours avec sa taille par défaut, il faut définir les valeurs weightx et weighty à 0 pour tous les composants de cette ligne ou colonne. ■ Attention la moindre contrainte erronée peut gâcher toute la mise en forme □ Il est donc très important d’une part de bien tester l’interface et d’autre part de bien vérifier tous les paramètres du GridBagConstraints. 314
    • GridBagLayout(5) Redimensionnement 315
    • Mise en forme complexe (1) super(quot;AppliComplexeLayoutquot;); setLayout(new BorderLayout()); Panel pnorth = new Panel(); pnorth.add(b1); pnorth.add(b2); pnorth.add(b3); pnorth.add(b4); this.add(pnorth,BorderLayout.NORTH); Panel pcenter = new Panel(); pcenter.setLayout(new GridLayout(2,2)); pcenter.add(gr1); pcenter.add(gr2); pcenter.add(gr3); pcenter.add(gr4); this.add(pcenter,BorderLayout.CENTER); Panel psouth = new Panel(); psouth.setLayout(new FlowLayout()); psouth.add(ch); psouth.add(tf); this.add(psouth, BorderLayout.SOUTH); 316
    • Mise en forme complexe (2) Comparaison avec une mise en forme avec le GridBagLayout Redimensionnememt Sans GridBagLayout Redimensionnememt Avec GridBagLayout 317
    • D’autres gestionnaires? – On peut imposer à un objet « container » de n’avoir pas de gestionnaire en fixant son LayoutManager à la valeur null – Frame f = new Frame(); f.setLayout(null); ■ A la charge alors du programmeur de positionner chacun des composants « manuellement » en indiquant leur position absolu dans le repère de la fenêtre. ■ Sauf dans des cas particuliers, c’est à éviter. – Ilest possible d’écrire ses propres LayoutManager… – D’autres gestionnaire existe avec Swing (BoxLayout)… ■ ils seront abordés un peu plus tard... 318
    • Récapitulatif (1) – FlowLayout ■ Flux : composants placés les uns derrière les autres – BorderLayout ■ Ecran découpé en 5 zones (« North », « West », « South », « East », « Center ») – GridLayout ■ Grille : une case par composant, chaque case de la même taille – CardLayout ■ « Onglets » : on affiche un élément à la fois – GridBagLayout ■ Grille complexe : plusieurs cases par composant 319
    • Récapitulatif (2) Component Par défaut, les « Container » disposent d'un gestionnaire de présentation. Ce gestionnaire dépend du type de conteneur. Container Certains conteneurs sont spécifiques et gèrent eux même leur présentation comme ScrollPane et FileDialog. Panel : FlowLayout Applet : BorderLayout ScrollPane : Spécifique Window : BorderLayout Dialog : BorderLayout FileDialog : Spécifique Frame : BorderLayout 320
    • Les événements graphiques (1) –Apartir de Java 1.1 le modèle d'événements est un modèle par délégation. ■ Les événements sont envoyés au composant, mais c'est à chaque composant d'enregistrer une routine de traitement d'événement (appelé écouteur) pour recevoir l'événement. ■ De cette façon, le traitement d'événement peut figurer dans une classe distincte du composant. Le traitement de l'événement est ainsi délégué à une classe séparée. 321
    • Les événements graphiques (2) – L'utilisateur effectue ■ une action au niveau de l'interface utilisateur (clic souris, sélection d'un item, etc) ■ alors un événement graphique est émis. – Lorsqu'un événement se produit ■ il est reçu par le composant avec lequel l'utilisateur interagit (par exemple un bouton, un curseur, un champ de texte, etc.). ■ Ce composant transmet cet événement à un autre objet, un écouteur qui possède une méthode pour traiter l’événement (on parle de traitement d’événement) □ cette méthode reçoit l’objet événement généré de façon à traiter l'interaction de l'utilisateur. 322
    • Les événements graphiques (3) – Lagestion des événements passe par l'utilisation d'objets quot;écouteur d'événementsquot; (les Listener) et d'objets sources d'événements. ■ Un objet écouteur est l'instance d'une classe implémentant l'interface XXXXListener. ■ Une source d'événements est un objet pouvant recenser des objets écouteurs et leur envoyer des objets événements. – Lorsqu'un événement se produit, ■ la source d'événements envoie un objet événement correspondant à tous ses écouteurs. ■ Les objets écouteurs utilisent alors l'information contenue dans l'objet événement pour déterminer leur réponse. 323
    • Les événements graphiques (3) – Au niveau du code, ■ pour enregistrer un écouteur MyListener auprès d'une source d'événement MySource, on va avoir quelque chose de la forme : MySource.addEvtListener(MyListener) ■ Voir l’exemple les sources TestButton.java et ButtonHandler. 324
    • Les événements graphiques (4) – Les écouteurs sont des interfaces – Don une même classe peut implémenter plusieurs interfaces écouteur. ■ Par exemple une classe héritant de Frame implémentera les interfaces MouseMotionListener (pour les déplacements souris) et MouseListener (pour les clics souris). – Chaque composant de l’AWT est conçu pour être la source d’un ou plusieurs types d'événements particuliers. ■ Cela se voit notamment grâce à la présence dans la classe de composant d'une méthode nommée addXXXListener(). 325
    • Les événements graphiques (5) – L’objetévénement envoyé aux écouteurs et passé en paramètres des fonctions correspondantes peut contenir des paramètres intéressants pour l'application. ■ Par exemple, getX() et getY() sur un MouseEvent retournent les coordonnées de la position du pointeur de la souris. ■ Une information généralement utile quelques soit le type d’événement est la source de cet événement que l’on obtient avec la méthode getSource(). 326
    • Les événements graphiques (6) import java.awt.*; import java.awt.event.*; import java.awt.event.*; import ButtonHandler; public class ButtonHandler class TestButton implements ActionListener { { public void actionPerformed (ActionEvent e) Frame f; Button b; { public TestButton() System.out.println (quot;Action occuredquot;) ; { }} super(); f = new Frame (quot;TestButtonquot;); b = new Button (quot;Press Mequot;); f.add (quot;Centerquot;, b) ; f.pack (); f.setVisible (true) ; b.addActionListener (new ButtonHandler ()); } public static void main(String args[]) { TestButton that = new TestButton(); }} 327
    • Les événements graphiques (7) 328
    • Catégories d'événements graphiques (1) – Plusieurs types d'événements sont définis dans le package java.awt.event. – Pour chaque catégorie d'événements, il existe une interface qui doit être définie par toute classe souhaitant recevoir cette catégorie événements. ■ Cette interface exige aussi qu'une ou plusieurs méthodes soient définies. ■ Ces méthodes sont appelées lorsque des événements particuliers surviennent. 329
    • Catégories d'événements graphiques (2) Catégorie Nom de l’interface Méthodes Action ActionListener actionPerformed (ActionEvent) Item ItemListener itemStateChanged (ItemEvent) Mouse MouseMotionListener mouseDragged (MouseEvent) mouseMoved (MouseEvent) Mouse MouseListener mousePressed (MouseEvent) mouseReleased (MouseEvent) mouseEntered (MouseEvent) (MouseEvent) mouseExited mouseClicked Key KeyListener keyPressed (KeyEvent) keyReleased (KeyEvent) keyTyped (KeyEvent) Focus FocusListener focusGained (FocusEvent) focusLost (FocusEvent) 330
    • Catégories d'événements graphiques (3) Adjustment AdjustmentListener adjustmentValueChanged (AdjustmentEvent) Component ComponentListener componentMoved (ComponentEvent) componentHiddent (ComponentEvent) componentResize (ComponentEvent) componentShown (ComponentEvent) Window WindowListener windowClosing ( WindowEvent) windowOpened ( WindowEvent) windowIconified ( WindowEvent windowDeiconified ( WindowEvent) windowClosed ( WindowEvent) windowActivated ( WindowEvent) windowDeactivated ( WindowEvent) Container ContainerListener componentAdded ( ContainerEvent) componentRemoved( ContainerEvent) Text TextListener textValueChanged ( TextEvent) 331
    • Catégories d'événements graphiques (4) – ActionListener ■ Action (clic) sur un bouton, retour chariot dans une zone de texte, « tic d’horloge » (Objet Timer) – WindowListener ■ Fermeture, iconisation, etc. des fenêtres – TextListener ■ Changement de valeur dans une zone de texte – ItemListener ■ Sélection d’un item dans une liste 332
    • Catégories d'événements graphiques (5) – MouseListener ■ Clic, enfoncement/relâchement des boutons de la souris, etc. – MouseMotionListener ■ Déplacement de la souris, drag&drop avec la souris, etc. – AdjustmentListener ■ Déplacement d'une échelle – ComponentListener ■ Savoir si un composant a été caché, affiché … – ContainerListener ■ Ajout d'un composant dans un Container 333
    • Catégories d'événements graphiques (6) – FocusListener ■ Pour savoir si un élément a le quot;focusquot; – KeyListener ■ Pour la gestion des événements clavier 334
    • Catégories d'événements graphiques (7) import java.awt.*; import java.awt.event.*; public class EssaiActionEvent1 extends Frame implements ActionListener Implémentation de { l'interface ActionListener public static void main(String args[]) {EssaiActionEvent1 f= new EssaiActionEvent1();} public EssaiActionEvent1() On enregistre l’écouteur { d’evt action auprès de super(quot;Utilisation d’un ActionEventquot;); l’objet source quot;bquot; Button b = new Button(quot;actionquot;); b.addActionListener(this); add(BorderLayout.CENTER,b);pack();show(); Lorsque l'on clique sur } le bouton dans public void actionPerformed( ActionEvent e ) l ’interface, le titre de la { fenêtre change setTitle(quot;bouton cliqué !quot;); }} 335
    • Catégories d'événements graphiques (8) public class EssaiActionEvent2 extends Frame implements ActionListener { private Button b1,b2; public static void main(String args[]) {EssaiActionEvent2 f= new EssaiActionEvent2();} public EssaiActionEvent2(){ Les 2 boutons ont le même super(quot;Utilisation d’un ActionEventquot;); écouteur (la fenêtre) b1 = new Button(quot;action1quot;); b2 = new Button(quot;action2quot;); b1.addActionListener(this); e.getSource()quot; renvoie b2.addActionListener(this); l'objet source de add(BorderLayout.CENTER,b1); l’événement. On effectue add(BorderLayout.SOUTH,b2); un test sur les boutons (on pack();show(); } compare les références) public void actionPerformed( ActionEvent e ) { if (e.getSource() == b1) setTitle(quot;action1 cliquéquot;); if (e.getSource() == b2) setTitle(quot;action2 cliquéquot;); }} 336
    • Catégories d'événements graphiques (9) import java.awt.*; import java.awt.event.*; public class WinEvt extends Frame implements WindowListener Implémenter cette { interface impose public static void main(String[] args) { l’implémentation de bcp WinEvt f= new WinEvt();} de méthode public WinEvt() { super(quot;Cette fenêtre se fermequot;); addWindowListener(this); La fenêtre est son pack();show();} propre écouteur public void windowOpened(WindowEvent e){} public void windowClosing(WindowEvent e) WindowClosing() est {System.exit(0);} appelé lorsque l'on public void windowClosed(WindowEvent e){} clique sur la croix de la public void windowIconified(WindowEvent e){} fenêtre public void windowDeiconified(WindowEvent e){} public void windowActivated(WindowEvent e){} quot;System.exit(0)quot; permet public void windowDeactivated(WindowEvent e){} } de quitter une application java 337
    • Les adapteurs (1) – Les classes « adapteur » permettent une mise en œuvre simple de l'écoute d'événements graphiques. ■ Ce sont des classes qui implémentent les écouteurs d'événements possédant le plus de méthodes, en définissant un corps vide pour chacune d'entre elles. ■ Plutôt que d'implémenter l'intégralité d'une interface dont une seule méthode est pertinente pour résoudre un problème donné, une alternative est de sous-classer l'adapteur approprié et de redéfinir juste les méthodes qui nous intéressent. □ Par exemple pour la gestion des événements fenêtres... 338
    • Les adapteurs (2) Solution en implémentant l’interface class Terminator implements WindowListener { public void windowClosing (WindowEvent e) {System.exit(0);} public void windowClosed (WindowEvent e) {} public void windowIconified (WindowEvent e) {} public void windowOpened (WindowEvent e) {} public void windowDeiconified (WindowEvent e) {} public void windowActivated (WindowEvent e) {} public void windowDeactivated (WindowEvent e) {} } Solution en utilisant un WindowAdapter class Terminator extends WindowAdapter { public void windowClosing (WindowEvent e) {System.exit(0);} } 339
    • Les adapteurs (3) – Enpratique, et notamment avec la classe WindowAdapter, on utilise très souvent une classe anonyme Frame f = new Frame(quot;Machinquot;) f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); 340
    • Les adapteurs (4) – Il existe 7 classes d'adapteurs (autant que d'interfaces d'écouteurs possédant plus d'une méthode) : – ComponentAdapter – ContainerAdapter – FocusAdapter – KeyAdapter – MouseAdapter – MouseMotionAdapter – WindowAdapter 341
    • Les composants graphiques (1) – Button – Canvas (zone de dessin) – Checkbox (case à cocher) – CheckboxGroup – Label – Choice (Sélecteur) – List – Scrollbar (barre de défilement) – TextField (zone de saisie d’1 ligne) – TextArea (zone de saisie multilignes) 342
    • Les composants graphiques (2) – Button ■ C'est un composant d'interface utilisateur de base de type quot;appuyer pour activerquot;. ■ Il peut être construit avec une étiquette de texte (un label) précisant son rôle à l'utilisateur. ■ Un objet de la classe Button est une source d’ActionEvent ■ Les écouteurs associés à des objets de la classe Button doivent implémenter interface ActionListener – Il n’y a qu’une méthode dans l’interface ActionListener, c ’est la méthode public void actionPerformed(ActionEvent e). Button b = new Button (quot;Samplequot;) ; add (b) ; b.addActionListener (...) ; 343
    • Les composants graphiques (3) – CheckBox ■ La case à cocher fournit un dispositif d'entrée quot;actif / inactifquot; accompagné d'une étiquette de texte. ■ La sélection ou la déselection est notifiée par un ItemEvent à un écouteur implémentant l’interface ItemListener. □ la méthode getStateChange() de ItemEvent retourne une constante : ItemEvent.DESELECTED ou ItemEvent.SELECTED. □ le méthode getItem() de ItemEvent renvoie la chaîne contenant l'étiquette de la case à cocher considérée. Checkbox one = new Checkbox(quot;Onequot;, false); add(one); one.addItemListener(...); 344
    • Les composants graphiques (4) – CheckboxGroup ■ On peut regrouper des cases à cocher dans un CheckboxGroup pour obtenir un comportement de type boutons radio □ On ne peut sélectionner qu’une seule case du groupe de cases à cocher en même temps. □ Sélectionner une case fera que toute autre case précédemment cochée sera désélectionnée CheckboxGroup cbg = new CheckboxGroup(); Checkbox one = new Checkbox(quot;Onequot;, cbg, false); ... add(one); ... 345
    • Les composants graphiques (5) – Choice ■ Ce composant propose une liste de choix. □ On ajoute des éléments dans l’objet Choice avec la méthode addItem(String nomItem). ▪ La chaîne passée en paramètre sera la chaîne visible dans la liste □ On récupère la chaîne de caractère correspondant à l’item actuellement sélectionné avec la méthode String getSelectedItem() □ Cet objet est source de ItemEvent, l’écouteur correspondant étant un ItemListener Choice c = new Choice(); c.addItem(quot;Firstquot;); c.addItem(quot;Secondquot;); ... c.addItemListener (...); 346
    • Les composants graphiques (6) – Label ■ Un Label affiche une seule ligne de texte (étiquette) non modifiable. ■ En général, les étiquettes ne traitent pas d'événements. Label l = new Label (quot;Bonjour !quot;); add(l); 347
    • Les composants graphiques (7) – List ■ Un objet de la classe List permet de présenter à l'utilisateur plusieurs options de texte parmi lesquelles il peut sélectionner un ou plusieurs éléments. ■ Source d’ActionEvent et d’ItemEvent ■ méthode String getSelectedItem() et String[] getSelectedItems() pour récupérer des items. List l =new List (4, false); l.add(quot;item1quot;); nombre d'items visibles sélections multiples possibles ou non. (ici 4 éléments seront Ici, avec la valeur false, non possible visible en même temps) 348
    • Les composants graphiques (8) – TextField ■ Le champ de texte est un dispositif d'entrée de texte sur une seule ligne. ■ Il est source d’ActionEvent ■ On peut définir un champ de texte comme étant éditable ou non. ■ Méthodes void setText(String text) et String getText() pour mettre ou retirer du texte dans le TextField TextField f = new TextField (quot;Une ligne seulement ...quot;, 30); add(f); Texte par défaut mis Nombre de caractères visibles dans le TextField dans le TextField 349
    • Les composants graphiques (9) – TextArea ■ La zone de texte est un dispositif d'entrée de texte multi-lignes, multi- colonnes avec éventuellement la présence ou non de « scrollbars » (barres de défilement) horizontal et/ou vertical. ■ Il peut être ou non éditable. ■ Méthode setText(), getText() et append() (pour ajouter du texte à la fin d ’un texte existant déjà dans le TextArea) TextArea t = new TextArea (quot;Hello !quot;, 4, 30,TextArea.SCROLLBARS_BOTH); add(t); Valeur constante Texte par défaut mis précisant la dans le TextArea présence ou Nombre de colonnes l’absence de Nombre de lignes (en nbre de caractères) « scrollbar » 350
    • Les composants graphiques (10) – Menu : ■ menu déroulant de base, qui peut être ajoutée à une barre de menus (MenuBar) ou à un autre menu. ■ Les éléments de ces menus sont □ des MenuItem ▪ ils sont rajoutés à un menu ▪ En règle générale, ils sont associés à un ActionListener. □ des CheckBoxMenuItem, ie. des éléments de menus à cocher ▪ ils permettent de proposer des sélections de type quot;activé / désactivé quot; dans un menu. 351
    • Les composants graphiques (11) – PopupMenu ■ des menus autonomes pouvant s'afficher instantanément sur un autre composant. □ Ces menus doivent être ajoutés à un composant parent (par exemple un Frame), grâce à la méthode add(...). □ Pour afficher un PopupMenu, il faut utiliser la méthode show(...). 352
    • Les composants graphiques (12) – Canvas ■ Il définit un espace vide □ Sa taille par défaut est zéro par zéro (Ne pas oublier de la modifier avec un setSize(...) ) et il n’a pas de couleur. ▪ Tip : pour forcer un canvas (ou tout autre composant) à avoir une certaine taille il faut redéfinir les méthodes getMinimumSize() et getPreferredSize(). ■ On peut capturer tous les événements dans un Canvas. □ Il peut donc être associé à de nombreux écouteurs : KeyListener, MouseMotionListener, MouseListener. □ On l’utilise en général pour définir une zone de dessin 353
    • Les composants graphiques (13) class Ctrait extends Canvas implements MouseListener { Point pt; public Ctrait() { addMouseListener(this); } public void paint(Graphics g) {g.drawLine(0,0,pt.x,pt.y); g.setColor(Color.red); g.drawString(quot;(quot;+pt.x+quot;;quot;+pt.y+quot;)quot;,pt.x,pt.y+5);} public Dimension getMinimumSize() {return new Dimension(200,100);} public Dimension getPreferredSize() {return getMinimumSize();} public void mouseClicked(MouseEvent e){} public void mousePressed(MouseEvent e){} public void mouseReleased(MouseEvent e) {pt=e.getPoint();repaint();} public void mouseEntered(MouseEvent e){} public void mouseExited(MouseEvent e){}} 354
    • Les composants graphiques (14) Utilisation de la classe précédente import java.awt.*; (Ctrait) par une autre classe. import java.awt.event.*; Voir le fichier Dessin.java pour public class Dessin extends Frame voir la manière exacte dont les 2 { classes sont définies et utilisées. public static void main(String[] args) { Dessin f= new Dessin(); } public Dessin() { super(quot;Fenêtre de dessinquot;); Ctrait c= new Ctrait(); add(BorderLayout.CENTER,c); pack(); show(); } } 355
    • Les composants graphiques (15) – Contrôle des couleurs d'un composant ■ Deux méthodes permettent de définir les couleurs d'un composant □ setForeground (Color c) : la couleur de l’encre avec laquelle on écrira sur le composant □ setBackground (Color c) : la couleur du fond ■ Ces deux méthodes utilisent un argument instance de la classe java.awt.Color. □ La gamme complète de couleurs prédéfinies est listée dans la page de documentation relative à la classe Color. ■ Il est aussi possible de créer une couleur spécifique (RGB) int r = 255, g = 255, b = 0 ; Color c = new Color (r, g, b) ; 356
    • Les composants graphiques (16) – Contrôle des polices de caractères ■ La police utilisée pour afficher du texte dans un composant peut être définie avec setFont(...) avec comme argument une instance de java.awt.Font. □ Font f = new Font (quot;TimesRomanquot;, Font.PLAIN, 14) ; ■ Les constantes de style de police sont en réalité des valeurs entières, parmi celles citées ci-après : □ Font.BOLD □ Font.ITALIC □ Font.PLAIN □ Font.BOLD + Font.ITALIC ■ Les tailles en points doivent être définies avec une valeur entière. 357
    • Conteneurs particuliers (1) – Dialog ■ Un objet Dialog ressemble à un objet Frame mais ne sert qu'à afficher des messages devant être lus par l'utilisateur. □ Il n'a pas de boutons permettant de le fermer ou de l'iconiser. □ On y associe habituellement un bouton de validation. □ Il est réutilisable pour afficher tous les messages au cours de l'exécution d'un programme. ■ Un objet Dialog dépend d'un objet Frame (ou héritant de Frame) □ ce Frame est passé comme premier argument au constructeur). ■ Un Dialog n'est pas visible lors de sa création. Utiliser la méthode show() pour la rendre visible (il existe une méthode hide() pour la cacher). □ Voir EssaiDialog.java 358
    • Conteneurs particuliers (2) – FileDialog ■ C’est une sous-classe de Dialog ; par défaut elle n’est pas visible. ■ C'est un dispositif de sélection de fichier : on peut préciser si c’est en vue d’une sauvegarde ou du chargement d’un fichier ■ Un FileDialog ne gère généralement pas d'événements. ■ Comme pour un objet Dialog, un FileDialog dépend d’un objet Frame ■ Un FileDialog est une fenêtre modale : à partir du moment ou la fenêtre a été rendue visible par la méthode show(...), la main n’est rendu à l’utilisateur que quand un fichier a été sélectionné. □ Voir EssaiFileDialog.java 359
    • Conteneurs particuliers (3) – FileDialog □ EssaiFileDialog.java 360
    • Conteneurs particuliers (4) – ScrollPane ■ C'est un conteneur général de type Panel □ tout comme un Panel il ne peut pas être utilisé de façon indépendante □ il fournit des barres de défilement (scrollbars) verticales et/ou horizontales ■ Un ScrollPane ne peut contenir qu'un seul composant ■ Ce conteneur n’est pas très intéressant mais est cité pour information. – AvecSwing de nouveauxcomposants ont fait leur apparition... 361
    • Dessiner avec Java
    • Dessiner avec l’AWT (1) – Rendu déclenché par le système ■ Le système demande à un composant de se peindre quand : □ le composant est rendu visible pour la première fois sur l’écran □ le composant a été redimensionné □ le rendu du composant a été endommagé et doit maintenant être réparé (par exemple, quelque chose qui cachait une partie du composant a été déplacé. Cette partie à nouveau visible doit être repeinte) – Rendu déclenché par l’application ■ Le composant décide de se repeindre pour refléter un changement dans son état interne 363
    • Dessiner avec l’AWT (2) – La demande de repeinte du composant ■ demandée par l’intermédiaire de la méthode public void paint (Graphics g) □ qu’elle soit déclenchée par le système ou par l’application – Donc le code indiquant ce qu’il faut peindre dans un composant doit être placée dans cette méthode (en la redéfinissant) 364
    • Dessiner avec l’AWT (3) – Quand l’AWT appelle cette méthode ■ l’objet Graphic est pré-configuré avec un état approprié pour dessiner sur ce composant particulier ■ l’objet color de cet objet Graphic prend pour valeur celle du foreground du composant ■ son objet font celle de la propriété font du composant ■ son objet translation est fixé de sorte que les coordonnées (0,0) représente le coin supérieur gauche du composant ■ son objet clip rectangle est fixé à la zone qui a besoin d’être repeinte 365
    • Dessiner avec l’AWT (4) – De manière générale, il faut éviter de placer du code servant pour le dessin/redessin des composants en dehors de la méthode paint() ■ pour éviter que ce genre de code soit appelé à un moment inapproprié (par exemple avant que le composant ne soit visible ou ait accès à un objet Graphics valide) 366
    • Dessiner avec l’AWT (5) – Il faut également éviter dans un programme de faire un appel directe à la méthode paint() ■ L ’AWT fournit un certain nombre de méthodes pour appeler la méthode paint() indirectement □ public void repaint ( ) □ public void repaint (long tm) □ public void repaint (int x, int y, int width, int height) □ public void repaint (long tm, int x, int y, int width, int height) 367
    • Dessiner avec l’AWT (6) – Opérations réalisées dans un rendu déclenché par le système ■ l’AWT détermine si le re-dessin concerne tout ou partie du composant ■ l’AWT appelle la méthode paint() sur le composant 368
    • Dessiner avec l’AWT (7) – Opérations réalisées dans un rendu déclenché par une application ■ le programme détermine si le re-dessin concerne tout ou partie du composant en réponse à un changement d’état interne ■ le programme appelle repaint() sur le composant qui a besoin d ’être repeint. ■ l’AWT provoque l’appel de la méthode update() sur le composant ■ si ce composant ne redéfinit pas update(), l’implémentation par défaut d’update() nettoie l’arrière plan du composant (si ce n ’est pas un composant léger) et appelle paint() . 369
    • Dessiner avec l’AWT (8) – pour résumer (I) ■ Pour la majorité des programmes le code pour le rendu graphique du composant doit être placé dans la méthode paint(). ■ Les programmes peuvent faire déclencher un futur appel à paint() en appelant repaint() mais ne doit généralement pas appeler paint() directement. ■ Sur des composants avec un rendu complexe, la méthode repaint() devrait être invoquée avec des arguments pour définir un rectangle de clipping 370
    • Dessiner avec l’AWT (9) – pour résumer (II) ■ Un appel a repaint() provoquant d’abord un appel à update(), qui est ensuite suivi d ’un appel à paint() par défaut, les composants lourds peuvent redéfinir update() pour réaliser du « dessin incrémental » (le dessin incrémental n’est pas possible avec les composant légers) ■ Les classes dérivées de java.awt.Container qui redéfinissent paint() devrait toujours invoquer dans le corps de cette méthode super.paint() pour s’assurer que tous ses composants sont redessinés. ■ Les composants avec un rendu graphique complexe devraient utilisées le rectangle de clipping pour restreindre la zone à redessiner 371
    • Swing (Survol)
    • Introduction à Swing (1) – La bibliothèque Swing est une nouvelle bibliothèque de composants graphiques pour Java. – Swing est intégré à Java 1.2. – Swing peut être téléchargé séparément pour une utilisation avec des versions de Java antérieures (1.1.5+) 373
    • Introduction à Swing (2) – Cette bibliothèque s'ajoute à celle qui était utilisée jusqu'alors (AWT) pour des raisons de compatibilité. – Swing fait cependant double emploi dans beaucoup de cas avec AWT. ■ L'ambition de Sun est que, progressivement, les développeurs réalisent toutes leurs interfaces avec Swing et laissent tomber les anciennes API graphiques. Image issue de l’article Getting Started with Swing http://java.sun.com/products/jfc/tsc/articles/getting_started/index.html 374
    • Composants graphiques lourds (1) – Un composant graphique lourd (heavyweight GUI component) s'appuie sur le gestionnaire de fenêtres local, celui de la machine sur laquelle le programme s'exécute. □ awt ne comporte que des composants lourds. □ Ce choix technique a été initialement fait pour assurer la portabilité. 375
    • Composants graphiques lourds (2) – Exemple : ■ Un bouton de type java.awt.Button intégré dans une application Java sur la plate-forme Unix est représenté grâce à un vrai bouton Motif (appelé son pair - peer en anglais). ■ Java communique avec ce bouton Motif en utilisant la Java Native Interface. Cette communication induit un coût. ■ C'est pourquoi ce bouton est appelé composant lourd. 376
    • Composants légers de Swing – Uncomposant graphique léger (en anglais, lightweight GUI component) est un composant graphique indépendant du gestionnaire de fenêtre local. ■ Un composant léger ressemble à un composant du gestionnaire de fenêtre local mais n'en est pas un : un composant léger émule les composants de gestionnaire de fenêtre local. ■ Un bouton léger est un rectangle dessiné sur une zone de dessin qui contient une étiquette et réagit aux événements souris. ■ Tous les composants de Swing, exceptés JApplet, JDialog, JFrame et JWindow sont des composants légers. 377
    • Atouts de Swing – Plus de composants, offrant plus de possibilités. – Les composants Swing dépendent moins de la plate- forme : ■ Il est plus facile d'écrire une application qui satisfasse au slogan quot;Write once, run everywherequot; ■ Swing peut pallier aux faiblesses (bogues ?) de chaque gestionnaire de fenêtre. 378
    • Look & Feel (1) – Les programmeurs peuvent choisir l'aspect qu'ils désirent pour leur application ■ en effet ceux-ci sont sont émulés. ■ On parle de pluggable look and feel ou plaf. ■ Exemple : Une application exécutée sur un système Windows ayant l'aspect d'une application Motif. ■ Ce choix peut même intervenir en cours d'exécution. 379
    • Look & Feel (2) – Sun a choisi de créer son propre look-and-feel, ■ il permet de donner une quot;identité graphiquequot; aux applications Java. □ C’est le look-and-feel Metal. – Un inconvénient est que ■ pour des raisons de copyright tous les look-and-feel ne sont pas disponibles sur toutes les plate-formes. 380
    • Conventions de nommage – Lescomposants Swing sont situés dans le paquetage javax.swing et ses sous paquetages. ■ Un certain nombre de paquetages d'extensions du langage java 1.1 (par opposition aux paquetages standards java) sont regroupés sous javax. □ Cette convention permet de télécharger ces paquetages dans un environnement navigateur avec une machine virtuelle java 1.1. Ces navigateurs ne sont, en effet, pas autorisés à télécharger des paquetages dont le nom commence par java. – Ils portent des noms similaires à leurs correspondants de AWT précédés d'un J. – JFrame, JPanel, JTextField, JButton, JCheckBox, JLabel, etc. 381
    • Aperçu des composants Swing (1) 382
    • Aperçu des composants Swing (2) 383
    • Aperçu des composants Swing (3) 384
    • Aperçu des composants Swing (4) 385
    • Principaux paquetages Swing (1) – javax.swing – le paquetage général – javax.swing.border – pour dessiner des bordures autour des composants – javax.swing.colorchooser – classes et interfaces utilisées par le composant JColorChooser – javax.swing.event – les événements générés par les composants Swing – javax.swing.filechooser – classes et interfaces utilisées par le composant JFileChooser 386
    • Principaux paquetages Swing (2) – javax.swing.plaf – les classes et interfaces autour du plaf – javax.swing.table – classes et interfaces pour gérer les JTable – javax.swing.text – classes et interfaces pour la gestion des composants « texte » – javax.swing.tree – classes et interfaces pour gérer les JTree – javax.swing.undo – pour la gestion de undo/redo dans une application 387
    • Quelques composants Swing (1) – Le JFrame ■ Le conteneur d'un JFrame n'est plus confondu avec le cadre lui- même. □ Il possède une couche de contenu, dans laquelle on peut ajouter les composants graphiques et dont on peut changer le gestionnaire de présentation. – Un objet JFrame a un comportement par défaut associé à une tentative de fermeture de la fenêtre. □ Contrairement à la classe Frame, qui ne réagissait pas par défaut, l'action de fermeture sur un JFrame rends par défaut la fenêtre invisible. □ Ce comportement par défaut peut être modifié par setDefaultCloseOperation(). 388
    • Quelques composants Swing (2) Avec AWT Frame monFrame = new Frame (quot;Mon Framequot;); Button monBouton = new Button (quot;Mon Boutonquot;); monFrame.add(monBouton); Avec Swing JFrame monFrame = new JFrame (quot;Mon Framequot;); JButton monBouton = new JButton (quot;Mon Boutonquot;); Container paneauContenu = monFrame.getContentPane(); paneauContenu.add(monBouton); 389
    • Quelques composants Swing (3) – La classe ImageIcon et l’interface Icon ■ Les objets de cette classe permettent de définir des icônes à partir d’images (gif, jpg, etc.) qui peuvent être ajoutés au classique texte d'un JLabel, d'un JButton, etc. Icon monIcone = new ImageIcon(quot;Image.gifquot;); // Un JLabel JLabel monLabel = new JLabel(quot;Mon Labelquot;); monLabel.setIcon(monIcone); monLabel.setHorizontalAlignment(JLabel.RIGHT); // Un JButton JButton monBouton = new JButton(quot;Mon boutonquot;, monIcone); 390
    • Quelques composants Swing (4) – JTextPane ■ un éditeur de texte qui permet la gestion de texte formaté, le retour à la ligne automatique (word wrap), l'affichage d'images. – JPasswordField ■ un champ de saisie de mots de passe : la saisie est invisible et l'affichage de chaque caractère tapé est remplacé par un caractère d'écho (* par défaut). – JEditorPane ■ un JTextComponent pour afficher et éditer du code HTML 3.2 et des formats tels que RTF. 391
    • Quelques composants Swing (5) – Des bordures peuvent être dessinées autour de tous composants graphiques. Swing en définit 9 types : □ AbstractBorder : ne fait rien □ BevelBorder : une bordure 3D en surépaisseur ou en creux □ CompoundBorder : permet de composer des plusieurs bordures □ EmptyBorder □ EtchedBorder □ LineBorder : bordures d'une seule couleur) □ MatteBorder □ SoftBevelBorder : une bordure 3D aux coins arrondis □ TitledBorder : une bordure permettant l'inclusion d’une chaîne de caractères 392
    • Quelques composants Swing (6) 393
    • Quelques composants Swing (7) – JLayeredPane ■ un conteneur qui permet de ranger ses composants en couches (ou transparents). ■ Cela permet de dessiner les composants, selon un certain ordre: premier plan, plan médian, arrière plan, etc. ■ Pour ajouter un composant, il faut spécifier la couche sur laquelle il doit être dessiné monJlayeredPane.add (monComposant, new Integer(5)); □ des « layer » sont définis en natif et des constantes pour y accéder existent dans la classe. 394
    • Quelques composants Swing (8) – ToolTipText ■ permet de créer des aides en lignes qui apparaissent lorsque la souris passe sur un composant. JButton monBouton = new JButton (quot;Un boutonquot;); monBouton.setToolTipText (quot;Aide de mon boutonquot;); – Cesquelques nouveautés ne sont qu'un aperçu de ce que propose Swing. ■ Il y a beaucoup de composants, de nouveaux gestionnaires de présentation, de nouveaux événements graphiques que l’on ne peut présenter et détailler dans le cadre de ce cours. □ Par exemple le conteneur Box qui utilise un BoxLayout (voir le programme AppliBoxLayout.java) 395
    • Quelques composants Swing (9) – Cesquelques nouveautés ne sont qu'un aperçu de ce que propose Swing. ■ Il y a beaucoup de composants, de nouveaux gestionnaires de présentation, de nouveaux événements graphiques que l’on ne peut présenter et détailler dans le cadre de ce cours. □ Par exemple le conteneur Box qui utilise un BoxLayout (voir le programme AppliBoxLayout.java) 396
    • L’architecture MVC (1) – Les composants Swing sont réalisés selon une architecture MVC ■ acronyme pour Modèle / Vue / Contrôleur – MVC est issue du langage Smalltalk. – Cette architecture permet notamment de gérer la coexistence des différents look-and-feel pour un même composant. 397
    • L’architecture MVC (2) – Un même objet va être décomposé en 3 parties distinctes : ■ le modèle qui représentant le contenu de l’objet, les données qu ’il représentent. ■ la vue qui présente les informations contenues dans le modèle à l’utilisateur ■ le contrôleur qui permet à l’utilisateur de manipuler les données 398
    • L’architecture MVC (3) 399
    • L’architecture MVC (4) – Ce type d'architecture peut s'appliquer à tous les composants graphiques ■ un même modèle de document texte peut avoir deux vues, une vue WYSIWYG et une vue brute (code html) □ L'architecture MVC permet, par exemple, de répercuter des modification effectuées sur une vue au modèle, qui lui-même les répercute sur l'autre vue. – Autre exemple ■ le modèle : le calcul prévisionnel du budget d’une société ■ les vues : une représentation textuelle, une sous forme graphique, etc. ■ les contrôle : des éléments de l’interface pour faire varier les paramètres du calcul 400
    • L’architecture MVC (5) Modèle lit les contenus signale tout changement de contenu Vue met à jour en cas de changement de contenu met à jour les éléments visuels reçoit les événements graphiques de l'utilisateur Contrôleur 401
    • MVC et Swing (1) –A partir d'un composant Jcomponent il est possible d'agir sur ■ son modèle (méthodes setModel() et getModel()) ■ sur sa vue (méthodes setUI() et getUI()). –A chaque composant (par exemple,) est associé un ou plusieurs modèles et toute une série de vues – à un JButton correspond le modèle DefaultButtonModel et les vues WindowsButtonUI, MotifButtonUI, MetalButtonUI, MacButtonUI. 402
    • MVC et Swing (2) – Swing est basé sur une variante de l’architecture MVC ■ La vue et le contrôleur sont regroupés en un même objet appelé le UI Object (User Interface Object). Le V+C - le UI Object est aussi appelé le UI-Delegate Le modèle Gère le look and feel 403
    • Aperçu sur le dessin avec Swing (1) – Comme pour l’AWT, en Swing on va utiliser les méthodes paint() et repaint(). Swing supporte de plus quelques propriétés additionnelles ■ le double buffering ■ la transparence ■ le chevauchement des composants 404
    • Aperçu sur le dessin avec Swing (2) – Pour tenir compte des spécificités des composants Swing, la méthode paint() va appeler 3 méthodes distinctes dans l’ordre suivant – protected void paintComponent(Graphics g) – protected void paintBorder(Graphics g) – protected void paintChildren(Graphics g) – Par conséquent, un programme Swing devrait redéfinir ■ paintComponent() et non paint() ■ Généralement, il n’est pas nécessaire de redéfinir les 2 autres méthodes. 405
    • La gestion des fichiers et des entrées/sorties en Java
    • Les entrées / sorties – Dansla plupart des langages de programmation les notions d'entrées / sorties sont considérées comme une technique de base ■ les manipulations de fichiers, notamment, sont très fréquentes. – EnJava, et pour des raisons de sécurité, on distingue deux cas : ■ le cas des applications Java autonomes, où, comme dans n'importe quel autre langage, il est généralement fait un usage important de fichiers, ■ le cas des applets Java qui, ne peuvent pas, en principe, accéder, tant en écriture qu'en lecture, aux fichiers de la machine sur laquelle s'exécute le navigateur (machine cliente). 407
    • La gestion des fichiers (1) – La gestion de fichiers proprement dite se fait par l'intermédiaire de la classe File. ■ Cette classe possède des méthodes qui permettent d'interroger ou d'agir sur le système de gestion de fichiers du système d'exploitation. ■ Un objet de la classe File peut représenter un fichier ou un répertoire. 408
    • La gestion des fichiers (2) – Voici un aperçu de quelques méthodes de la classe File : ■ File (String name) ■ File (String path, String name) ■ File (File dir, String name) ■ boolean isFile( ) / boolean isDirectory( ) – boolean mkdir( ) – boolean exists( ) – boolean delete( ) – boolean canWrite( ) / boolean canRead( ) – File getParentFile( ) – long lastModified( ) 409
    • La gestion des fichiers (3) import java.io.*; Les objets et classes relatifs à la public class Listeur gestion des fichiers se trouvent { dans le package java.io public static void main(String[] args) { A partir du chemin d'un dossier ou litrep(new File(quot;.quot;)); d'un fichier, on peut créer un objet } File : icion va lister le répertoire public static void litrep(File rep) courant (« . ») { if (rep.isDirectory()) Les méthodes isFile() et { //liste les fichier du répertoire isDirectory() permettent String t[]=rep.list(); de déterminer si mon objet File for (int i=0;i<t.length;i++) est une fichier ou un répertoire System.out.println(t[i]); } } } 410
    • La gestion des fichiers (4) import java.io.*; public class Listeur { public static void main(String[] args) { litrep(new File(quot;d:quot;));} public static void litrep(File rep) Le nom complet du fichier { est repfichier File r2; if (rep.isDirectory()) {String t[]=rep.list(); Pour chaque fichier, for (int i=0;i<t.length;i++) on regarde s'il est { un répertoire. r2=new File(rep.getAbsolutePath()+quot;quot;+t[i]); if (r2.isDirectory()) litrep(r2); else System.out.println(r2.getAbsolutePath()); }} Si le fichier est un }} répertoire litrep s'appelle récursivement elle-même 411
    • Notion de flux (1) – Les E / S sont gérées de façon portable grâce à la notion de flux (stream en anglais). – Un flux est en quelque sorte un canal dans lequel de l'information transite. L'ordre dans lequel l ’information y est transmise est respecté. – Un flux peut être : ■ Soit une source d’octets à partir de laquelle il est possible de lire de l'information. On parle de flux d'entrée. ■ Soit une destination d’octets dans laquelle il est possible d'écrire de l'information. On parle de flux de sortie. 412
    • Notion de flux (2) – Certainsflux de données peuvent être associés à des ressources qui fournissent ou reçoivent des données comme : ■ les fichiers, ■ les tableaux de données en mémoire, ■ les lignes de communication (connexion réseau) 413
    • Notion de flux (3) – L'intérêt de la notion de flux est qu'elle permet une gestion homogène : ■ quelle que soit la ressource associée au flux de données, ■ quel que soit le flux (y compris stdin, stdout et stderr). – Certains flux s’apparentent plus à des filtres ■ Combinés à des flux d’entrée ou de sortie, ils permettent de traduire les données. 414
    • Notion de flux (4) – Les flux sont regroupés dans le paquetage java.io ■ Il existe de nombreuses classes représentant les flux □ il n'est d'ailleurs pas toujours aisé de se repérer. ■ Certains types de flux agissent sur la façon dont sont traitées les données qui transitent par leur intermédiaire □ E / S bufferisées, traduction de données, … ■ Il s’agit donc de combiner ces différents types de flux pour réaliser la gestion souhaitée pour les E / S. 415
    • Notion de flux (5) Couche d'abstraction sur Reader Outils d'exploitation l'entrée BufferedReader Lecture Bufferisée Fichier FileReader LineNumberReader Déplacement ligne à Flux InputStreamReader ligne... Chaine StringReader ... 416
    • Flux d'octets et flux de caractères – Il existe des flux de bas niveau et des flux de plus haut niveau (travaillant sur des données plus évoluées que les simples octets). Citons : ■ Les flux d’octets □ classes abstraites InputStream et OutputStream et leurs sous- classes concrètes respectives, ■ Les flux de caractères □ classes abstraites Reader et Writer et leurs sous-classes concrètes respectives. 417
    • La hiérarchie des flux d'octets en entrée 418
    • La hiérarchie des flux d'octets en sortie 419
    • Les flux d’octets – Classe DataInputStream ■ sous classes de InputStream permet de lire tous les types de base de Java. – Classe DataOutputStream ■ sous classes de OutputStream permet d'écrire tous les types de base de Java. – Classes ZipOutputStream et ZipInputStream ■ permettent de lire et d'écrire des fichiers dans le format de compression zip. 420
    • Lecture de fichier import java.io.*; A partir du chemin d'un dossier ou d'un public class LireLigne fichier, on peut créer un objet { FileReader puis à partir ce celui-ci, public static void main(String[] args) on crée un BufferedReader { try { FileReader fr=new FileReader(quot;c:winntsystem.iniquot;); BufferedReader br= new BufferedReader(fr); while (br.ready()) System.out.println(br.readLine()); br.close(); } catch (Exception e) Dans l'objet BufferedReader {System.out.println(quot;Erreur quot;+e);} on dispose d'une méthode } readLine() } 421
    • Ecriture dans un fichier import java.io.*; A partir du chemin d'un dossier ou d'un public class Ecrire fichier, on peut créer un objet FileWriter { puis à partir ce celui-ci, public static void main(String[] args) on crée un BufferedReader { try { FileWriter fw=new FileWriter(quot;c:tempessai.txtquot;); BufferedWriter bw= new BufferedWriter(fw); bw.write(quot;Ceci est mon fichierquot;); bw.newLine(); bw.write(quot;Il est à moi...quot;); bw.close(); } catch (Exception e) Attention, lorsque l'on a écrit, il { System.out.println(quot;Erreur quot;+e);} ne faut pas oublier de fermer le }} fichier 422
    • La classe InputStream (1) – Un InputStream est un flux de lecture d’octets. – InputStream est une classe abstraite. ■ Ses sous-classes concrètes permettent une mise en œuvre pratique. ■ Par exemple, FileInputStream permet la lecture d'octets dans un fichier. 423
    • La classe InputStream (2) – Les méthodes principales qui peuvent être utilisées sur un InputStream sont : – public abstract int read () throws IOException qui retourne l’octet lu ou -1 si la fin de la source de données est atteinte. C'est cette méthode qui doit être définie dans les sous-classes concrètes et qui est utilisée par les autres méthodes définies dans la classe InputStream. – int read (byte[ ] b) qui emplit un tableau d’octets et retourne le nombre d’octets lus – int read (byte [] b, int off, int len) qui emplit un tableau d’octets à partir d’une position donnée et sur une longueur donnée, 424
    • La classe InputStream (3) – Les méthodes principales qui peuvent être utilisées sur un InputStream sont (suite) : – void close () qui permet de fermer un flux, □ Il faut fermer les flux dès qu'on a fini de les utiliser. ▪ En effet, un flux ouvert consomme des ressources du système d'exploitation qui sont en nombre limité. 425
    • La classe InputStream (4) – Les méthodes principales qui peuvent être utilisées sur un InputStream sont (suite) : – int available () qui retourne le nombre d’octets prêts à être lus dans le flux, □ Attention : Cette fonction permet d'être sûr qu'on ne fait pas une tentative de lecture bloquante. Au moment de la lecture effective, il se peut qu’il n'y ait plus d’octets disponibles. – long skip (long n) qui permet d’ignorer un certain nombre d’octets en provenance du flot. | Cette fonction renvoie le nombre d'octets effectivement ignorés. 426
    • La classe OutputStream (1) – Un OutputStream est un flot d’écriture d’octets. ■ La classe OutputStream est abstraite. – Les méthodes principales qui peuvent être utilisées sur un OutputStream sont : – public abstract void write (int) throws IOException qui écrit l’octet passé en paramètre, – void write (byte[] b) qui écrit les octets lus depuis un tableau d’octets, – void write (byte [] b, int off, int len) qui écrit les octets lus depuis un tableau d’octets à partir d’une position donnée et sur une longueur donnée, 427
    • La classe OutputStream (2) – Les méthodes principales qui peuvent être utilisées sur un OutputStream sont (suite) : – void close () qui permet de fermer le flux après avoir éventuellement vidé le tampon de sortie, – flush () qui permet de purger le tampon en cas d'écritures bufferisées. 428
    • Empilement de flux filtrés (1) – En Java, chaque type de flux est destiné à réaliser une tâche. – Lorsque le programmeur souhaite un flux qui ait un comportement plus complexe ■ Il quot;empilequot;, à la façon des poupées russes, plusieurs flux ayant des comportements plus élémentaires. □ On parle de « flux filtrés ». ■ Concrètement, il s'agit de passer, dans le constructeur d'un flux, un autre flux déjà existant pour combiner leurs caractéristiques. 429
    • Empilement de flux filtrés (2) – FileInputStream ■ permet de lire depuis un fichier mais ne sait lire que des octets. – DataInputStream ■ permet de combiner les octets pour fournir des méthodes de lecture de plus haut niveau (pour lire un double par exemple), mais ne sait pas lire depuis un fichier. – Unecombinaison des deux permet de combiner leurs caractéristiques : FileInputStream fin = new FileInputStream (quot;fichierquot;); DataInputStream din = new DataInputStream (fin); double d = din.readDouble (); 430
    • Empilement de flux filtrés (3) Lecture bufferisée de nombres depuis un fichier DataInputStream din = new DataInputStream(new BufferedInputStream( new FileInputStream (quot;monfichierquot;))); Lecture de nombres dans un fichier au format zip ZipInputStream zin = new ZipInputStream ( new FileInputStream (quot;monfichier.zipquot;)); DataInputStream din = new DataInputStream (zin); 431
    • Constructeurs de flux (1) – Classe FileInputStream – FileInputStream (String name) – FileInputStream (File f) – Classe FileOutputStream – FileOutputStream (String name) – FileOutputStream (String name, boolean append) – FileOutputStream (File f) 432
    • Constructeurs de flux (2) – Classe BufferedInputStream – BufferedInputStream (InputStream in) – BufferedInputStream (InputStream in, int n) – Classe BufferedOutputStream – BufferedOutputStream (OutputStream out) – BufferedOutputStream (OutputStream out, int n) 433
    • Flux de fichiers à accès direct (1) – La classe RandomAccessFile ■ permet de lire ou d'écrire dans un fichier à n'importe quel emplacement (par opposition aux fichiers à accès séquentiels). – Elle implémente les interfaces DataInput et DataOutput ■ permettent de lire ou d'écrire tous les types Java de base, les lignes, les chaînes de caractères ascii ou unicode, etc ... 434
    • Flux de fichiers à accès direct (2) – Un fichier à accès direct peut être ■ ouvert en lecture seule (option quot;rquot;) ou ■ en lecture / écriture (option quot;rwquot;). – Cesfichiers possèdent un pointeur de fichier qui indique constamment la donnée suivante. ■ La position de ce pointeur est donnée par long getFilePointer () et celui-ci peut être déplacé à une position donnée grâce à seek (long off). 435
    • Les flux de caractères (1) – Ce sont des sous-classes de Reader et Writer. – Ces flux utilisent le codage de caractères Unicode. – Exemples ■ les morceaux de code suivant convertissent respectivement les caractères saisis au claviers en caractères dans le codage par défaut des caractères de la machine hôte et avec un codage explicitement indiqué InputStreamReader in = new InputStreamReader (System.in); InputStreamReader in = new InputStreamReader ( new FileInputStream (quot;chinois.txtquot;), quot;ISO2022CNquot;); 436
    • Les flux de caractères (2) – Pourécrire des chaînes de caractères et des nombres sous forme de texte ■ on utiliser la classe PrintWriter qui possède un certain nombre de méthodes print (...) et println (...). – Pour lire des chaînes de caractères sous forme texte, il faut utiliser, par exemple, – BufferedReader qui possède une méthode readLine() . □ Pour la lecture de nombres sous forme de texte, il n'existe pas de solution toute faite : il faut par exemple passer par des chaînes de caractères et les convertir en nombres. 437
    • La hiérarchie des flux de caractères 438
    • Analyseurs lexicaux – Ilpeut être utile, lorsqu'on lit une chaîne de caractère, de la découper en morceaux délimités par des caractères spéciaux. ■ C'est ce qu'on appelle écrire un analyseur lexical. ■ Java fournit une classe qui permet d'écrire des analyseurs lexicaux: java.util.StringTokenizer ■ Il est possible de spécifier un ou plusieurs délimiteurs. String line = in.readLine (); StringTokenizer t = new StringTokenizer (line, quot; ntquot;); while (t.hasMoreTokens ()) { String information = t.nextToken (); } 439
    • Bases de la programmation réseau en Java
    • La lecture d’URL (1) import java.io.*; import java.net.*; public class LireNet Si on veut lire une URL, { au lieu d'un fichier public static void main(String[] args) 1. On crée une URL { 2. On ouvre le flux try { 3. On le met dans un URL u = new URL(quot;http://www.stjodijon.comquot;); objet « Reader » InputStream is= u.openStream(); 4.puis dans un objet InputStreamReader fr=new InputStreamReader(is); « Reader bufferisé » BufferedReader br= new BufferedReader(fr); while (br.ready()) System.out.println(br.readLine()); br.close(); } catch (Exception e) {System.out.println(quot;Erreur quot;+e);} }} 441
    • La lecture d’URL (2) InputStreamReader FileReader URL InputStream File BufferedReader Readline() 442
    • Programmation réseau en java (1) – Lepaquetage java.net offre des services de programmation réseau ■ communications sur TCP (flux) ■ communications via UDP (datagrammes) ■ datagrammes avec diffusion multiple (multicast) 443
    • Programmation réseau en java (2) – Javapermet la communication entre deux applications distantes au travers de canaux de communication bidirectionnels (sockets). ■ Java permet la mise en œuvre de deux types de sockets : □ Stream sockets (TCP) permettent une communication en mode connecté, caractérisées par le caractère continu du flux de données (ordre correct - données non corrompues). □ Datagram sockets (UDP) permettent une communication en mode non-connecté, caractérisées par plus grande rapidité, au prix d'une fiabilité moindre (perte, duplication ou désordre possibles). 444
    • Utilisation des sockets TCP / IP Côté serveur Côté client 1- Enregistrement du service 1- Création d'un client et tentative de Construction d'un objet de type connexion ServerSocket (paramètres : n° de port Construction d'un objet de type Socket et nombre connexions) (paramètres : hôte et n° de port) 2- Attente d'une demande de connexion du client Méthode accept() qui retourne, lorsqu'une connexion est acceptée, un objet de type Socket 2- Echange 3- Echange OutputStream InputStream InputStream OutputStream 3- Fermeture (méthode close()) 4- Fermeture (méthode close()) 445
    • Classe Serveur (1) import java.net; import java.io; public class Serveur { ServerSocket ss; public Serveur (int port) throws IOException {ss = new ServerSocket (port); } public void go () { while (true) { try { Socket so = srv.accept (); echange (so.getInputStream(), so.getOutputStream ()); so.close (); } catch (IOException e) {} } } // suite page suivante 446
    • Classe Serveur (2) //suite page précédente public void echange (InputStream is, OutputStream os) throws IOException { DataOutputStream dos = new DataOutputStream (os); dos.writeUTF (quot;Hello net world !!!quot;); } public static void main (String args []) { Serveur s = new Serveur (Integer.parseInt (args[0])); s.go (); } } 447
    • Classe Client (1) import java.net; import java.io; public class Client { Socket so; public Client (String host, int port) throws IOException { so = new Socket (host, port); } public void go () { try{ echange (so.getInputStream(), so.getOutputStream ());} catch (IOException e) {} } public void stop () { try { so.close ();} catch (IOException e) { } } //suite page suivante 448
    • Classe Client (2) //suite page précédente public void echange (InputStream is, OutputStream os) throws IOException { DataInputStream dis = new DataInputStream (is); System.out.println (dis.readUTF ()); } public static void main (String args []) { Client c = new Client (arg[0], Integer.parseInt (args[1])); c.go (); c.stop (); } } 449
    • Sockets de datagrammes (UDP) (1) – Lescanaux UDP sont ouverts grâce à la création d'instances de DatagramSocket DatagramSocket ss = new DatagramSocket (9789); DatagramSocket cs = new DatagramSocket (); – Les paquets d'information sont des instances de la classe DatagramPacket. Ils contiennent : ■ les données et leur longueur, ■ l'adresse et le port destination (dans le cas d'un envoi). DatagramPacket envoi = new DatagramPacket (buff, len, addr, port); s.send (envoi); DatagramPacket recept = new DatagramPacket (buff, len); s.receive (recept); 450
    • Sockets de datagrammes (UDP) (2) – Adresses internet ■ La classe InetAddress permet de construire une adresse à partir d'une désignation (méthode getByName () ) ou de la machine locale (méthode getLocalHost() ). 451
    • Diffusion multiple (multicast) – La classe MulticastSocket permet de diffuser des données simultanément à un groupe d'abonnés. – Sur une instance de MulticastSocket, il est possible : ■ de s'abonner à un groupe, grâce à la méthode joinGroup(InetAddress address) ■ de se désabonner d'un groupe, grâce à la méthode leaveGroup(InetAddress address) – Laméthode d'envoi des données permet de limiter éventuellement le nombre de routeurs traversés – send (DatagramPacket dp, byte b) 452