50
Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les chapitres essentiels Java, la notion d’Objet et de Classes L’héritage et le polymorphisme Les collections, Les exceptions, les fichiers Les interfaces graphiques en Swing x sujets de TD/TP Sujets donnés à l’avance 1 examen écrit de 2h Documents : Site : http://tdinfo.phelma.grenoble-inp.fr/2APOO/ Le poly Les sujets de TD Site indispensable : http://java.sun.com/j2se/1.5.0/docs http://java.sun.com/javase/6/docs/api 2 Introduction 3 Objet : Inspiré du C++, Objective C et Smalltalk : Java fortement objet. Simple Suppression des sources d’erreurs classiques : pas de pointeurs, pas de gestion mémoire par le programmeur Robuste Nombreuses vérifications sont faites à la compilation (protection des classes, ) Sécurisé à la conception du langage Les notions de sécurité réseau sont incluses (SecurityManager), en particulier pour les applets Compact Java a été conçu pour fonctionner dans un environnement évolutif. L'interpréteur Java n'a besoin que de 215Ko. Chargement dynamique des classes Caractéristiques

Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

  • Upload
    others

  • View
    11

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Programmation Objet et JAVA

Phelma 2015

1

Organisation du cours

  10 séances de CM/TD/TP Les chapitres essentiels   Java, la notion d’Objet et de Classes   L’héritage et le polymorphisme   Les collections, Les exceptions, les fichiers   Les interfaces graphiques en Swing

  x sujets de TD/TP   Sujets donnés à l’avance

  1 examen écrit de 2h

  Documents :   Site : http://tdinfo.phelma.grenoble-inp.fr/2APOO/

  Le poly   Les sujets de TD

  Site indispensable :   http://java.sun.com/j2se/1.5.0/docs   http://java.sun.com/javase/6/docs/api

2

Introduction

3

  Objet :   Inspiré du C++, Objective C et Smalltalk : Java fortement objet.

  Simple   Suppression des sources d’erreurs classiques : pas de pointeurs, pas de

gestion mémoire par le programmeur   Robuste

  Nombreuses vérifications sont faites à la compilation (protection des classes,…)

  Sécurisé à la conception du langage   Les notions de sécurité réseau sont incluses (SecurityManager), en

particulier pour les applets   Compact

  Java a été conçu pour fonctionner dans un environnement évolutif.   L'interpréteur Java n'a besoin que de 215Ko.   Chargement dynamique des classes

Caractéristiques

Page 2: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Introduction : caractéristiques

Langage Interprété Traduit et exécuté à chaque chargement Développement plus simple

Temps d’exécution plus long

Fichier *.class Indépendant du

processeur et de l ’OS dépend de la définition de la machine virtuelle

Fichier *.java Indépendant du

processeur et de l ’OS dépend de la définition de la machine virtuelle

Pas de Fichier Executable Dépendant du processeur et

de l ’OS Dépend de la Réalisation de

la machine virtuelle

  Indépendant de l'architecture : Portable   Conçu pour cela (machine virtuelle)

  Ensemble complet d’exécution : machine à pile 32 bits •  Jeu d’instructions précis •  Des registres •  Une pile •  Interprète du byte_code : intermédiaire entre compilation et interprétation •  Seule, la JVM change entre MAC, PC, Windows, Unix….

  Les types de base ont des tailles fixes   Multithread

  Gestion de plusieurs tâches prévue   Réseau

  Ensemble de classes pour utiliser des protocoles TCP/IP tels que HTTP et FTP   Gestion des langues   Deux types de programmation différents

  Applications   Programmes écrits en Java   Exécuté sur une machine qui possède un interpréteur java. Ce programme pourra se lancer

indifféremment sous n'importe quelle machine/OS.   Applets

Introduction : caractéristiques

Introduction : Applets

Applets : intégration de java au www Programmes écrits en Java, installés

généralement sur un serveur Web

L'applet est téléchargée depuis le serveur Web sur le poste client

Exécutés sur le poste Client par la JVM du navigateur à la demande de celui-ci

Testés grâce à appletviewer

Serveur www distant

Poste client netscape, IE, ...

1 : demande 2

chargement applet (.class)

3 execution

Java versus C

  JAVA est portable sans recompilation sur toutes les plates formes (processeur/OS)   PC, Mac,   PDA, telephone, etc…

  Même syntaxe, même structure de contrôle que C et C++   Principales différences

  Pas de variables globales   Pas de préprocesseur #define, #include #ifdef   Pas de pointeurs   Le main est une fonction interne à une classe   C++ : Pas de surcharge des opérateurs   C++ : Pas d'héritage multiple

  Nombreuses bibliothèques standard   Réseau,Système, thread   Graphisme, Interface utilisateur, Multimédia   E/S, chaînes et expressions régulières`   RMI : applications réparties sur plusieurs machines   Securité, cryptographie   Base de données, xml

8

Page 3: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Types de base

  Langage fortement typé comme C++   huit types de base Type Taille Valeur int 4 bytes -2147483648 à + 2147483647 ( 231) short 2 bytes -32768 à +32767 long 8 bytes 263 byte 1 byte -128 à +127 float 4 bytes +/- ( 1,4.10 - 45 à 3.4 10 + 38 ) double 8 bytes +/- ( 4,94 .10 -324 à 1,79 . 10 + 308 ) char 2 bytes 65536 caractères (internationaux) boolean true or false   Valeurs extrémales par Type.MAX_VALUE, type.MIN_VALUE

  char c = Byte.MAX_VALUE

9

POO et UML

Notions de base

10

Concept de classe : le point 2D

  Problème posé   Définir les outils nécessaires pour un logiciel de géométrie tel que cabri ou pour un logiciel de

dessin   Exemple : définir la symétrie centrale et les translations et homothéties sur des points dans le

plan cartésien

  Qu’est ce qu’un point du plan   Définition statique : ce sont les champs ou attributs

  Une entité comportant 2 coordonnées   abscisse   ordonnée

  Que doit on pouvoir faire avec : ce sont les méthodes

  Entrées/sorties   Le créer : mettre des valeurs dans les coordonnées   L’afficher : ecrire les valeurs à l’écran

  L’utiliser pour résoudre un problème   Translation d’un vecteur donné   Homothétie par un facteur k   Trouver le symétrique d’un point

11

class point

Le point 2D en procédural ou en objet

12

Structure point avec champs x et y

Fonctions void affiche (point)

void translate(point*, double,double) point homothetie(point, double)

point symetriecentrale(point)

Attributs x et y

Méthodes void affiche ()

void translate(double,double) point homothetie(double) point symetriecentrale()

  En C, pas de liens entre les fonctions et les structures de données qu’elles manipulent

  Exemple : on peut utiliser affiche sur un entier par erreur

  En POO, on regroupe champs et fonctions au sein de la classe

  il existe un lien physique entre attributs, méthodes et objets

  On ne peut pas utiliser affiche sur un int

Page 4: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

En C, le point 2D et ses fonctions

typedef struct Point { /* Definition des champs d'un point */ double x; double y; } POINT;

/* definition des fonctions sur un point */ /* Comment afficher un point */ void affiche(POINT a) {printf("x:%lf y:%lf\n",a.x,a.y);} /* Comment translater un point */ void translate(POINT* ax, double a, double b) { ax->x += a; ax->y += b;

} /* constante x point ==> point */ POINT multcste(POINT a, double k) { POINT res; res.x = k*a.x; res.y = k*a.y; return res; } /* Symetrie centrale d’un point : ==> point */ POINT symetriecentrale(POINT a) {POINT res; res.x = -a.x; res.y = -a.y; return res; } }

Point : 2 coordonnées

Quelles sont les actions réalisables sur un point ?

13

En C, le point 2D et ses fonctions

void main() { int i; POINT p1, p2, p3; printf("Premier exemple"); p1.x=2; p1.y=8; affiche(p1); translate( &p1, 1,-6); // Attention aux pointeurs !!! affiche(p1); p2 = multcste(p1, 10.0); affiche(p2); p3=symetriecentrale(p1); affiche(p3); affiche(i); // Rien n’empeche cela : il n’y a aucun lien entre affiche et la structure POINT

}

14

Exemple de classe : le point 2D public class Point { /* Definition des champs d'un point */ private double x; private double y; /* definition des methodes d'un point */ /* Constructeur : valeurs initiales d'un point */ public Point () { x = 0; y = 0; } public Point (double a, double b) { x = a; y = b; } /* Comment afficher un point */ public void affiche() { System.out.println("Abcisse "+x+"

ordonnee : "+y);} /* Comment translater un point */ public void translate(double a, double b) { x += a; y += b; } /* constante x point ==> point */ public Point multcste(double k) { Point res; res = new Point(this.x, this.y); // Ou Point(x,y) res.x = k*res.x; res.y = k*res.y; return res; } /* Symetrie centrale d’un point : ==> point */ public Point symetriecentrale() { return new Point(-x,-y); } }

Point : 2 coordonnées

Comment initialiser un point : 2 possibilités

Quelles sont les actions réalisables sur un point ?

15

Exemple d’objet : des points particuliers

public class Ex1b { public static void main (String[] args){ Point p1, p2, p3; System.out.println("Premier exemple"); p1 = new Point(2,8); p1.affiche(); p1.translate(1,-6); p1.affiche(); p2 = p1.multcste(10.0); p2.affiche(); p2=null; p3=p1.symetriecentrale(); p3.affiche(); } }

3 Points : p1 p2 p3

Creation de p1

Affichage de p1

16

Page 5: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

POO : concepts de base

  Héritage   Graphe de parenté entre des Classes   Héritage des méthodes et données qui ne sont pas à redéfinir   Ajouter des nouvelles fonctionnalités à ce qui existe déjà   Isole les éléments nouveaux pour la sécurité du code existant

  Encapsulation : données+méthodes+sécurité   Données et méthodes dans une même entité : la classe

  données : les informations propres à un objet,   méthodes : les actions réalisables sur/avec cet objet

  Objet : instance d'une classe   Sécurité : Cloisonne l’intérieur et l’extérieur de l’objet

  privé : inaccessible de l'extérieur de la classe ou de l’objet   public : ce qui l'extérieur à le droit d'utiliser

  Réutiliser   sans connaître le fonctionnement interne   Sans risquer de modifier ce qui est fait

  Polymorphisme : une même méthode prend plusieurs formes   Une méthode est typée par ses paramètres. Le même nom est utilisable

par plusieurs classes ou type de données   Quand on utilise une classe donnée, elle sait quelle est la bonne

fonction à utiliser ! pas de test de type en POO.

  1 programme ; 1 ensemble d’objets qui s’envoient des messages

17

Conception, Modèles et Diagrammes en POO

  UML : Unified Modeling Langage   Langage graphique de modélisation de projet informatique orienté

objet :   Définition des classes/attributs et des méthodes (modèle statique)   Définition des aspects dynamiques et temporels (modèle dynamique).

  Le modèle statique permet   de structurer les besoins de l’utilisateur du logiciel : diagramme use-cases   de structurer les attributs et les méthodes en les répartissant dans des classes,

reliées entre elles par des liaisons de trois types : héritage, agrégation, relation : diagrammes d’objets, de classes,

  De structurer l’application en terme de modules (diagramme de composants) et de matériel utilisé (diagramme de déploiement)

  Le modèle dynamique décrit le comportement dynamique et temporel du système :   Structurer les interactions entre objets (diagramme de collaboration) et leur

séquencement temporel, ie ordre d'exécution des méthodes (diagramme de séquence)

  Spécifier les séquences d’etats possibles des objets (automates) : diagramme d’etat-transition

18

Diagramme de classe : UML

Nom de la classe

+ : public # : protégé - : private

méthodes

Attributs ou champs

  Une classe

19

Questions

  Faire le diagramme de classe d’un complexe   Quels sont ses attributs ?   Donnez les prototypes de 4 méthodes utiles

20

Page 6: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Notion d’objet

Les classes et les objets

21

Les classes en JAVA

  Une classe permet de définir des modèles ayant une certaine autonomie   La classe définit la structure des objets

  Les champs   les méthodes utilisables par un objet de ce type, i.e. les actions qu’un

objet de ce type peut réaliser   Syntaxe [public] class Nom_de_ma_classe {

// déclaration des champs; [public, private] type nom_champ;

//déclaration de methodes; [public, private] type_retour nom_de_fonction(type nom_parametre, …)

}

  En java, pas de rédéfinition des opérateurs à l’inverse du C++   En pratique, le nom d’une classe commence par une majuscule   Le nom du fichier est celui de la classe contenant la fonction main ou celui de la

classe public

22

Les objets et les variables en JAVA

  Un objet = un exemple ou une entité dont le modèle (type) est une classe   On dit aussi une instance de classe.

  La variable est une référence (pointeur constant) sur cet objet

  En Java, 3 étapes   Définition de la variable : Point p1;

  Sa durée de vie est celle du bloc

  Création et allocation de l’objet : p1= new Point(2,8);   Sa durée de vie est celle de son utilisation   Elle est détruite AUTOMATIQUEMENT par le garbage collector, quand elle est devenue inutile

  Utilisation du point p1 :   par exemple, appliquer affiche() à p1 : p1.affiche()   ou changer la valeur de l’abscisse : p1.x=10;

  Donc

  En java, une variable est une référence, i.e. un pointeur "masqué"   Le passage d’un objet comme paramètre d’une fonction permet de modifier cet objet : pas

besoin de passage de l’adresse   Pas de pointeur, de gestion mémoire par le programmeur

23

Concept d'objet : exemple

public class Ex1c { public static void main (String[] args){ System.out.println("Premier exemple"); Point p1=null, p2=null; // Définition p1, p2

2

8

p1 p1 p1 = new Point(); // Creation p1 p1.x=2; p1.y=8; // On change p1 p1.affiche();

p1.affiche()

p2.affiche()

p1.affiche()

p2 p1 20

80

p2 = new Point(20,80); ` p2.affiche();

p1.x = p1.x + 20; p1.y += 80; p1.affiche();

p2=null; // l’objet pointé par p2 est libre

22

88

p1

} // les variables p2 et p1 sont détruites }

24

Page 7: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Notion d’objet

Les attributs et les méthodes

25

Accès aux membres

  Accès aux membres d’un objet : objet.champ   Attention, objet est une référence   Exemple : a.x est l’abscisse du point a.

  Appeler/exécuter une méthode : objetappelant.methode(param);   Cela signifie que l’on exécute methode(parametres) « SUR » objetappelant   Les méthodes s’exécutent sur un objet   p.affiche() signifie

  On cherche la classe de p : c’est la classe Point   On cherche si une méthode affiche() existe dans la classe Point :

•  si elle n’existe pas, erreur de compilation « Cannot find Symbol »

  On exécute cette fonction avec un paramètre supplémentaire invisible :this, qui est l’objet sur lequel on travaille = objet appelant. Ici, this = p

public void translate(double a, double b) { x = x + a; y = y + b;

} Si on appelle translate avec le point p sous la forme p.translate(2,3), p.x et p.y qui

sont incrémentés de 2 et 3   Comment écrire public void translate(double x, double y) 26

Paramètre this

  Dans une méthode, il y a toujours un paramètre « implicite » this, qui est l’objet sur lequel on travaille   p.translate(1,2) ==> this est une référence sur p

  Donc public void translate(double a, double y) { ATTENTION !!!!! x = x + a; y = y + y;

} // Quand on écrit y, est ce le paramètre de la fonction ou

l’attribut de p ?

27

public void translate(double a, double y) { x = x + a; this.y = this.y + y;

}

Notion d’objet

Sécurité

28

Page 8: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Accès et protection

  Public   Les membres public sont accessibles pour toutes les méthodes et

fonctions du programme   On peut lire et ecrire les champs à n’importe quel endroit dans le code   On peut executer une méthode dans n’importe quelle lméthode

  Private   Un membre private n’est accessible que par les méthodes de sa

classe ou de son package   Une méthode private peut être exécutée par une autre méthode de la

classe, mais pas par celles des autres classes.   Un champ private n’est accessible que par une méthode de la classe.   En particulier, main() est une fonction qui n’appartient pas à la classe Point :

elle ne peut pas accéder aux champs x et y d’un objet de la classe Point

  Principe de la POO : L’objet est responsable de son état   les membres (attributs ou méthodes) peuvent etre protégés en lecture/écriture des

autres fonctions ou objets du programme.

29

Accès aux membres et aux méthodes (2)

Lecture de 2 nombres au clavier, creation d’un point … Ex6.java import java.util.*; public class Ex6 { public static void main (String []arg) {double x1, x2; Point a,b,c ; Scanner clavier = new Scanner(System.in); System.out.println("Entrer 2 reels "); x1=clavier.nextDouble(); // Lecture d’un reel x2=clavier.nextDouble(); // 3,14567 :virgule a= new Point(x1,x2); // Création du point avec x1 et x2 a.affiche(); // On execute affiche sur a; ici, this = a b = new Point(3,8); b.affiche(); // On execute affiche sur a; ici, this = b b.x=x1; // Interdit car x est privé b.translate(2,6); b.affiche(); a.translate(b); a.affiche(); c = a.multcst(2.); c.affiche(); } } 30

Accès et protection Exemple :Fichier Ex7.java class Point { private double x,y;…… // x et y ne peuvent être lus/modifiés que par des méthodes de la classe

private void interdit() {x=0; System.out.println("Appel interdit hors classe"); }

// interdit() ne peut être appelée que par des méthodes de la classe public void autorise() {this.interdit(); } // OK car autorise()

est dans la classe // autorise() peut être appelée par des méthodes d’autres classes

}; public class Ex7 { public static void main (String []arg) { Point a,b ; a= new Point(1,2); a.affiche(); b= new Point(); b.affiche(); a.x=5; // Interdit car x est private b.interdit(); // Interdit car interdit() est private b.autorise(); // Autorise car autorise() est public } } 31

Accès et protection : pourquoi ?

class Fraction{ public double numerateur, denominateur;

// Constructeur : jamais de denominateur nul public Fraction(double a, double b) { if (b==0) { System.out.println("Denominateur nul"); System.out.exit(1); } else {set=a; denominateur=b; } } Fraction produit(Fraction q) { // Attention si q.denominateur est nul, rien n’est verifié ici numerateur *= q. numerateur; denominateur *= q. denominateur; } public String toString() { return numerateur + "/" + denominateur; } }; public class Ex7c { public static void main (String []arg) { Fraction a = new Fraction(1,2); Fraction b = new Fraction(3,4); System.out.println("b vaut " + b); b.produit(a); System.out.println("b vaut " + b); a.denominateur=0;

// C’est contraire au fonctionnement de la classe, mais comme denominateur n’est pas privé, c’est syntaxiquement correct.

b.produit(a); System.out.println("b vaut " + b); } }

32

Page 9: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

 Classe Fraction

Accesseurs et mutateurs

  Le concepteur de la classe se pose la question :   Qu’est ce qui est utile aux autres classes et

fonctions de ma classe, i.e. le monde extérieur

  Ce qui est utile est public, le reste, utile au fonctionnement interne de l’objet est private.

  De cette manière, « l’extérieur » ne peut modifier le comportement interne et voulu par le concepteur : c’est l’encapsulation

  En pratique,   les champs sont souvent privés   Si besoin, autoriser la lecture du champ par

un accesseur getchamp() que vous devez définir

  Parfois, autoriser la modification du champ par un mutateur setchamp() que vous devez définir

  Les mutateurs/accesseurs peuvent etre public ou privé

  Toujours initialiser les champs grâce aux constructeurs

  C’est le concepteur qui décide et non l’utilisateur de l’accès possible

33

 Attributs  num et denum

 Méthodes internes à la classe

void init(double,double)

 Méthodes autorisées à

l’extérieur

 main() {  }

 Mutateurs/Accesseurs

Accesseurs et mutateurs

34

class Fraction{ //Attributs privés

private double numerateur, denominateur;

// Accesseurs et Mutateurs: public double getnumerateur(){ return numerateur; } public double getdenominateur() { return denominateur; } public void setnumerateur(double a) {numerateur=a; }

// Avec ce mutateur, on est sur que jamais une fraction ne sera infinie public void setdenominateur(double a) { if (b==0) {System.out.println("Denominateur nul"); System.exit(1); } else denominateur=a; }

// Methode interne à la classe, inutile pour les autres classes private void init(double a, double b){setnumerateur(a); setdenominateur(b); }

// Constructeurs : on utilise la méthode privée public Fraction(double a, double b) { init(a,b); } public Fraction(Fraction q) { init(q.a,q.b); }

// Meme la methode produit peut utiliser les mutateurs, avec verification automatique du denominateur.

public void produit(Fraction q) { setnumerateur(numerateur*q. numerateur); setdenominateur(denominateur*q. denominateur); } };

Accesseurs et mutateurs

35

public class Ex7c { public static void main (String []arg) { Fraction a = new Fraction(1,2); Fraction b = new Fraction(a); System.out.println("b vaut " + b); b.produit(a); System.out.println("b vaut " + b); a.setdenominateur(0); // C’est contraire au fonctionnement de la classe, qui refuse les fractions infinies, et le programme va quitter à cet endroit.

b.produit(a); System.out.println("b vaut " + b); } }

Notion d’objet

Initialisation, construction, destruction

36

Page 10: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Constructeur

  Constructeur : méthode appelée automatiquement à la création d'un objet

  Rôle   Initialise les différentes parties de l'objet : on connaît

toujours l’état initial   Réalise les actions indispensable à l'état initial de l'objet   Plusieurs manières d'initialiser un objet " Surcharge

possible i.e. plusieurs constructeurs de même nom   Construire un point à partir de 2 réels   Construire un point à partir de rien   Construire un point à partir d’un autre point

  Syntaxe   Fonction de même nom que la classe, comme en C++

  Attention

  Par défaut, java ajoute un constructeur sans paramètres   Quand on définit un constructeur, on ne peut plus construire des

points sans utiliser un de ceux ci

37

Constructeur class Point { private double x; private double y; /* Constructeur : quelles sont les valeurs initiales d'un point */ public Point (double a, double b) {System.out.println("C1"); x = a; y = b;} public Point () { System.out.println("Constructeur 2"); x = 0; y = 0; } public Point (Point a) { System.out.println("Cons 3"); x = a.x; y = a.y; } }; public class Ex4 { public static void main (String []arg) { Point a ; System.out.println("Creation de a"); a= new Point(1,2); // Création du point 1,2, constructeur 1 System.out.println("Fin xreation de a"); System.out.println("Creation de b"); Point b = new Point(); // Création du point 0,0 constructeur 2 System.out.println("Fin creation de b"); System.out.println("Creation de c"); Point c = new Point(b); // Création de C à partir de b; System.out.println("Fin creation de c"); } }

38

Destructeur

  Fonction appelée automatiquement lors de la destruction des objets   Prototype : protected void finalize()   En C++, ~nom_de_la_classe()

  En java, très peu utilisé car vous ne gérez pas la libération de la mémoire : c’est automatique, grâce au ramasse miette

  GC ou ramasse miette :   Récupère automatiquement la mémoire des objets devenus inutiles et appelle la méthode

finalize   On ne sait pas quand il est appelé : on ne sait donc pas quand est utilisé le destructeur

  Objets inutiles :   objets réels alloués qui ne sont plus utilisés   Difficile à trouver ==> quand un objet est inutile, pour qu’il puisse etre détruit, mettre sa référence à null

  En général,   on n’appelle pas le gc() directement car il peut etre tres lent   pas de destructeur

39

Destructeur

import java.util.*; class Point { …… protected void finalize() {System.out.println("Appel au Destructeur"); } }; public class Ex5 { public static void main (String []arg) {Point a ; Scanner clavier = new Scanner(System.in); System.out.println("Creation de a"); a= new Point(1,2); // Création du point 1,2, constructeur 1 System.out.println("Fin xreation de a"); a=null; clavier.nextLine(); System.gc(); // Destruction du point a System.out.println("Creation de b"); Point b = new Point(); // Création du point 0,0 constructeur 2 }

On passe dans le destructeur Ligne : System.gc()

40

Page 11: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Notion d’objet

Surcharge de méthodes

41

Surcharge ou Polymorphisme de méthodes :

  Possibilité pour une fonction ou méthode d’avoir un même nom si les signatures différentes   Signature : type de retour, nombre et type des paramètres   En Java et C++, surcharge uniquement sur les paramètres   La fonction réellement exécuter est déterminée sur la base des

paramètres utilisés   En java, il y a liaison dynamique décidé à l’execuion

  Attention :   on ne peut pas surcharger uniquement sur le type de retour

42

Surcharge ou Polymorphisme de méthodes :

class Point { private double x, y; /* Constructeur */ public Point (double a, double b) {x = a; y = b; } public Point (Point a) {x = a.x; y = a.y; } public void affiche() { System.out.println( "x:"+x+" y:"+y);} // Deux methodes de translations : A partir de 2 reels

public void translate(double a, double b) { x += a; y += b; } // A partir d’un point

public void translate(Point p) { x += p.x; y += p.y; } }; public class Ex5 { public static void main (String []arg) { Point a= new Point(1,2); // Création du point 1,2 Point b = new Point(10,20); Point c = new Point(b); // Création de C à partir de b; b.affiche(); b.translate(1,2); b.affiche(); c.affiche(); c.translate(a); c.affiche(); } } 43

Objets et références

44

Page 12: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Objets et référence ou le retour des pointeurs

  p1 = new Point (2,3);   p1 est une référence sur un objet réel   C’est donc un pointeur constant

public class Ex8b { public static void main (String []arg) { Point a,b,c ; a= new Point(1,2); a.affiche(); b = a; c = new Point(a);

b.affiche(); c.affiche(); a.setx(8); a.affiche(); b.affiche(); c.affiche(); } } Qu’est ce que ce programme affiche

1

2 a

b

1

2

c 8

2

45

Le passage d’objets en paramètres

class Point { …. /* Cette fonction modifie son parametre meme si elle est stupide : */ void ajoutemoiap(Point p) { p.x = p.x+x; p.y += y; } public class Ex1c { public static void main (String[] args){ Point p1=null, p2=null;

2

8

p1 p1

p1 = new Point(2,8); p1.affiche();

p1.affiche()

p2.affiche()

p1.affiche()

p2 p1 20

80

p2 = new Point(20,80); ` p2.affiche(); p2.ajoutemoiap(p1);

// Ici p1 est modifié à cause de ajoutemoiap p1.affiche();

22

88

p1

} // les variables p2 et p1 sont détruites }

46

  Un objet passé en paramètre d’une méthode est passé par adresse et il peut être modifié par la fonction

Divers

47

Les Entrées Sorties en pratique

  Lire des nombres et des chaines : classe Scanner   Créer un objet de la classe scanner associé au flux de lecture voulu : le clavier   Les méthodes nextDouble(), nextInt(), nextLine() de la classe scanner permettent la lecture

des réels, entiers et chaines.   Afficher : System.out.println() import java.util.*; public class Essai { public static void main (String []arg) { double x1, x2; String x; Scanner clavier = new Scanner(System.in); System.out.println("Entrer 2 reels "); x1=clavier.nextDouble(); // Lecture d’un reel x2=clavier.nextDouble(); // 3,14567 :virgule System.out.println("Voici x1 : " + x1); System.out.println("Tapez une chaine"); x=clavier.nextLine(); System.out.println("Ce que vous avez ecrit : " + x); } } 48

Page 13: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Méthodes existantes dans une classe

  Tous les classes JAVA héritent de la classe de base Object, qui contient :   Pour l’affichage : toString()

  Doit retourner une représentation textuelle de l’objet   Elle est utilisée par System.out.println

  Pour les tests d’égalité : equals()   a==b ne test pas si les objets a et b sont identiques mais si a et b regarde le même objet   Il faut définir le test d’égalité avec la méthode equals

  Pour recopier un objet : clone() class Point { …… public String toString() {return("abscisse:"+x+" ordonnée:"+y);}

// Avec cette methode, on peut afficher point avec System.out.println(a) public boolean equals(Point b) {return( x==b.x && y==b.y); } }; public class Ex8c { public static void main (String []arg) { Point a,b,c,d; a= new Point(1,2); b = new Point(1,2); c=new Point(1,3); d=a; System.out.println(a);// Affiche a if (a==b) System.out.println("a et b pointe le meme objet"); if (a==d) System.out.println("a et d pointe le meme objet"); if (a.equals(b)) System.out.println("a et b de contenu identique"); if (a.equals(c)) System.out.println("a et c de contenu identique"); if (a.equals(d)) System.out.println("a et d de contenu identique"); } }

49

Résumé

  Un programme objet :   1 fonction main qui démarre le programme, crée les objets et les enchainements d’actions   1 ensemble de classes décrivant les capacités des données manipulées

  1 classe : type de données qui rassemble des données (champs) et la manière de s’en servir (méthodes)   Données et méthodes protégées si besoin :

  public : n’importe quelle fonction du programme peut les modifier ou les utiliser   private : seules les méthodes de la classe concernée peuvent les modifier ou les utiliser

  En pratique   données privées.   Que doit faire l’utilisateur avec la classe que je développe ? ==> seules méthodes publiques

•  Initialisation, affichage, addition, etc..   Autres méthodes privées

  Constructeurs : comment initialiser l’objet ?   Accesseurs et mutateurs : méthodes publiques ou privées définissant l’accès en lecture/ecriture à un champ   Surcharge : plusieurs fonctions peuvent avoir le même nom, mais pas les mêmes nombres et/ou types de

paramètres   1 objet : 1 instance

  Définir la variable   Créer l’objet   Destruction de l’objet automatique quand on n’en a plus besoin : pas de gestion mémoire ni pointeurs   Exécuter une méthode ou fonction : objet.méthode(parametres);

  x.affiche(); ou c1.add(c2,c3);   INTERDIT : affiche(x)

  Aucune fonction/méthode hors d’une classe, aucune variable hors d’une méthode   Mélanger, ajouter 3 litres de jus d’orange, 1 litre de vodka, et ca doit marcher !!!

50

Tableaux

Tableaux et tableaux d’objets

Tableaux

  Ensemble d’objets de même type à accès direct   Les tableaux sont des OBJETS   Taille du tableau fixe, n’est pas modifiable, accessible par la valeur (et pas la

méthode) length: tab.length;   Accès aux éléments par tab[i]   Vérification des bornes, ArrayIndexOutOfBoundsException si erreur   Indices débutant à 0

1 2 3 0 9 Indices

Tableau de 10 éléments

tableau 0 2 4 6

  Création d’un tableau en 3 étapes

3/ Utilisation : tableau [i] = 2*i

1/ Déclaration d’une variable : int [] tableau;

2/ Instanciation ou création : tableau = new int [10];

Page 14: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Tableaux (2)

  Ex9.java   Lire la dimension au clavier, créer un tableau de nombre, le remplir et l’afficher

import java.util.*; public class Ex9 { public static void main(String[] arg) { int [] tableau; Scanner clavier = new Scanner (System.in); System.out.println("Nombre d'element du tableau ?"); int nb = clavier.nextInt(); tableau = new int [nb]; for (int i=0; i<tableau.length ; i++) tableau[i]=2*i+1; for (int i=0; i< tableau.length ; i++) System.out.print(tableau[i]+" " ); tableau[2+ tableau.length ]=0; // ERREUR : pourquoi ? } }

Copie de tableaux de nombres ou partage

  Copie : fonction arraycopy : la destination doit etre créée (allouée) System.arraycopy(Object src, int indsrc, Object dest, int inddest, int long)

public class Ex10 { public static void main (String []arg) {Scanner clavier = new Scanner(System.in); double [] t1, t2,t3; System.out.println("Entrer le nombre de reels"); t1 = new double [ clavier.nextInt()]; for (int i=0; i< t1.length ; i++) t1[i]=2*i+1; for (int i=0; i< t1.length ; i++) System.out.print(t1[i]+" "); System.out.println(); t2=t1; t3 = new double [ t1.length ]; System.arraycopy(t1,0,t3,0,t1.length); for (int i=0; i< t2.length ; i++) System.out.print(t2[i]+" "); System.out.println(); for (int i=0; i< t3.length ; i++) System.out.print(t3[i]+" "); System.out.println(); for (int i=0; i< t2.length ; i++) t2[i]=-1; for (int i=0; i< t1.length ; i++) System.out.print(t1[i]+" "); System.out.println(); for (int i=0; i< t2.length ; i++) System.out.print(t2[i]+" "); System.out.println(); for (int i=0; i< t3.length ; i++) System.out.print(t3[i]+" "); System.out.println(); } }

Copie de tableaux de nombres ou partage

1 2 3 0 9 t1 1 3 5 7

1 2 3 0 9 t3 1 3 5 7

t2

-1 -1 -1 -1

Tableaux d’objets

  Création d’un tableau d’objet : 2 étapes   Créer le tableau :

  Point [] tab = new Point [ clavier.nextInt()];   Créer chaque objet du tableau :`

  for (int i=0; i< tab.length ; i++) tab[i]=new Point(2*i,2*i+1);

  Exemple : tableau de points public class Ex11 { public static void main (String []arg) { Point [] tab; Scanner clavier = new Scanner(System.in); System.out.println("Entrer le nombre de points"); tab = new Point [ clavier.nextInt()]; clavier.nextLine(); // Attention ; les points ne sont pas créés for (int i=0; i< tab.length ; i++) System.out.print(tab[i]+" "); System.out.println(); clavier.nextLine(); // Creation des points for (int i=0; i< tab.length ; i++) tab[i]=new Point(2*i,2*i+1); for (int i=0; i< tab.length ; i++) System.out.print(tab[i]+" "); System.out.println(); } }

Page 15: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Copie légère ou profonde de tableaux d’objets

  arraycopy ! recopie de tous les éléments du tableau   Ne duplique pas les objets !!! --> partage des objets t[i] : copie légère   SI le programmeur duplique aussi les objets t[i] : copie profonde

public class Ex12 { public static void main (String []arg) { Point [] tab, copie1, copie2; Scanner clavier = new Scanner(System.in); System.out.println("Entrer le nombre de points"); tab = new Point [ clavier.nextInt()]; // Creation des points for (int i=0; i< tab.length ; i++) tab[i]=new Point(2*i,2*i+1); // Pour tous les points du tableau tab for (Point a : tab) System.out.print(a+" "); System.out.println(); copie1 = tab; copie2 = new Point [tab.length] ; System.arraycopy(tab,0,copie2,0,tab.length); for (Point a : tab) System.out.print(a+" "); System.out.println(); for (Point a : copie1) System.out.print(a+" "); System.out.println(); for (Point a : copie2) System.out.print(a+" "); System.out.println(); // On met toutes les abcisses de tab a zero for (int i=0; i< tab.length ; i++) tab[i].setx(0); for (Point a : tab) System.out.print(a+" "); System.out.println(); for (Point a : copie1) System.out.print(a+" "); System.out.println(); for (Point a : copie2) System.out.print(a+" "); System.out.println(); } }

Copie légère de tableaux d’objets

0 1

2 3

2 3

tab 1 2 3 0 9

copie1

copie1=tab

arraycopy(…)

copie2

  Pour la copie profonde, il faut utiliser la méthode clone(). Voir plus loin sur les interfaces

0 1

0 3

0 3

Copie légèrede tableaux d’objets

Notion d’objet

Les classes et objets composés

Page 16: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Les points essentiels

  Agrégation ou composition   Construction

  Héritage   Chainage des constructeurs   Protection des attributs   Redéfinition des méthodes / Surcharge des méthodes

  Polymorphisme

  Liaison dynamique   Classe abstraite

  Héritage multiple

Des objets dans les objets

  Une classe Cercle   Les champs

  Le point du centre : de la classe Point: C’est un lien de COMPOSITION   Le rayon : un double

  Les méthodes   La surface   L’affichage   La translation

Classe Point

import java.util.*; class Point { /* Definition des donnees d'un point */ private double x; private double y; /* Constructeur : 1 seule définition, les 2 autres l'appellent */ public Point (double a, double b) { setx(a); sety(b); } public Point () { this(0.,0.); } public Point (Point a) { this(a.getx(),a.gety()); } /* Accesseurs et mutateurs */ public double getx() { return x; } protected void setx(double val) { x=val; } public double gety() { return y; } protected void sety(double val) { y=val; } public void affiche() { System.out.println("Abcisse "+getx()+" ordonnee : "+gety());} /* Comment translater un point */ public void translate(double a, double b) { setx(getx()+a); sety(gety()+b); } public void translate(Point t) { translate(t.getx(),t.gety()); }

/* Afficher un nombre : deux ecritures */ public String toString() { return Double.toString(x)+","+ y +" "; }

public boolean equals(Point b) {return( getx()==b.getx() && gety()==b.gety()); } public Point multcste(double k) { Point res= new Point(this); res.setx(getx()*k); res.sety( gety()*k); return res; } };

Des objets dans les objets

class Cercle { // on utilise au maximum les méthodes de Point. private Point cdg; private double rayon; public Cercle() { rayon=0; cdg= new Point(); } // Attention : créer le cdg public Cercle(Point p, double r) { rayon=r; cdg=new Point(p); } // pas cdg=p; public Cercle(double cdgx, double cdgy, double r) { rayon=r; cdg=new Point(cdgx, cdgy); } public double surface() { return (Math.PI*rayon*rayon); } public String toString() { return("Cercle de Cdg "+cdg.toString()+" et de rayon"+rayon);} //OU public String toString() { return("Cercle de Cdg "+cdg+" et de rayon"+rayon);} public void translate(double a, double b) { cdg.translate(a,b); } } public class Ex13 { public static void main (String []arg) { Scanner clavier = new Scanner(System.in); Cercle c1, c2; double x1, x2,r; Point a; // Creation du cercle avec les 3 valeurs lues au clavier System.out.println("Entrer le cdg du cercle 1, puis le rayon"); c1 = new Cercle(clavier.nextDouble(), clavier.nextDouble(),clavier.nextDouble()); System.out.println("C1 : "+c1 + "de surface :"+c1.surface()); System.out.println("Cdg cercle 2"); x1=clavier.nextDouble(); x2=clavier.nextDouble(); a= new Point(x1,x2); // Création du point avec les x1 et x2 1 System.out.println("Entrer le rayon du cercle 2"); r=clavier.nextDouble(); c2 = new Cercle(a,r); System.out.println("C2 : "+c2+" de surface :"+c2.surface()); System.out.println("translation ?"); x1=clavier.nextDouble(); x2=clavier.nextDouble(); c1.translate(x1,x2); System.out.println("C1 : "+c1); } }

Page 17: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Héritage

Héritage simple

Héritage   L’héritage est un concept pour les fainéants qui exploitent le travail

des autres   L’héritage permet de réutiliser ce qui a déjà été fait très

simplement   La nouvelle classe (fille) hérite d’une classe existante (père)   Elle possède les mêmes champs et les mêmes méthodes   On peut ajouter de nouveaux champs et de nouvelles méthodes

  L’héritage est récursif : une classe dérivée peut devenir classe de base

  Les liens hiérarchiques forment un arbre : l’arbre d’héritage

Héritage : Augmenter les capacités

  Augmenter les capacités d’un point   Exemple : Ajout de la gestion de la couleur d’un point : class Point { private double x, y; ……………

public void translate(double a,double b) {setx(x+a); sety(y+b); } } class PointCouleur extends Point { /* Definition des champs d'un point couleur ; on a déjà x et y */ private int couleur; public PointCouleur () { // Par defaut, x et y sont nuls super(); // ATENTTION : x=0; y=0; est interdit couleur=0; } public PointCouleur (double a, double b, int c) { super(a,b); couleur=c; } public String toString(){return (super.toString()

+ "couleur"+Integer.toString(couleur));} };

Héritage : Spécialiser l’objet

  Spécialiser les capacités d’un point   Exemple : Uniquement les points positifs : class Pointpositif extends Point { // on autorise que les nombres positifs public void setx (double a) { if (a>=0) super.setx(a); else

System.out.println("Erreur "+a); }; public void sety (double a) { if (a>=0) super.sety(a); else

System.out.println("Erreur "+a); }; }; public class Ex16 { public static void main (String []arg) {PointCouleur a,b,c ; Pointpositif d; a=new PointCouleur(1,2,0); b=new PointCouleur(4,5,255); c=new PointCouleur(8,9,65535); System.out.println("a "+a); System.out.println("b "+b); a.translate(2,3); System.out.println("a "+a); //c = b.multcste(5); System.out.println("c "+c); d =new Pointpositif(1,2); System.out.println("d "+d); d.translate(1,1); System.out.println("d "+d); d.translate(-3,0); } }

Page 18: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Héritage : Mettre en commun

  Faire des classes permettant de manipuler les cercles et les rectangles   Créer   Calculer la surface   Translater

Héritage : Mettre en commun

  Les cercles et les rectangles ont des points communs   Le cdg   La creation

  On fait donc une classe « pere » qui reroupe les parties communes des cercles et des rectangles

  On peut faire encore plus !!

Héritage : intérêt

  Définir explicitement les liens entre les classes   Une classe augmente ou étend les possibilités d’une autre classe : on ajoute la notion de couleur   Une classe spécialise une autre classe : le point positif est un point du quart de plan x>0 y>0   Une classe adapte le comportement d’une autre classe à un besoin concret   A l’inverse, une classe mère regroupe des comportements communs (voir la classe forme ci

dessous)   Un mélange des trois raisons précédentes

  Exploiter les classes existantes   Sans écrire de code   Sans connaître le code

  Génie logiciel : organisation du développement logiciel   Regrouper les aspects (ici, champs ou methodes) communs   Définir les accès et les protections des structures de données   Mieux conceptualiser les développements

  Comment ?   Trouver les relations de type « est-un » : classe dérivée   Trouver les points communs et les regrouper : classe mère

Héritage : ne pas confondre avec l’association

  Relation de spécialisation/généralisation   Spécialisation d’une classe par rapport à

un modèle de base : héritage   Ex : le lien Ecran-Périphérique

  Relation structurelle d’agrégation   Composition d’un objet par un ou

plusieurs composants ou objets appartenant uniquement à cet objet

  Ex : Ordi possède un écran et clavier

  Relation structurelle d’association   Relation existant entre deux objets,

moins forte que la précédente (non exclusive)

  Ex : une entreprise emploie une personne mais les objets représentant la personne et l’entreprise existe séparément.

  Le graphe complet pour un ordi

Page 19: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Champs hérités :

  Un objet possède tous les champs de sa classe et de sa classe mère, de grand-mère…   Le nom est comme précédemment : objet.nom_du_champ

  Le nom de la classe mère n’apparaît pas : si a est un PointCouleur : on écrit a.couleur, a.x, a.y   Mais

  Les protections s’appliquent : les champs privés ne sont accessibles que par les méthodes de la classe où ils sont définis. Les champs x et y de Point sont privés

  Un objet de la classe PointCouleur accède au champ couleur mais pas aux champs x et y s’ils sont private.   Important quand vous définissez une hiérarchie de classes utilisées par d’autres !!!!   Trop lourd lorsque c’est un ensemble de classes cohérentes comme les Point, PointCouleur

  Donc   Le mot clé protected permet l’accès aux champs pour toutes les classes dérivées   Le mot clé final interdit à une classe d’etre superclasse, à une méthode d’etre redéfinie.

Champs hérités privés :

class Point { private double x, double y; …. } class PointCouleur extends Point { private int couleur;

/* Les nouveaux constructeurs */ public PointCouleur () { x=y=0; couleur=0; } // INTERDIT car x et y privé public PointCouleur (double a, double b, int c) { super(a,b); couleur=c; } public String toString(){ return (super.toString()+ "couleur

"+Integer.toString(couleur)); } }; public class Ex17a { public static void main (String []arg) { PointCouleur a,b; a=new PointCouleur(1,2,0); b=new PointCouleur(4,5,255); System.out.println("a "+a);

System.out.println("b "+b); a.translate(2.,3.); System.out.println("a

"+a); a.x=56; INETRDIT, car main n’est pas une

méthode de PointCouleur } }

  Impossible d’utiliser les parties privées x et y d’un point couleur sans mutateur

  Parfois lourd à programmer

Champs hérités protected :

class Point { protected double x, double y; …. } class PointCouleur extends Point { /* Definition des champs d'un point couleur ; on a déjà x et y */ protected int couleur;

/* Les nouveaux constructeurs */ public PointCouleur () { x=y=0; couleur=0;} // ATENTION : on peut modifier x et y public PointCouleur (double a, double b, int c) { super(a,b); couleur=c; } public String toString(){ return (super.toString()+ "couleur "+Integer.toString(couleur)); // super, c’est la classe mere } }; class Truand extends PointCouleur {

public void setx(double a) { x=a; } // Je modifie x, meme si je n’ai pas le code PointCouleur: contraire à la POO

} public class Ex17 { public static void main (String []arg) {PointCouleur a,b; Truand c; a=new PointCouleur(1,2,0); b=new PointCouleur(4,5,255); System.out.println("a "+a); System.out.println("b "+b); a.translate(2,3); System.out.println("a "+a); //a.x=56; A Eviter, car main n’est pas une méthode de PointCouleur c = new Truand(); System.out.println(c); //Vraiment pas recommandé; il suffit de déclarer PointCouleur comme classe finale

pout etre tranquille c.setx(8); System.out.println(c); } }

  Utilisation directe des parties protected x et y d’un point   Attention à la protection qui peut etre détournée

  On suppose que Point et PointCouleur sont écrites et on ne dispose pas du source

  Truand hacke la classe Point par héritage

Champs hérités : conserver la protection

class Point { protected double x, double y; …. } final class PointCouleur extends Point { /* Definition des champs d'un point couleur ; on a déjà x et y */ protected int couleur;

…………. }; class Truand extends PointCouleur { // Interdit car classe PointCouleur est

final public void setx(double a) { x=a; }

} public class Ex17b { public static void main (String []arg) {PointCouleur a,b; Truand c; …. } }

  Pour empecher n’importe quel utilisateur de modifier les champs protected, il faut interdire l’héritage

  La classe truand ne peut plus hériter de PointCouleur

Page 20: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Méthodes héritées : comment s’y retrouver

  Un objet possède toutes les méthodes de sa classe et de sa classe mère, de grand-mère…

  L’appel est comme précédemment : objet.nom_de_methode(parametres);   Le nom de la classe mère n’apparaît pas :

si a est un PointCouleur : a.translate(2,3);   Comment trouve t on la bonne méthode ?

  On cherche dans la classe de l’objet a :   si la méthode est ici (meme nom, meme nombre et type de paramètres), on l’execute

  Sinon On cherche dans la classe mère de a, puis dans la classe grandmère….   Mot clé super : désigne la classe mère de l’objet ou de la classe.

  Permet d'exécuter les méthodes dont on hérite   exemple : méthode toString dans la classe PointCouleur

  Attention au vocabulaire   Une méthode est redéfinie dans une hiérarchie lorsqu’elle a le même nom et les

mêmes types de paramètre   Une méthode est surchargée lorsqu’elle a le même nom et des types différents de

paramètres

Méthodes redéfinies et surchargées :

class Point { ….. public void translate(double a,double b) { System.out.println("Methode translate de point"); x += a; y+= b; } class PointCouleur extends Point { /* Definition des champs d'un point couleur ; on a deja x et y */ protected int couleur; /* Les nouveaux constructeurs */ public PointCouleur () { super(); couleur=0;} public PointCouleur (double a, double b, int c) { super(a,b); couleur=c; } public String toString(){ return ("redefinie : "+super.toString()+"couleur " +Integer.toString(couleur)); } public void translate(double a,double b, int c) { // SURCHARGE : c System.out.println(" Surcharge methode translate "); super.translate(a,b); couleur += c; } }; public class Ex18 { public static void main (String []arg) {PointCouleur a,b; a=new PointCouleur(1,2,0); b=new PointCouleur(4,5,255); System.out.println("a "+a); System.out.println("b "+b); a.translate(2,3); System.out.println("a "+a); b.translate(4,8,-1); System.out.println("b "+b); } }

Cas particulier des constructeurs

  La classe PointCouleur dérive de Point.   Donc,   lors de la construction d’un PointCouleur, il faut qu’un constructeur de

Point soit appelé, car seul Point est responsable de la construction d’un point

  Donc, un constructeur de PointCouleur appelle toujours un constructeur de Point   Soit explicitement

  super(parametres) : appel explicite en PREMIERE instruction à un constructeur de Point

  this(parametres) : appel explicite en PREMIERE instruction à un constructeur de PointCouleur

  Soit implicitement   Aucun appel explicite: le compilateur ajoute un appel à super() en tete de

constructeur.   S’il n’y a pas de constructeur Point(), erreur d’execution

Cas particulier des constructeurs (2)

import java.util.*; class Point { protected double x,y; public Point (double a, double b) {

System.out.println("Point : Constructeur 1"); x = a; y = b; } public Point () {

System.out.println("Point : Constructeur 2"); x = 0; y = 0; } public Point (Point a) {

System.out.println("Point : Constructeur 3"); x = a.x; y = a.y; } }; class PointCouleur extends Point { protected int couleur; public PointCouleur (double a, double b, int c) { super(a,b); couleur=c; System.out.println("PointCouleur : Constructeur

1"); } public PointCouleur () { System.out.println("PointCouleur : Constructeur 2"); couleur=0; } public PointCouleur (PointCouleur a) { this(a.x,a.y,a.couleur); System.out.println("PointCouleur :

Constructeur 3"); } } public class Ex19 { public static void main (String []arg) { PointCouleur a,b,c; Scanner clavier = new Scanner(System.in); System.out.printf("Construction a"); a = new PointCouleur(1,2,3); System.out.printf("Construction b"); b = new PointCouleur(a); System.out.printf("Construction c"); c = new PointCouleur(); } }

Page 21: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Héritage et Polymorphisme

Liaison statique et dynamique

Héritage et Polymorphisme

  Polymorphisme : même traitement pour des objets de classe différentes   Interet : même nom pour des choses identiques (clone(), toString(), translate()…)   Liaison dynamique : si x est une forme, quelle est la vraie méthode qui s’applique à x   Exemple : surface() ?

Polymorphisme : exemple

class Forme { protected Point cdg; public Forme() { cdg=new Point(0,0);} public Forme(double a, double b) { cdg=new Point(a,b);} public Forme(Point a) { cdg=new Point(a); } double surface() { System.out.println("Surface de Forme"); return 0; } void translate(double a, double b) { System.out.println("Translate de

Forme"); cdg.translate(a,b); } public String toString() {return cdg.toString(); } } class Cercle extends Forme{ protected double rayon; public Cercle() { super(); rayon=0; } public Cercle(Point p, double r) { super(p); rayon=r; } // pas cdg=p; public Cercle(double cdgx, double cdgy, double r) { super(cdgx,cdgy);

rayon=r; } public double surface() { System.out.println("Surface de Cercle"); return

(Math.PI*rayon*rayon); } public String toString() { return ("Cercle de Cdg "+cdg.toString()+" et de

rayon "+Double.toString(rayon)); } }

Polymorphisme : exemple

class Rectangle extends Forme { protected double largeur, hauteur; public Rectangle() { super(); largeur=hauteur=0; } public Rectangle(Point p, double l, double h) { super(p);largeur=l;hauteur=h; } public Rectangle(double cdgx, double cdgy, double l, double h)

{super(cdgx,cdgy);largeur=l;hauteur=h; } public double surface() { System.out.println("Surface de Rectangle"); return

(largeur*hauteur);} public String toString() { return (getClass().getName()+"Rectangle "+super.toString()

+" "+hauteur+" "+largeur); } } public class Ex20 { public static void main (String []arg) { Scanner clavier = new Scanner(System.in); Cercle c1; Rectangle r1; Forme f1, f; c1=new Cercle(2,3,4); r1=new Rectangle(8,9,2,3); f1 = new Forme(6,7); double s1=c1.surface(); System.out.println("Surface de c1 "+s1); double s2=r1.surface(); System.out.println("Surface de r1 "+s2); double s3=f1.surface(); System.out.println("Surface de f1 "+s3); f=c1; System.out.println("Surface de f"+f.surface()); f=r1; System.out.println("Surface de f"+f.surface()); f=f1; System.out.println("Surface de f"+f.surface()); f = new Cercle(5,6,7); System.out.println("Surface de f"+f.surface()); } }

On connaît les classes de c1, r1,f1

Ici, on ne connaît pas la classe réelle de f

Quel est le résultat ?

Page 22: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Polymorphisme : exemple (3)

  Conclusion   Liaison statique : lorsque la classe est connue, la fonction surface utilisée est celle de la

classe de l’objet appelant. JAMAIS EN JAVA   Liaison dynamique : lorsque la classe effective est inconnue (f est une forme), le type

réel de l’objet est déterminé dynamiquement (au moment de l'exécution) avant de chercher la fonction. C’est donc la fonction de la classe réelle qui est utilisée, et non celle de la classe visible

  Attention, c’est la notion de conversion entre classe de base et dérivée : un rectangle est une forme, mais l’inverse n’est pas vrai.

Liaison dynamique, vérification statique

  Vérifications statiques   À la compilation   À partir du type déclaré de l’objet : la classe de cette objet doit contenir une méthode dont la signature

est compatible avec l’appel   On ne connaît pas le type réel de l’objet, donc impossible de vérifier la classe effective contient une

méthode correcte   Le type de la méthode est définit à la compilation en fonction des paramètres. Si Forme et ses dérivés

contiennent les fonctions surface() et surface(int), c’est à la compilation que l’on définit si on utilisera des méthode surfe’) ou surface(int)

Forme a = new Forme(); a.surface(); // La classe Forme doit contenir une méthode surface() Forme b = new Rect(); b.surface(); // La classe Forme doit contenir une méthode surface(), car ici

le compilateur ne peut pas savoir que b est un rectangle. Mais il sait que la méthode surface ne prend pas de paramètres

b.surface(10); // La classe Forme doit contenir une méthode surface(int),   L’execution recherche simplement dans la classe réelle de l’objet la méthode dont

la compilation a définit le choix. Forme a = new Forme(); a.surface(); /l’execution execute surface() de Forme Forme b = new Rect(); b.surface(); //l’execution execute surface() de Rect b.surface(10); //l’execution execute surface(int) de Rect

Polymorphisme et classe abstraite

Polymorphisme et classe abstraite

  Peut on déterminer la surface d’une forme ?   Qu’est ce qu’une forme ?

  Un concept : on ne peut créer un objet de type Forme, puisque qu’on ne peut pas le définir complètement   La méthode surface est impossible à écrire. Renvoyer 0 est une aberration   Que faut il faire ?

  Dans la classe Forme, surface est donc une méthode abstraite   Surface() doit exister dans les classes dérivées, mais on ne sait pas l’écrire au niveau de

forme

  De ce fait, la classe Forme est une classe abstraite   On ne peut pas créer un objet à partir d’une classe abstraite, car il n’est pas

complètement défini   Une classe peut hériter d’une classe abstraite. Si une classe hérite d’une méthode

abstraite et que cette méthode n’est pas redéfinie dans la classe, alors la classe est obligatoirement abstraite.

Page 23: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Polymorphisme et classe abstraite

abstract class Forme { protected Point cdg; public Forme() { cdg=new Point(0,0);} public Forme(double a, double b) { cdg=new Point(a,b);} public Forme(Point a) { cdg=new Point(a); } abstract double surface(); void translate(double a, double b) { System.out.println("Translate de Forme");

cdg.translate(a,b); } public String toString() {return cdg.toString(); } } class Cercle extends Forme{ protected double rayon; public Cercle() { super(); rayon=0; } public Cercle(Point p, double r) { super(p); rayon=r; } // pas cdg=p; public Cercle(double cdgx, double cdgy, double r) { super(cdgx,cdgy); rayon=r; } public double surface() { System.out.println("Surface de Cercle"); return

(Math.PI*rayon*rayon); } public String toString() { return ("Cercle de Cdg "+cdg.toString()+" et de rayon

"+Double.toString(rayon)); } }

Polymorphisme et classe abstraite

class Rectangle extends Forme { protected double largeur, hauteur; public Rectangle() { super(); largeur=hauteur=0; } public Rectangle(Point p, double l, double h) { super(p); largeur=l;hauteur=h; } public Rectangle(double cdgx, double cdgy, double l, double h)

{super(cdgx,cdgy);largeur=l;hauteur=h; } public double surface() { System.out.println("Surface de Rectangle"); return

(largeur*hauteur);} public String toString() { return (getClass().getName()+"Rectangle "+super.toString()

+" "+hauteur+" "+largeur); } } public class Ex21 { public static void main (String []arg) { Scanner clavier = new Scanner(System.in); Cercle c1; Rectangle r1; Forme f1, f; c1=new Cercle(2,3,4); r1=new Rectangle(8,9,2,3); // f1 = new Forme(6,7); double s1=c1.surface(); System.out.println("Surface de c1 "+s1); double s2=r1.surface(); System.out.println("Surface de r1 "+s2); double s3=f1.surface(); System.out.println("Surface de f1 "+s3); f=c1; System.out.println("Surface de f"+f.surface()); f=r1; System.out.println("Surface de f"+f.surface()); // f=f1; System.out.println("Surface de f"+f.surface()); f = new Cercle(5,6,7); System.out.println("Surface de f"+f.surface()); } }

Polymorphisme et classe abstraite

  Un tableau de formes à dessiner ou à calculer ? public class Ex22 { public static void main (String []arg) { Scanner clavier = new

Scanner(System.in); Forme [] tab; System.out.println("Nombre de forme "); tab = new Forme [clavier.nextInt()]; for (int i=0; i< tab.length; i++) { switch( (int) ((Math.random()+0.5)*2)) { case 1: System.out.println(i+" est un rectangle "); tab[i]=new Rectangle(Math.random(),Math.random(),Math.random(),Math.random()); break; case 2: System.out.println(i+" est un cercle "); tab[i]=new Cercle(Math.random(),Math.random(),Math.random()); break; } for (int i=0; i< tab.length; i++) System.out.println("Surface de "+ i+" = "+tab[i].surface());

// Modifions l’ordre Forme f = tab[0]; tab[0]=tab[tab.length -1]; tab[tab.length -1]=f; for (int i=0; i< tab.length; i++) System.out.println( i+" = "+tab[i]); } }

Interface

Page 24: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Interface

  Une interface est un ensemble d'opérations utilisée pour spécifier un service offert par une classe.   Elle peut être vue comme une classe sans attributs et dont toutes les opérations

sont spécifiées mais pas définies à priori (ie vides)�   Elle peut être vue comme un contrat ou un modèle que doivent offrir toutes les

classes qui se réclame (implémente) de cette interface public interface objetgeometrique{ public int surface(); public void translate(int , int ); }

Héritage

Héritage multiple

Héritage multiple

animaux

Animaux volant Animaux nageant Animaux courant

Truites

  Les animaux sont définis par une classe   Les animaux volant, nageant, courant sont eux aussi défini par une classe

  Une truite est définie par une classe dérivant de nageant

Héritage multiple : le canard

animaux

Animaux volant Animaux nageant Animaux courant

Truites Canard

  Un canard vole

  Un canard court (pas vite)

  Un canard nage (mal)

  Pour respecter la notion d’héritage, il faut donc que la classe canard hérite des 3 classes volant, nageant, courant

Page 25: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Héritage multiple : problème Héritage multiple : problème

  Une truite hérite des champs   Vitesse par Nageant   Poids, nom et cdg par Nageant/Animaux

  Un canard hérite des champs

  Vitesse par Nageant   Poids, nom et cdg par Nageant/Animaux   Vitesse par Volant   Poids, nom et cdg par Volant/Animaux   Vitesse par Courant   Poids, nom et cdg par Courantt/Animaux

  Donc un canard a 3 poids !!!   Il faudrait de l’héritage partagé (cela existe en C++ avec l’heritage virtuel) de manière

à ce que la classe Canard n’hérite qu’une seule fois des champs poids, nom et cdg.

Héritage multiple : solution

  Solution proposée pour le cas du canard

Héritage multiple

  Interdit en JAVA : une classe ne peut hériter que d’une seule autre classe   mais autorisé en C++   Remplacé par la notion d’interface   Qu’est ce qu’une interface en JAVA

  Précise des comportements (des méthodes) que doivent avoir les objets qui en dérive   Ne définit pas ses comportements   N’a pas de champs (hormis des constantes)

  Une interface peut hériter d’une autre interface

Page 26: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Héritage multiple Héritage multiple

class Animaux { protected int poids; protected Point cdg; public Animaux( int p) { poids=p; cdg=new Point(0,0);} public void deplace(int a, int b) {cdg.translate(a,b); } public String toString() { return ("Animal : poids "+poids+" au point

"+cdg); } }; interface Volant { void vole(); public String toString(); }; interface Nageant { void nage(); public String toString(); }; interface Courant { void coure(); public String toString(); };

Héritage multiple

class Canard extends Animaux implements Volant, Nageant, Courant { private int vitessecourse=2, vitessenage=5, vitessevole=3; private String nom; public Canard (String name, int p){super(p); nom=new String (name); } public String toString() { return ("Canard "+nom+" "+super.toString()); } public void vole() { super.deplace(vitessevole,vitessevole); } public void nage() { super.deplace(vitessenage,vitessenage); } public void coure() { super.deplace(vitessecourse,vitessecourse); } } Class Chien extends Animaux implements Courant { private int vitessecourse=10; private String nom; public Chien (String name, int p){super(p); nom=new String (name); } public String toString() { return ("Canard "+nom+" "+super.toString()); } public void coure() { super.deplace(vitessecourse,vitessecourse); } } public class Ex23 { public static void main (String []arg) { Canard a; Chien b; a=new Canard("Duffy",10); System.out.println(a); b = new Chien("Medor",50); System.out.println(b); a.vole(); System.out.println(a); a.nage(); System.out.println(a); a.coure(); System.out.println(a); b.coure(); System.out.println(b); // b.vole (); } }

Héritage multiple

  Exemple : Affiche image est un composant qui permet d’afficher une image   Quand j’ écris ce composant, je veux qu’il soit utilisable pour afficher facilement d’autres

images. Par exemple, Comment l’utiliser sur les classes Fractales que vous avez faites   Dans l’écriture de AfficheImage, les éléments dont j’ai besoin sont la dimension de l’image et

les pixels de l’image.   Pour pourvoir afficher, il faut donc que l’image possède ces 3 éléments : on pourrait faire de

l’héritage des classes (Mendel) à afficher   MAIS Julia hérite de Fractale, qui hérite de Object.   Elle ne peut pas hériter de Imagecalcul.   On fait donc de Imagecalcul une interface

Page 27: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Les containers

Tableaux, Listes, Ensembles, Listes associatives

Les containers

  Les structures de données classiques   Listes

  Accès séquentiel : premier, suivant ==> recherche lente   Dynamique : nombre d’éléments variable dans le temps   Insertion, suppression faciles et efficace

  Tableaux   Accès direct   Nombre d’éléments fixés à l’avance   Insertion et suppression lentes

  Containers : les structures classiques + les principaux algorithmes disponibles

  Structures linéaires   Listes   Ensembles, ensembles triés: éléments ne peuvent etre dupliqués   Tableaux, Tableaux dynamiques

  Structures associatives ou dictionnaire =Map   Eléments : couple clé-valeur   Exemples : (nom, n°telephone)

  Structures plus complexes : tables hachage, arbres binaire, arbres balancés   Méthodes et algorithmes

  Ajout, suppression, appartenance, recherche   Tri,

Les containers

Classe concrete Interface

2 catégories de conteneurs

  Collection<E>

  List<E> structure séquentielle, l'utilisateur contrôle l'ordre des éléments.   ArrayList<E> implémentation dans tableau de taille variable, accès par indice   Vector<E> toujours implémentation dans tableau … (plus vieux)   LinkedList<E> implémentation par double chaînage et pointeurs

  Queue<E> FIFO, file à priorité   Set<E> (pas deux éléments identiques)

  HashSet<E> ensemble non ordonné, impléménté par table de hachage   TreeSet<E> ensemble ordonné implémenté par arbre binaire de recherche équilibré

(red black tree)

  Map<K,V> ensemble associatif   HashMap<K,V> les clés sont un ensemble non ordonné   TreeMap<K,V> : item les clés sont un ensemble ordonné

Page 28: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Quelques méthodes communes aux collections

Collection<E>

boolean isEmpty(); int size(); boolean add(E elt); // vrai s’il est effectivement ajouté boolean remove(Object o); // vrai s’il est effectivement retiré void clear(); boolean contains(Object o);

  Pour l’instant, utiliser contains et remove avec le profil :

  boolean remove(E elt);   boolean remove(E elt);

  Méthodes static de la classe outil Collections : des algo génériques

  void Collections.sort(List<E>);   E Collections.max(Collection<E>); E Collections.min(Collection<E>);   void Collections.reverse(List<E>);

  Aller voir l’API pour plus !!!

Quels containers choisir ?

  En général, on sait si on a besoin d’une liste, d’un tableau, d’un ensemble, d’un ensemble trié, d’un dictionnaire, d’un dictionnaire trié, d’un arbre binaire de recherche.

  On définit un objet du type de l’interface la plus générique : Collection   On crée ensuite l’objet réel du type voulu :

  Linkedlist : liste séquentielle classique avec pointeur   ArrayList : liste implantée par un tableau avec accès par index rapide. On peut aussi

considérer que c’est un tablleau dont la taille peut varier dans le temps.   Vector, à peu pres identique à ArrayList   Queue (FIFO) : file !!!   HashSet : ensemble implémenté par une table de hashage

  Ensemble : une seule occurrence de chaque élément autorisé   Accès aux éléments rapide

  TreeSet, : ensemble implémenté avec un arbre binaire de recherche, trié en permanence   HashMap : ensemble associatif (clé valeur)   TreeMap : Ensmble associatif trié en permanence sur la clé

  Accès aux éléments rapide en log(n)

Les collections : les méthodes générales

  Méthodes de la classe collections   boolean isEmpty() : test si le conteneur est vide   int size() : renvoi le nombre d’éléments du conteneur   boolean add(Object) : ajoute un élément au conteneur   boolean addAll(Collection) : ajoute tous les éléments d’une collection au conteneur   boolean remove(Object) : supprime un élément au conteneur   boolean removeall(Collection) : supprime tous les éléments d’une collection du conteneur   void clear() : supprimer tous les éléments du conteneur   boolean contains(Object) : appartenance d’un élément au conteneur   Object [] toArray() : transforme une collection en tableau

  Iterator iterator() : définit un itérateur pour le parcours du conteneur

  Méthodes statiques : algorithmes génériques

  void sort(List)   Object max(Collections), Object min(Collections)   void reverse(list)   void rotate(collection, distance)

L’interface list : les méthodes

  Methodes   boolean add(int index, Object o) : ajoute un élément d’indice index au conteneur   Object get(int index) : obtient l’objet à l’indice index du conteneur   boolean remove(int index) : supprime un élément d’indice index au conteneur   boolean removeall(Collection) : supprime tous les éléments d’une collection du conteneur

  LinkedList

  Implantation par une liste doublement chainée   Accès direct au début et à la fin   Accès séquentiel aux éléments (attention au cout des fonctions utilisant un indice)   Méthodes supplémentaires

  addFirst(), addLast(),, getFirst(), getLast(), removeFisrt(),, removeLast()

  ArrayList

  Implantation par un tableau   Accès direct à tous les éléments   Insertion et suppression obligent à décaler les éléments

Page 29: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Collection : utilisation et iterateur

  Déclarer une collection   Collection<Classe> col;

  Créer une collection vide (classe non abstraite : linkedList, ArrayList, Vector, …)   col = new LinkedList<Classe>();

  Ajouter des éléments à la collection   col.add(mon_nouvel_element);

  Utiliser les algo génériques si besoin   Collections.sort(col);

  Parcourir ou traiter les collections : passer d’un élément à un autre, en utilisant un

code générique ==> la classe iterator permet le parcours d’une collection quelconque;   Déclarer un iterateur :

  Iterator<Classe> p;   Créer un iterateur SUR la collection à parcourir (methode iterator() de la classe Collections)

  p= col.iterator();

  Parcourir la collection :   p.hasNext() : y a t il encore des éléments dans la collection ?   Classe o; o = p.next() : retourne le prochain élément de la collection

Exemple : liste de points

public class Ex24 { public static void main (String []arg) { Collection<Point> liste; // Definir une collection liste = new LinkedList<Point>(); // Créer la liste de point Point a = new Point(3,3); // Ajout des points dans la liste

liste.add(a); liste.add(new Point(2,2)); liste.add(new Point(1,1)); // Parcours de la liste pour affichage for (Iterator<Point> p=liste.iterator(); p.hasNext(); ) { Point b=p.next(); // Remarquer le cast vers un Point System.out.println("Point = "+b); } } }

Exemple : tri de liste de points class PointComparable extends Point implements Comparable { public PointComparable (double a, double b) { super(a,b); } public PointComparable () { super(); } public PointComparable (PointComparable a) { super((Point) a); } public int compareTo(Object b) { Point a = (Point)b; if (getx() < a.getx()) return -1; else if (getx() >a.getx()) return 1; else if (gety() < a.gety()) return -1; else if (gety() >a.gety()) return -1; else return 0; } } public class Ex24b { // C’est le meme code que precedement public static void main (String []arg) { Collection<PointComparable> liste; liste = new LinkedList<Forme>(); PointComparable a = new PointComparable(3,3);

// Ajout des points dans la liste liste.add(a); liste.add(new PointComparable(2,2));liste.add(new PointComparable(1,1)); // Parcours de la liste pour affichage for (Iterator<PointComparable> p=liste.iterator(); p.hasNext(); ) { PointComparable b; b= p.next(); // Remarquer l’absence de cast vers un Point System.out.println("Point = "+b); } Collections.sort((List) liste); // methode de tri générique System.out.println("Apres le tri"); for (Iterator <PointComparable> p=liste.iterator(); p.hasNext(); ) System.out.println("Point = "+ (PointComparable) p.next()); } }

Exemple : liste de Formes

public class Ex25 { public static void main (String []arg) { Scanner clavier = new Scanner(System.in); Collection<Forme> liste; liste = new LinkedList<Forme> (); liste.add(new Cercle(1,2,3)); liste.add(new Cercle(4,5,6)); liste.add(new Rectangle(9,8,7,6)); for (Iterator <Forme> p=liste.iterator(); p.hasNext(); ) System.out.println("Forme = "+ p.next());

// remarquer le cast en Forme : on doit indiquer que l’object // est une forme, mais le polymorphisme de l’affichage permet // la liaisoon dynamique

for (Iterator <Forme> p=liste.iterator(); p.hasNext(); ) { Forme a= p.next(); System.out.println("surface de = "+a.surface()); } } }

Page 30: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Généricité : tableau dynamique de Formes

public class Ex26 { public static void main (String []arg) { Scanner clavier = new Scanner(System.in); Collection <Forme> tab; tab = new ArrayList<Forme>(); // La seule chose à changer !!!!! tab.add(new Cercle(1,2,3)); tab.add(new Cercle(4,5,6)); tab.add(new Rectangle(9,8,7,6)); for (Iterator<Forme> p=tab.iterator(); p.hasNext(); ) System.out.println("Forme = "+ p.next());

// remarquer le cast en Forme : on doit indiquer que l’object // est une forme, mais le polymorphisme de l’affichage permet // la liaisoon dynamique

for (Iterator <Forme> p=liste.iterator(); p.hasNext(); ) { Forme a= p.next(); System.out.println("surface de = "+a.surface()); } } }

Parcourir une association (map)

  Les entrées sont des couples clés-valeur (K,V) " différents parcours

possibles   Des méthodes permettent d’obtenir :

  Ensemble des clés public Set<K> keySet ();   Ensemble des valeurs public Collection<classe> values ();   Ensemble des entrées public Set<Map.Entry<K,V>> entrySet ();

  Map.Entry<K,V>

  Type des objets contenus dans l'ensemble retourné par entrySet   Enregistrement à 2 champs (paire), l'un de type K, l'autre de type V   Accès aux champs par : public K getKey (); public V getValue

Parcourir une association (map) : exemple // déclaration et création d’une association vide TreeMap <String, String > map = new TreeMap <String , String >(); // remplissage… map.put(" rouge ", " ... définition du mot rouge ..."); map.put(" vélo ", "... définition du mot vélo ..."); map.put(" artichaut ", " ... définition du mot artichaut ... "); // parcours de l’ensemble des mots (= les clés) : System.out.print("ensemble des mots :"); for (String mot: map.keySet()) System.out.print(mot + ", "); // parcours de l’ensemble des définitions (= les valeurs) : System.out.print(« \nensemble des définitions :"); for (String def: map.values()) System.out.println(def. toString () + "; "); // parcours de l'ensemble des paires (cle , valeur) System.out.println("\nensemble des paires (mot,définition) : "); Iterator<Map.Entry<String,String>> itAssoc = map.entrySet().iterator(); while (itAssoc.hasNext()) { Map.Entry<String,String> e = itAssoc.next(); String mot = e.getKey(); String def = e.getValue(); System.out.println(mot + " est défini par : " + def); }

MAP : tableau associatif : histogramme

public class Ex29 { public static void main (String []arguments) { Map<String, Integer> m = new HashMap<String, Integer>(); for (String a : arguments) { Integer freq = m.get(a); m.put(a, (freq == null) ? 1 : freq + 1); } System.out.println("Nombre de mots differents "+m.size()); System.out.println("Histogramme des mots :"+m); } }

Page 31: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Généricité

En Java 1.5

JAVA 1.5 : la généricité en plus

  Généricité : ne pas tenir compte des objets réellement manipulés pour définir les structures de données et les algorithmes   Exemple : supprimer le cast lors du parcours et de la récupération de l’élément. Faire des

listes de qqchoses valable pour tous les qqchoses   Définir les structures (classes) ou méthodes en fonction d’un type paramétrique   Exemple : des piles de n’importe quoi class Pile<E> { private int nb; // Nombre d’elements utilises private E[] tab; // Attention : pas de creation des tableaux generiques

==> les passer dans le constructeur t=new E[2]; est interdit public Pile(E[] tableau) { tab = tableau; nb=0; }; public void empiler(E e) { if (nb < tab.length) tab[nb++] = e; } public E depiler() { return (nb>0 ?tab[--nb]:null); } public void afficher() { for (E e : tab) System.out.println(e); } } public class Ex27 { // pile d’entiers et pile de point public static void main (String []arguments) { Pile<Integer> p1= new Pile<Integer>(new Integer[10]); p1.empiler(8); p1.empiler(10); p1.afficher(); Pile<Point> p2 = new Pile<Point>(new Point [8]); Point a = new Point(8,9); p2.empiler(a); p2.empiler(new Point()); p2.empiler(new Point(1,2)); p2.afficher(); } }

Exemple : liste de Formes en java 1.5

#  Remarquer #  la boucle for #  L’absence de cast

public class Ex28 { public static void main (String []arg) { Collection<Forme> liste; // Collection de Forme liste = new ArrayList<Forme>(); // tableau de Forme liste.add(new Cercle(1,2,3)); liste.add(new Cercle(4,5,6)); liste.add(new Rectangle(9,8,7,6)); System.out.println("Affichage par un foreach"); for ( Forme a : liste) System.out.println(a); // Pratique, n’est il pas ? System.out.println("Affichage de la surface par iterateur"); for (Iterator<Forme> p=liste.iterator(); p.hasNext(); ) { Forme a= p.next(); // Pas de conversion utile System.out.println("surface de = "+a.surface()); } } }

Traitement des erreurs

Les exceptions

Page 32: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Exceptions

  Classes et Méthodes permettant de décrire ce qui doit se passer en cas d'erreur   Séparation du code normal du cas "exceptionnel »   Traitement de l’erreur pas obligatoirement à proximité de l’erreur   Propagation facile de l'erreur à travers les sous programmes   Regroupement possible des exceptions   Chaque méthode déclare les exceptions qu’elle est susceptible de déclencher

  Une exception est créée par   Le système : IOException pour les ES, ArrayIndexOutOfBoundsException par

exemple   Vos méthodes :

  Pour lancer une exception vous même: throw new MaclasseException(parametres)

  Les exceptions sont des objets dont les classes dérivent de la classe

Exception Throwable   On y met les informations utiles au gestionnaire d’exceptions ie les méthodes qui

vont gérer l’erreur.

Exceptions : classes particulières

  Les exceptions sont classées en 3 classes   Error : exceptions pour les erreurs systèmes comme pas assez de mémoire. En

général, on ne peut rien faire, sinon quitter   RuntimeException : erreur classique, mais le compilateur n’oblige pas l’utilisateur à

déclarer que ses méthodes peuvent déclencher une exception. Pratique, mais des vérifications en moins. Toutes les exceptions arithmétiques, erreurs d’indice de java sont de ce type par exemple.

  Exception : erreur classique, mais le compilateur oblige l’utilisateur à déclarer que sa méthode peut déclencher cette exception par le mot clé throws. Les exceptions générées par les Entrées sorties par exemple.

Exceptions : Transmettre une exception

  Lorsqu’une exception apparaît, on peut soit   Retransmettre (throws) ou jeter l’exception : ignorer et retransmettre l’exception à

la fonction appelante.   throws permet de dire qu’une méthode peut déclencher une exception. C’est

obligatoire

public static void main(String[] args) throws IOException { int r;

FileReader in = new FileReader(new File("rgb.txt")); while ((r = in.read()) != -1) System.out.println(" Caractere lu"+r); in.close(); }

  Capturer et traiter l’exception ( try .. Catch)

Exceptions : Capturer une (ou plus) exception

  Capturer et traiter l’exception ( try .. Catch)   Ouverture d’un fichier passé en paramètre de commande et

affichage de ce fichier

public static void main(String[] args) try { int r; FileReader in = new FileReader(new File (args[0])); while ((r = in.read()) ==-1)

System.out.println(" Caractere lu"+r); } catch (FileNotFoundException e) { // Fichier pas existant System.out.println("Pas de fichier "+e); e.printStackTrace(); System.exit(1); } catch (IOException e) { // Autre erreur d’E/S System.out.println("Autre erreur"); } }

Page 33: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Exceptions : Capturer une exception Exceptions : lancer une exception

  Beaucoup d’exceptions sont déjà possibles en java   Pour lancer une exception, on utilise le mot clé throws suivi de la création de l’objet

dont la classe est celle de l’exception voulue   Ne pas oublier de déclarer que la méthode en question est susceptible de lancer une

exception par le mot clé throws dans le prototype class Except2 { static int factorielle(int n) throws Exception { int res = 1; if (n<0){ throw new Exception(); } for(int i = 1; i <= n; i++) res = res * i; return res; } public static void main (String [] args) { int x; System.out.println("Entrez un nombre (petit):"); Scanner clavier=new Scanner(System.in); x = clavier.nextInt(); try { System.out.println(factorielle(x)); } catch (Exception e) System.out.println("Factorielle de " +x+" pas definie !");

} }

Exceptions : créer votre exception

  Beaucoup d’exceptions sont déjà possibles en java. Rare de créer une exception   Gestion des exceptions pour assurer que les Pointspositifs ont bien des coordonnées

positives   Créer une classe Monexception dérivant de RuntimeException   Détection et lancement des exceptions dans les mutateurs setxexception(), setyexception()   La classe MonException stocke le point dans son état avant la tentative de coordonnées

négatives ainsi que la valeur négative.   Le traitement est simplement l’affichage du point et de la valeur aberrante

class Monexception extends RuntimeException { private Point a; double valeur; public Monexception() {} public Monexception(Point x, double val) { a=x; valeur=val;} public String toString() { return("Exception positif "+a+"Valeur non positive "+valeur); } } class Pointpositif extends Point { // nombres positifs uniquement public Pointpositif(double a, double b) {super(a,b); } public void setx (double a) { if (a>=0) super.setx(a); else throw new Monexception(this,a); }; public void translate(double a, double b) { setx(getx()+a); sety(gety()+b); } }

Exceptions : gérer une exception

  Dans cet exemple,   la fonction f fait une translation, ne gère pas les exceptions et les retransmet à la

fonction qui l’a appelée (main) qui devra traiter l’erreur   La fonction g fait une translation et gère les exceptions. La gestion de l’erreur se

limite ici à afficher cette erreur public class Ex38b { // f ne gère pas les exceptions, g les gère

// Ici le throws n’est pas obligatoire, car Monexception est Runtime public static void f(Pointpositif a) throws Monexception { System.out.println("Entree dans f qui ne gere pas les exceptions"); a.translate(-3,-5); System.out.println("Sortie de f qui ne gere pas les exceptions"); } // Remarque : on ne passe pas par sortie si exception !!! public static void g(Pointpositif a) { System.out.println("Entree dans g qui gere les exceptions"); try { a.translate(-3,-5); } catch (Monexception e) { // Que faire si point negatif ?? System.out.println("Erreur due a une exception dans g"); System.out.println("Les appels qui ont genere cette exception :"); e.printStackTrace(System.out); } }

Page 34: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Exceptions : créer une exception

public static void main (String []arg) {Pointpositif c,a,b; Scanner clavier=new Scanner(System.in); a = new Pointpositif(1,2); b = new Pointpositif(1,2); c = new Pointpositif(1,2); try { a.translate(-3,0); System.out.println("a "+a); } catch (Monexception e) { System.out.println("Les appels qui ont genere cette exception :"); e.printStackTrace(System.out); } clavier.nextLine(); try { // Obligatoire pour utiliser f(), sauf si main transmet exceptions f(b); } catch (Monexception e) { System.out.println("Les appels qui ont genere cette exception :"); e.printStackTrace(System.out); } clavier.nextLine(); g(c); } }

Exceptions : créer une exception

Sérialisation

Stocker et relire des objets dans des flots (disques ou réseau)

Sérialisation

  Sérialisation : Comment stocker et relire facilement des objets dans un fichier ou un flot

  Importer java.io.*   Interface Serializable

  Aucune méthode, indique seulement la possibilité de sérialisation   Cela implique que des informations sur la classe de l’objet sont stockés dans le flux   Attention : les objets « internes » doivent aussi être sérialisés

  Voir la classe Point pour le champ cdg dans l’exemple ci apres.

  Rien à faire : on utilise   le flux ObjectOutputStream et la méthode writeObject(object a) pour écrire

ObjectOutputStream fic=new ObjectOutputStream(new FileOutputStream("Forme.dat")); fic.writeObject(a);

  le flux ObjectIntputStream et la méthode readObject(object a) pour lire

Page 35: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Sérialisation

class Point implements Serializable { …. // comme précédemment } abstract class Forme implements Serializable { …. // comme précédemment } class Point extends Forme{ …. // comme précédemment } class Rectangle extends Forme{ …. // comme précédemment }

Serialisation

  Exemple : liste de formes   On crée une liste de formes   On y met 2 cercle et 1 rectangle puis un autre cercle   On les stocke dans un fichier :

  D’abord le nombre de forme   Ensuite, on parcours la liste pour les stocker une par une

  On relit ce fichier à l’aide d’une deuxième liste

public class Ex39 { public static void main (String []arg) { Collection<Forme> liste = new ArrayList<Forme>(); // tableau de Forme liste.add(new Cercle(1,2,3)); liste.add(new Cercle(4,5,6)); liste.add(new Rectangle(9,8,7,6)); liste.add(new Cercle(10,11,12)); for ( Forme a : liste) System.out.println(a); // Pratique, n’est il pas ? System.out.println("Ecriture fichier des formes"); try { ObjectOutputStream fic=new ObjectOutputStream(new

FileOutputStream("Forme.dat")); fic.writeObject(new Integer(liste.size())); // Nombre de formes for (Forme a : liste) fic.writeObject(a); // Ecriture des formes fic.flush(); fic.close(); // Fermeture du flux } catch (java.io.IOException e) { System.out.println("Erreur"); }

Serialisation

System.out.println("Relecture des formes"); Collection<Forme> liste2 = new ArrayList<Forme>(); // tableau de Forme try { ObjectInputStream fic=new ObjectInputStream(new

FileInputStream("Forme.dat")); Integer nb = fic.readObject(); // Lecture du nombre de Forme for (int i=0; i<nb; i++) { liste2.add((Forme) fic.readObject()); // Lecture, Ajout dans liste2 } } catch (IOException e) {System.out.println("Erreur : E/S");} catch (ClassNotFoundException e) {System.out.println("Forme inexistante");} for ( Forme a : liste2) System.out.println(a); // Affichage de la liste2 } }

Serialisation : encore mieux

  Une liste est déjà sérialisable   On stocke directement la liste dans un fichier :   On relit ce fichier à l’aide d’une deuxième liste

public class Ex39 { public static void main (String []arg) { Collection<Forme> liste = new ArrayList<Forme>(); // tableau de Forme liste.add(new Cercle(1,2,3)); liste.add(new Cercle(4,5,6)); liste.add(new Rectangle(9,8,7,6)); liste.add(new Cercle(10,11,12)); for ( Forme a : liste) System.out.println(a); // Pratique, n’est il pas ? System.out.println("Ecriture fichier des formes"); try { ObjectOutputStream fic; fic = new ObjectOutputStream(new FileOutputStream("Forme.dat")); fic.writeObject(liste); fic.flush(); fic.close(); // Fermeture du flux } catch (java.io.IOException e) {System.out.println("Erreur");}

Page 36: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Serialisation

System.out.println("Relecture des formes"); Collection<Forme> liste2 = new ArrayList<Forme>(); // tableau de Forme try { ObjectInputStream fic; fic = =new ObjectInputStream(new FileInputStream("Forme.dat")); liste2=(ArrayList<Forme>) fic.readObject()); // Lecture des forme et } } catch (IOException e) {System.out.println("Erreur : E/S");} catch (ClassNotFoundException e) {System.out.println("Erreur : classe

inexistante");} for ( Forme a : liste2) System.out.println(a); // Affichage de la liste2 } }

JAVA

Interface Graphique SWING

SWING

  Du LEGO   Méthode de construction :

  Une plaque de base   On ajoute des briques prédéfinies par dessus

  Plaque de base : Composants de haut niveau

  Fenêtre de base : objets Jframe, Jwindow, Jdialog, Objets JApplet

  Briques prédéfinies : composants ou contrôle

  boutons, textfield,etc..

Construire une IG en pratique

  Construire une fenetre de base (JFrame, JDialog, JApplet…)   Construire un conteneur intermédiaire : Jpanel, JScrollPane, JSplitPane,…   Ajouter des objets graphiques ou d’autres conteneurs intermédiaires dans le

conteneur intermédiaire   Ajouter le conteneur intermédiaire à la fenetre de base   Visualiser la fenetre de base (methode setvisble(true))   On peut aussi construire de nouveaux objets graphiques à partir (héritant)

d'autres objets sous forme de classe

Page 37: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Swing : exemple 1

import javax.swing.*; import java.awt.*; class Deuxboutons { private JFrame frame; JButton button; JLabel label; public Deuxboutons(){ frame = new JFrame("Exemple"); // La fenetre de base et son titre JPanel pane = new JPanel(); // Le panneau qui contiendra les boutons button = new JButton("Mon bouton"); //Le bouton label = new JLabel("Du texte"); // Zone texte pane.add(button); // Ajout du bouton au Panel pane.add(label); // Ajout de la zone de texte // frame.getContentPane().add(pane); Avant java 1.5

frame.add(pane); // Depuis java 1.5, un raccourci frame.pack(); // Dimensions préférées frame.setVisible(true); // Sinon, pas visible } } public class Ex30 { public static void main(String[] args) { new Deuxboutons(); } }

Swing : exemple 1 bis

import javax.swing.*; import java.awt.*; class Deuxboutons extends JFrame { private JButton button; JLabel label; public Deuxboutons(){ super("ex31 : premiere interface"); JPanel pane = new JPanel(); button = new JButton("Mon bouton"); label = new JLabel("Du texte"); pane.add(button); pane.add(label); add(pane); pack(); setVisible(true); } } public class Ex31 { public static void main(String[] args) { new Deuxboutons(); } }

SWING

  Couche logicielle indépendante de la plate forme physique   Modèle-Vue-Contrôleur

  modèle : les données à afficher   vue : représentation graphique de ces données   contrôleur : traite des interactions du composant avec l’utilisateur   avantages

  meilleure modularité   plusieurs vues distinctes pour un même modèle   possibilité de modifier l’implémentation d’un modèle (optimisation,

réorganisation, ...) sans rien changer aux vues et aux contrôleurs.

  Look and Feel modifiable, internationalisation,   Composants de premier niveau

  fille de la fenêtre de fond : objets Jframe, JFenetre, JDialog, JApplet

Apports de SWING

  Nouveaux objets et capacité accrue   Image dans les boutons   Gestion des bordures de fenêtres   fenêtres de formes non rectangulaires   Double buffering   Jlist, Jtree, JTable   Copier/coller

  java.awt.datatransfert.DataFlavor

  Timers   Filechooser,Colorchooser   Java2D API   Fenêtre texte

  JTextField, JtextArea : idem AWT   JPasswordField : masquée   JEditorPane, JTextPane : editeur de texte complet

(plusieurs polices simultanées..)

Page 38: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

SWING : la hiérarchie classique d'une IG

  La fenêtre principale (top-level) : JFrame, ou JDialog ou JApplet   Contient un root pane : en général, inutilisé par le programmeur, qui contient

  glass pane : transparent et invisible sauf si sa méthode paint est définie. Il peut intercepter alors tous les événements du root pane

  layered pane : ensemble de couches, comprenant le Content Pane, utilisé par exemple pour les pop-up, le drag and drop, etc.. permettant et positionner les composants et d’afficher par ordre de profondeur . Par defaut, contient la barre de menu et le ContentPane, sans superposition   barre de menu : position de la barre de menu qui sera créée par JMenuBar et mise en place par

setJMenuBar   Content Pane : utilisé par la plupart des applications et applets

•  obtenu par GetContentPane() •  contient les composants, sauf la barre de menu •  facilite le placement des composants : il contient le gestionnaire de positionnement

SWING : Modèle objet

  Le sous système graphique est objet   chaque composant s'affiche   chaque composant provoque l'affichage des composants

qu'il contient   Exemple : Ex30.java

  La fenêtre top level JFrame s'affiche   Le contentpane affiche un fond opaque   Le JPanel s'affiche (par dessus le précédent) :

•  le fond (paintComponent()) •  les bordures(paintBorder())

  Il demande à son contenu de s'afficher(paintChildren()) •  Le JButton "Mon bouton" s'affiche par paintComponent()

–  le fond –  le texte

•  Le Jlabel "Du texte" s'affiche par paintComponent()

–  le texte

  Pour provoquer l'affichage, utiliser   repaint() : affiche tout le composant   repaint(int,int,int,int) : affiche le rectangle

JFrame

getContentPane()

JButton

Mon Bouton

JPanel

Jlabel

Du Texte

SWING : les contrôles de base

import javax.swing.*; import java.awt.*; class Testswing extends JFrame {super("les controlesf de base"); public Testswing(){ JPanel pane = new JPanel(); pane.add(new JButton("Mon bouton")); pane.add(new JLabel("Du texte")); pane.add(new JRadioButton("Bouton Radio")); pane.add(new JCheckBox("Case a cocher")); String [] texte = { "aa","bb","cc","dd"}; pane.add(new JComboBox(texte)); pane.add(new JSlider(JSlider.HORIZONTAL,0,5,3)); pane.add(new JTextField(5)); getContentPane().add(pane); pack(); setVisible(true); } } public class Ex32 { public static void main(String[] args) { new Testswing();} }

SWING : les objets de base

  Les boutons   Classique : JButton   JCheckBox pour les case à cocher   JRadioBouton pour un ensemble de bouton   JMenutItem pour un bouton dans un menu   JCheckBoxMenuItem   JRadioButtonMenuItem   JToggleButton Super Classe de CheckBox et Radio

  JComboBox : composant permettant de faire un choix parmi plusieurs propositions

  JList : liste à choix multiple en colonne   JSlider : saisie et visualisation graphique d’un nombre entre 2 valeurs   JTextField: permet d’écrire du texte dans une zone monoligne   JTextArea: permet d’écrire du texte dans une zone multiligne   JLabel: permet d’afficher du texte ou une image   JTree : affiche une arborecense   JFileChooser, JColorChooser   JProgressBar

Page 39: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Comment positionner les composants

  Pas de positionnement statique et fixé à l’avance   Disposition et dimensionnement des objets dans une IG

  Effectué à l'initialisation et au redimensionnement   dépend de l'ordre de création   de la politique de placement du containeur

  flowlayout : ligne/ligne   borderlayout : position du composant défini par les points cardinaux (4+1)   gridlayout : grille (un par case) remplie de gauche à droite, de haut en bas   cardlayout : composants visibles séquentiellement (comme les onglets)   gridbaglayout : grille dont les composants peuvent occuper plusieurs cases

  methode setlayout(new borderlayout) : positionnement de la politique   pack() oblige les composants à prendre leur taille "préférée"   composant visible ou non : setVisible()

  Disposition et dimensionnement absolu : possible, mais à éviter

Positionnement dans une IG

Swing : Borderlayout

import javax.swing.*; import java.awt.*; class TestBorder extends JFrame { public TestBorder(){ super("Test du Border"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel pane = new JPanel(new BorderLayout()); pane.add(new JButton("Mon bouton"),BorderLayout.NORTH); pane.add(new JLabel("Dutexte",JLabel.CENTER),BorderLayout.SOUTH); pane.add(new JRadioButton("Bouton Radio"),BorderLayout.EAST); pane.add(new JCheckBox("Case a cocher"),BorderLayout.WEST); String [] texte = { "aa","bb","cc","dd"}; pane.add(new JComboBox(texte),BorderLayout.CENTER); getContentPane().add(pane); pack(); setVisible(true); } } public class Ex33 { public static void main(String[] args) { new TestBorder(); } }

Swing : Gridlayout

import javax.swing.*; import java.awt.*; class TestGrid extends JFrame { public TestGrid(){ super("Test du grid"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel pane = new JPanel(new GridLayout(3,2)); pane.add(new JButton("Mon bouton")); pane.add(new JLabel("Du texte",JLabel.CENTER)); pane.add(new JRadioButton("Bouton Radio")); pane.add(new JCheckBox("Case a cocher")); String [] texte = { "aa","bb","cc","dd"}; pane.add(new JComboBox(texte)); pane.add(new JSlider(JSlider.HORIZONTAL,0,5,3)); pane.add(new JTextField(5)); getContentPane().add(pane); pack(); setVisible(true); } } public class Ex34 { public static void main(String[] args) { new TestGrid(); } }

Page 40: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Swing : Boxlayout

import javax.swing.*; import java.awt.*; class TestBox extends JFrame { public TestBox(){ super("Test de BoxLayout "); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel pane = new JPanel(); pane.setLayout(new BoxLayout(pane,BoxLayout.Y_AXIS)); pane.add(new JButton("Mon bouton")); pane.add(new JLabel("Du texte",JLabel.CENTER)); pane.add(new JRadioButton("Bouton Radio")); pane.add(new JCheckBox("Case a cocher")); String [] texte = { "aa","bb","cc","dd"}; pane.add(new JComboBox(texte)); pane.add(new JSlider(JSlider.HORIZONTAL,0,5,3)); pane.add(new JTextField(5)); getContentPane().add(pane); pack(); setVisible(true); } } public class Ex35 { public static void main(String[] args) { new TestBox(); } }

Structurer une interface : description hiérarchique

Structurer l’interface

import javax.swing.*; import java.awt.*; // L'ordre d'inclusion n'a pas d'importance, les ajouts sont répercutés immédiatement class Pandanspan extends Jframe { public Pandanspan () { super("Hierarchique"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JButton button1 = new JButton("bouton1"); JLabel label1 = new JLabel("texte1"); JLabel label2 = new JLabel("texte2"); JButton button2 = new JButton("bouton2"); JButton button3 = new JButton("bouton3"); JButton button4 = new JButton("bouton4"); JButton button5 = new JButton("bouton5"); JPanel pane1 = new JPanel(new BorderLayout()); //layout spécifié à la construction JPanel pane2 = new JPanel(new BorderLayout()); JPanel pane3 = new JPanel(new BorderLayout()); pane1.add(button1, BorderLayout.EAST); pane1.add(label1, BorderLayout.WEST); pane1.add(pane2, BorderLayout.CENTER); pane2.add(button2, BorderLayout.NORTH); pane2.add(button3, BorderLayout.SOUTH); pane2.add(pane3, BorderLayout.CENTER); pane3.add(button4, BorderLayout.EAST); pane3.add(button5, BorderLayout.WEST); pane3.add(label2, BorderLayout.CENTER); getContentPane().add(pane1, BorderLayout.CENTER); pack(); setVisible(true); } } public class Ex36 { public static void main(String[] args) { new Pandanspan(); } }

Créer un nouveau composant pour dessiner

  La classe Graphics est une classe abstraite   permettant de dessiner des formes simples et des chaines de caractères   D’etre indépendant du support réel :carte graphique, imprimante, image en mémoire   contient des informations sur :

  Les couleurs d’affichage, de fond, le type d’opération de dessin (xor)   Le composant abstrait dans lequel on dessine

  Pour dessiner dans une fenetre:

  On crée un nouveau composant d’affichage dérivant de JPanel et on redéfinit les méthodes   PaintComponent(Graphics g) pour l’affichage   PaintBorder pour les bordures

public void paintComponent(Graphics g) { super.paintComponent(g); //Le fond g.drawRect(10, 20, 99, 199); g.setColor(Color.yellow); // Dessine un rectangle jaune g.fillRect(10+1, 20 + 1,98,198); }

Page 41: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Dessiner une liste de forme

  On utilise la liste de forme (rectangle et cercle)   Ces classes sont modifiées pour avoir une méthode dessiner sur un élément de

type Graphics. Chaque classe sait quel dessin elle doit faire   On crée un nouveau composant AfficheForme qui contient la liste à afficher

  Cette liste est passée à la construction de Afficheforme   AfficheForme dérive de JPanel et sa méthode PaintCOmponent explicite le

dessin à faire ie dessiner chaque forme de la liste

abstract class Forme { protected Color couleur; …. } class Cercle extends Forme{ …… public void dessine(Graphics g) { g.setColor(couleur); g.fillOval(cdg.getx(),cdg.gety(),rayon,rayon); }; } class Rectangle extends Forme { …. public void dessine(Graphics g) { g.setColor(couleur); g.fillRect(cdg.getx(),cdg.gety(),largeur, hauteur);} };

Dessiner une liste de forme class AfficheForme extends JPanel { // nouveau composant affichant une

liste de forme Collection<Forme> liste; public AfficheForme( Collection<Forme> l) { liste=l; } public void paintComponent(Graphics g) { super.paintComponent(g); for ( Forme a : liste) a.dessine(g); } } public class Ex37 { public static void main (String []arg) {

/* Creation de la liste de formes */ Collection<Forme> liste= new LinkedList<Forme>(); liste.add(new Cercle(10,20,30,Color.yellow)); liste.add(new Cercle(100,100,30,Color.green)); liste.add(new Rectangle(150,10,50,80,Color.magenta));

/* Creation de la fenetre et affichage par le composant Afficheforme */ JFrame f = new JFrame("Paint"); f.getContentPane().add(new AfficheForme(liste)); f.setSize(250,200); f.setVisible(true); f.repaint(); } }

Graphics : couleurs, pinceaux

  Tous les attributs classiques de dessin sont disponibles à travers les classes et methodes de Java

    Gestion des couleurs, épaisseur, etc. : setPaint, setStroke   Remplissage : classes Color, GradientPaint, TexturePaint, ��%!"������!.

������!����!   Transformations affines AffineTransform textAt = new AffineTransform();

textAt.translate(0,(float)textTl.getBounds().getHeight());

Image

  AWT : getImage, drawImage myImage = Toolkit.getDefaultToolkit().getImage(filenameOrURL); g.drawImage(myImage, 0, 0, this);

  SWING : une image est simplement affichée dans un JPanel, un JButton

  interface icons   Classe ImageIcon : implemente icons, lit du GIF ou JPEG, mais aussi des

BufferedImage (!= Image)   la fonction paintIcon(Component,Graphics,int,int) personnalise l'affichage d'une

image si besoin (assez rare)   Exemple : classe Ex2 au début

  Java2D : On utilise la classe BufferedImage qui définit de nombreux outils de rendu, de filtrage, etc…   ImageIO.read(File), ImageIO.write(BufferedImage, "Format",File)   g.drawImage(….) : affiche l’image, applique des filtres

Page 42: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Afficher une image dans un composant (1)

class AfficheImage extends JLabel { private ImageIcon icon=null; public AfficheImage(String im) { updateImage(im); } public void updateImage(String im) { icon=new ImageIcon(im);

setIcon(icon);} // Creation et affichage de l’image } class AppliAffiche extends JFrame { private AfficheImage affiche =null; public AppliAffiche(String im) { getContentPane().add(affiche=new AfficheImage(im)); pack();

setVisible(true); } public void suite(String im) { affiche.updateImage(im); pack(); } } public class Ex40 { public static void main (String []arg) { Scanner clavier = new

Scanner(System.in); if (arg==null) {System.out.println("Usage : java Ex40 im1

im2 ...."); } else { AppliAffiche p = new AppliAffiche(arg[0]); System.out.println("Photo suivante"); clavier.nextLine(); for (int i=1; i<arg.length; i++) { p.suite(arg[i]); System.out.println("Photo suivante"); clavier.nextLine(); } } } }

Afficher une image dans un composant (2)

class AfficheImage extends JPanel{ private BufferedImage img = null; public AfficheImage(BufferedImage i) { img=i;} public void updateImage(BufferedImage i) { img=i; repaint();} public void paintComponent(Graphics g) { g.drawImage(img, 0, 0, null); } public Dimension getPreferredSize() { return (img==null) ? new Dimension(100,100): new Dimension(img.getWidth(null),

img.getHeight(null)); } } class AppliAffiche extends JFrame { private AfficheImage affiche =null; public AppliAffiche(BufferedImage im) { getContentPane().add(affiche=new AfficheImage(im)); pack(); setVisible(true); } public void suite(BufferedImage im) { affiche.updateImage(im); pack(); } } public class Ex40b { public static void main(String [] arg) {Scanner clavier = new Scanner(System.in); BufferedImage img = null; if (arg==null) {System.out.println("Usage : java Ex40 im1 im2 ...."); } else { try { img = ImageIO.read(new File(arg[0])); } catch (IOException e) {} AppliAffiche p = new AppliAffiche(img); System.out.println("Photo suivante"); clavier.nextLine(); for (int i=1; i<arg.length; i++) { try { img = ImageIO.read(new File(arg[i])); } catch (IOException e) {} p.suite(img); System.out.println("Photo suivante"); clavier.nextLine(); } System.exit(0); } } }

Menu

1.  Création d’une barre de menu $  JMenuBar barreMenu=new JMenuBar();

2.  Création d’un menu, type Fichier, Edition, …. •  JMenu menu=new JMenu("Formes");

3.  Création des éléments du menu •  JMenuItem item1=new JMenuItem("Sauver");

4.  Ajout des éléments au menu •  menu.add(item1);

5.  Ajout du menu à la barre •  barreMenu.add(menu);

6.  Remarque : un JMenuItem génère un événement de type ActionEvent lorsqu’il est sélectionné

1.  Voir la gestion des événements en JAVA

Menu

import javax.swing.*; class TestMenu extends JFrame { private JMenuBar menuBar; public TestMenu() { super("exemple"); creationMenu(); getContentPane().add(new JPanel()); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(400,300); setVisible(true); } private void creationMenu() { menuBar = new JMenuBar(); JMenu menu = new JMenu("Fichier"); JMenu menu2 = new JMenu("Formes"); JMenu submenu = new JMenu("Formes simples"); menu.add(new JMenuItem("Nouveau")); menu.add(new JMenuItem("Ouvrir")); menu.add(new JMenuItem("Sauver")); menu2.add(submenu); submenu.add(new JMenuItem("Rectangle")); submenu.add(new JMenuItem("Cercle")); menuBar.add(menu); menuBar.add(menu2); setJMenuBar(menuBar); } } public class Ex41 { public static void main (String []arg) { new TestMenu(); } }

Page 43: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

JAVA

Gestion des évènements en SWING

Gestion des évenements

  Que se passe t il ?   quand on appuie sur un bouton,   quand on ferme une fenetre,   quand on bouge la souris …

  Un événement contenant le lieu, la nature et l’objet « actionné » est créé par le système graphique. Cet événement est différent selon qu’il s’agit d’un clic sur un bouton, le déplacement de la souris, etc…

  Cet événement est mis dans l’EDT (Emploi du temps ou mieux, Event Dispatcher Thread).

  Le « dispatcher » envoie cet événement aux objets qui se sont déclarés intéressés par cet événement

  Qui est intéressé ?   Des objets de type écouteur (aux portes)   C’est le bouton qui provoque les événements qui autorise les écoutes.   Les objets écouteurs (un ou plusieurs) définissent l(es) action(s) qui doivent avoir

lieu   Cette action est définie par un <typeevenement>Listener, fonction qui précise

l’entete des fonctions gérant l’action. Ce sont des callback dans d’autres systemes.

Ecouter un bouton : premier exemple

  Il faut créer l’interface graphique :   une fenetre de base   Un bouton

  Il faut créer la classe qui ecoute (ici Monecouteur) : elle implémente l’interface actionlistener qui permet de gérer les clics sur un bouton, les sélections de menu   On définit dans cette classe la méthode actionPerformed(…) qui explicite ce qui

doit être fait quand on clique sur un bouton : ici on affiche sur la fenetre console le texte « Action sur le bouton »

  On crée un objet de cette classe : objetecoutant   En pratique, le nom de la variable est souvent inutile : on crée des objets

anonymes, sans nom   On enregistre cet objet aupres du bouton par la méthode

addActionListener, car c’est quand meme le bouton qui autorise ou non l’ecoute

Ecouter un bouton et réagir

import javax.swing.*; import java.awt.*; import java.awt.event.*; class Ecouteur1 extends JFrame { private JButton button; public Ecouteur1 () { super("exemple ecouteur 1");

button = new JButton("Appuyer pour afficher un texte"); Monecouteur objetecoutant = new Monecouteur();

button.addActionListener(objetecoutant); add(button, BorderLayout.CENTER); pack(); setVisible(true); } /* Classe interne à la classe ecouteur1 souvent utilisée pour les listener On peut aussi définir une classe externe. */ class Monecouteur implements ActionListener { public void actionPerformed(ActionEvent event) { System.out.println("Action surle bouton"); } } } public class Ex45 { public static void main(String[] args) { new Ecouteur1();} }

Page 44: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Fermer la fenetre

  Il faut créer l’interface graphique : c’est le meme code   Il faut créer une classe (ici Monecouteurfenetre) qui implémente l’interface

windowlistener qui permet de gérer les fenetres   Il faut définir 7 méthodes, meme si elles sont vides

  void windowOpened(WindowEvent e) : ouverture de la fenetre   void windowClosed(WindowEvent e) : apres la fermeture de la fenetre   void windowClosing(WindowEvent e) : au moment de la fermeture de la fenetre   void windowIconified(WindowEvent e) : iconifier la fenetre   void windowDeiconified(WindowEvent e) : deiconifier de la fenetre   void windowActivated(WindowEvent e) : focus dans la fenetre; Utiliser de préférence

windowGainedFocus de WindowFocusListener   void windowDeactivated(WindowEvent e) : perte du focus de la fenetre. Utiliser de préférence

windowLostFocus de WindowFocusListener

  On crée un objet anonyme, sans nom car c’est inutile   On enregistre cet objet aupres de la fenetre par la méthode addWindowListener

Fermer la fenetre

import javax.swing.*; import java.awt.*; import java.awt.event.*; class Ecouteur1 { private JButton button; JFrame frame; public Ecouteur1 () { frame=new JFrame("exemple ecouteur 1");

button = new JButton("Appuyer pour afficher un texte"); Monecouteur objetecoutant = new Monecouteur();

button.addActionListener(objetecoutant); frame.addWindowListener(new Monecouteurfenetre()); frame.add(button, BorderLayout.CENTER); frame.pack(); frame.setVisible(true); } class Monecouteur implements ActionListener { public void actionPerformed(ActionEvent event) { System.out.println("Action surle bouton"); } } class Monecouteurfenetre implements WindowListener { public void windowClosing(WindowEvent event) { System.exit(0); } public void windowClosed(WindowEvent e) {} public void windowOpened(WindowEvent e) {} public void windowIconified(WindowEvent e) {} public void windowDeiconified(WindowEvent e) {} public void windowActivated(WindowEvent e) {} public void windowDeactivated(WindowEvent e) {} } } public class Ex45b { public static void main(String[] args) { new Ecouteur1();}}

Les adapteurs : Fermer la fenetre

  Gérer les événements par adaptateur

  une interface listener ! toutes les méthodes doivent être écrites, même vides   exemple : windowsListener : 7 méthodes à redéfinir

  $����$��!�#�!��, $����$��� ����$����$��� ���, W����$����!�#�!��, $����$�����������, $����$��������, $����$ �����

  Un adaptateur : une classe contient déjà une version vide ! on ne surcharge que les fonctionnalités dont on a besoin

  Attention : la classe ecouteur HERITE de la classe Adapter au lieu de IMPLEMENTE une interface   ComponentAdapter   ContainerAdapter   FocusAdapter   KeyAdapter   MouseAdapter   MouseMotionAdapter   WindowAdapter

Ecouter 2 boutons (1)

  Une application qui affiche un compteur mis à jour par 2 boutons   Il faut créer l’interface graphique :

  une fenêtre de base   un bouton « plus », un bouton « moins »   Un label qui affiche le compteur   Une variable entière contenant le compteur

  Pour gérer les boutons, plusieurs solutions   Version objet avec 2 écouteurs : une classe écouteur spécifique pour chaque

bouton. Il y a donc 2 classes, une pour le moins, une pour le plus. Aucun test n’est à faire dans l'écouteur, puisqu’il sait quel bouton est utilisé

  Version 1 écouteur : une seule classe écouteur, qui teste si le composant d’où provient l’événement est le bouton plus ou le bouton moins

  Version 1 ecouteur this : la classe ecouteur est la classe qui définit l’application elle-même

Page 45: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Ecouter 2 boutons (1)

import javax.swing.*; import java.awt.*; import java.awt.event.*; // Deux boutons : un qui décrémente, un qui incrémente class Ecouteur2 extends JFrame { private int count = 0; JLabel label; JButton buttonPlus, buttonMoins; private void creationinterface() { buttonPlus = new JButton("plus"); buttonMoins = new JButton("moins"); label = new JLabel("0", JLabel.CENTER); JPanel buttons = new JPanel(new GridLayout(0, 1)); buttons.add(buttonPlus); buttons.add(buttonMoins); JPanel pane = new JPanel(new BorderLayout()); pane.add(buttons, BorderLayout.WEST); pane.add(label, BorderLayout.CENTER); getContentPane().add(pane, BorderLayout.CENTER); pack(); setVisible(true); } public Ecouteur2() { super("exemple"); creationinterface(); buttonPlus.addActionListener(new MyActionListener1()); buttonMoins.addActionListener(new MyActionListener2()); addWindowListener(new MyWindowListener ()); }

Ecouter 2 boutons : 2 ecouteurs

private class MyActionListener1 implements ActionListener { public void actionPerformed(ActionEvent event) { count++; label.setText(Integer.toString(count)); } } private class MyActionListener2 implements ActionListener { public void actionPerformed(ActionEvent event) { count--; label.setText(Integer.toString(count)); } } // Remarque ; les classes internes ont accès aux champs de l’interface private class MyWindowListener extends WindowAdapter { public void windowClosing(WindowEvent event) { System.exit(0); } } } public class Ex46 { public static void main(String[] args) { new Ecouteur2(); } }

Ecouter 2 boutons : 1 seul ecouteur

private class MyActionListener implements ActionListener { public void actionPerformed(ActionEvent event) { if(event.getSource() == buttonPlus) count++; else count--; label.setText(Integer.toString(count)); } } private class MyWindowListener extends WindowAdapter { public void windowClosing(WindowEvent event) { System.exit(0); } } } public class Ex47 { public static void main(String[] args) { new Ecouteur2(); } }

Ecouter 2 boutons : 1 ecouteur=this

import javax.swing.*; import java.awt.*; import java.awt.event.*; class Ecouteur2 extends WindowAdapter implements ActionListener {JFrame frame; private int count = 0; JLabel label; JButton buttonPlus, buttonMoins; private void creationinterface() { frame=new JFrame("Exemple"); buttonPlus = new JButton("plus"); buttonMoins = new JButton("moins"); label = new JLabel("0", JLabel.CENTER); JPanel buttons = new JPanel(new GridLayout(0, 1)); buttons.add(buttonPlus); buttons.add(buttonMoins); JPanel pane = new JPanel(new BorderLayout()); pane.add(buttons, BorderLayout.WEST); pane.add(label, BorderLayout.CENTER); frame.getContentPane().add(pane, BorderLayout.CENTER); frame.pack(); frame.setVisible(true); } public Ecouteur2() { creationinterface(); buttonPlus.addActionListener(this); buttonMoins.addActionListener(this); frame.addWindowListener(this); } public void actionPerformed(ActionEvent event) { if(event.getSource() == buttonPlus) count++; if(event.getSource() == buttonMoins) count--; label.setText(Integer.toString(count)); } public void windowClosing(WindowEvent event) { System.exit(0); } } public class Ex48 {public static void main(String[] args) { new Ecouteur2(); } }

Page 46: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Résumé

  la gestion des événements est faite par délégation par un listener ou un adapter   l'événement n'est pas géré par le composant source de l’événement mais par un objet qui

s'est déclaré intéressé (écouteur) par ce type d'événement au moyen de add<type>Listener() ou set<type>Listener() auprès de l'objet source

  cet objet écouteur doit implanter la ou les méthodes précisées par le type de listener. Ces méthodes décrivent ce qui doit être fait avec l'événement. Un listener est une interface au sens Java du terme. Il faut définir toutes les méthodes de l’interface, même si elles sont vides.

  Un adapter est une classe contenant des versions vides des méthodes. On redéfinit uniquement celles qui sont nécessaires. Une classe ecouteur doit alors héritée de l’adapter.

  s'il existe plusieurs objets écouteurs, tous reçoivent une copie de l'événement dans un ordre non défini.

  Si aucun listener n'est défini, l'événement est ignoré   un écouteur peut écouter plusieurs sources différentes   Un objet peut écouter plusieurs boutons   Un objet peut écouter les événements issu de ses propres composants

  En pratique   Définir et cééer l’interface graphique et ses boutons.   Définir les écouteurs et les actions : ecrire les classes (Monecouteur) et méthodes

(ActionPerformed)   Créer les ecouteurs des différents composants graphiques (new Monecouteur())   Enregistrer les ecouteurs aupres des boutons à écouter (addActionListener(…))

Résumé

  Les évènements sont typés, organisé en classes   Mouse ! ��" ��#��! , clicbouton ! ��!����#��!

  Méthodes utiles   �!�������!��!������������ : retourne la chaîne associée à l'évènement   ��!���!�������� �� : entier contenant les touches enfoncées par l'utilisateur

(SHIFT,CTR)   Object getSource() : composant émettant l'événement   int getID() : retourne le type de l’événement   long getWhen() : retourne le temps écoulé depuis l’apparition de l’évènement

Quel écouteur définir pour quelle action ?

  Interface ActionListener   Utilisée par les clics bouton, choix de menu, et les CR dans un zone de texte (JTextField,

JTextArea)   Méthodes à définir

  void actionPerformed(ActionEvent e) : que faire lors de l'apparition d’un des évènements

  Interface MouseListener ou classe MouseAdapter   Utilisée pour les actions souris entrant et sortant dans la fenetre, les clics dans la fenetre   Méthodes à définir

  void mouseClicked(MouseEvent e) : clic dans la fenetre   void mouseEntered(MouseEvent e) : souris entrant dans la fenetre   void mouseExited(MouseEvent e) : souris sortant de la fenetre   void mousePressed(MouseEvent e) : touche souris appuyée dans la fenetre   void mouseRealised(MouseEvent e) : touche souris relachée dans la fenetre

  Principales méthodes de la classe MouseEvent   boolean isAltDown(), boolean isControlDown(), boolean isMetaDown(), boolean isShiftDown()   int getModifiers(), int getX(), int getY()

  Méthodes utiles   boolean isLeftMouseButton(MouseEvent e) : vrai si e concerne le bouton gauche de la souris   boolean isMiddleMouseButton(MouseEvent e) : vrai si e concerne le bouton milieu de la souris   boolean isRightMouseButton(MouseEvent e) : vrai si e concerne le bouton droit de la souris

  Interface MouseMotionListener ou classe MouseMotionAdapter   Utilisée pour les déplacement souris dans la fenetre   Méthodes à définir

  void mouseDragged(MouseEvent e) : clic dans la fenetre   void mouseMovedMouseEvent e) : déplacement souris dans la fenetre

Exemple pour la souris

import javax.swing.*;import java.awt.event.*;import java.awt.*; class Appli extends JFrame { JLabel zone1; public Appli() { zone1 = new JLabel("Test de mouse",Jlabel.CENTER); zone1.addMouseMotionListener(new Ecouteur()); getContentPane().add(zone1); setSize(200,200); setVisible(true); } private class Ecouteur implements MouseMotionListener { private void affiche(MouseEvent e) { System.out.println("x= "+e.getX()+", y="+e.getY()); ` } public void mouseMoved(MouseEvent e) { System.out.print("Mouvement"); affiche(e); } public void mouseDragged(MouseEvent e) { System.out.print("Glisser"); affiche(e); } } } public class Ex49 { public static void main(String[] args) { new Appli(); } }

Page 47: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Quel écouteur définir pour quelle action (2) ?

  Interface KeyListener ou classe KeyAdapter   Utilisée pour les actions clavier sur un composant   Le Composant doit pouvoir obtenir le focus avec setFocusable(true)   Méthodes à définir

  void keyTyped(KeyEvent e) : touche unicode (ascii) tapée   void keyPressed(KeyEvent e) : touche quelconque appuyée dans le composant   void keyRealised(KeyEvent e) : touche quelconque relachée dans le composant

  Principales méthodes de la classe KeyEvent   boolean isActionKey()   int getKeyChar(), int getKeyCode()

  Interface ChangeListener   Utilisée les Sliders, les ColorChooser, les Spinners   Méthodes à définir

  void stateChanged(ChangeEvent e) : changement dans le composant

  Interface ItemListener   Utilisée les checkBoxes, les ComboBoxes   Méthodes à définir

  void itemStateChanged(ItemEvent e) : changement dans le composant   Principales méthodes de la classe ItemEvent

  ItemSelectable getItemSelectable() : similaire à getSource()   Object getItem(), int getStateChange()

Quel écouteur définir pour quelle action (3) ?

  Interface WindowListener ou classe WindowAdapter   Utilisée pour les actions sur les fenetres : ouverture, fermeture, iconification, quitter   Méthodes à définir

  void windowOpened(WindowEvent e) : ouverture de la fenetre   void windowClosed(WindowEvent e) : apres la fermeture de la fenetre   void windowClosing(WindowEvent e) : au moment de la fermeture de la fenetre   void windowIconified(WindowEvent e) : iconifier la fenetre   void windowDeiconified(WindowEvent e) : deiconifier de la fenetre   void windowActivated(WindowEvent e) : focus dans la fenetre; Utiliser de préférence

windowGainedFocus de WindowFocusListener   void windowDeactivated(WindowEvent e) : perte du focus de la fenetre. Utiliser de préférence

windowLostFocus de WindowFocusListener

  La principale action à redéfinir est celle de la fermeture d’une application. Pour cela, il faudrait   Soit vos applications graphiques implémentent l’interface WindowListener avec ses 7

methodes   redéfinir systématiquement la fonction windowClosed   Ecrire un corps de fonction vide pour les autres

  Soit vos applications graphiques héritent de WindowAdapter avec ses 7 methodes   redéfinir systématiquement la fonction windowClosed   Mais votre application ne peut plus hérité d’une autre classe

  Solution : la méthode définit la sortie propre sans redéfinir le listener ou l’adapter   setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

Un chat local (1)

  Taper du texte dans une fenêtre,   Recevoir dans une autre, avec ascenseur

Chat local (2)

import javax.swing.*; import java.awt.*; import java.awt.event.*; public class Ex51 { private JTextArea texte, copie; public Ex51() {

// Fenetre principale qui envoie JFrame frame = new JFrame("Chat");

// Gestion de la sortie de fenetre frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

//Création du panel de la fenetre principale JPanel panelprincipal = new JPanel(new BorderLayout()); texte = new JTextArea();

// Partie texte de la Fenetre d’emission JScrollPane paneltexte = new JScrollPane (texte);

// Bouton de la Fenetre d’emission JButton button = new JButton("Envoyer"); panelprincipal.add(paneltexte, BorderLayout.CENTER); panelprincipal.add(button, BorderLayout.SOUTH);

// Gestion de l'appui sur le bouton "Envoyer" button.addActionListener(new MyActionListener()); frame.getContentPane().add(panelprincipal);

Page 48: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Chat local (3)

// Creation de la deuxième fenetre pour la reception JFrame fenetrecopie = new JFrame("Fenetre de reception"); // Création d'une zone de texte pour le message recu avec edition impossible copie = new JTextArea(); copie.setEditable(false); // Creation du panel de la fenetre de reception JScrollPane panelcopie = new JScrollPane (copie); fenetrecopie.getContentPane().add(panelcopie); frame.setSize(200, 200); frame.setLocation(0, 0); frame.setVisible(true); fenetrecopie.setSize(200, 200); fenetrecopie.setLocation(400, 0); fenetrecopie. setVisible(true); } private class MyActionListener implements ActionListener { public void actionPerformed(ActionEvent event) { copie.append(texte.getText() + "\n"); // Lecture dans la fenetre d'emission (texte) texte.setText(""); // et ecriture dans la fenetre de reception } } public static void main(String[] args) { new Ex51();} }

Swing : Applets (1)

  Applet ! dérive de JApplet : possède un root pane   Possède un unique contentPane   barre de menu disponible   Conséquences

  ajout des composants dans le ContentPane, pas dans l'applet   idem pour le gestionnaire de placement (layout)

  Sous système graphique

  chaque composant se redessine à partir de la hiérarchie objet de l'IG   ! inutile et dangereux de redéfinir paint ou update   ! paintComponent d'un composant assure l'affichage personnalisé

  l’IG de l'applet est créée dans la fonction init() par ajout de composants

  Les actions sont définies par les ecouteurs/adapteurs   Plug-in java pour utiliser swing dans les applets

  Balise APPLET maintenant

Swing : Applets (2)

import javax.swing.*; import java.awt.*; public class HelloSwingApplet extends JApplet { public void init() { JLabel label = new Jlabel ("Hello Swing applet!"); label.setHorizontalAlignment(JLabel.CENTER);

label.setBorder(BorderFactory.createMatteBorder(1,1,2,2,Color.black)); getContentPane().add(label, BorderLayout.CENTER); } } <HTML> <HEAD> <TITLE>Swing Applet</TITLE>

</HEAD> <BODY> <APPLET code="HelloSwingApplet"

width=600 height=300> Your browser does not support Java, so nothing is displayed. </APPLET>

</BODY> </HTML>

Swing : les threads

  En SWING, pas de difficultés si l'application ne modifie pas ses propres composants   Exemple: création de l'IG dans init() pour l'applet, modification dans les

gestionnaires d'événements

  Dans le cas contraire, les composants swing ne doivent être accessibles que par un thread à la fois.

  Règle générale

  Construire l'application dans le thread principal, Construire l'applet dans init   les threads secondaires passent par les gestionnaires d'événements (sans action

directe sur l'IG) pour leur modification   les méthodes repaint() et revalidate() postent des messages et ne modifient pas

directement l'IG : utilisables.   Pour les cas spéciaux, exécution de code utilisateur par le thread event-

dispatching   ��#�����!�� : soumet la requête (met en evenement dans la file d’ev) et n'attend

pas   ��#���������! : soumet la requête et attend

Page 49: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Swing : JTable

  JTable : javax.swing.table   Tableau dont les cellules sont des Component   Un Modèle (AbstractTableModel), une vue (Jtable)   En général JTable dans une JScrollPane. Sinon, pas d'entêtes de colonnes

  Modèle par défaut   Données dans un vector ou un tableau   Cellules éditables

  Une table peut provoquer des événements pour faire réagir d'autres objets   son modèle doit les créer par appels de méthode fireTablexxx provoque les

événements   fireTableCellUpdated, fireTableChanged, fireTableDataChanged, fireTableRowsDeleted,

fireTableRowsInserted, fireTableRowsUpdated, fireTableStructureChanged   l'objet récepteur (écouteur) doit implémenter l'interface public class SimpleTableDemo ... implements TableModelListener { ... public SimpleTableDemo() { ...

model = table.getModel(); model.addTableModelListener(this); ... } public void tableChanged(TableModelEvent e) {... int row = e.getFirstRow(); int column = e.getColumn(); String columnName = model.getColumnName(column); Object data = model.getValueAt(row, column);... } }

Swing : Jtable (2)

import javax.swing.*; import java.awt.*; import javax.swing.table.*; public class jtab2 { public static void main(String [] a){ Object [][] donnees = { {"8h-9h", new Integer(100),"Mathématiques"}, {"9h-10h",new Integer(10),"Physique"},{"10h-11h", new

Integer(190),"Chimie"} }; String [] enTete = { "Heures", "Salle", "Matières"}; DefaultTableModel dtm = new DefaultTableModel(donnees, enTete); JTable jt = new JTable(dtm); JScrollPane jsp = new JScrollPane(jt); JFrame appl = new JFrame("Exemple de table : emploi du temps"); JPanel p1 = new JPanel(new BorderLayout()); appl.getContentPane().add(p1); p1.add(jsp); appl.pack(); appl.show(); } }

  JTable   les colonnes sont des objets   indexées à partir de 0   méthodes pour changer la largeur d'une colonnes

  (jt.getColumnModel().getColumn(1)).setPreferredWidth(10);

Swing : Jtable (3)

  JTable : construire son propre modèle Class MonModel extends AbstractTableModel() {

String [] entete = { ......}; Object [][] donnees = { .....};

public String getColumnName(int col) { return entete[col].toString(); } public int getRowCount() { return donnees.length; } public int getColumnCount() { return entete.length; } public Class getColumnClass(int c){return getValueAt(0, c).getClass();} public Object getValueAt(int row, int col) { return donnees[row][col];

} public boolean isCellEditable(int row, int col) { return true; // ICI on met celles qui peuvent changer}

public void setValueAt(Object value, int row, int col) { donnees[row][col] = value; fireTableCellUpdated(row, col); } }

Labels et Onglets

  JLabel : Image possible Icon image = new ImageIcon("image.jpg"); JLabel labelImage = new JLabel(image);

  JTabbedPane : Onglet   addTab : ajoute un onglet

import java.awt.*; import java.util.*; import java.awt.event.*; import javax.swing.*; public class TabTest extends JPanel { private JTabbedPane jtp; private JLabel labelImage; private JPanel panneau1 = new JPanel(); private JPanel panneau2 = new JPanel(); private JPanel panneau3 = new JPanel(); public TabTest() { setLayout(new BorderLayout()); jtp = new JTabbedPane(); Icon image = new ImageIcon("dauphin09.jpg"); labelImage = new JLabel("dauphins nageants",

image, SwingConstants.CENTER); panneau1.add(labelImage); Icon image2 = new ImageIcon("chien.gif"); panneau2.add(new JLabel(image2));

panneau3.add(new JLabel("JLabel avec du texte seulement"));

jtp.addTab("Image & Texte", panneau1); jtp.addTab("image seule", panneau2); jtp.addTab("texte seul", panneau3); add(jtp, BorderLayout.CENTER); } public static void main(String args[]) { JFrame jf = new JFrame("Tabbed Pane Test"); TabTest tt = new TabTest(); jf.getContentPane().add(tt, BorderLayout.CENTER); jf.setSize(600,300); jf.setVisible(true); } }

Page 50: Programmation Objet et JAVA - PHELMAtdinfo.phelma.grenoble-inp.fr/2Apoo/java2015.pdf · Programmation Objet et JAVA Phelma 2015 1 Organisation du cours 10 séances de CM/TD/TP Les

Labels et Onglets JTree

import java.awt.*; import javax.swing.*; import javax.swing.tree.*; public class jtree { private static Object [] nodeNames = { "one", "two", "three", "four", "five", "six",

"seven", new Integer(8), new Integer(9), new Float(10) }; private static boolean [] leaf = { false, true, true, false, true, true, false, true,

true, true }; public static void main(String args[]) { JFrame jf = new JFrame("Tree Test"); DefaultMutableTreeNode [] nodes = new DefaultMutableTreeNode[10]; for (int i = 0; i < nodes.length; i++) { nodes[i] = new DefaultMutableTreeNode(nodeNames[i], !leaf[i]); } nodes[0].add(nodes[1]); nodes[0].add(nodes[2]); nodes[0].add(nodes[3]); nodes[0].add(nodes[6]); nodes[0].add(nodes[9]); nodes[3].add(nodes[4]); nodes[3].add(nodes[5]); nodes[6].add(nodes[7]); nodes[6].add(nodes[8]); JTree jt = new JTree(nodes[0]); jf.getContentPane().add(jt, BorderLayout.CENTER); jf.pack(); jf.setVisible(true); } }

Exemple : JTree