Programmation Objet et JAVA - Retour au site des enseignements d

publicité
Organisation du cours
Programmation Objet et
JAVA
 
10 séances de CM/TD/TP Les chapitres essentiels
 
 
 
 
 
x sujets de TD/TP
 
Phelma 2015
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
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
1
Caractéristiques
 
 
 
 
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
Introduction : caractéristiques
Introduction : caractéristiques
Langage Interprété
 
Traduit et exécuté à chaque chargement
Développement plus simple
Indépendant de l'architecture : Portable
 
Pas de Fichier Executable
 
Ensemble complet d’exécution : machine à pile 32 bits
Dépendant du processeur et
de l ’OS
Temps d’exécution plus long
Dépend de la Réalisation de
la machine virtuelle
 
Indépendant du
processeur et de l ’OS
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
 
Réseau
 
 
Gestion des langues
Deux types de programmation différents
 
Fichier *.java
• 
 
 
dépend de la définition
de la machine virtuelle
Conçu pour cela (machine virtuelle)
 
Fichier *.class
Gestion de plusieurs tâches prévue
Ensemble de classes pour utiliser des protocoles TCP/IP tels que HTTP et FTP
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.
Indépendant du
processeur et de l ’OS
 
Applets
dépend de la définition
de la machine virtuelle
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
Java versus C
Serveur www
distant
2
chargement
applet
(.class)
1 : demande
Poste client
netscape, IE, ...
3 execution
  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
Types de base
POO et UML
  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
Notions de base
  Valeurs extrémales par Type.MAX_VALUE, type.MIN_VALUE
  char c = Byte.MAX_VALUE
9
Concept de classe : le point 2D
 
Le point 2D en procédural ou en objet
Problème posé
 
 
 
10
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
class point
Structure point
avec champs x et y
Attributs x et y
Qu’est ce qu’un point du plan
Méthodes
Fonctions
 
Définition statique : ce sont les champs ou attributs
 
 
void affiche (point)
void translate(point*, double,double)
Une entité comportant 2 coordonnées
 
 
void affiche ()
void translate(double,double)
point homothetie(double)
point symetriecentrale()
abscisse
ordonnée
point homothetie(point, double)
point symetriecentrale(point)
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
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
12
En C, le point 2D et ses fonctions
typedef struct Point {
En C, le point 2D et ses fonctions
Point : 2 coordonnées
/* Definition des champs d'un point */
double x;
double y; } POINT;
Quelles sont les actions
réalisables sur un point ?
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
/* 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;
}
Exemple de classe : le point 2D
public class Point {
/* Definition des champs d'un point */
private double x;
private double y;
}
13
Point : 2 coordonnées
Quelles sont les actions
réalisables sur un point ?
/* definition des methodes d'un point */
/* Constructeur : valeurs initiales d'un point */
public Point () { x = 0; y = 0; }
Comment initialiser
public Point (double a, double b) { x = a; y = b; } un point : 2 possibilités
}
/* 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); }
15
14
Exemple d’objet : des points particuliers
3 Points : p1 p2 p3
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);
Affichage de p1
p1.affiche();
p2 = p1.multcste(10.0);
p2.affiche();
p2=null;
p3=p1.symetriecentrale();
p3.affiche();
}
}
Creation de p1
16
POO : concepts de base
 
1 programme ; 1 ensemble d’objets qui s’envoient des messages
 
Encapsulation : données+méthodes+sécurité
 
 
données : les informations propres à un objet,
méthodes : les actions réalisables sur/avec cet objet
  Définition des classes/attributs et des méthodes (modèle statique)
  Définition des aspects dynamiques et temporels (modèle dynamique).
Objet : instance d'une classe
Sécurité : Cloisonne l’intérieur et l’extérieur de l’objet
 
 
 
 
  Le modèle statique permet
privé : inaccessible de l'extérieur de la classe ou de l’objet
public : ce qui l'extérieur à le droit d'utiliser
  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)
Réutiliser
 
 
 
sans connaître le fonctionnement interne
Sans risquer de modifier ce qui est fait
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
 
 
 
 
 
  UML : Unified Modeling Langage
  Langage graphique de modélisation de projet informatique orienté
objet :
Données et méthodes dans une même entité : la classe
 
 
Conception, Modèles et Diagrammes en POO
  Le modèle dynamique décrit le comportement dynamique et temporel du
système :
 
 
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.
17
Diagramme de classe : UML
 
  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
Polymorphisme : une même méthode prend plusieurs formes
18
Questions
Une classe
 
 
 
Faire le diagramme de classe d’un complexe
Quels sont ses attributs ?
Donnez les prototypes de 4 méthodes utiles
Nom de la classe
Attributs ou champs
+ : public
# : protégé
- : private
méthodes
19
20
Les classes en JAVA
Notion d’objet
 
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
 
Les classes et les objets
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, …)
}
 
 
 
21
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
Les objets et les variables en JAVA
Concept d'objet : exemple
  Un objet = un exemple ou une entité dont le modèle (type) est une classe
public class Ex1c {
public static void main (String[] args){
System.out.println("Premier exemple");
Point p1=null, p2=null; // Définition p1, p2
  On dit aussi une instance de classe.
 
La variable est une référence (pointeur constant) sur cet objet
p1 = new Point();
p1.x=2; p1.y=8;
p1.affiche();
  En Java, 3 étapes
  Définition de la variable : Point p1;
 
p2 = new Point(20,80);
p2.affiche();
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
p1.x = p1.x + 20;
p1.affiche();
p2=null;
  Utilisation du point p1 :
 
 
// Creation p1
// On change p1
p1
 
22
2
p1
88
8
`
20
p1
p2
p1.y += 80;
80
p1
// l’objet pointé par p2 est libre
} // les variables p2 et p1 sont détruites
par exemple, appliquer affiche() à p1 : p1.affiche()
ou changer la valeur de l’abscisse : p1.x=10;
}
  Donc
 
 
22
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
p1.affiche()
p2.affiche()
p1.affiche()
24
Accès aux membres
Notion d’objet
  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 :
 
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
• 
Les attributs et les
méthodes
si elle n’existe pas, erreur de compilation « Cannot find Symbol »
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)
25
26
Paramètre this
Notion d’objet
  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 ?
Sécurité
public void translate(double a, double y) {
x = x + a; this.y = this.y + y;
}
27
28
Accès et protection
Accès aux membres et aux méthodes (2)
  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.
  Public
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 ;
  Les membres public sont accessibles pour toutes les méthodes et
fonctions du programme
 
 
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
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
 
 
 
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é
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
b.translate(2,6); b.affiche();
a.translate(b); a.affiche();
c = a.multcst(2.); c.affiche();
}
29
Accès et protection
}
30
Accès et protection : pourquoi ?
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
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
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
Accesseurs et mutateurs
class Fraction{
//Attributs privés
private double numerateur, denominateur;
 Classe Fraction
 Attributs
 num et denum
// Accesseurs et Mutateurs:
public double getnumerateur(){ return numerateur; }
public double getdenominateur() { return denominateur; }
 Mutateurs/Accesseurs
 Méthodes internes
à la classe
void
init(double,double)
 Méthodes
autorisées à
l’extérieur
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); }
 main() {
 }
33
// 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);
}
};
34
Accesseurs et mutateurs
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
35
36
Constructeur
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");
}
}
  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
Destructeur
Destructeur
import java.util.*;
class Point { ……
protected void finalize()
};
Fonction appelée automatiquement lors de la destruction
des objets
 
Prototype : protected void finalize()
En C++, ~nom_de_la_classe()
 
 
 
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 :
 
 
 
{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
}
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
 
38
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
On passe dans le destructeur
Ligne : System.gc()
En général,
 
 
on n’appelle pas le gc() directement car il peut etre tres lent
pas de destructeur
39
40
Surcharge ou Polymorphisme de méthodes :
Notion d’objet
  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
Surcharge de méthodes
  Attention :
  on ne peut pas surcharger uniquement sur le type de retour
42
41
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; }
Objets et références
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
}
44
Objets et référence ou le retour des pointeurs
Le passage d’objets en paramètres
 
p1 = new Point (2,3);
 
 
 
p1 est une référence sur un objet réel
C’est donc un pointeur constant
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 {
22
2
p1
p1
public static void main (String[] args){
Point p1=null, p2=null;
88
8
p1 = new Point(2,8);
p1.affiche();
20
p1
p2 = new Point(20,80);
`
p2
p2.affiche();
80
p2.ajoutemoiap(p1);
p1
// Ici p1 est modifié à cause de ajoutemoiap
p1.affiche();
} // les variables p2 et p1 sont détruites
}
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
a
1
8
2
c
Un objet passé en paramètre d’une méthode est passé par adresse et il peut être
modifié par la fonction
1
2
p1.affiche()
b
p2.affiche()
45
p1.affiche()
46
Les Entrées Sorties en pratique
Divers
  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);
}
47
}
48
Méthodes existantes dans une classe
 
Tous les classes JAVA héritent de la classe de base Object, qui contient :
 
Pour l’affichage : toString()
 
 
 
Un programme objet :
 
 
 
Doit retourner une représentation textuelle de l’objet
Elle est utilisée par System.out.println
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)
 
Pour les tests d’égalité : equals()
 
 
 
Résumé
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
 
Données et méthodes protégées si besoin :
 
En pratique
 
 
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");
}
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
 
 
données privées.
Que doit faire l’utilisateur avec la classe que je développe ? ==> seules méthodes publiques
 
Autres méthodes privées
• 
 
 
 
Initialisation, affichage, addition, etc..
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 !!!
 
 
}
49
50
Tableaux
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
Création d’un tableau en 3 étapes
1/ Déclaration d’une variable : int [] tableau;
Tableaux et tableaux
d’objets
2/ Instanciation ou création : tableau = new int [10];
3/ Utilisation : tableau [i] = 2*i
0
tableau
0
1
2
2
3
4
6
9
Tableau de 10 éléments
Indices
Tableaux (2)
Copie de tableaux de nombres ou partage
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();
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]+"
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]+" " );
}
for (int i=0; i< t2.length ; i++) System.out.print(t2[i]+"
for (int i=0; i< t3.length ; i++) System.out.print(t3[i]+"
tableau[2+ tableau.length ]=0; // ERREUR : pourquoi ?
for (int i=0; i< t1.length ; i++) System.out.print(t1[i]+"
for (int i=0; i< t2.length ; i++) System.out.print(t2[i]+"
for (int i=0; i< t3.length ; i++) System.out.print(t3[i]+"
}
t1
t2
t3
0
1
2
3
1
-1
3 -1
5
-1
7
-1
9
1
1
3
2
3
5
7
"); System.out.println();
"); System.out.println();
"); System.out.println();
}
Tableaux d’objets
  Création d’un tableau d’objet : 2 étapes
  Créer le tableau :
 
0
"); System.out.println();
"); System.out.println();
for (int i=0; i< t2.length ; i++) t2[i]=-1;
}
Copie de tableaux de nombres ou partage
"); System.out.println();
t2=t1;
t3 = new double [ t1.length ];
System.arraycopy(t1,0,t3,0,t1.length);
Point [] tab = new Point [ clavier.nextInt()];
  Créer chaque objet du tableau :`
9
 
 
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();
}
}
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+"
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);
}
0
1
2
3
9
tab
copie1=tab
copie1
"); System.out.println();
copie1 = tab;
copie2 = new Point [tab.length] ;
System.arraycopy(tab,0,copie2,0,tab.length);
}
Copie légère de tableaux d’objets
0
2
0
2
0
1
3
3
arraycopy(…)
copie2
  Pour la copie profonde, il faut utiliser la méthode clone(). Voir plus loin sur
les interfaces
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èrede tableaux d’objets
Notion d’objet
Les classes et objets
composés
Les points essentiels
Des objets dans les objets
  Agrégation ou composition
  Une classe Cercle
 
Construction
  Les champs
 
 
  Héritage
 
 
 
Le point du centre : de la classe Point: C’est un lien de COMPOSITION
Le rayon : un double
  Les méthodes
Chainage des constructeurs
Protection des attributs
Redéfinition des méthodes / Surcharge des méthodes
 
 
 
La surface
L’affichage
La translation
  Polymorphisme
 
 
Liaison dynamique
Classe abstraite
  Héritage multiple
Classe Point
Des objets dans les objets
import java.util.*;
class Point {
/* Definition des donnees d'un point */
private double x;
private double y;
class Cercle { // on utilise au maximum les méthodes de Point.
private Point cdg;
private double rayon;
/* 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 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());
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;
}
};
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);
Héritage
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 simple
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);
}
}
Héritage : Mettre en commun
 
Héritage : Mettre en commun
Faire des classes permettant de manipuler les cercles et les rectangles
 
 
 
 
Créer
Calculer la surface
Translater
 
 
 
 
Héritage : intérêt
 
 
 
 
 
Relation structurelle d’agrégation
 
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
 
 
 
Sans écrire de code
Sans connaître le code
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 ?
 
 
 
 
 
 
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.
Relation de spécialisation/généralisation
 
Trouver les relations de type « est-un » : classe dérivée
Trouver les points communs et les regrouper : classe mère
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
Génie logiciel : organisation du développement logiciel
 
 
 
 
On fait donc une classe « pere » qui reroupe les parties communes des cercles et
des rectangles
On peut faire encore plus !!
Exploiter les classes existantes
 
 
Le cdg
La creation
Héritage : ne pas confondre avec l’association
Définir explicitement les liens entre les classes
 
 
 
 
Les cercles et les rectangles ont des points communs
Spécialisation d’une classe par rapport à
un modèle de base : héritage
Ex : le lien Ecran-Périphérique
Le graphe complet pour un ordi
Champs hérités :
Champs hérités privé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
 
Mais
 
 
 
 
 
 
Le nom de la classe mère n’apparaît pas : si a est un PointCouleur : on écrit a.couleur, a.x, a.y
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 protected :
 
 
Utilisation directe des parties protected x et y d’un point
Attention à la protection qui peut etre détournée
class Point {
protected double x, double y;
  On suppose que Point et PointCouleur sont écrites et on ne
….
dispose pas du source
}
  Truand hacke la classe Point par héritage
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);
}
}
 
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 : conserver la protection
 
 
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
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;
….
}
}
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 :
 
Sinon On cherche dans la classe mère de a, puis dans la classe grandmère….
si la méthode est ici (meme nom, meme nombre et type de paramètres), on l’execute
 
 
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
Cas particulier des constructeurs (2)
  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
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();
}
}
  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
Héritage et
Polymorphisme
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() ?
Liaison statique et
dynamique
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
double s1=c1.surface(); System.out.println("Surface de c1
double s2=r1.surface(); System.out.println("Surface de r1
double s3=f1.surface(); System.out.println("Surface de f1
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
Forme(6,7);
"+s1);
"+s2);
"+s3);
Ici, on ne connaît pas la
classe réelle de f
Quel est le résultat ?
Polymorphisme : exemple (3)
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),
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.
Polymorphisme et classe
abstraite
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();
Forme b = new Rect();
b.surface();
b.surface(10);
/l’execution execute surface() de Forme
//l’execution execute surface() de Rect
//l’execution execute surface(int) de Rect
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
 
 
 
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
 
 
La méthode surface est impossible à écrire. Renvoyer 0 est une aberration
Que faut il faire ?
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.
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); }
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; }
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)); }
}
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
Interface
  Une interface est un ensemble d'opérations utilisée pour spécifier un service
offert par une classe.
Héritage
  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 multiple
Héritage multiple
Héritage multiple : le canard
 
 
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
 
Un canard vole
 
Un canard court (pas vite)
 
Un canard nage (mal)
 
animaux
Pour respecter la notion d’héritage, il faut donc que la classe canard hérite des 3
classes volant, nageant, courant
animaux
Animaux volant
Animaux nageant
Animaux courant
Animaux volant
Animaux nageant
Truites
Canard
Truites
Animaux courant
Héritage multiple : problème
Héritage multiple : problème
 
Une truite hérite des champs
 
 
 
Un canard hérite des champs
 
 
 
 
 
 
Héritage multiple : solution
 
Solution proposée pour le cas du canard
Vitesse par Nageant
Poids, nom et cdg par Nageant/Animaux
Vitesse par
Poids, nom
Vitesse par
Poids, nom
Vitesse par
Poids, nom
Nageant
et cdg par Nageant/Animaux
Volant
et cdg par Volant/Animaux
Courant
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
 
 
 
 
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
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
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 ();
}
}
 
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
Les containers
Les containers
 
Les structures de données classiques
 
Listes
 
 
 
 
Tableaux
 
 
 
 
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
 
 
Les containers
Accès direct
Nombre d’éléments fixés à l’avance
Insertion et suppression lentes
Containers : les structures classiques + les principaux algorithmes disponibles
 
Tableaux, Listes,
Ensembles, Listes
associatives
Accès séquentiel : premier, suivant ==> recherche lente
Dynamique : nombre d’éléments variable dans le temps
Insertion, suppression faciles et efficace
Ajout, suppression, appartenance, recherche
Tri,
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
 
 
Classe
concrete
Interface
HashMap<K,V> les clés sont un ensemble non ordonné
TreeMap<K,V> : item les clés sont un ensemble ordonné
Quelques méthodes communes aux collections
Quels containers choisir ?
Collection<E>
 
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 :
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);
 
boolean remove(E elt);
boolean remove(E elt);
 
 
 
 
void Collections.sort(List<E>);
E Collections.max(Collection<E>); E Collections.min(Collection<E>);
void Collections.reverse(List<E>);
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)
Aller voir l’API pour plus !!!
Les collections : les méthodes générales
 
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
 
 
Méthodes static de la classe outil Collections : des algo génériques
 
 
 
 
 
 
 
Pour l’instant, utiliser contains et remove avec le profil :
 
 
 
 
 
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
Collection : utilisation et iterateur
 
Déclarer une collection
 
Collection<Classe> col;
 
Créer une collection vide (classe non abstraite : linkedList, ArrayList, Vector, …)
 
Ajouter des éléments à la collection
 
Utiliser les algo génériques si besoin
 
 
 
 
col = new LinkedList<Classe>();
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);
col.add(mon_nouvel_element);
// Ajout des points dans la liste
liste.add(a); liste.add(new Point(2,2));
liste.add(new Point(1,1));
Collections.sort(col);
// 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);
}
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 :
 
Créer un iterateur SUR la collection à parcourir (methode iterator() de la classe Collections)
 
 
 
Iterator<Classe> p;
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 : 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());
}
}
}
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) : 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);
}
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
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);
}
}
JAVA 1.5 : la généricité en plus
Généricité
 
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
En Java 1.5
public
public
public
public
Pile(E[] tableau) { tab = tableau; nb=0; };
void empiler(E e) { if (nb < tab.length) tab[nb++] = e; }
E depiler() { return (nb>0 ?tab[--nb]:null); }
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
Traitement des erreurs
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());
}
}
}
Les exceptions
Exceptions
Exceptions : classes particulières
  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.
 
 
 
 
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
Exceptions : Capturer une (ou plus) exception
  Lorsqu’une exception apparaît, on peut soit
  Capturer et traiter l’exception ( try .. Catch)
  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();
}
  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");
}
  Capturer et traiter l’exception ( try .. Catch)
}
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);
}
}
Exceptions : créer une exception
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);
}
}
Sérialisation
Sérialisation
 
Sérialisation : Comment stocker et relire facilement des objets dans un fichier ou un
flot
 
 
Importer java.io.*
Interface Serializable
 
Stocker et relire des objets
dans des flots (disques ou
réseau)
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
Sérialisation
Serialisation
class Point implements Serializable {
…. // comme précédemment
}
  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 :
abstract class Forme implements Serializable {
…. // comme précédemment
}
 
 
  On relit ce fichier à l’aide d’une deuxième liste
class Point extends Forme{
…. // comme précédemment
}
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");
}
class Rectangle extends Forme{
…. // comme précédemment
}
Serialisation
Serialisation : encore mieux
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);
}
}
D’abord le nombre de forme
Ensuite, on parcours la liste pour les stocker une par une
// Affichage de la liste2
  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");}
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
Swing : exemple 1
Swing : exemple 1 bis
import javax.swing.*;
import java.awt.*;
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
}
}
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 Ex30 {
public static void main(String[] args) {
new Deuxboutons();
}
}
SWING
Apports de SWING
  Couche logicielle indépendante de la plate forme physique
  Modèle-Vue-Contrôleur
 
 
 
 
public class Ex31 {
public static void main(String[] args) {
new Deuxboutons();
}
}
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
  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
 
 
 
 
Timers
Filechooser,Colorchooser
Java2D API
Fenêtre texte
 
 
 
 
java.awt.datatransfert.DataFlavor
JTextField, JtextArea : idem AWT
JPasswordField : masquée
JEditorPane, JTextPane : editeur de texte complet
(plusieurs polices simultanées..)
SWING : la hiérarchie classique d'une IG
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 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 : 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();}
}
La fenêtre top level JFrame s'affiche
Le contentpane affiche un fond opaque
Le JPanel s'affiche (par dessus le précédent) :
JFrame
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()
getContentPane
JPanel
–  le texte
 
()
Pour provoquer l'affichage, utiliser
 
 
repaint() : affiche tout le composant
repaint(int,int,int,int) : affiche le rectangle
JButton
Jlabel
Mon Bouton
Du Texte
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
Comment positionner les composants
Positionnement dans une IG
  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
Swing : Borderlayout
Swing : Gridlayout
import javax.swing.*;
import java.awt.*;
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();
}
}
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();
}
}
Swing : Boxlayout
Structurer une interface : description
hiérarchique
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 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);
}
Dessiner une liste de forme
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);}
};
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
Image
  Tous les attributs classiques de dessin sont disponibles à travers les
classes et methodes de Java
 
  Gestion des couleurs, épaisseur, etc. : setPaint, setStroke
  AWT : getImage, drawImage
  Remplissage : classes Color, GradientPaint, TexturePaint,
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…
  Transformations affines
AffineTransform textAt = new AffineTransform();
textAt.translate(0,(float)textTl.getBounds().getHeight());
  ImageIO.read(File), ImageIO.write(BufferedImage, "Format",File)
  g.drawImage(….) : affiche l’image, applique des filtres
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();
}
}
}
}
Menu
1. 
Création d’une barre de menu
$ 
2. 
JMenuBar barreMenu=new JMenuBar();
Création d’un menu, type Fichier, Edition, ….
• 
3. 
JMenu menu=new JMenu("Formes");
Création des éléments du menu
• 
4. 
JMenuItem item1=new JMenuItem("Sauver");
Ajout des éléments au menu
• 
5. 
menu.add(item1);
Ajout du menu à la barre
• 
6. 
barreMenu.add(menu);
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
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
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(); }
}
Gestion des évenements
JAVA
Gestion des évènements en
SWING
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
  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 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();}
}
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
 
 
 
Fermer la fenetre
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
Les adapteurs : 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();}}
Ecouter 2 boutons (1)
  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
  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
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 : 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 : 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 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(); } }
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
 
 
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
 
 
 
 
 
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
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(…))
Quel écouteur définir pour quelle action ?
 
  Les évènements sont typés, organisé en classes
En pratique
 
 
 
Résumé
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(); }
}
Quel écouteur définir pour quelle action (2) ?
 
Interface KeyListener ou classe KeyAdapter
 
 
 
 
 
boolean isActionKey()
int getKeyChar(), int getKeyCode()
Utilisée les Sliders, les ColorChooser, les Spinners
Méthodes à définir
 
 
 
void stateChanged(ChangeEvent e) : changement dans le composant
Utilisée les checkBoxes, les ComboBoxes
Méthodes à définir
 
Principales méthodes de la classe ItemEvent
 
 
 
 
ItemSelectable getItemSelectable() : similaire à getSource()
Object getItem(), int getStateChange()
 
 
  Taper du texte dans une fenêtre,
  Recevoir dans une autre, avec ascenseur
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
 
Un chat local (1)
Soit vos applications graphiques implémentent l’interface WindowListener avec ses 7
methodes
 
 
void itemStateChanged(ItemEvent e) : changement dans le composant
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
Interface ItemListener
 
 
Utilisée pour les actions sur les fenetres : ouverture, fermeture, iconification, quitter
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
Interface ChangeListener
 
 
 
Interface WindowListener ou classe WindowAdapter
Principales méthodes de la classe KeyEvent
 
 
 
 
Utilisée pour les actions clavier sur un composant
Le Composant doit pouvoir obtenir le focus avec setFocusable(true)
Méthodes à définir
 
 
 
 
Quel écouteur définir pour quelle action (3) ?
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
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);
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 eventdispatching
: soumet la requête (met en evenement dans la file d’ev) et n'attend
 
pas
 
: soumet la requête et attend
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 (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);
}
}
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);
Labels et Onglets
 
JLabel : Image possible
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);
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 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);
}
}
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));
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
Téléchargement