Vous êtes sur la page 1sur 80

Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

Contenu du cours

Chapitre 0. INTRODUCTION
1. Généralités
2. Objectifs du cours
3. Présentation
4. JVM

Chapitre I : STRUCTURE DU LANGAGE


1. Éléments du langage
2. Opérateurs
3. Commentaires
4. Structure de contrôle

Chapitre II. PROGRAMMATION ORIENTE OBJET EN JAVA


1. Concepts de classes
2. Héritage
3. Modificateur d’accès
4. Paquets java
5. Super classe Objet
6. Classe System
7. Notation Lambda

Chapitre III : ERREURS ET EXCEPTIONS


1. Bloc try\catch
2. Le mot clé throws
3. Le mot clé finally

Chapitre IV. L’INTERACTION AVEC LES BASES DE DONNES


1. JDBC
2. Sérialisation
3. Étude de cas.

CHAPITRE V. INTERFACE GRAPHIQUE (GUI)


1. SWING
2. JAVAFX

Msc student Ruphin NYAMI Page 1


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

CHAPITRE 0. INTRODUCTION
1. Généralités

Les causes d’échec d’un projet informatiques ont comme principales sources les risques
potentiels liés naturellement à la notion du projet. Techniquement, ces risques potentiels sont entre autres :
- Les risques liés aux ressources humaines : dit au manque de compétences, de formation,...
- Les risques techniques : ces risques sont liés au non-respect de la normalisation et de la
standardisation informatique.

Il n’existe pratiquement aucune solution universelle à tous les problèmes générés par ces
risques. Les actions envisagées pour limiter ces risques se situe la mise en place de formation, adaptée
aux outils de génie logiciel faisant parti l’espace de solution.

La conception consiste à « appliquer différent principes et techniques dans le but de définir un


appareil, un processus ou un système avec suffisamment de précision pour permettre sa réalisation
physique ». C’est aussi la phase la plus créative du processus de développement d’un logiciel et il existe
peu de règles pour la guider.

La conception converti le « Quoi » de la spécification en « Comment ». Elle doit aboutir à un


document suffisamment précis pour que le système puisse être implémenté sans faire appel à l’utilisateur
final ou à la personne ayant rédigé les spécifications.

La phase de conception doit convertir également la thermologie de l’espace du problème des


spécifications vers l’espace de solution de l’implémentation. (ex. dans le domaine du problème on parlera
d’un objet du monde réel Véhicule alors que dans l’espace de solutions, on parlera d’une classe Java
appelée Véhicule.)

Il est cependant question de savoir :


 Comment effectuer ce passage de la conception à l’implémentation (pseudo-code) qui a comme
résultat structure modulaire détaillée, interfaces précises et implicites, de texte détaillé de chaque
module.
 Comment faciliter la réalisation de ces étapes ?
 Comment assurer la cohérence entre les concepts de l’espace du problème et ceux de l’espace de
ma solution ?

Ainsi le Génie logiciel demande de la part de l’informaticien :


 Une bonne formation aux différents outils et techniques (le « savoir ») ;
 Un certain entrainement et de l’expérience (le « savoir faire »).

2. Objectifs

Ce cours a comme objectifs d’apprendre aux étudiants d’approfondir la connaissance de différents


outils de conception (upper-case) et les environnements de développement (lower-case) afin de :
 Maîtriser la productivité ;
 Améliorer le suivi
 Améliorer la qualité
 Produire un logiciel (évoluable, fiable, efficace et réutilisable)
 Faire un choix judicieux dans le marché d’outils de développement et ce conception.

a. Les environnements de conception (upper case):

Msc student Ruphin NYAMI Page 2


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

Ces outils supportent les phases d’analyse et de conception du processus logiciel.


Ils intègrent généralement :
 Les outils pour l’édition de diagramme (avec vérification syntaxique)
 Des dictionnaires de données
 Des outils pour des éditions de rapports,
 Des générations de (squelette) de code,
 Des outils pour les prototypages

Ils sont généralement basés sur une méthode d’analyse et de conception (UML, Merise, …)

Examples: Objecteering, ArgoUML, StarUML, Windev, powerDesigner et Power AMC,


Rational Rose.

b. Les environnements de développement (lower case)

Ils supportent les phases d’implémentation et de test du processus logiciel.


Ils intègrent généralement :

 Des éditeurs (éventuellement dirigés par la syntaxe)


 Des générateurs d’interfaces homme/machine
 Des SGBD
 Des compilateurs
 De debugger

Exemple :
Sous LINUX :
- Il intègre des outils de programmation et de test
- L’intégration de données se fait par l’intermédiaire de fichier UNIX

Certains environnements, plus évolués, sont dédiés à un langage particulier


Exemple :
 Éclipse,
 Small talk,
 NetBeans

Ces différents environnements proposent :


 Des bibliothèques de composants
 Une interface graphique
 Des éditeurs dédiés au langage
 Des interprètes
 Debugger,…

Enfin, il existe des générateurs d’environnement de programmation, qui à partir d’une description
formelle d’un langage, ils génèrent un environnement de programmation dédié au langage contenant :
 Un éditeur dédié au langage
 Un pretty-printer
 Un debugger
 Un interpréteur

Exemple :
- Centaur
- Smart tools

Msc student Ruphin NYAMI Page 3


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

- VB NET
- NetBeans
- Jbuilder

Outil dédié : Java (NetBeans)

Le langage Java est un langage de programmation informatique orienté objet créé par James
Gosling et Patrick Naughton employés de Sun Microsystems avec le soutien de Bill Joy (cofondateur de
Sun Microsystems en 1982), présenté officiellement le 23 mai 1995 au Sun World.(
http://en.wikipedia.org/wiki/Java_programming_language)
Java est un langage de programmation orienté objet. Le passage à la programmation
orientée objet (POO) à partir d’autres modèles de programmation peut être difficile. Java est axé
sur la création d’objets (structures de données ou comportements) qui peuvent être répartis et
manipulés par le programme.
Comme d’autres langages de programmation, Java prend en charge la lecture et l’écriture des
données dans différents dispositifs d’entrée et de sortie.

3. Présentation

Java est un langage de programmation à usage général, évolué et orienté objet dont la syntaxe est
proche du C. Il existe 2 types de programmes en Java : les applets et les applications. Une application
autonome (stand alone program) est une application qui s'exécute sous le contrôle direct du système
d'exploitation. Une applet est une application qui est chargée par un navigateur et qui est exécutée sous
le contrôle d'un plug in de ce dernier.

a. Caractéristiques
Parmi les points forts de java nous citons :
 Java est interprété : le code source est compilé en pseudo code ou byte code avant d’être
interprété par le compilateur java « JVM » qui est partout installé.
 Portable (indépendant de toute plate-forme) : il n’y a pas de compilateur spécifique pour chaque
plateforme. La présence de la machine virtuelle de java dans n’importe quelle plateforme permet
d’exécuter les codes java.
 Java est orienté objet : comme la plupart des langages récents, Java est orienté objet. Chaque
fichier source contient la définition d'une ou plusieurs classes qui sont utilisées les unes avec les
autres pour former une application.
 Java est simple : le choix de java a été d'abandonner des éléments mal compris ou mal exploités
des autres langages tels que la notion de pointeurs (pour éviter les incidents en manipulant
directement la mémoire), l'héritage multiple et la surcharge des opérateurs, ...
 Java est fortement typé : toutes les variables sont typées et il n'existe pas de conversion
automatique qui risquerait une perte de données. Si une telle conversion doit être réalisée, le
développeur doit obligatoirement utiliser un cast ou une méthode statique fournie en standard
pour la réaliser.
 Java assure la gestion de la mémoire : l'allocation de la mémoire pour un objet est automatique
à sa création et Java récupère automatiquement la mémoire inutilisée grâce au garbage collector
qui restitue les zones de mémoire laissées libres suite à la destruction des objets.

4. La machine virtuelle (JVM)

La machine virtuelle Java (Java Virtual Machine ou JVM) est l’environnement d’exécution des
programmes Java. Elle définit un ordinateur abstrait et précise les instructions que ce dernier peut

Msc student Ruphin NYAMI Page 4


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

exécuter. Ces instructions sont appelées bytecodes. De façon générale, les bytecodes Java sont à la JVM
ce que le jeu d’instructions est à une CPU.

Un bytecode est une instruction d’un octet de long générée par le compilateur Java et exécutée
par l’interpréteur Java. Lors de la compilation d’un fichier .java, le compilateur produit une suite de
bytecodes qu’il stocke dans un fichier .class. L’interpréteur Java peut ensuite exécuter les bytecodes
stockés dans le fichier .class.

La machine virtuelle est la seule partie de Java qui interagit directement avec le système
d’exploitation de l’ordinateur. Comme chaque système d’exploitation est différent, toute
implémentation JVM spécifique doit savoir comment interagir avec le système d’exploitation spécifique
pour lequel elle est conçue.

L’exécution des programmes Java sous une implémentation de la JVM garantit un


environnement d’exécution prévisible, car toutes les implémentations de la JVM sont conformes à la
spécification JVM. Même s’il y a différentes implémentations de la JVM, elles suivent toutes un certain
nombre d’exigences qui garantissent la portabilité. En d’autres termes, les différences éventuelles entre
les diverses implémentations n’affectent pas la portabilité.

La JVM est responsable de l’exécution des fonctions suivantes :

 Allocation de mémoire aux objets créés


 Récupération des données périmées (garbage collection)
 Gestion du recensement et des piles
 Appel du système hôte pour certaines fonctions, comme l’accès aux périphériques
 Suivi de la sécurité des applications Java

Msc student Ruphin NYAMI Page 5


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

CHAPITRE I : STRUCTURE DU LANGAGE JAVA


1.1. Éléments du langage
Cette section présente les concepts fondamentaux relatifs aux éléments du langage de
programmation Java qui seront utilisés dans le programme java.

1.1.1. Les règles de base


- Java est sensible à la casse
- Le bloc de codes sont encadré des accolades « {} »,
- Chaque instruction se termine par un point-virgule « ; »
- Une instruction peut se tenir sur plusieurs lignes
- L’indentation est ignorée par le compilateur mais elle est importante pour le programmeur

1.1.2. Les identificateurs


L’identificateur est le nom choisi par le programmeur pour appeler un élément (une
variable ou une méthode, une classe, …).
Chaque objet, classe, programme ou variable est associer à un nom : l'identificateur qui peut se
composer de tous les caractères alphanumériques et des caractères _ et $. Le premier caractère doit être
une lettre, le caractère de soulignement ou le signe dollar.
Un identificateur doit être constitué d’un seul mot (pas d’espace) et ne peut pas appartenir à la
liste des mots réservé du langage Java : abstract, assert, boolean, break, byte, case, catch, char, class,
const, continue, default, do, double, else, extends, false, final, finally, floatfor, goto, if, implements,
import, instanceof, int interface, long, native, new, null, package, private, protected, public, return,
short, static, super, switch, synchronized, this, throw, throws, transient, true, try, void, volatile,
while.

1.1.3. Les commentaires


Ils ne sont pas pris en compte par le compilateur donc ils ne sont pas inclus dans le pseudo code.
Ils ne se terminent pas par un ;.
Il existe trois types de commentaire en Java :
Types de Exemples
commentaire
Commentaire abrégé // commentaire sur une seule ligne
Int i = 0 ; // déclaration du compteur i
Commentaire multi-lignes /* commentaires ligne 1
…. Lignes n */
Commentaire de la /**
documentation * commentaire de la methode
* @param val la valeur à traiter
automatique * @since 1.0
* @return Rien
* @deprecated Utiliser la nouvelle methode XXX
*/

1.1.3.1. Les variables


Une variable est une petite information stockée en mémoire. Elle doit avoir un nom, un type et une
valeur. La déclaration d'une variable permet de réserver la mémoire pour en stocker la valeur.

Msc student Ruphin NYAMI Page 6


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

Le type d’une variable peut être :


 soit un type élémentaire dit aussi type primitif déclaré sous la forme type_élémentaire variable;
 soit une classe déclarée sous la forme classe variable ;
exemple : long nombre ;
String chaine ;
Int compteur ;
Il est possible de définir plusieurs variables de même type en séparant chacune d'elles par une virgule.
(String nom, prénom, adresse).

Pour les objets, il est nécessaire en plus de la déclaration de la variable de créer un objet avant de pouvoir
l'utiliser. Il faut réserver de la mémoire pour la création d'un objet (remarque : un tableau est un objet en
Java) avec l'instruction new. La libération de la mémoire se fait automatiquement grâce au garbage
collector.

Exemple
MaClasse instance; // déclaration de l'objet
instance = new maClasse(); // création de l'objet
OU MaClasse instance = new MaClasse();//déclaration et création de
l'objet

int[] nombre = new int[10];

Il est possible en une seule instruction de faire la déclaration et l'affectation d'une valeur à une
variable ou plusieurs variables.

Exemple
Int nombre = 9 ; String nom = ‘KAKOKO’ ;

1.1.3.2. La durée de vie de variables :


a. portée locale : une variable est dite locale si sa déclaration est faite à l’intérieur d’une
méthode. Cela signifie que cette variable n’est accessible que pour le code se trouvant
dans cette méthode. Quand la méthode se termine, la variable est automatiquement
effacée de la mémoire.

b. Variable membre ou variables d’instance : cette variable est déclarée en dehors de toutes
les méthodes de la classe et elle est vivante tant que l’instance de l’objet existe en
mémoire. Elles peuvent être partagées et réutilisées par toutes les méthodes de la classe
et, dans certains cas, elles peuvent même être visibles depuis des classes extérieures.
NB. Si une variable membre ou une méthode est déclarée avec l’attribut « static », elle utilisable
partout sans l’instance de la classe où elle a été créée. Car Les membres statiques d'une classe
sont utilisés pour stocker les valeurs qui sont identiques pour toutes les instances d'une classe.

1.1.3.3. Les types élémentaires


Les types élémentaires ont une taille identique quel que soit la plate-forme d'exécution :
c'est un des éléments qui permet à Java d'être indépendant de la plate-forme sur lequel le code
s'exécute. Elles commencent tous par une minuscule.

Msc student Ruphin NYAMI Page 7


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

Type Désignation Longueur Valeurs Commentaires


boolean Valeur 1 bit True ou false pas de conversion possible
logique vers un autre
type
byte Octet signé 8 bits -128 à 127
Short Entier cout 16 bits −32768 à 32767
signé
Char Caractère 16 bits \u0000 à \uFFFF entouré de cotes simples
unicode dans du code
Java
Int Entier signé 32 bits −2147483648 à
2147483647
Float virgule 32 bits 1.401e−045 à
flottante 3.40282e+038
simple
précision
(IEEE754)
double virgule 64 bits 2.22507e−308 à
flottante 1.79769e+308
double
précision
(IEEE754)
Long Entier long 64 bits −9223372036854775808
à
9223372036854775807

1.1.3.4. Types de données composites

Les types de données composites, ou de référence, sont constitués de plusieurs éléments.


Les types de données composites sont de deux sortes : classes et tableaux. Les noms de classes
et de tableaux commencent par une lettre majuscule et la première lettre de chaque mot qui les
constitue est en majuscule (capitalisation en dents de scie), par exemple, NomDeClasse).

Toute classe peut être utilisée comme type de données une fois qu’elle a été créée et
importée dans le programme. Comme la classe String est la plus souvent utilisée comme type de
données, c’est à elle que nous nous consacrerons dans ce chapitre.
Exemple
public class Vehicuel{
Vehicule vehicule ;
}

1.1.3.5. Les chaines


Le type de données String est en réalité la classe String. La classe String stocke toute
séquence de caractères alphanumériques, espaces et ponctuation normale (ce qu’on appelle des
chaînes), entourée de guillemets. Les chaînes peuvent contenir n’importe quelle séquence
d’échappement Unicode et nécessitent \" pour placer des guillemets à l’intérieur de la chaîne,

Msc student Ruphin NYAMI Page 8


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

mais, en général, la classe String elle-même indique au programme comment interpréter


correctement les caractères.

Exemple
String nom, prénom, adresse ;
nom = ‘’ KAKOKO’’ ;
prénom = ‘’Alains5’’ ;
adresse = ‘’ N° 65/Bis, KAMANYOLA, Kinhsasa’’ ;

1.1.3.6. Les tableaux


Un tableau est une structure de données contenant un groupe de valeurs du même type.
Par exemple, un tableau accepte un groupe de valeurs String, un groupe de valeurs int ou un
groupe de valeurs boolean. Tant que les valeurs sont du même type, elles peuvent être placées
dans le même tableau.
Les tableaux sont repérés par des crochets, placés soit après le nom de la variable, soit
après le type de données :

String [] joueurs; Ou String joueurs [];

Exemple :
Supposons que ton programme doit stoker les noms de quatre joueurs. Au
lieu de déclarer quatre variables de type String, tu peux déclarer un
Tableau (array) qui aura quatre éléments de type string. Chaque élément
possède son propre indice partant de zéro.

joueurs = new String [4];


joueurs[0] = "Trésor";
joueurs[1] = "Patu";
joueurs[2] = "Alain";
joueurs[3] = "KULUKUTA";

1.1.3.7. Les littérales


Un littéral est la représentation réelle d’un nombre, d’un caractère, d’un état ou d’une chaîne. Un
littéral représente la valeur d’un identificateur. Un littéral représente la valeur d’un identificateur.

1.1.3.8. Les opérateurs


Les opérateurs sont des symboles qui permettent de manipuler des variables. Ils permettent
notamment d’effectuer des opérations, d’affecter ou de comparer des valeurs, etc.
Les opérateurs en java sont généralement classés en six catégories : affectation,
arithmétique, logique, comparaison, niveau bits et ternaire.

a) Les opérateurs d’affectation


L’affectation signifie le stockage de la valeur qui est à la droite du signe =dans la variable
qui est à sa gauche.
Exemple
int compteur = 1 ;
String joueur = ‘’Trésor’’ ;
float montant = 3,77

Msc student Ruphin NYAMI Page 9


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

L’opérateur d’affectation = est une opération qui renvoie une valeur. La valeur renvoyée est la valeur
affectée, ce qui permet de faire des affectations en chaîne :
Exemple
int x = 3;
int y ;
int z = y = 5 ;

b) Opérateurs arithmétiques
Opérateur Opération
+ Addition

- Soustraction

* Multiplication

/ Division

% Modulo

++/-- Incrémente et
décrément
automatiquement

int y = 3, x; //1. déclaration des variables


int b = 9; //2.
int a; //3.
x = ++y; //4. pré-incrémentation
a = b--; //5. post-décrémentation

c) Les opérateurs logiques

Les opérateurs logiques servent énormément dans les structures de contrôle.

Opérat exemples Évalué à VRAI(TRUE) quand :


eur
! if (!etat.equals("Ruanda")) (non logique) L’expression
ne renvoie pas TRUE.
& if (art.equals("cahier") & (Et logique and ) : Les
prix > 110) deux expressions renvoient
TRUE. C'est-à-dire les deux
expressions doivent être
vraies au même moment.
&& if (art.equals("cahier") && Si la première expression
prix > 110) est false, la seconde ne
sera même pas évaluée
| if(état.equals("Ruanda") | ou logique Au moins l’un
état.equals("Congo")) des deux renvoie TRUE.(les
deux expressions sont
obligatoirement évaluées

Msc student Ruphin NYAMI Page 10


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

|| if (état.equals("Ruanda") ou exclusif (si la première


|| état.equals("Congo")) expression est vraie, la
seconde ne sera pas
évaluée).

d) Opérateurs de comparaison

Les opérateurs de comparaison sont principalement utilisés en combinaison avec les structures
conditionnelles (if, for, while, etc.).
Ces opérateurs permettent de comparer deux termes et de renvoyer un booléen vrai ou faux (TRUE ou
FALSE) selon la véracité de la comparaison.

Opérateur Signification Exemple Description


== Égal à if( a == b) Renvoi TRUE si a est égal à b
< Inférieur à if(a < b) Renvoi TRUE si a est plus petit que b
> Supérieur à if(a > b) Renvoi TRUE si b est plus petit que a
<= Inférieur ou égal à if(a <= b) Renvoie TRUE si a est inférieur ou égal à b.
>= Supérieur ou égal à if(a >= b) Renvoie TRUE si a est supérieur ou égal à b.
!= Différent de if (a != b) Renvoie TRUE si a est différent b.

e) Opérateur conditionnel ternaire

If : on l'utilise pour affecter une valeur à une variable en fonction d'une expression terminée par un point
d'interrogation. Si l'expression est vraie, la valeur suivant le point d'interrogation est utilisée ; sinon, la
valeur suivant les deux points est affectée à la variable située à gauche du signe égal :

remise = prix > 50 ? 10 : 5;

Si le prix est supérieur à 50, la variable remise prend la valeur 10 ; sinon, elle vaut 5. C'est juste un raccourci
pour exprimer une clause if normale :

if (prix > 50)


{
remise = 10;
}
else
{
remise = 5;
}

else if : Enfin, il est possible d’enchaîner une série d’instructions if (sans avoir besoin de les
imbriquer) à l’aide de l’instruction else if.

Exemple
public class BulletinAppréciation {

public char convertirNiveaux(int noteDevoir) {

Msc student Ruphin NYAMI Page 11


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

char niveau;

if (noteDevoir >= 18) {


niveau = 'E';
}
else if (noteDevoir >= 16 && noteDevoir < 18) {
niveau = 'T';
}
else if (noteDevoir >= 14 && noteDevoir < 16) {
niveau = 'B';
}
else if (noteDevoir >= 12 && noteDevoir < 14) {
niveau = 'A';
}
else if (noteDevoir >= 10 && noteDevoir < 12) {
niveau = 'P';
}
else {
niveau = 'I';
}
return niveau;
}

public static void main(String[] args) {

BulletinAppréciation convertisseur = new BulletinAppréciation();

char tonNiveau = convertisseur.convertirNiveaux(17);

System.out.println("Ton premier niveau est " + tonNiveau);

tonNiveau = convertisseur.convertirNiveaux(15);

System.out.println("Ton second niveau est " + tonNiveau);


}
}

1.1.3.9. L’instruction switch

Cette instruction permet de faire plusieurs tests sur la valeur d’une variable, ce qui évite de faire
plusieurs if imbriqués et simplifie ainsi la lecture du code.

Syntaxe:
switch (variable)
{
case condition1:
//Traitement de la condition 1
break;
case condition2:
//Traitement de la condition 2
break;

Msc student Ruphin NYAMI Page 12


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

….
case conditionN:
//Traitement de la condition N
break;
default:
//Traitement par défaut
}

Exemple
public static void main(String[] args) {
BulletinAppréciation convertisseur = new BulletinAppréciation();
char tonNiveau = convertisseur.convertirNiveaux(15);
switch (tonNiveau) {
case 'E': System.out.println("Excellent travail !");
break;
case 'T': System.out.println("Très bon travail !");
break;
case 'B': System.out.println("Bon travail !");
break;
case 'A': System.out.println("Tu peux mieux faire !");
break;
case 'P': System.out.println("Tu dois travailler plus !");
break;
case 'I': System.out.println("Change d'attitude !");
break;
}
}

1.1.4. Les structures de contrôles

Comme quasi totalité des langages de développement orienté objets, Java propose un
ensemble d'instructions qui permettent de d'organiser et de structurer les traitements. L'usage de
ces instructions est similaire à celui rencontré dans leur équivalent dans d'autres langages.

1.1.4.1. Les boucles


Les boucles sont des structures qui permettent d’exécuter plusieurs fois une même série
d’instructions en fonction d’une (ou plusieurs) condition(s).
while ( boolean )
{
... // code a exécuter dans la boucle
}
Le code est exécuté tant que le booléen est vrai. Si avant l'instruction while, le booléen est faux,
alors le code de la boucle ne sera jamais exécuté.
Ne pas mettre de ; après la condition sinon le corps de la boucle ne sera jamais exécuté

do {
...
} while ( boolean )

Msc student Ruphin NYAMI Page 13


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

//Cette boucle est au moins exécuté une fois quelque soit la


valeur du booléen;

for (initialisation; condition; modification) {


...
}

Exemple :
for (i = 0 ; i < 10; i++ ) { ....}
for (int i = 0 ; i < 10; i++ ) { ....}
for ( ; ; ) { ... } // boucle infinie

La condition peut ne pas porter sur l'index de la boucle :

boolean trouve = false;


for (int i = 0 ; !trouve ; i++ ) {
if ( tableau[i] == 1 )
trouve = true;

Il est possible de nommer une boucle pour permettre de l'interrompre


même si cela est peu recommendé :

int compteur = 0;
boucle:
while (compteur < 100) {
for(int compte = 0 ; compte < 10 ; compte ++) {
compteur += compte;
System.out.println("compteur = "+compteur);
if (compteur> 40) break boucle;
}
}

1.1.5. Les conversions de types


Lors de la déclaration, il est possible d'utiliser un cast :
Exemple :
int entier = 5;
float flottant = (float) entier;

La conversion peut entrainer une perte d'informations. Il n'existe pas en Java de fonction
pour convertir : les conversions de type se font par des méthodes. La bibliothèque de classes API
fournit une série de classes qui contiennent des méthodes de manipulation et de conversion de
types élémentaires.

Classe Rôle
String Pour la chaine de caractère unicode
Integer Pour les valeurs entières
Long Pour les entiers longs signés
Float Pour les nombres à des virgules flottantes

Msc student Ruphin NYAMI Page 14


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

Double Pour les nombres à des virgules flottantes


doubles précision

a. La conversion d'un entier int en chaîne de caractère String

Exemple
int i = 10;
String montexte = new String();
montexte = montexte.valueOf(i);

valueOf est également définie pour des arguments de type boolean, long, float, double et char

b. La conversion d'une chaîne de caractères String en entier int

Exemple
String montexte = new String("10");
Integer nomnombre = new Integer(montexte);
int int i = monnombre.intValue(); //convertion d'Integer en int

c. La conversion d'un entier int en entier long

Exemple
int I = 10;
Integer monnombre = new Integer(i);

1.1.6. Opération sur les chaines de caractères

1.1.6.1. L'addition de chaines


Java admet l'opérateur + comme opérateur de concaténation de chaines de caractères.
L'opérateur + permet de concaténer plusieurs chaines. Il est possible d'utiliser l'opérateur +=

1.1.6.2. La comparaison de deux chaines


Il faut utiliser la méthode equals()
Exemple
String pays = ‘’congo’’ ;
If (pays.equals(‘’congo’’) {

1.1.6.3. La détermination de la longueur d'une chaine


Exemple :
String texte = ‘’texte’’;
int longueur = texte.length();

Msc student Ruphin NYAMI Page 15


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

1.1.6.4. La modification de la casse d'une chaine


Les méthodes Java toUpperCase() et toLowerCase() permettent respectivement d'obtenir une
chaîne tout en majuscule ou tout en minuscule.

Exemple
String texte = ’’ texte ‘’;
String textemaj = texte.toUpperCase();

1.1.6.5. Extraire une sous chaine


La méthode substring() et subsequence() permettent d’extraire une sous chaine.

Exemple :
String cours = ‘’informatique’’;
String partie = cours.substring(0,5) ; // partie = informat

1.1.6.6. Convertir un objet enchaine


La méthode toString() permet cette conversion
Exemple :
Objet monobjet ;
System.out.println(monobjet.toString())

Msc student Ruphin NYAMI Page 16


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

CHAPITRE II. PROGRAMMATION ORIENTE OBJET EN JAVA


2.1. Généralités

L'apprentissage de la programmation commence par une longue phase d'écriture de petits logiciels
qui ont la particularité d'être spécifiés, analysés, codés, utilisés et maintenus par une même personne
travaillant isolément.
Les objectifs de ces programmes sont relativement modestes, ils s'inscrivent dans le cadre des
projets d'un cours par exemple, ils n'ont pas à être très fiables et ils ont une durée de vie limitée.
Leur réutilisation, leur maintenance, ou leur adaptation à des situations nouvelles n'est pas
prévue. Si les paramètres du problème changent légèrement, le programme doit être modifié et recompilé.

2.2. Programmation Procédurale


Un programme est une suite d’instruction exécutée par une machine. L’exécution de ses
instructions agit sur les données. Principe de la programmation procédurale :

Les fonctions et les procédures travaillent à distance sur les données, et l’accent est mis
sur les actions « que veut-on faire ? ».
Faiblesses :
 La dissociation de données et traitement a de conséquences directes lors du changement
de la structure de données.
 Les procédures s’appellent entre elles et peuvent modifier les mêmes données.
Finalement conception plat de spaghettis dans les appels de procédures. Il serait bien
"responsabiliser" nos parties de programmes ; d'où une autre vision de la programmation.

2.3. Programmation Par Objet.


• Un programme = une société d'entités (objet)
• Son exécution : les entités collaborent pour résoudre le problème final en s'envoyant des
messages.
• une entité = un objet qui prend en compte sa propre gestion (objet responsable)

Msc student Ruphin NYAMI Page 17


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

• Liaison inévitable entre données et procédures opérant sur ces données.


• La question est: De quoi parle-t-on ?
Quelles sont les entités qui interviennent dans mon problème ?

2.3.1. Principes généraux de la POO : Rappels


La Programmation Orientée Objet (POO) est un style de programmation qui consiste à
définir et assembler des briques de code appelées "objets", il s'oppose au style de programmation
classique dit "procédural".

L'intérêt est de favoriser l'évoluabilité du code en concevant une application non plus à
partir de ses fonctionnalités, mais à partir de ses données qui sont généralement plus stables

Un objet peut représenter un concept (fichier) ou une entité du monde physique (voiture,
personne).
Un objet est une structure qui regroupe des données (attributs) et les moyens de traiter ces
données (des fonctions que l'on appelle "méthodes" en POO).

2.3.1.1. La classe et Objet


En POO, l'élément de base est la classe qui représente des objets du monde réel.
Une classe est un support d’encapsulation : c'est-à-dire est un ensemble de données et de
fonctions regroupées dans une même entité. Une classe est une description abstraite d'un objet.
Les fonctions qui opèrent sur les données sont appelées des méthodes. Instancier une classe
consiste à créer un objet sur son modèle. Entre classe et objet il y a, en quelque sorte, le même
rapport qu'entre type et variable.
Nb. Java est un langage orienté objet : tout appartient à une classe sauf les variables de type primitives.

 Les classes java peuvent posséder des méthodes et des attributs.


 Les méthodes définissent les actions qu’une classe peut effectuer.
 Les attributs décrivent la classe.

Une classe se compose en deux parties : un entête et un corps. Le corps peut être divisé
en 2 sections : la déclaration des données et des constantes et la définition des méthodes. Les
méthodes et les données sont pourvues d'attributs de visibilité qui gère leur accessibilité par les
composants hors de la classe.

Msc student Ruphin NYAMI Page 18


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

2.3.1.1.1. Terminologies
Les concepts les plus usuels en POO sont :
 Classe : type de données défini par le programmeur. Une classe est une représentation
abstraite d’un objet du monde réel.
 Objet : instance de la classe. On définit la classe une seule fois et
on l’utilise plusieurs fois pour créer des objets.
 Donnée membre : aussi appelée attribut ou propriété et
représente une valeur faisant partie des données de la classe. Bref les données membre
constituent l’Etat de la classe.
 Fonction membre : aussi appelée méthode et représente une
fonction permettant d’agir sur les données de la classe. Elles représentent le
comportement de la classe.
 Classe parent : c’est la classe utilisée pour dériver une nouvelle
classe. On l’appelle aussi classe de base.
 Classe enfant : c’est la nouvelle classe dérivée à partir d’une classe
parent.

La classe est l’élément de base de la programmation par objets en java.


Elle est le modèle à partir duquel des instances peuvent être créées. Une classe
est un conteneur pour des propriétés (variables) et des méthodes
(fonctions). On dit propriétés et méthodes membres.

2.3.1.1.2. Formalisme général et exemple


Les trois compartiments de base sont :
• la désignation de la classe,
• la description des attributs,
• la description des opérations.
Exemples de classes et représentation d’objets

Msc student Ruphin NYAMI Page 19


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

2.3.1.1.3. Objet
Un objet est un concept, une abstraction ou une chose qui a un sens dans le contexte du
système à modéliser. Chaque objet a une identité et peut être distingué des autres sans considérer
a priori les valeurs de ses propriétés. En d’autres termes, un objet est caractérisé par les valeurs
de ses propriétés (hydratation) qui lui confèrent des états significatifs suivant les instants
considérés. Le formalisme de représentation d’un objet est donné après celui d’une classe.

Objet = Etat + Comportement + Identité

2.3.2. Syntaxe de la déclaration d’une classe


Modificateurs ou visibilité, nom_de_classe [extends classe_mere] [implements interface] { ... }

Exemple :
Public class JeuVideo{
//le corps de la classe ou tu peux déclarer tes attributs et méthodes
}

2.3.2.1. Modificateurs de classe

Modificateur Rôle
Abstract la classe contient une ou des méthodes abstraites, qui n'ont pas de définition
explicite. Une classe déclarée abstract ne peut pas être instanciée : il faut définir
une classe qui hérite de cette classe et qui implémente les méthodes nécessaires
pour ne plus être abstraite.
Final la classe ne peut pas être modifiée, sa redéfinition grace à l'héritage est interdite.
Les classes déclarées final ne peuvent donc pas avoir de classes filles.
Private La classe n’est accessible qu’à partir du fichier ou elle déclarée (package)
Public La classe est accessible partout

Nb.
- Les modificateurs abstracts et final ainsi que public et private sont
mutuellement exclusifs.

- Le mot clé extends permet de spécifier une superclasse éventuelle : ce mot clé
permet de préciser la classe mère dans une relation d'héritage.

- Le mot clé implements permet de spécifier une ou des interfaces que la classe
implémente. Cela permet de récupérer quelques avantages de l'héritage multiple.

- L'ordre des méthodes dans une classe n'a pas d'importance. Si dans une classe, on
rencontre d'abord la méthode A puis la méthode B, B peut être appelée sans
problème dans A.

Exemple de la classe employé

public class Employe {

Msc student Ruphin NYAMI Page 20


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

private String nom;


private float salaire;

public Employe(String nom, float salaire) {


this.nom = nom;
this.salaire = salaire;
}
@Override
public String toString() {
return "Employe{" + "nom=" + nom + ", salaire=" + salaire +
'}';
}
public static void main(String[] args){
Employe kasongo = new Employe("KASONGO LUBABA", 2500);
System.out.println(kasongo.toString());
}
}

2.3.2.2. Utilisation de this


 Afin de faire référence à une propriété à l’intérieur de la classe, il faut utiliser
this.
Exemple : this.nom = "KAYUMBA USELE";

2.3.2.2. Héritage
Le concept d’héritage est le plus important de la POO. Il permet la
réutilisation de type de base défini par l’utilisateur tout en permettant de
spécialiser le type. C’est la base des notions de réutilisation de composants logiciels.
 L’idée est de pouvoir définir (dériver) une nouvelle classe en se
servant d’une classe existante (base).
 La classe dérivée hérite des membres de la classe de base tout en
lui ajoutant de nouveaux.
 Il s’agit d’écrire de nouvelles classes plus spécifiques en se
servant des définitions de base.
 Par exemple, nous pouvons dériver une nouvelle classe Employe
en se servant de la classe de base Personne.
 Permet de définir la relation “est un”. Par exemple, un employé
est une personne ou encore un étudiant est une personne.
 Un cercle est une forme géométrique.

Msc student Ruphin NYAMI Page 21


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

Personne
- adresse: String
- nom: String
- telephone: String
+ afficher(): void

Employe Etudiant Client


- poste: String - cours: String - achat: float
- salaire: float - note: float

2.3.2.3. Génération de la structure de codes en java sous Entreprise


Architect
L’un des objectifs d’un Atelier de Génie Logiciel (AGL) est de faciliter la productivité du
développeur. En créant un diagramme de classes UML dans EA, il aisé d’avoir déjà le squelette
de code selon le langage choisi par exemple.

- Sélectionnez toutes les classes Ctrl + A

- Faites clic-droit :

Msc student Ruphin NYAMI Page 22


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

- Pointer sur Code GenerationGenerate Selected Elements


Une fois cliquer, choisir le dossier de destination de classes java.
Sous l’AGL Entreprise Architecte,
Les classes dérivées héritent des propriétés nom, adresse et tel en plus de
pouvoir utiliser les méthodes définies dans la classe de base.
public class Personne {
private String adresse;
private String nom;
private String telephone;

public Personne(String adresse, String nom, String telephone) {


this.adresse = adresse;
this.nom = nom;
this.telephone = telephone;
}

public String afficher(){


return "Personne{" + "nom=" + this.nom + ", adresse=" +
this.adresse + " Telephone = " + this.telephone + "}";
}
}

La classe dérivée Employé


public class Employe extends Personne{
private String poste;
private float salaire;

public Employe(String poste, float salaire, String adresse,


String nom, String telephone) {
super(adresse, nom, telephone);
this.poste = poste;
this.salaire = salaire;
}

@Override
public String afficher() {
return super.afficher() + " Salaire . " + this.salaire + "
Poste " + this.poste; //To change body of generated methods, choose
Tools | Templates.
}

public static void main(String[] args){

Msc student Ruphin NYAMI Page 23


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

Employe instancs = new Employe("GARDE", 250, "KINKONDJA 53


KAMPEMBA", "TABARO", "09986633535");
System.out.println(instancs.afficher());
}
}

La classe dérivée Etudiant


public class Etudiant extends Personne {

private String cours;


private float note;

public Etudiant(String cours, float note, String adresse,


String nom, String telephone) {
super(adresse, nom, telephone);
this.cours = cours;
this.note = note;
}
@Override
public String afficher() {
return super.afficher() + " Cours " + this.cours + "
Cote " + this.note + " / 20"; }

Test
public class Test {
public static void main(String[] args){
Employe instancs = new Employe("GARDE", 250,
"KINKONDJA 53 KAMPEMBA", "TABARO", "09986633535");
System.out.println(instancs.afficher());

Etudiant tshibola = new Etudiant("QSAGL", 12, "55 AV


Victime", "TSHIBOLA LUFULUABO", "0816665334");
System.out.println(tshibola.afficher());

Client ganelon = new Client(260, "88 AV TUTA LUTA",


"KINGOMBE", "099775534");
System.out.println(ganelon.afficher());
}
}

2.3.2.4. Encapsulation
L’encapsulation consiste à cacher les détails internes utiles au fonctionnement et à
l’implémentation du type de données. Au niveau programmation on pourra décider de rendre
disponible
seulement certaines portions du type de données au monde
extérieur et cacher le reste (les détails d’implémentation).
Il est également possible de forcer la modification des données en
passant par un mutateur (fonction de modification) qui permettra

Msc student Ruphin NYAMI Page 24


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

de valider le changement avant qu’il soit effectué. De la même manière il est possible de forcer
la lecture en passant par un accesseur (fonction de lecture)

2.3.2.5. Constructeurs
- Un constructeur servira à initialiser le contenu d’un
objet et même dans certains cas à allouer l’espace
nécessaire aux données membres de l’objet. Le constructeur est appelé automatiquement
lors de la création de l’objet, il est alors impossible de l’oublier.
- Le constructeur est une méthode dont le nom est
nomClass ( ). Il peut avoir ou non des paramètres.

2.3.2.6. Polymorphisme
Le polymorphisme est un mécanisme par lequel, une classe hérite de plusieurs
comportements. Le polymorphisme n’est pas supporté en java car chaque classe a un seul parent.
La redéfinition
d’une méthode dans une classe enfant permettra de surcharger ce nom et la méthode
correspondante sera appelée en fonction du type de l’objet utilisé. Une classe ne peut pas étendre
plusieurs autres classes à cause des problèmes d’héritage multiple. En revanche, une classe peut
tout à fait implémenter plusieurs interfaces.

2.3.2.7. Conventions à respecter


Le nom d’une classe débute généralement par une majuscule. Ceux des attributs et méthodes par une
minuscule. Ne manipulez pas les attributs d’une classe à l’extérieur de celle-ci, mais définissez des
méthodes pour l’accès :
 Accesseurs: pour lire un attribut getAtt()
par exemple: bob.getNom();
 Mutateurs: pour modifier la valeur setAtt(var)
par exemple: bob.setNom("Larue");

2.3.3. Les Interfaces de classes


En programmation orientée objet (POO), les interfaces définissent le comportement
publique d’une classe. Les interfaces regroupent donc la signature des méthodes qui pourront
être utilisées sur l’instance d’une classe. En implémentant une interface, une classe s’oblige à
définir l’ensemble des méthodes de l’interface.

Msc student Ruphin NYAMI Page 25


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

2.3.3.1. Définir et implémenter une interface en pratique


Pour pouvoir définir une interface de la même manière qu’une classe mais en utilisant cette fois-
ci le mot clef interface à la place de class. Nous nommerons généralement nos fichiers d’interface
en utilisant « interface » à la place de « classe ». Par exemple, si on crée une interface
nommée Utilisateur, on enregistrera le fichier d’interface sous le nom utilsateur.interface.php par
convention.
Classe Compte
public class Compte {
private String intitule;
private int numero;
private float solde;
private String type;

public Compte(){}

public Compte(String intitule, int numero, float solde, String


type) {
this.intitule = intitule;
this.numero = numero;
this.solde = solde;
this.type = type;
}
public String getIntitule() {return intitule; }
public void setIntitule(String intitule) {
this.intitule = intitule;
}
public int getNumero() {
return numero;
}
public void setNumero(int numero) {
this.numero = numero;
}
public float getSolde() {
return solde;
}
public void setSolde(float solde) {
this.solde = solde;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}

L’Interface ICompte :

public interface ICompte {


public Compte consulter(int numero);
public List consulterListe();
public Compte crediter(float mt, Compte c, consulter);

Msc student Ruphin NYAMI Page 26


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

public Compte debiter(float mt, Compte c);


public Compte virement(Compye c1, float mt, Compte c2);
}
On va ensuite pouvoir réutiliser les définitions de notre interface dans des classes. Pour cela, on
va implémenter notre interface. On va pouvoir faire cela de la même manière que lors de la
création de classes étendues mais on va cette fois-ci utiliser le mot clef implements à la place
de extends.
1. public class CompteImpl implements ICompte {
2. public CompteImpl(){
3. }
4. public Compte consulter(int numero){
5. return null;
6. }
7. public List consulterListe(){
8. return null;
9. }
10. public Compte crediter(float mt, Compte c, consulter){
11. return null;
12. }
13. public Compte debiter(float mt, Compte c){
14. return null;
15. }
16. public Compte virement(Compye c1, float mt, Compte
c2){
17. return null;
18. }
19. }

Créons et discutons une classe nommée JeuVidéo. Cette classe peut avoir
plusieurs méthodes, qui représentent les actions que les objets de cette classe peuvent
effectuer : démarrer le jeu, l’arrêter, enregistrer le score, etc. Cette classe peut aussi
posséder des attributs ou propriétés : prix, couleur de l’écran, nombre de télécommandes
et autres.

public class JeuVidéo


{
String couleur;
int prix;
void démarrer () {
}
void arrêter () {
}
void sauverScore(String nomJoueur, int score) {
}
}

Msc student Ruphin NYAMI Page 27


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

2.3.3.2. Instanciation d’une classe

Les objets contiennent des attributs et des méthodes. Les attributs sont des variables ou des
objets nécessaires au fonctionnement de l'objet. En Java, une application est un objet. La classe
est la description d'un objet. Un objet est une instance d'une classe. Pour chaque instance d'une
classe, le code est le même, seules les données sont différentes à chaque objet.

2.3.3.2.1. La création d’un objet : instancier une classe


Il est nécessaire de définir la déclaration d'une variable ayant le type de l'objet désiré. La
déclaration est de la forme nom_de_classe nom_de_variable
Exemple
JeuVideo monjeu ; // on vient de déclarer un objet monjeu du type JeuVideo
String chaine ; // un objet chaine est déclaré de la classe String

L’opérateur new permet d’instancier une classe ;


Exemple :
JeuVideo monjeu ; // on vient de déclarer un objet monjeu du type JeuVideo
monjeu = new JeuVideo() ; // ici l’instance est créée grâce à l’opérateur new
String chaine ; // un objet chaine est déclaré de la classe String

Remarque :
- Chaque instance d'une classe nécessite sa propre variable. Plusieurs variables peuvent
désigner un même objet.

- En Java, tous les objets sont instanciés par allocation dynamique. Dans l'exemple, la
variable monjeu contient une référence sur l'objet instancié (contient l'adresse de l'objet qu'elle
désigne : attention toutefois, il n'est pas possible de manipuler ou d'effectuer des opérations
directement sur cette adresse comme en C).

- Si monjeu2 désigne un objet de type JeuVideo, l'instruction mojeu2 = monjeu ne définit


pas un nouvel objet mais monjeu et monjeu2 désignent tous les deux le même objet.

- L'opérateur new est un opérateur de haute priorité qui permet d'instancier des objets et
d'appeler une méthode particulière de cet objet : le constructeur. Il fait appel à la machine
virtuelle pour obtenir l'espace mémoire nécessaire à la représentation de l'objet puis appelle le
constructeur pour initialiser l'objet dans l'emplacement obtenu. Il renvoie une valeur qui
référence l'objet instancié. Si l'opérateur new n'obtient pas l'allocation mémoire nécessaire, il lève
l'exception OutOfMemoryError.

- Remarque sur les objets de type String : un objet String est automatiquement créé lors de
l'utilisation d'une constante chaîne de caractères sauf si celle ci est déjà utilisée dans la classe.
Ceci permet une simplification lors de la compilation de la classe.
public class TestChaines1 {
public static void main(String[] args)
{
String chaine1 = "bonjour";
String chaine2 = "bonjour";

Msc student Ruphin NYAMI Page 28


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

System.out.println("(chaine1 == chaine2) = " +


(chaine1 == chaine2) );
}
}

Pour obtenir une seconde instance de la chaine, il faut explicitement demander sa création
en utilisant l'opérateur new.

public class TestChaines2 {


public static void main(String[] args) {
String chaine1 = "bonjour";
String chaine2 = new String("bonjour");
System.out.println ("(chaine1 == chaine2) = " + (chaine1
== chaine2) );
}
}

2.3.3.3. La durée de vie d’un objet


Les objets ne sont pas des éléments statiques et leur durée de vie ne correspond pas
forcément à la durée d'exécution du programme. La durée de vie d’un objet passe par trois étapes :
 La déclaration et l’instanciation grâce à l’opérateur new ;
 L’utilisation de l’objet en appelant ses méthodes publiques ;
 La suppression de l’objet : cela se fait automatiquement par la machine virtuelle grâce au
garbage collector. Il n’existe pas d’instruction delete comme en C++ pour libérer de
l’espace mémoire.

2.3.3.3.1. La création d’objets identiques


Exemple :
JeuVideo monjeu1 = new JeuVideo() ;
JeuVideo monjeu2 = monjeu1 ;
Monjeu1 et monjeu2 contiennent la même référence et pointent donc tous les deux sur le
même objet : les modifications faites à partir d'une des variables modifient l'objet.

Copie d’un objet : Pour créer une copie d'un objet, il faut utiliser la méthode clone() : cette
méthode permet de créer un deuxième objet indépendant mais identique à l'original. Cette
méthode est héritée de la classe Object qui est la classe mère de toutes les classes en Java.

Exemple :
JeuVideo monjeu1 = new JeuVideo() ;
JeuVideo monjeu2 = monjeu1.clone() ;
Monjeu1 et monjeu2 ne contiennent pas la même référence et pointent donc tous les
objets différents

Msc student Ruphin NYAMI Page 29


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

2.3.3.2. Les références et la comparaison d'objets


Les variables de type objet que l'on déclare ne contiennent pas un objet mais une référence
vers cet objet. Lorsque l'on écrit c1 = c2 (c1 et c2 sont des objets), on copie la référence de l'objet
c2 dans c1 : c1 et c2 réfèrent au même objet (ils pointent sur le même objet). L'opérateur ==
compare ces références. Deux objets avec des propriétés identiques sont deux objets distincts :

Exemple :
Rectangle r1 = new Rectangle(100,50);
Rectangle r2 = new Rectangle(100,50);
if (r1 == r1) {...} // vrai
if (r1 == r2) {...} // faux
Pour comparer l'égalité des variables de deux instances, il faut munir la classe d'un méthode
à cette effet : la méthode equals héritée de Object.

(obj1.getClass().equals(obj2.getClass())

 L'objet null

L'objet null est utilisable partout. Il n'appartient pas à une classe mais il peut être utilisé
à la place d'un objet de n'importe quelle classe ou comme paramètre. null ne peut pas être utilisé
comme un objet normal : il n'y a pas d'appel de méthodes et aucune classe ne peut en hériter.
Le fait d'initialiser une variable référant un objet à null permet au ramasse miette de
libérer la mémoire allouée à l'objet.

 L'opérateur instanceof
L'opérateur instanceof permet de déterminer la classe de l'objet qui lui est passé en
paramètre. La syntaxe est objet instanceof classe

Exemple :
void testClasse(Object o) {
if (o instanceof JeuVideo )
System.out.println(« o est une instance de la classe
JeuVideo »);
else System.out.println(« o n'est pas un objet de la classe
JeuVideo »);
}

Il n'est toutefois pas possible d'appeler une méthode de l'objet car il est passé en paramètre avec
un type Object

Exemple :
void afficheChaine(Object o) {
if (o instanceof MaClasse)
System.out.println(o.getChaine());
// erreur à la compil car la méthode getChaine()
//n'est pas définie dans la classe Object
}
 Les modificateurs d'accès

Msc student Ruphin NYAMI Page 30


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

Ils se placent avant ou après le type de l'objet mais la convention veut qu'ils soient placés
avant. Ils s'appliquent aux classes et/ou aux méthodes et/ou aux attributs. Ils ne peuvent pas être
utilisés pour qualifier des variables locales : seules les variables d'instances et de classes peuvent
en profiter.

Ils assurent le contrôle des conditions d'héritage, d'accès aux éléments et de modification
de données par les autres objets.

 Les mots clés qui gèrent la visibilité des entités

Il existe 3 modificateurs qui peuvent être utilisés pour définir les attributs de visibilité des
entités (classes, méthodes ou attributs) : public, private et protected. Leur utilisation permet de
définir des niveaux de protection différents (présentés dans un ordre croissant de niveau de
protection offert) :
Modificateur Rôle
public Une variable, méthode ou classe déclarée public est visible par tous les
autres objets. Dans la version
1.0, une seule classe public est permise par fichier et son nom doit
correspondre à celui du fichier. Dans la philosophie orientée objet aucune
donnée d'une classe ne devrait être déclarée publique : il est préférable
d'écrire des méthodes pour la consulter et la modifier
Par défaut : Il n'existe pas de mot clé pour définir ce niveau, qui est le niveau par défaut
Package fieldly lorsqu'aucun modificateur n'est précisé. Cette déclaration permet à une
entité (classe, méthode ou variable) d'être visible par toutes les classes se
trouvant dans le même package.
private C'est le niveau de protection le plus fort. Les composants ne sont visibles
qu'à l'intérieur de la classe : ils ne peuvent être modifiés que par des
méthodes définies dans la classe prévues à cet effet. Les méthodes déclarées
private ne peuvent pas être en même temps déclarée abstract car elles ne
peuvent pas être redéfinies dans les classes filles.
protected Si une classe, une méthode ou une variable est déclarée protected , seules
les méthodes présentes dans le même package que cette classe ou ses sous
classes pourront y accéder. On ne peut pas qualifier une classe avec
protected.
Nb. Ces modificateurs d'accès sont mutuellement exclusifs.

 Le mot clé static


Le mot clé static s'applique aux variables et aux méthodes.
Les variables d'instance sont des variables propres à un objet. Il est possible de définir
une variable de classe qui est partagée entre toutes les instances d'une même classe : elle n'existe
donc qu'une seule fois en mémoire. Une telle variable permet de stocker une constante ou une
valeur modifiée tour à tour par les instances de la classe. Elle se définit avec le mot clé static.

Exemple :
public class Cercle {
static float pi = 3.1416f;
float rayon;
public Cercle(float rayon) { this.rayon = rayon; }

Msc student Ruphin NYAMI Page 31


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

public float surface() { return rayon * rayon * pi;}


}
Nb. Une méthode static est une méthode qui n'agit pas sur des variables d'instance mais
uniquement sur des variables de classe.

 Le mot clé final

Le mot clé final s'applique aux variables de classe ou d'instance, aux méthodes et aux
classes. Il permet de rendre l'entité sur laquelle il s'applique non modifiable une fois qu'elle est
déclarée pour une méthode ou une classe et initialisée pour une variable.
Une variable qualifiée de final signifie que la valeur de la variable ne peut plus être
modifiée une fois que celle-ci est initialisée. On ne peut pas déclarer de variable final local à une
méthode.

 Le mot clé abstract

Le mot clé abstract s'applique aux méthodes et aux classes. Abstract indique que la classe
ne pourra être instanciée telle quelle. De plus, toutes les méthodes de cette classe abstract ne sont
pas implémentées et devront être redéfinies par des méthodes complètes dans ses sous classes.
Abstract permet de créer une classe qui sera une sorte de moule. Toutes les classes dérivées
pourront profiter des méthodes héritées et n'auront à implémenter que les méthodes déclarées
abstract.

 Le mot clé synchronized

Permet de gérer l'accès concurrent aux variables et méthodes lors de traitement de thread
(exécution « simultanée » de plusieurs petites parties de code du programme)

 Le mot clé volatile

Le mot clé volatile s'applique aux variables.


Précise que la variable peut être changée par un périphérique ou de manière asynchrone.
Cela indique au compilateur de ne pas stocker cette variable dans des registres. A chaque
utilisation, on lit la valeur et on réécrit immédiatement le résultat s'il a changé.

 Le mot clé native

Une méthode native est une méthode qui est implémentée dans un autre langage.
L'utilisation de ce type de méthode limite la portabilité du code mais permet une vitesse exécution
plus rapide.

2.3.3.4. Les propriétés ou attributs


Les données d'une classe sont contenues dans des variables nommées propriétés ou
attributs. Ce sont des variables qui peuvent être des variables d'instances, des variables de classes
ou des constantes.

Msc student Ruphin NYAMI Page 32


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

 Les variables d’instances


Une variable d'instance nécessite simplement une déclaration de la variable dans le corps
de la classe.
Exemple :
public class Client{
private String nom, prenom, adresse ;
protected int telephon ;
}

 Les variables de classes


Les variables de classe sont définit avec les mots clés static

Exemple :
public class cercle{
static double pi =3.14;
}

 Les constantes
Les constantes sont définies avec le mot clé final : leur valeur ne peut pas être modifiée
une fois qu'elles sont initialisées.
Exemple :
public class cercle{
final double pi =3.14;
}

 Les méthodes
Les méthodes sont des fonctions qui implémentent les traitements de la classe.

 La signature ou syntaxe de la déclaration


La signature d’une méthode est constituée d’éléments suivants :
Modificateur, le type retourné, le nom de la méthode (arg1, …){}

Exemple :
public void direBonjou(String nom)
{
System.ou.println(‘’Bonjour ‘’ + nom ) ;
}
// cette méthode a comme modificateur public, le type retourné est void (rien) et le nom de la
méthode est direBonjour entre parenthèse elle attends un paramètre de type String

Le type retourné peut être élémentaire ou correspondre à un objet.


Si la méthode ne retourne rien, alors on utilise void. Le type et le nombre d'arguments
déclarés doivent correspondre au type et au nombre d'arguments transmis.
Il n'est pas possible d'indiquer des valeurs par défaut dans les paramètres. Les arguments
sont passés par valeur : la méthode fait une copie de la variable qui lui est locale. Lorsqu'un objet
est transmis comme argument à une méthode, cette dernière reçoit une référence qui désigne son
emplacement mémoire d'origine et qui est une copie de la variable. Il est possible de modifier

Msc student Ruphin NYAMI Page 33


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

l'objet grâce à ces méthodes mais il n'est pas possible de remplacer la référence contenue dans la
variable passée en paramètre : ce changement n'aura lieu que localement à la méthode.

Les modificateurs sont :


Modificateur Rôle
public La méthode est accessible aux méthodes des autres classes
private L'usage de la méthode est réservé aux autres méthodes de la même classe
protected La méthode ne peut être invoquée que par des méthodes de la classe ou de
ses sous classes
final La méthode ne peut être modifiée (redéfinition lors de l'héritage interdite)
static La méthode appartient simultanément à tous les objets de la classe (comme
une
constante déclarée à l'intérieur de la classe). Il est inutile d'instancier la
classe pour,appeler la méthode mais la méthode ne peut pas manipuler de
variable d'instance. Elle ne peut utiliser que des variables de classes.
synchronized La méthode fait partie d'un thread. Lorsqu'elle est appelée, elle barre l'accès
à son
instance. L'instance est à nouveau libérée à la fin de son exécution.
native Le code source de la méthode est écrit dans un autre langage

Nb. Sans modificateur, la méthode peut être appelée par toutes autres méthodes des classes du
package auquel appartient la classe.

La valeur de retour de la méthode doit être transmise par l'instruction return. Elle indique la
valeur que prend la méthode et termine celle-ci : toutes les instructions qui suivent return sont
donc ignorées.

2.4. La superclasse Object


Tous les objets Java héritent donc de ces méthodes. Il s’agit de la classe principale, elle
contient les fonctions :
• protected Object clone() qui crée et retourne une copie de l’objet
• boolean equals(Object obj) qui détermine si obj est égal à l’objet courant.
• String toString() retourne une chaîne représentant l’objet
• protected void finalize() appelé par le ramasse miettes s’il n’y a plus de référence à l’objet
• Class getClass() retourne la classe courante de l’objet
• int hashCode() retourne une clé pouvant être utilisée pour un tri
• void notify() réveille un processus en attente sur l’objet
• void notifyAll() réveille tous les processus en attente
• void wait() met en pause le processus courant en attendant un réveil

Exemple de classe
class Personne {
String prenom; int age = -1;
// constructeur par défaut
Personne( ){prenom="";}
// constructeurs avec paramètres
Personne(String prenom) { this.prenom = prenom; }

Msc student Ruphin NYAMI Page 34


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

Personne(String prenom, int age) { this(prenom) ; this.age = age;


}
// surcharge de la méthode héritée de Object
public String toString() {
String retour = (prenom!=null?(prenom+ ", " ):"");
if(age>=0) retour = retour + " age : " + age;
return retour;
}
}

Exemple de classe : Getter & Setter


• Par défaut, il vaut mieux protéger les attributs et les rendre accessibles par des
méthodes publiques getXX() & setXX(..). Ce sont les « getters et setters »
• Leurs écritures nécessaires mais laborieuses sont heureusement réalisées à la
demande par les principaux IDE (Eclipse, IntelliJ, NetBeans, ..)
public class Personne {
String prenom; int age = -1;
//constructeur par défaut
public Personne() {prenom = "";}
// constructeurs avec paramètres
public Personne(String prenom) { this.prenom = ""; }
// constructeurs avec paramètres
public Personne(String prenom, int age) {
this.prenom = prenom;
this.age = age; }
public String getPrenom() { return prenom; }
public void setPrenom(String prenom) { this.prenom = prenom;}
public int getAge() {return age;}
public void setAge(int age) {this.age = age;}
@Override
public String toString() {
String retour = (prenom!=null?(prenom+ ", " ):"");
if(age>=0) retour = retour + " age : " + age;
return retour;}
}

Méthodes Object : clone()


2.4.1.
protected Object clone() est donnée aux fonctions qui retourne une copie de l’objet
Syntaxe générale, qui recopie tous les champs :
public class Personne implements Cloneable{
….
public Personne clone() {
Object leClone =null;
try { leClone = super.clone();}
catch(CloneNotSupportedException e) {e.printStackTrace();}
return (Personne) leClone;
}
}
Bien sûr vous pouvez remplacer ce code par celui de votre choix pour maîtriser ce qui est recopié
ou non
Exemple de clonage :
Personne p1 = new Personne("KABONDO");

Msc student Ruphin NYAMI Page 35


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

// p2 est un clone de p1
Personne p2 = p1.clone();
System.out.println(p1 + "-" +p2); // KABONDO– KABONDO
p2.prenom = "KIKANDA";
System.out.println(p1 + "-" +p2); // KABONDO– KIKANDA

Méthodes Object : equals(..)


2.4.2.
La méthode boolean equals(Object obj) détermine si obj est égal à l’objet courant.
La méthode equals est une fonction qui doit être :
• Reflexive : a.equals(a)
• Symétrique : a.equals(b) <=> b.equals(a)
• Transitive : a.equals(b) ET b.equals(c) => a.equals(c)

Exemple: méthode equals()


public class Personne {
String prenom; int age ;
public boolean equals(Object o) {
boolean rep = false;
//si l’objet passé est différent de null et est de type
Personne
if(o!=null && (o.getClass() == Personne.class)) {
Personne p = (Personne)o;
// rep est vrai ssi les personnes ont le même age ET
rep = (age == p.age) &&
//si le prenom est défini et est égal au prenom de l’autre
// ou si les deux prenoms sont nuls
(prenom!=null)?(prenom.equals(p.prenom)):(p.prenom==null);}
return rep;}}

2.4.3. Types Génériques


Le type générique consiste à l’utilisation de caractères remplaçant un type défini à l’exécution.
Exemple avec les méthodes :
//affiche les objets d’un tableau de …
public <T>void affiche(T[] tab) {
for (Object o : tab) System.out.println(o.toString());
}
On indique ici, avant sa description, que la méthode utilise un type générique nommé ici T

Type Générique : Exemple


public class AppHelloWorld {
public static void main(String[] args){
Personne[] liste = new Personne[3];
liste[0] = new Personne("KALANGA", 23);
liste[1] = new Personne("KISULA", 15);
liste[2] = new Personne("BITOTA", 16);
AppHelloWorld app = new AppHelloWorld();

app.affiche(liste);
}

Msc student Ruphin NYAMI Page 36


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

public <T>void affiche(T[] tab) {


for (Object o : tab) System.out.println(o.toString());
}
}

Possibilité d’utiliser plusieurs types génériques :


//T et V sont des types génériques
public <T, V> void afficheEtVal(T[] tab, V v){
for (Object o : tab) System.out.println(o);
System.out.println("valeur = " + v.toString());
}
Possibilité de préciser le type :
//T doit être un type comparable
public <T extends Comparable<T>> void compare(T a, T b) {
int comp = a.compareTo(b);
if(comp<0) System.out.println(a + " est plus petit que " + b);
if(comp==0) System.out.println(a + " est égal à " + b);
if(comp>0) System.out.println(a + " est plus grand que " + b);
}

Exemple 2 : Utilisation de 2 Types :


Utilisation d'une classe utilisant des listes génériques :
Personne p = new Personne();
Article a = new Article();
Couple<Personne, Article> couple = new Couple<>(p,a);
System.out.println(couple);
Exemple
public static void main(String[] args){
Personne p = new Personne("BILULU", 66);
Article a = new Article("MBOKA", "7000 FC", "2kgs");
Couple<Personne, Article> couple = new Couple<>(p, a);
System.out.println(couple);
}

2.4.4. La classe System


La classe système est principalement utilisé pour la gestion du système :
• static PrintStream err : sortie d'erreur standard
• static InputStream in : entrée standard
• static PrintStream out : sortie standard
• static void arraycopy(...) : copie de tableaux
• static long currentTimeMillis() : temps courant en
millisecondes
• static long nanoTime() : temps courant en nanoseconde
• static void exit(int status) : sortie de programme
• static void gc() : lance le ramasse-miettes
• static void load(String fichier) : charge le code en tant
que librairie dynamique

Msc student Ruphin NYAMI Page 37


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

2.4.4.1. La classe String


• Les chaînes sont constantes, leurs valeurs ne peuvent être
changées après leurs créations.
• StringBuffer et StringBuilder(non synchronisée) permettent
l’utilisation de chaînes "dynamiques".
Construction : String str = "abc"; est équivalent à String str
= new String("abc");
• La classe String comporte des méthodes d’accès aux
caractères, de comparaisons, de recherche, d’extraction, de
copie, de conversion minuscules/majuscule, ...
• L’opérateur (+) est surchargé pour permettre la
concaténation
• Toute conversion se fait de manière automatique en faisant
appel à la méthode toString() héritée de la classe Object.
• Par défaut, toString() retourne le nom de la classe de
l’objet et son adresse en mémoire virtuelle :
td1.Personne@3d4eac69
• Il est possible de surcharger cette méthode dans les
nouvelles classes créées.

2.5. Des classes très utiles (import java.util.*)


Interfaces : Collection, Comparator, Enumeration, EventListener, Iterator, List, ListIterator,
Map, Map.Entry,Observer, Set, SortedMap, SortedSet

Classes : AbstractCollection, AbstractList, AbstractMap,


AbstractSequentialList, AbstractSet, ArrayList, Arrays, BitSet, Calendar,
Collections, Date, Dictionary, EventObject, GregorianCalendar, HashMap,
HashSet, Hashtable, LinkedList, ListResourceBundle, Locale, Observable,
Properties, PropertyPermission, PropertyResourceBundle, Random,
ResourceBundle, SimpleTimeZone, Stack, StringTokenizer, TimeZone, TreeMap,
TreeSet, Vector, WeakHashMap

2.5.1.La classe Arrays


Cette classe contient des méthodes statiques pour la gestion de tableaux : (remarque, les
fonctions présentées existent pour tous les types)
• static int binarySearch(int []tab, int valeur) retourne l’index de la valeur, -1 si
introuvable
• static boolean equals (boolean []tab1, boolean []tab2)teste l’égalité de deux tableaux
• static boolean deepEquals (Object []tab1, Object []tab2)teste l’égalité de deux tableaux
récursivement (deepEquals effectue un appel à elle même si tab1 et tab2 contiennent des
tableaux)
• static void fill (double []tab, double valeur) remplit le tableau avec la valeur
• static void copyOf (long []tab, int taille)retourne une copie du tableau tab
• Exemple d’autres méthodes statiques pour la gestion de tableaux :
• static void sort(long []tab) : trie le tableau
• static void sort(Object [] tab) : trie le tableau si les objets contenus sont comparables
• static String toString(int []tab) : retourne un chaine contenant l’ensembles des valeurs
entières. fonctionne pour toutes primitives et également les objets

Msc student Ruphin NYAMI Page 38


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

• static String deepToString(Object []tab) : retourne un chaine résultant de la


concaténation des appels à deepToString() pour chaque élément
• static <T> List<T> asList(T... tab) : retourne un liste dynamique à partir du tableau tab
(T remplace tout type d’objets)

2.5.2. Interface Collection


Une Collection est une suite d’éléments, ordonnés ou non, uniques ou non. La Collection
est généralement utilisé pour des ensembles de taille variables. Toute Collection possède ces
méthodes :
boolean add(E e) : ajoute un élément dans la collection
boolean addAll(Collection<? extends E> c) : ajoute une collection dans
la collection
void clear() : retire tous les éléments de la collection
boolean contains(Object o) : retourne si un objet existe ou non dans
la collection
boolean containsAll(Collection<?> c) : retourne si une collection
appartient à la collection
boolean isEmpty() : retourne vrai si la collection est vide
boolean remove(Object o) : retire un objet de la collections si présent
boolean removeAll(Collection<?> c) : retire les éléments d’une
collection présent dans lacollection
int size() : retourne la taille de la collection
Object[] toArray() : Retourne un tableau contenant les éléments de la collection
<T> T[] toArray(T[] tab) : Retourne un tableau contenant les éléments de la collection

2.5.3. Interface List


Les classes implémentant l’interface List sont, pour simplifier, des tableaux extensibles à
volonté. On y trouve les objets Vector, LinkedList et ArrayList. On peut y
insérer autant d'éléments que l’on souhaite sans craindre de dépasser la taille du tableau. Ils
fonctionnent tous de la même manière : la récupération des éléments de la liste se fait via leurs
indices. De plus, les List contiennent des objets.

Un objet de type List est une Collection d’éléments ordonnés, uniques ou non. Toute List
possède en plus méthodes :

• boolean add(int index, E e) : insère l’élément e dans la position


index
• boolean addAll(int index, Collection<? extends E> c) : insère la
collection c dans la collection à partir de l’index
• int indexOf (Object o) : retourne l’index de l’élément dans la
liste (-1 si non présent)
• int lastIndexOf (Object o) : retourne la dernière position de
l’élément dans la liste (-1 si non présent)
• boolean remove(int index) : retire l’élément à l’index donné
• boolean set(int index, E e) : remplace l’élément dans la position
index par e
• boolean subList(int from, int to) : retourne une vue de la liste
entre les index from et to exclusif

Depuis Java 8, quelques méthodes sont ajoutées :

Msc student Ruphin NYAMI Page 39


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

void sort(Comparator<? super E> c): trie les éléments de la liste selon
le comparator default void replaceAll(UnaryOperator<E> operator) :
remplace chaque élément de la liste en appliquant l’opérateur unaire
static <E> List<E> copyOf(Collection<? extends E> coll) : retourne
copie immuable d'une collection
static <E> List<E> of(E e1) : retourne une liste immuable contenant un
élément
static <E> List<E> of(E... elements) : retourne une liste immuable
contenant les éléments
Remarque : il n’est pas possible d’ajouter, de retirer des objets d’une
liste immuable , ni de remplacer ses objects par d’autres. (par contre,
les caractéristiques accessibles et non constantes des objets peuvent
être modifiées)

2.5.4. Classe ArrayList


La classe ArrayList est une implémentation de l’interface List. Elle permet de stocker,
trier, modifier des objets dans un ensemble de longueur variable. Non synchronisée, elle est
majoritairement utilisée. Les objets de la classe ArrayList n'ont pas de taille limite et qui, en
plus, acceptent n'importe quel type de données, y compris null.
Exemple 1 :
public static void main(String[] args){
ArrayList al = new ArrayList();
al.add(12);
al.add("TSHIMANKINDA");
al.add(12.20f);
al.add('d');

for(int i = 0; i < al.size(); i++)


{
System.out.println("donnée à l'indice " + i + " = " + al.get(i));
}
}

Exemple 2:

public static void main(String[] args){


List<String> maListe = new ArrayList<String>();
maListe.add("KADIMOYA");
maListe.add("TUNDA");
maListe.add("PANDA");
System.out.println(maListe);
Random hasard= new Random();
ArrayList<Personne> liste = new ArrayList<>();
for (int i = 0; i < 10; i++)
liste.add(new Personne("p" + i, hasard.nextInt(100)));
liste.forEach(p->System.out.println(p));
}

2.5.5. LinkedList
Une liste chaînée (LinkedList en anglais) est une liste dont chaque élément est lié aux
éléments adjacents par une référence à ces derniers. Chaque élément contient une référence à
l'élément précédent et à l'élément suivant, excepté le premier, dont l'élément précédent vaut null,
et le dernier, dont l'élément suivant vaut également null.

Msc student Ruphin NYAMI Page 40


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

La classe LinkedList permet l’utilisation en tant que FIFO (First In First Out) ou LIFO (Last
In First Out) :
• push(objet) : ajoute un objet sur la pile ;
• pop(), pollLast() : retirent l’objet du dessus de la pile;
• remove(), poll(), pollFirst() : retirent l’objet en bas de la
pile;
• peek() : renvoie une référence à l’objet du bas de la pile sans
le retirer;
• peekLast() : renvoie une référence à l’objet du haut de la pile
sans le retirer ;
• isEmpty() : teste si la pile est vide.

La figure suivante représente un schéma représentant le fonctionnement des objets de cette classe
:

Exemple
public static void main(String[] args){
List l = new LinkedList();
l.add(2019);
l.add("KABONDO");
l.add(12.20f);
for(int i = 0; i < l.size(); i++)
System.out.println("Élément à l'index " + i + " = " +
l.get(i));
}

La classe ListLinked implémente l'interface Iterator. Un itérateur est un objet qui a


pour rôle de parcourir une collection. Ainsi, utiliser cette interface pour lister
notre LinkedList devient une obligation.
public static void main(String[] args){
List l = new LinkedList();
l.add(2019);
l.add("KABONDO");
l.add(12.20f);
for(int i = 0; i < l.size(); i++)
System.out.println("Élément à l'index " + i + " = " +
l.get(i));
System.out.println("\n \tParcours avec un itérateur ");
System.out.println("-----------------------------------");
ListIterator li = l.listIterator();
while(li.hasNext()) System.out.println(li.next());
}

Msc student Ruphin NYAMI Page 41


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

Contrairement aux LinkedList, les ArrayList sont rapides en lecture, même avec un gros
volume d'objets. Elles sont cependant plus lentes si l’on doit ajouter ou supprimer des données
en milieu de liste. En résumer à l'extrême, si l’on effectue beaucoup de lectures sans se soucier
de l'ordre des éléments, il recommander d’opter pour une ArrayList.

2.5.6. TreeSetTreeSet
La classe TreeSet définit un ensemble ne pouvant contenir qu’un exemplaire d’un objet.
Quelques méthodes :
• add(objet) qui n’ajoute l’objet que s’il n’est pas déjà présent
contains(objet) ;
• remove(objet) ;
• ceiling(objet) : retourne le plus petit élément de l’ensemble plus
grand ou égal à l’objet
• floor(objet) : retourne le plus grand élément de l’ensemble plus
petit ou égal à l’objet

2.5.7. Interface Map


• Une Map lie une clé à exactement une valeur. Une clé ne peut être dupliquée dans une
Map. On y trouve les objets Hashtable, HashMap, TreeMap, WeakHashMap… La clé,
qui sert à identifier une entrée dans notre collection, est unique. La valeur, au contraire,
peut être associée à plusieurs clés.

• Toute Map possède, entres autres, ces méthodes :


• void clear() : retire tous les éléments de la map
• boolean containsKey(Object key) : retourne si une clé existe ou
non dans la collection
• boolean containsValue(Object v) : retourne si une valeur existe
ou non dans la collection
• boolean get(Object key) : retourne la valeur associée à la clé,
ou null
• boolean isEmpty() : retourne vrai si la map est vide
• V put(K key, V value) : lie une valeur à une clé, retourne la
valeur précédemment associée
• void putAll(Map<K,V> map) : copie la map passée en paramètre à la
map en cours
• V remove(Object key) : retire une clé et son association. retourne
la valeur associée
• boolean remove(Object key, Object value) : retire l’association,
si elle existe
• V replace(K key, V value) : lie une nouvelle valeur à une clé
existante, retourne la valeur
• précédemment associée
• int size() : retourne la taille de la collection
• Collection<V> values() : Retourne les valeurs de la map
• Set<K> keySet() : Retourne les clés de la map dans un ensemble

Msc student Ruphin NYAMI Page 42


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

2.5.8. Classe HashMap & Hashtab


La classe HashMap (non synchronisée) est une implémentation d’une Map. La classe
Hashtable est quasi identique mais synchronisée.
• Ces classes implémentent les fonctions de l’interface Map.
• Exemple d’utilisation : association login - nom complet
HashMap<String, String> users = new HashMap<>();
users.put("GIV", "GIVEN");
users.put("KAS", "KASONGO");
users.put("KAD", "KADIMOYA");
String key = "KAS";
String val = users.get(key);
if(val!=null) System.out.println("valeur associee à " + key + "=" +
val);
// affiche valeur associée à KAS = KASONGO

Exemple d’utilisation de foreach :


HashMap<String, String> users = new HashMap<>();
users.put("GIV", "GIVEN");
users.put("KAS", "KASONGO");
users.put("KAD", "KADIMOYA");
users.forEach((k,v) ->
System.out.println("valeur associée à " + k + "=" + v));
Modification de la valeur GIVEN associée à la clé GIV:
users.put("GIV", "BUA NKANGA");

2.5.8.1. L'objet Hashtable : table de hachage


On parcourt cet objet grâce aux clés qu'il contient en recourant à la classe Enumeration.
L'objet Enumeration contient notre Hashtable et permet de le parcourir très simplement.
public static void main(String[] args){
Hashtable ht = new Hashtable();
ht.put(1, "Janvier");
ht.put(10, "Févirer");
ht.put(12, "Mars");
ht.put(45, "Jeudi");
Enumeration e = ht.elements();
while(e.hasMoreElements())
System.out.println(e.nextElement());
}

2.5.8.2. Les objets Set


L’interface Set est une collection qui n'accepte pas les doublons y compris le null, car deux
valeurs null sont considérées comme un doublon. On trouve parmi les Classes implémentants
l’interface Set : HashSet, TreeSet, LinkedHashSet. Certains Set sont plus restrictifs que
d'autres : il en existe qui n'acceptent pas null, certains types d'objets, etc.

Les Set sont particulièrement adaptés pour manipuler une grande quantité de données.
Cependant, les performances de ceux-ci peuvent être amoindries en insertion. Généralement, on

Msc student Ruphin NYAMI Page 43


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

opte pour un HashSet, car il est plus performant en temps d'accès, mais si l’on souhaite que la
collection soit constamment triée, un TreeSet est un bon choix.

2.5.8.3. L'objet HashSet


On peut parcourir ce type de collection avec un objet Iterator ou extraire de cet objet un
tableau d'Object :
public static void main(String[] args){
HashSet hs = new HashSet();
hs.add("TSHIMANKINDA");
hs.add(12);
hs.add('d');

Iterator it = hs.iterator();
while(it.hasNext())
System.out.println(it.next());

System.out.println("\nParcours avec un tableau d'objet");


System.out.println("-----------------------------------");

Object[] obj = hs.toArray();


for(Object o : obj)
System.out.println(o);
}

Exercices :
1. Ecrire un programme java qui stocke les objets de la classe Parcelle dans un HashSet
et le parcours et affiche à l’écran. L’initialisation des objets peut se faire via la saisie
au clavier ou en statique.
2. Ecrire un programme java qui utilise un HashMap pour stocker les Produits et
Leurs Catégories. Avec la possibilité de rechercher par mot clés, ajoute, modifier et
supprimer un produit.
3. Ecire un programme qui utilise une classe implémentant l’interface List au choix
pour stocker les Ventes dans un magasin avec possibilité de rechercher, d’ajouter,
supprimer.

Créez la classe Article

public class Article {


private String code, libelle, prix, qte;
public Article(String code, String libelle, String prix, String
qte) { this.libelle = libelle; this.prix = prix; this.qte = qte;
this.code = code;}
public Article() { super(); }
public String getCode() {return code; }
public void setCode(String code) {this.code = code;}
public String getLibelle() {return libelle;}
public void setLibelle(String libelle) {this.libelle = libelle;}
public String getPrix() {return prix;}
public void setPrix(String prix) {this.prix = prix;}

Msc student Ruphin NYAMI Page 44


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

public String getQte() {return qte;}


public void setQte(String qte) {this.qte = qte;}
@Override
public String toString() { return "Article [libelle=" + libelle +
", prix=" + prix + ", qte=" + qte + "]";}}

La méthode main
public static void main(String[] args){
HashMap<String, Article> hmArticle = new HashMap<>();
//Stockage des Articles dans le HashMap
hmArticle.put("A1", new Article("A1", "BONBON", "50", "70"));
hmArticle.put("A2", new Article("A2", "BISCUIT", "500", "170"));
hmArticle.put("A3", new Article("A3", "SWIT", "50", "800"));
hmArticle.put("A4", new Article("A4", "NIDO", "25000", "10"));
//Afficher tous les articles
System.out.println(hmArticle.values());
//Afficher un Article à partic de son code
System.out.println(hmArticle.get("A3"));
//Supprimer un article à partir de son code
System.out.println(hmArticle.remove("A3"));
System.out.println(hmArticle.values()); }

Msc student Ruphin NYAMI Page 45


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

2.6. Les expressions lambda


L'ajout des expressions lambda dans le langage Java a été un processus long qui a nécessité
plus de huit années de travail. Les premières propositions datent de 2006. En 2006-2007,
plusieurs propositions de spécifications s'opposent :
 BGGA : proposée par Gilad Bracha, Neal Gafter, James Gosling et Peter von der Ahé.
Elle utilise une syntaxe avec l'opérateur =>. Elle définit les functions type, l'annotation @Shared
pour pouvoir modifier une variable du contexte, les methods references avec l'opérateur #
 CICE : proposée par Bob Lee, Doug Lea et Josh Bloch. Elle utilise une écriture simplifiée
des classes anonymes internes
 FCM : proposée par Stephen Colebourne et Stefan Schulz. Elle est plus simple que BGGA
et plus complète que CICE. La définition de method types se fait avec l'opérateur #. Elle permet
la modification des variables du contexte englobant
Aucune de ces propositions ne sera intégralement retenue mais les meilleures idées sont
utilisées pour spécifier les expressions lambda :
- ne pas ajouter un nouveau type fonction au lagange pour éviter les écueils des generics
- s'appuyer sur les interfaces qui existent déjà et permettent donc une transition en douceur.
Les expressions lambda ne sont pas transformées en classes par le compilateur : elles
n'utilisent donc pas les classes anonymes internes. Lors de la conception des expressions lambda,
le choix a été fait de ne pas ajouter un type spécial dans le langage, ce qui limite les
fonctionnalités d'une expression lambda par rapport à leur équivalent dans d'autres langages mais
réduit les impacts dans le langage Java.
Par exemple, il n'est pas possible d'assigner une expression lambda
à une variable de type Object parce que le type Object n'est pas une
interface fonctionnelle.
Ce n'est qu'en 2014, avec Java 8, que les expressions lambda qui permettent la mise en
oeuvre d'une forme de closures sont intégrées dans le langage Java. Avant Java 8, la seule
solution était d'utiliser une classe anonyme interne.

Java est un langage orienté objet : à l'exception des instructions et des données primitives,
tout le reste est objets, même les tableaux et les chaînes de caractères. Java ne propose pas la
possibilité de définir une fonction/méthode en dehors d'une classe ni de passer une telle fonction
en paramètre d'une méthode. Depuis Java 1.1, la solution pour passer des traitements en
paramètres d'une méthode est d'utiliser les classes anonymes internes.
Pour faciliter, entre autres, cette mise à oeuvre, Java 8 propose les expressions lambda. Les
expressions lambda sont aussi nommées closures ou fonctions anonymes : leur but
principal est de permettre de passer en paramètre un ensemble de traitements.
Les expressions lambda sont donc une des plus importantes nouveautés de Java 8 voire
même la plus importante évolution apportée au langage Java depuis sa création. C'est donc
logiquement la fonctionnalité la plus médiatique de Java 8.
Les spécifications des expressions lambda sont définies dans la JSR 335 (Project Lambda).
De plus, la programmation fonctionnelle est devenue prédominante dans les langages récents.
Dans ce mode de programmation, le résultat de traitements est décrit mais pas la façon dont ils
sont réalisés. Ceci permet de réduire la quantité de code à écrire pour obtenir le même résultat.

Msc student Ruphin NYAMI Page 46


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

Par exemple, pour afficher les éléments d'une liste


public static void main(String[] args) {
List liste = new ArrayList();
liste.add("WATANABE");
liste.add(2019);
liste.add("MUNGULDIAKE");
liste.add("KITALA TALA");
for (int i = 0; i < liste.size(); i++) {
System.out.println(liste.get(i));
}
}

Ce code est composé de deux traitements : une boucle pour itérer sur chaque élément et
l'affichage d'un élément dans l'itération. Le code de la boucle pourrait être factorisé dans une
méthode qui attendrait en paramètre une fonction qui contenant le traitement à réaliser sur chaque
élément.
public static void main(String[] args) {
List liste = new ArrayList();
liste.add("WATANABE");
liste.add(2019);
liste.add("MUNGULDIAKE");
liste.add("KITALA TALA");
liste.forEach(System.out::println);
}

2.6.1. Interface à unique fonction : remplacement de classes anonymes


Une expression Lambda permet de définir une implémentation d'une interface fonctionnelle sous
la forme d'une expression composée d'une liste de paramètres et d'un corps qui peut être une
simple expression ou un bloc de code.
Une expression lambda est utilisée pour représenter une interface fonctionnelle sous la forme
d'une expression de la forme : (arguments) -> corps
L'opérateur -> sépare le ou les paramètres du bloc de code qui va les utiliser. Le type du
paramètre n'est pas obligatoire : le compilateur va tenter de réaliser une inférence du type pour
le déterminer selon le contexte. Dans l'exemple ci-dessus, le compilateur va déterminer que le
paramètre de l'interface ActionListener est de type ActionEvent.
Une expression lambda est typée de manière statique. Ce type doit être une interface
fonctionnelle.

Si une interface n'a qu'une fonction, on peut se passer de la création d'une classe anonyme.
Exemple d’une interface à une opération
public interface ICalcul {
public double somme(int nb1, int nb2);
}

Classiquement on instancie en créant une classe anonyme à la volée :

public class MetierImp {


ICalcul addition = new ICalcul() {
@Override

Msc student Ruphin NYAMI Page 47


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

public double somme(int nb1, int nb2) {


return nb1 + nb2;
}
};
}

En Lambda on écrit :
public class MetierImp { ICalcul add = (nb1, nb2)->{return (nb1 + nb2);}; }

On peut également préciser le type :


public class MetierImp {
ICalcul add = (int nb1, int nb2)->{return (nb1 + nb2);}; }

Ou être plus simple :


public class MetierImp { ICalcul add = (nb1, nb2)->(nb1 + nb2);}

De manièrere générale : (listes de variables) -> code


s'il n'y a qu'un paramètre, les parenthèses sont facultative.

Exemple 2 : L’interface ActionListener


public static void main(String[] args) {
JButton monBouton = new JButton("Valider");
monBouton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Tu as cliqué");
} } );
}

Dans ce cas, une nouvelle instance du type de l'interface est passée en paramètre. Avec Java 8, il
est possible d'utiliser une expression lambda.
monBouton.addActionListener(event -> System.out.println("Tu as cliqué"));

2.6.2. La syntaxe d'une expression lambda


Les expressions lambda permettent d'écrire du code plus concis, donc plus rapide à écrire, à relire
et à maintenir. C'est aussi un élément important dans l'introduction de la programmation
fonctionnelle dans le langage Java qui était jusqu'à la version 8 uniquement orienté objet.
Une expression lambda est une fonction anonyme : sa définition se fait sans déclaration explicite
du type de retour, ni de modificateurs d'accès ni de nom. C'est un raccourci syntaxique qui
permet de définir une méthode directement à l'endroit où elle est utilisée.
Une expression lambda est donc un raccourci syntaxique qui simplifie l'écriture de
traitements passés en paramètre. Elle est particulièrement utile notamment lorsque le traitement
n'est utile qu'une seule fois : elle évite d'avoir à écrire une méthode dans une classe.
Une expression lambda permet d'encapsuler un traitement pour être passé à d'autres
traitements. C'est un raccourci syntaxique aux classes anonymes internes pour une interface qui
ne possède qu'une seule méthode abstraite. Ce type d'interface est nommé interface fonctionnelle.
Lorsque l'expression lambda est évaluée par le compilateur, celui-ci infère le type vers l'interface
fonctionnelle. Cela lui permet d'obtenir des informations sur les paramètres utilisés, le type de la

Msc student Ruphin NYAMI Page 48


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

valeur de retour, les exceptions qui peuvent être levées. Elles permettent d'écrire du code plus
compact et plus lisible. Elles ne réduisent pas l'aspect orienté objet du langage qui a toujours été
une force mais au contraire, rendent celui-ci plus riche et plus élégant pour certaines
fonctionnalités.
Syntaxe
Un des avantages des expressions lambda est d'avoir une syntaxe très simple. La syntaxe d'une
expression lambda est composée de trois parties :
 un ensemble de paramètres, d'aucun à plusieurs
 l'opérateur ->
 le corps de la fonction
Elle peut prendre deux formes principales :
(paramètres) -> expression;
(paramètres) -> { traitements; }
L'écriture d'une expression lambda doit respecter plusieurs règles générales :
 zéro, un ou plusieurs paramètres dont le type peut être déclaré explicitement ou inféré par
le compilateur selon le contexte
 les paramètres sont entourés par des parenthèses et séparés par des virgules. Des
parenthèses vides indiquent qu'il n'y a pas de paramètre
 lorsqu'il n'y a qu'un seul paramètre et que son type est inféré alors les parenthèses ne sont
pas obligatoires
 le corps de l'expression peut contenir zéro, une ou plusieurs instructions. Si le corps ne
contient d'une seule instruction, les accolades ne sont pas obligatoires et le type de retour
correspond à celui de l'instruction. Lorsqu'il y a plusieurs instructions alors elles doivent
être entourées avec des accolades.

Des exemples d'expressions lambda


Cette section fournit quelques exemples d'expressions lambda :
Exemple Description
() -> 123 N'accepter aucun paramètre et renvoyer la
() -> { return 123 }; valeur 123
x -> x * 2 Accepter un nombre et renvoyer son double
(x, y) -> x + y Accepter deux nombres et renvoyer leur
somme
(int x, int y) -> x + y Accepter deux entiers et renvoyer leur
somme
(String s) -> System.out.print(s) Accepter une chaîne de caractères et
l'afficher sur la sortie standard sans rien
renvoyer
c -> { int s = c.size(); c.clear(); return s; } Renvoyer la taille d'une collection après
avoir effacé tous ses éléments.

Cela fonctionne aussi avec un objet qui


possède une méthode size() renvoyant un
entier et une méthode clear()

Msc student Ruphin NYAMI Page 49


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

n -> n % 2 != 0; Renvoyer un booléen qui précise si la valeur


numérique est impaire
(char c) -> c == 'z'; Renvoyer un booléen qui précise si le
caractère est 'z'
() -> { System.out.println("Hello World"); }; Afficher "Hello World" sur la sortie standard
(val1, val2) -> { return val1 >= val2; } Renvoyer un booléen qui précise si la
première valeur est supérieure ou égale à la
(val1, val2) -> val1 >= val2; seconde
() -> { for (int i = 0; i < 10; i++) traiter(); } Exécuter la méthode traiter() dix fois
p -> p.getSexe() == Sexe.HOMME Renvoyer un booléen pour un objet
&& p.getAge() >= 7 possédant une méthode getSexe() et
getAge() qui vaut true si le sexe est masculin
&& p.getAge() <= 77
et l'age compris entre 7 et 77 ans

Msc student Ruphin NYAMI Page 50


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

CHAPITRE III : ERREURS ET EXCEPTIONS


Imaginons que tu aies oublié une accolade fermante dans ton code Java. Il se
produirait une erreur de compilation, que tu pourrais corriger facilement. Mais
il se produit aussi ce qu'on appelle des erreurs d'exécution (run-time errors),
lorsque ton programme cesse tout à coup de fonctionner correctement.

Par exemple, une classe Java lit un fichier contenant les scores du jeu. Que se
passe-t-il si quelqu'un a supprimé ce fichier ? Le programme s'écroule-t-il en
affichant un gros message rouge d'erreur déroutant, ou reste-t-il en vie en
affichant un message compréhensible comme : "Cher ami, pour une raison
inconnue il m'est impossible de lire le fichier scores.txt. Merci de vérifier que ce
fichier existe." ?

Il est préférable de créer des programmes capables de gérer les situations


inhabituelles. Dans beaucoup de langages de programmation, le traitement des
erreurs dépend de la bonne volonté du programmeur. Mais Java rend obligatoire
l'inclusion de code de gestion des erreurs. A défaut, les programmes ne peuvent
même pas être compilés.

En Java, les erreurs d'exécution sont appelées des exceptions et le


traitement des erreurs est appelé gestion des exceptions (exception handling).
Tu dois placer le code susceptible de produire des erreurs dans des blocs try/catch
(essayer/capturer). C'est comme si tu disais ceci à Java : Essaie de lire le fichier
contenant les scores. Si quelque chose d'anormal se produit, capture l'erreur et
exécute le code qui doit la gérer.

try {
fichierScores.read();
}
catch (IOException exception) {
System.out.println(
"Cher ami, je ne peux pas lire le fichier scores.txt");
}
L'expression I/O ou input/output (entrée/sortie). Les opérations de lecture et d'écriture
(sur disque ou sur d'autres périphériques) sont appelées I/O ; ainsi, IOException est une
classe qui contient des informations relatives aux erreurs d'entrée/sortie. Une méthode lève une
exception en cas d'erreur. Différentes exceptions sont levées pour différents types d'erreurs. Si le
bloc catchexiste dans le programme pour un type particulier d'erreur, l'erreur est capturée et le
programme se débranche sur le bloc catch pour exécuter le code qui s'y trouve. Le programme
reste vivant et cette exception est considérée comme prise en charge. L'instruction qui affiche le
message dans le code ci-dessus n'est exécutée que dans le cas d'une erreur de lecture de fichier.

 Lecture de la trace de la pile

S'il se produit une exception inattendue, non gérée par le programme, un message
d'erreur multilignes est affiché à l'écran. Un tel message est appelé trace de la pile (stack
trace). Si ton programme a appelé plusieurs méthodes avant de rencontrer un problème, la

Msc student Ruphin NYAMI Page 51


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

trace de la pile peut t'aider à suivre la trace de ton programme et à trouver la ligne qui a
causé l'erreur.

Ecrivons le programme TestTracePile qui effectue volontairement une division par


0 (les numéros de ligne ne font pas partie du code).

public class TestTracePile {


public TestTracePile() { diviserParZero();}
int diviserParZero() { return 25 / 0; }
public static void main(String[] args) { new TestTracePile();}
}

La sortie de ce programme montre la séquence des appels de méthodes effectués jusqu'au


moment où l'erreur d'exécution s'est produite. Lis cette sortie en remontant à partir de la
dernière ligne.

Exception in thread "main" java.lang.ArithmeticException: / by zero


at TestTracePile.diviserParZéro(TestTracePile.java:9)
at TestTracePile.<init>(TestTracePile.java:4)
at TestTracePile.main(TestTracePile.java:14)

 Bloc try/catch

Il y a cinq mot-clés Java qui peuvent être utilisés dans le traitement des erreurs
: try, catch, finally, throwet throws.

Après un bloc try, tu peux mettre plusieurs blocs catch, si tu penses que différentes
erreurs sont susceptibles de se produire. Par exemple, quand un programme essaie de lire un
fichier, le fichier peut ne pas être là, ce qui génère l'exception FileNotFoundException,
ou le fichier peut être là mais le code continuer à le lire après avoir atteint la fin du fichier, ce
qui génère l'exception EOFException. L'extrait de code suivant affiche des messages en
bon français si le programme ne trouve pas le fichier contenant les scores ou atteint
prématurément la fin du fichier. Pour toute autre erreur, il affiche le message "Problème de
lecture de fichier" et une description technique de l'erreur.

public void chargerScores() {


try {
fichierScores.read();
System.out.println("Scores chargés avec succès");
} catch(FileNotFoundException e) {
System.out.println("Fichier Scores introuvable");
} catch(EOFException e1) {
System.out.println("Fin de fichier atteinte");
} catch(IOException e2) {
System.out.println("Problème de lecture de fichier" +
e2.getMessage());
}
}

Msc student Ruphin NYAMI Page 52


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

Si tu as besoin d'informations plus détaillées à propos de l'exception, utilise


la méthode printStackTrace(). Elle affiche la séquence d'appels de méthodes qui
a abouti à l'exception, de la même façon que dans l'exemple de la section Lecture de
la trace de la pile.

 Le mot-clé throws
Dans certains cas, il est plus approprié de traiter l'exception non pas dans la méthode
où elle se produit, mais dans la méthode appelante. Dans de tels cas, la signature de la
méthode doit déclarer (avertir) qu'elle peut lever une exception particulière. On utilise pour
cela le mot-clé spécial throws. Reprenons notre exemple de lecture de fichier. Puisque la
méthode read() peut déclencher une exception IOException, tu dois la gérer ou la déclarer.
Dans l'exemple suivant, nous déclarons que la méthode chargerTousLesScores() peut émettre
une IOException :
class MonSuperJeu {
void chargerTousLesScores() throws
IOException {
// …
// N'utilise pas try/catch si tu ne gères pas
// d'exceptions dans cette
méthode fichier.read();
}

public static void main(String[]


args) { MonSuperJeu jeu = new
MonSuperJeu();
System.out.println("Liste des
scores");

try {
// Puisque la méthode chargerTousLesScores() déclare
// une exception, nous la gérons
ici jeu.chargerTousLesScores();
} catch(IOException e) {
System.out.println(
"Désolé, la liste des scores n'est pas
disponible");}}}

 Le mot-clé finally
Le code inclus dans un bloc try/catch peut se terminer de trois façons :
 Le code à l'intérieur du bloc try est exécuté avec succès et le programme se
poursuit.
 Le code à l'intérieur du bloc tryrencontre une instruction return et le programme
sort de la méthode.
 Le code à l'intérieur du bloc try lève une exception et le contrôle passe au bloc
catch correspondant. Soit celui-ci gère l'erreur et l'exécution de la méthode se
poursuit ; soit il réémet l'exception à destination de la méthode appelante.
Si un morceau de code doit être exécuté quoi qu'il arrive, il faut le placer
dans un bloc finally :

Msc student Ruphin NYAMI Page 53


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

try {
fichier.read();
} catch(Exception e) {
e.printStackTrace();
} finally {
// Le code qui doit toujours être exécuté,
// par exemple file.close(), est placé ici.
}

 Manipulation des Fichiers avec Java.

Après qu'il se soit terminé, un programme est effacé de la mémoire. Cela signifie que toutes les
classes, méthodes et variables disparaissent jusqu'à ce que tu exécutes à nouveau ce
programme. Si tu souhaites sauvegarder certains résultats de l'exécution du programme, il
faut les enregistrer dans des fichiers sur un disque de ton grand père, une cassette, une carte
mémoire ou un autre périphérique capable de stocker des données pendant une longue
période. Dans ce chapitre, tu vas apprendre comment enregistrer des données sur disque à l'aide
des flux (streams) Java.

Fondamentalement, tu ouvres un flux entre ton programme et un fichier sur disque. Si tu veux
lire des données sur le disque, il te faut un flux d'entrée (input stream) ; si tu écris des
données sur le disque, ouvre un flux de sortie (output stream)..

Un programme lit ou écrit les données dans un flux en série – octet après octet, caractère
après caractère, etc. Comme ton programme utilise différents types de données tels que
String, int, double et autres, tu dois utiliser un flux Java approprié, par exemple un flux d'octets
(byte stream), un flux de caractères (character stream) ou un flux de données (data stream).

Les classes qui fonctionnent avec des flux de fichiers sont situées dans les paquetages java.io.
et java.nio.
Quel que soit le type de flux que tu vas utiliser, tu dois respecter les trois étapes suivantes
dans ton programme :

• Ouvrir un flux qui pointe sur un fichier.


• Lire ou écrire des données dans ce flux.
• Fermer le flux.
/Ainsi nous avons les deux classes suivantes : FileInputStream (pour la lecture
et FileOutputStream (l’écriture).
Exemple de la création d’un fichier sur disque dur écriture sur ce dernier.
Les lignes de codes suivant créent un fichier word du nom de syntyche et on y met les données
d’un tableau joueur.
public class ExerciceCours {
public static void main(String[] args) {
FileOutputStream monf = null;
int etudiant[] = {23, 88, 99,90};
try{
monf = new FileOutputStream("syntyche.doc");
for(int i = 0; i < etudiant.length; i++){
monf.write(etudiant[i]);

Msc student Ruphin NYAMI Page 54


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

}
}catch(IOException e){
System.out.println("Impossible d'ecrire sur le
fichier" + e.getMessage());
}finally{
try{
monf.close();
}catch(Exception ee){
ee.printStackTrace();} } }}

Lecture du fichier (n’importe quel fihier dans le disque dur)


FileInputStream lecture = null;
try{
lecture = new FileInputStream("syntyche.doc");
while(true){
int valeurOcte = lecture.read();
System.out.println(" " + valeurOcte );
if(valeurOcte == -1){
//Nous avons atteint la fin du fichier syntyche
break;
}
}
}catch(IOException eed){
System.out.println("Impossible d'ecrire sur le
fichier" + eed.getMessage());
}finally{
try{
monf.close();
}catch(Exception eee){
eee.printStackTrace();
}
System.out.println("Tuna fika ku mwinsho"); }}

Ouverture d’un Fichier à partir d’une application java.


if(Desktop.isDesktopSupported()){// Vérifier si votre système
permet d’écriture sur le disque par un programme client ou si
vous êtes Administrateur

if(Desktop.getDesktop().isSupported(Desktop.Action.OPEN)){
// Je precise ici qu’il s’agit d’une ouverture du fichier
try{
java.awt.Desktop.getDesktop().open(new File("mon
fichier.pdf"));
// ici je dois précisez l’URL du fichier à ouvrir
//en suite je l’imprime
java.awt.Desktop.getDesktop().print(new File("mon
fichier.pdf"));
}catch(IOException ex){System.out.println("Windows ana ni
tshiambula et ana katala" + ex.getMessage());}

Msc student Ruphin NYAMI Page 55


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

CHAPITRE IV. JAVA INTERACTIVITE AVEC LES


BASES DE DONNEES EN JAVA
4.2. Introduction
La couche JDBC est un package contenant des classes et interfaces permettant d'accéder
à une base de données à partir d'un programme Java. L'API (Application Programing Interface)
JDBC est contenu dans le package java.sql : connexion à une base de données expression de
requêtes relationnelles en SQL encapsulation des résultats des requêtes. L'hétérogénéité des
bases de données empêche une connexion directe entre une base de données et une application
Java.
Il faut utiliser un pilote qui "traduit" des commandes Java pour une base de données :
Chaque pilote est propre à une base de donnée Un pilote implémente l'interface java.sql.Driver.
La classe java.sql.DriverManager encapsule un ensemble de méthodes statiques pour :
 enregistrer la liste des pilotes disponibles;
 établir une connexion en trouvant le pilote approprié;
 gérer des fichiers de log.
L'utilisation de drivers est (presque) transparente.
L'interface java.sql.Connection est implémentée par des classes représentant une connexion à
une base de données. L'objet connexion est ensuite utilisé pour toutes les interactions avec la
BD :
 accéder à des informations sur la base;
 créer puis exécuter des requêtes;
 récupérer les résultats des requêtes.

4.2. Ouverture d'une connexion


Une connexion est ouverte par la classe DriverManager :
Connection getConnection(String url); L'URL JDBC a un format spécifique : jdbc:<sub-
protocol>:<sub-name> <sub-protocol> est généralement le nom du pilote;
<sub-name> est le nom de la source de donnée (interprété par le pilote).

Exemple : connexion à une base Oracle



try {
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
String url = "jdbc:oracle:thin:@educ.emse.fr:1521:DBEM";
String user = "laurent";
String passwd = "test";
Connection c = DriverManager.getConnection(url,user,passwd);

} catch (Exception e) {
e.printStackTrace(); }

//La classe Connexion est dejà implémenté et sockée dans la bibliothèque java. Tout ce //qui te reste de
d’implémenté l’interface fournie par cette classe pour acceder à une bas //de données.

4.3. La passerelle JDBC-ODBC


Afin d'illustrer la connexion à une base de données, nous allons nous connecter à une base
Access par l'intermédiaire de la passerelle ODBC-JDBC, en abordant toutes les étapes de la

Msc student Ruphin NYAMI Page 56


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

connexion à une base de données. Après création de la base sous Access, il faut dans un premier
temps intégrer la base UCANACCESS dans la bibliothèque du projet.

4.3.1. Connexion à la base de données


L'API (Application Programming Interface) JDBC, c'est-à-dire la bibliothèque de classes
JDBC, se charge de trois étapes indispensables à la connexion à une base de données :
1. la création d'une connexion à la base
2. l'envoi d'instructions SQL
3. l'exploitation des résultats provenant de la base
Supposons que notre source de données s’appelle « stock » voici la connexion java avec sa belle-
mère Access.

Pour se connecter à une base de données déclarée dans l'administrateur


ODBC, il est essentiel de charger dans un premier temps le pilote JDBC-ODBC
(appelé pont JDBC-ODBC) :
Class.forName("net.ucanaccess.jdbc.UcanaccessDriver");
String url = "jdbc:ucanaccess://"+db;
Connection con = DriverManager.getConnection(url);
L’URL contient le nom d’utilisateur, le mot de passé, et le nom de la base de
données. Comme Access ne t’oblige pas le mot de passe c’est pourquoi je le laisse
vide.

4.3.1.2. Exécution d'une requête SQL


Pour exécuter une requête SQL, il s'agit dans un premier temps de créer un objet Statement,
pouvant être obtenu à partir de l'objet Connection. Un objet ResultSet permettra de récupérer
les données en provenance de l'objet Statement.
String query = "SELECT * FROM Ma_Table;";
ResultSet results;
try { Statement stmt = con.createStatement();
results = stmt.executeQuery(query);}
catch(Exception e){ System.out.println("exception du a la requete");}

d. Les objets utilisables pour obtenir des informations sur la base sont :
DataBaseMetaData: Un objet contenant les informations sur la base de données en général (des
métadonnées), c'est-à-dire le nom de la table, les index, la version de la base, ...
ResultSet: Un objet contenant les informations sur une table ou le résultat d'une requête. L'accès
aux données se fait colonne par colonne, mais il est éventuellement possible d'accéder
indépendamment à chaque colonne par son nom
ResultSetMetaData: Un objet contenant des informations sur le nom et le type des colonnes
d'une table
Statement : c’est un Objet contenant les méthodes pour la construction de requêtes non
sécurisées il nécessite une connexion pour y arriver.

Msc student Ruphin NYAMI Page 57


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

PreparedStatement : un objet contenant les informations sur la table et faisant le travail génial
pour de requêtes préparées. Il est préférable d’utilisé cet objet pour éviter les injections sql (SQL
injection).

L'objet ResultSet : est l'objet le plus important de la technologie JDBC, car il s'agit d'une
abstraction de la table ou de la réponse à une requête (généralement un sous-ensemble d'une
table). Ainsi, presque toutes les méthodes et requêtes retournent les données sous forme d'un
objet ResultSet. Cet objet contient un nombre donné de colonnes repérées chacune par un nom,
ainsi qu'une ou plusieurs lignes contenant les données, et auxquelles il est possible d'accèder
séquentiellement une à une du haut vers le bas. Ainsi, afin d'exploiter un objet ResultSet, il est
nécessaire de récupérer le nombre de colonnes de celui-ci, à l'aide de l'objet
ResultSetMetaData.
ResultSetMetaData rsmd;
rsmd = results.getMetaData();
numcols = rsmd.getColumnCount();

Lors de l'obtention d'un objet ResultSet, le descripteur pointe avant la première ligne.
La méthode next() permet d'obtenir chacune des lignes suivantes, et retourne false lorsqu'il ne
reste plus aucune ligne. Etant donné que l'extraction de données de la base peut générer des
erreurs, il est indispensable d'inclure ces manipulations dans un bloc d'exception (try).
Les données contenues dans le ResultSet peuvent être obtenues sous différentes formes selon le
type de données stockées dans chaque colonne. Le contenu de chaque colonne peut être obtenu
soit par le nom de celle-ci, soit par son numéro (sachant que les numéros de colonne commencent
à 1 et non à 0).
Les principales méthodes de l'objet ResultSet sont les suivantes :
getInt(int): récupère sous forme d'entier le contenu d'une colonne désignée par son numéro
getInt(String): récupère sous forme d'entier le contenu d'une colonne désignée par son nom
getFloat(int): récupère sous forme de flottant le contenu d'une colonne désignée par son numéro
getFloat(String): récupère sous forme de flottant le contenu d'une colonne désignée par son nom
next(): déplace le pointeur de ligne sur la ligne suivante
close(): "ferme" l'objet
getMetaData(): retourne les métadonnées de l'objet (l'objet ResultSetMetaData)

L'objet ResultSetMetaData (obtenu de l'objet ResultSet) permet de connaître le nombre, le nom


et le type de chaque colonne à l'aide des méthodes suivantes :
getColumnCount(): récupère le nombre de colonnes
getColumnName(int): récupère le nom de la colonne spécifiée
getColumnLabel(int): récupère le label de la colonne spécifiée
getColumnType(int): récupère le type de données de la colonne spécifiée
L'objet DataBaseMetaData permet d'obtenir des informations sur la base de données entière. Il
sert notamment à récupérer le nom des tables contenues dans la base de données. De plus, étant
donné que de nombreuses bases de données supportent des variantes du langage SQL, il existe

Msc student Ruphin NYAMI Page 58


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

de nombreuses méthodes associées à l'objet DataBaseMetaData permettant de connaître les


méthodes SQL supportées par la base.
import java.sql.*;
public class Dal {
public Connection getOuvertur(){
Connection cnx = null;
try{
Class.forName("net.ucanaccess.jdbc.UcanaccessDriver");
String db = "db_epi.mdb";
String url = "jdbc:ucanaccess://"+db;
cnx = DriverManager.getConnection(url);
}catch(ClassNotFoundException ex){ System.out.println("pobleme
classe " + ex.getMessage());
} catch (SQLException ex) {System.out.println("poblem driver " +
ex.getMessage());}return cnx;}}

4.3.2. Base de données MySQL


La connexion Java avec une base de données MySQL, il est nécessaire
d’avoir le fichier jar de Mysql connector ajouté dans vos librairies
(bibliothèque du projet). Voici les codes sources de la connexion unique à
une base de données MySQL
import java.sql.*;
public class Dal {
static String user = "root";//le nom de l'utilisateur Mysql
static String pwd = "mot_de_passe"; // son password dans mon serveur
static String chemin = "jdbc:mysql://127.0.0.1:3306/db_epi"; // URl de
la db
/** La méthode getAutorisation sera appelée en cas de besoin de
connexion */
public static Connection getAutorisation(){
Connection geton = null;
try{Class.forName("com.mysql.jdbc.Driver");
geton = DriverManager.getConnection(chemin, user, pwd);
}catch(ClassNotFoundException ce){ System.out.println("Problème de la
Class de pilote choisie");}catch(SQLException ex){
System.out.println("Erreur du Chargement de Driver Manager driver" +
ex.getMessage());}
return geton; } }

Msc student Ruphin NYAMI Page 59


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

CHAPITRE V : INTERFACE GRAPHIQUE (GUI)


Le Graphic User Interface est la partie de l’application visible à l’utilisateur. Java est
fournie avec un tas de classes dont le programmeur averti doit se servir pour créer des
applications graphiques. Il y a trois groupes principaux de classes (librairies) utilisées
pour créer des fenêtres en Java : AWT, Swing et JavaFX.

5.1. Aperçu Général


Les programmes à interfaces graphiques font usage des classes awt(abstract windowing
toolkit), ou swing ou Javafx. Ils sont dirigés par évènements.
- Classe de base des awt : la classe abstraite Component.
- Classe de base des composants swing : JComponent. Swing est une bibliothèque graphique
pour le langage de programmation Java, faisant partie du package Java Foundation Classes (JFC), inclus
dans J2SE. Swing constitue l'une des principales évolutions apportées par Java 2 par rapport aux
versions antérieures. On distingue, par service :
- les classes conteneur
- les classes d'interaction
- les menus et dialogues

5.1.1. Architecture de Swing


Swing propose de nombreux composants dont certains possèdent des fonctions étendues,
une utilisation des mécanismes de gestion d'événements performants (ceux introduits par le JDK
1.1) et une apparence modifiable à la volée (une interface graphique qui emploie le style du
système d'exploitation Windows ou Motif ou un nouveau style spécifique à Java nommé Metal).

Tous les éléments de Swing font partie d'un package qui a changé plusieurs fois de nom :
le nom du package dépend de la version du J.D.K. utilisée :

 com.sun.java.swing : jusqu'à la version 1.1 beta 2 de Swing, de la version 1.1 des JFC et
de la version 1.2 beta 4 du J.D.K.
 java.awt.swing : utilisé par le J.D.K. 1.2 beta 2 et 3
 javax.swing : à partir des versions de Swing 1.1 beta 3 et J.D.K. 1.2 RC1

Les composants Swing forment une nouvelle hiérarchie parallèle à celle de l'AWT.
L'ancêtre de cette hiérarchie est le composant JComponent. Presque tous ses composants sont
écrits en pur Java : ils ne possèdent aucune partie native sauf ceux qui assurent l'interface avec
le système d'exploitation : JApplet, JDialog, JFrame, et JWindow. Cela permet aux composants
de toujours avoir la même apparence quel que soit le système sur lequel l'application s'exécute.

Tous les composants Swing possèdent les caractéristiques suivantes :

 ce sont des beans


 ce sont des composants légers (pas de partie native) hormis quelques exceptions.
 leurs bords peuvent être changés

Msc student Ruphin NYAMI Page 60


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

La procédure à suivre pour utiliser un composant Swing est identique à celle des
composants de la bibliothèque AWT : créer le composant en appelant son constructeur, appeler
les méthodes du composant si nécessaire pour le personnaliser et l'ajouter dans un conteneur.

Swing utilise la même infrastructure de classes qu'AWT, ce qui permet de mélanger des
composants Swing et AWT dans la même interface. Il est toutefois recommandé d'éviter de les
utiliser simultanément car certains peuvent ne pas être restitués correctement.

Les composants Swing utilisent des modèles pour contenir leurs états ou leurs données.
Ces modèles sont des classes particulières qui possèdent toutes un comportement par défaut.

Une application est composée de plusieurs Swing :


• Un composant top-level
• Plusieurs composants conteneur intermédiaire, ils contiennent d’autres composants
• Des composants atomiques

5.1.2. Le composant JComponent


Tous les composants Swing héritent de JComponent
• Les composants ont des Tool Tips
• Les composants ont des bordures
• Entité graphique la plus abstraite

5.1.3. Top-Level
• La bibliothèque Swing propose 3 composants top-level : JFrame, JDialog et
JApplet
• JWindow est aussi top-level mais il n’est pas utilisé
• JInternalFrame ressemble à un top-level mais il n’en est pas un
Une application graphique doit avoir un composant top-level comme composant racine
(composant qui inclut tous les autres composants). Les composants top-level possèdent un
content pane qui contient tous les composants visibles d’un top-level et peut contenir une barre
de menu.

Figure 1—Top level en SWING

Swing offre une palette bien plus large comme le démontre la figure suivante :

Msc student Ruphin NYAMI Page 61


Support de cours de Questions Spéciales et Ateliers de Génie Logiciel (L2 IG UPL 2019-2020)

Figure 2—Palette swing

Exemple :
import javax.swing.*;
class bjm {
public static void main(String[] args) {
JOptionPane.showMessageDialog(null, "Bonjour, monde");
System.exit(0);
}
}

Le programme java est dirigé par événements :


- un thread dédié: EventDispatchThread gère la distribution des événements
- le programme ne termine pas implicitement, d’où le System.exit(0)
5.2. Les conteneurs
 Container : classe abstraite, responsable du layout
 Window : pour interaction avec le système
 Frame : fenêtre principale d'application
 Panel contient des composants
 Applet
 ScrollPane : enrobe un conteneur d'ascenseurs

Msc student Ruphin NYAMI Page 62


A retenir : un programme étend Frame ! Une applette étend Applet

5.2.1.Gestion des évènements


 Un composant enregistre des auditeurs d’évènements (Listeners).
 Lorsqu’un événement se produit dans un composant, il est envoyé aux auditeurs
enregistrés.
 Chaque auditeur définit les actions à entreprendre, dans des méthodes aux noms
prédéfinis. Gestion des évènements
 Exemple: Un Button enregistre des ActionListener, lors d’un clic,
un ActionEvent est envoyé aux ActionListener enregistrés. Ceci provoque
l’exécution de la méthode actionPerformed de chaque ActionListener.

4.2.3. Quelques champs du formulaire avec SWING


Les objets graphiques que propose SWING sont variés et s'utilisent souvent de la même
manière.

4.2.3.1. JFrame

JFrame est l'équivalent de la classe Frame de l'AWT : les principales différences sont
l'utilisation du double buffering qui améliore les rafraichissements et l'utilisation d'un
panneau de contenu (contentPane) pour insérer des composants (ils ne sont plus insérés
sans le JFrame mais dans l'objet contentPane qui lui est associé). Elle représente une fenêtre
principale qui possède un titre, une taille modifiable et éventuellement un menu.

La classe possède plusieurs constructeurs :

Constructeur Rôle

JFrame()

Création d'une instance en précisant le


JFrame(String)
titre

Une JFrame est une fenêtre avec un titre et une bordure ayant quelques méthodes :
public JFrame();
public JFrame(String name);
public Container getContentPane();
public void setJMenuBar(JMenuBar menu);
public void setTitle(String title);
public void setIconImage(Image image);
Exemple :
import javax.swing.*;
public class TestJFrame1 {
public static void main(String argv[]) {
JFrame f = new JFrame("ma fenetre");
f.setSize(300,100);
f.setVisible(true);}}

Msci Student Ruphin NYAMI N.


Page 63
5.2.3.1.1. Le comportement par défaut à la fermeture

Il est possible de préciser comment un objet JFrame, JInternalFrame, ou


JDialog réagit à sa fermeture grâce à la méthode setDefaultCloseOperation(). Cette méthode
attend en paramètre une valeur qui peut être :

Constante Rôle

WindowConstants.DISPOSE_ON_CLOSE détruit la fenêtre

WindowConstants.DO_NOTHING_ON_CLOSE rend le bouton de fermeture inactif

WindowConstants.HIDE_ON_CLOSE cache la fenêtre

import javax.swing.*;
public class TestJFrame3 {
public static void main(String argv[]) {
JFrame f = new JFrame("ma fenetre");
f.setSize(300,100);
JButton b =new JButton("Mon bouton");
f.getContentPane().add(b);
f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
f.setVisible(true);
}
}

 La personnalisation de l'icône
La méthode setIconImage() permet de modifier l'icône de la JFrame.
ImageIcon image = new ImageIcon("book.gif");
f.setIconImage(image.getImage());
f.setVisible(true);

Si l'image n'est pas trouvée, alors l'icône est vide. Si l'image est trop grande, elle est
redimensionnée.

 Centrer une JFrame à l'écran


Par défaut, une JFrame est affichée dans le coin supérieur gauche de l'écran. Pour la centrer
dans l'écran, il faut procéder comme pour une Frame : déterminer la position de la Frame en
fonction de sa dimension et de celle de l'écran et utiliser la méthode setLocation() pour
affecter cette position.
f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
f.setLocation(dim.width/2 - f.getWidth()/2, dim.height/2 -
f.getHeight()/2);
f.setVisible(true);

Msci Student Ruphin NYAMI N.


Page 64
5.2.3.2. JDialog
Un JDialog est une fenêtre qui a pour but un échange d’information et qui dépend d’une fenêtre,
si celle-ci est détruite, le JDialog l’est aussi. Un JDilaog peut aussi être modal, il bloque tout
les inputs sur lui.

5.2.3.3. Conteneur Intermédiaire


Swing propose plusieurs conteneurs intermédiaires : JPanel, JScrollPane,
JSplitPane, JTabbedPane, JToolBar,..

5.2.3.4. Les composants atomiques


Un composant atomique est considéré comme étant une entité unique. Java propose beaucoup
de composants atomiques : boutons, CheckBox, Radio, Combo box, List,
menu, TextField, TextArea, Label, FileChooser, ColorChooser,…

b) Les boutons
Java propose différent type de boutons :
Méthode Rôle
AddActionListener Associer un écouteur sur un événement de type
ActionEvent
AddChangeListener Associer un écouteur sur un événement de type
ChangeEvent
AddItemListener Associer un écouteur sur un événement de type ItemEvent
doClick() Déclencher un clic par programmation
getText() Obtenir le texte affiché par le composant
setDisabledIcon() Associer une icône affichée lorsque le composant a l'état
désélectionné
setDisabledSelectedIcon() Associer une icône affichée lors du passage de la souris sur
le composant à l'état désélectionné
setEnabled() Activer/désactiver le composant
setMnemonic() Associer un raccourci clavier
setPressedIcon() Associer une icône affichée lorsque le composant est cliqué
setRolloverIcon() Associer une icône affichée lors du passage de la souris sur
le composant
setRolloverSelectedIcon() Associer une icône affichée lors du passage de la souris sur
le composant à l'état sélectionné
setSelectedIcon() Associer une icône affichée lorsque le composant a l'état
sélectionné
setText() Mettre à jour le texte du composant
isSelected() Indiquer si le composant est dans l'état sélectionné
setSelected() Définir l'état du composant (sélectionné ou non selon la
valeur fournie en paramètre

Tous les boutons peuvent afficher du texte et/ou une image. Il est possible de préciser une image
différente lors du passage de la souris sur le composant et lors de l'enfoncement du bouton :
dans ce cas, il faut créer trois images pour chacun des états (normal, enfoncé et survolé).
L'image normale est associée au bouton grâce au constructeur, l'image enfoncée grâce à la
méthode setPressedIcon() et l'image lors d'un survol grâce à la méthode setRolloverIcon(). Il
suffit enfin d'appeler la méthode setRolloverEnable() avec en paramètre la valeur true.

Exemple :

Msci Student Ruphin NYAMI N.


Page 65
ImageIcon imageNormale = new ImageIcon("arrow.gif");
ImageIcon imagePassage = new ImageIcon("arrowr.gif");
ImageIcon imageEnfoncee = new ImageIcon("arrowy.gif");

JButton bouton = new JButton("Mon bouton",imageNormale);


bouton.setPressedIcon(imageEnfoncee);
bouton.setRolloverIcon(imagePassage);
bouton.setRolloverEnabled(true);
getContentPane().add(bouton, "Center");

JPanel panneau = new JPanel();


panneau.add(bouton);
setContentPane(panneau);
setSize(200,100);
setVisible(true);

Un bouton peut recevoir des événements de type ActionEvents (le bouton a été activé),
ChangeEvents, et ItemEvents.
public static void main(String argv[]) {
JFrame f = new JFrame("ma fenetre");
f.setSize(300,100);
JPanel pannel = new JPanel();
JButton bouton1 = new JButton("Bouton1");
bouton1.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
}
);
pannel.add(bouton1);
f.getContentPane().add(pannel);
f.setVisible(true);
}

c) Les cases à cocher : la classe JCheckBox


 Les constructeurs sont les suivants :

Constructeur Rôle
JCheckBox(String) précise l'intitulé
JCheckBox(String, boolean) précise l'intitulé et l'état
JCheckBox(Icon) spécifie l'icône utilisée
JCheckBox(Icon, boolean) précise l'intitulé et l'état du bouton
JCheckBox(String, Icon) précise l'intitulé et l'icône
JCheckBox(String, Icon, boolean) précise l'intitulé, une icône et l'état
Exemple :
public static void main(String argv[]) {
JFrame f = new JFrame("ma fenetre");
f.setSize(300,100);
JPanel pannel = new JPanel();
JCheckBox bouton1 = new JCheckBox("Bouton 1");
pannel.add(bouton1);
JCheckBox bouton2 = new JCheckBox("Bouton 2");

Msci Student Ruphin NYAMI N.


Page 66
pannel.add(bouton2);
JCheckBox bouton3 = new JCheckBox("Bouton 3");
pannel.add(bouton3);

f.getContentPane().add(pannel);
f.setVisible(true);
}

c) Les boutons radio : la classe JRadioButton

Un objet de type JRadioButton représente un bouton radio d'un groupe de boutons. A un instant
donné, un seul des boutons radio associés à un même groupe peut être sélectionné. La classe
JRadioButton hérite de la classe AbstractButton.

Un bouton radio possède un libellé et éventuellement une icône qui peut être précisée, pour
chacun des états du bouton, en utilisant les méthodes setIcon(), setSelectedIcon() et
setPressedIcon().

public static void main(String argv[]) {


JFrame f = new JFrame("ma fenetre");
f.setSize(300,100);
JPanel pannel = new JPanel();
JRadioButton bouton1 = new JRadioButton("Bouton 1");
pannel.add(bouton1);
JRadioButton bouton2 = new JRadioButton("Bouton 2");
pannel.add(bouton2);
JRadioButton bouton3 = new JRadioButton("Bouton 3");
pannel.add(bouton3);
f.getContentPane().add(pannel);
f.setVisible(true);
}
d) JComboVox
Un JComboBox est un composant permettant de faire un choix parmi plusieurs propositions.
Quelques méthodes:
- public JComboBox(Vector v);
- public JComboBox(ComboBoxModel c);
- Object getSelectedItem();
- void addItem(Object o);

public class Fenetre extends JFrame {


private JPanel container = new JPanel();
private JComboBox combo = new JComboBox();
private JLabel label = new JLabel("La ComboBox");

public Fenetre(){
this.setTitle("Animation");
this.setSize(300, 300);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
container.setBackground(Color.white);
container.setLayout(new BorderLayout());
combo.setPreferredSize(new Dimension(100, 20));

Msci Student Ruphin NYAMI N.


Page 67
combo.addItem("Option 1");
combo.addItem("Option 2");
combo.addItem("Option 3");
combo.addItem("Option 4");
JPanel top = new JPanel();
top.add(label);
top.add(combo);
container.add(top, BorderLayout.NORTH);
this.setContentPane(container);
this.setVisible(true);
}
public static void main(String[] args) {
Fenetre f = new Fenetre();
f.setVisible(true);}}

L’initilisation d’un ComboBox avec un tableau de valeur :


String[] tab = {"Option 1", "Option 2", "Option 3", "Option 4"};
combo = new JComboBox(tab);

e) JList

Une JList propose plusieurs éléments rangés en colonne et peut proposer une sélection simple
ou multiple. Les JList sont souvent contenues dans un srolled pane
Quelques méthodes:
- public JList(Vector v);
- public JList( ListModel l);
- Object[] getSelectedValues();
f) JSlider

Les JSlider permettent la saisie graphique d’un nombre. Un JSlider doit contenir les bornes
max et min.
Quelques méthodes:
- public JSlider(int min ,int max, int value);
- public void setLabelTable(Dictionary d);

g) Les composants de saisie de text

Un JTextField est un composant qui permet d’écrire du texte. Un JTextField a une seul
ligne contrairement au JTextArea qui lui, permet de saisir un texte illimité. Le
JPasswordField permet de cacher ce qui est écrit.
La classe JTextComponent possède de nombreuses méthodes dont les principales sont :
Méthode Rôle
void copy() Copier le contenu du texte et le mettre dans le presse
papier système
void cut() Couper le contenu du texte et le mettre dans le presse
papier système
Document getDocument() Renvoyer l'objet de type Document qui encapsule le
texte saisi
String Renvoyer le texte sélectionné dans le composant
getSelectectedText()

Msci Student Ruphin NYAMI N.


Page 68
int getSelectionEnd() Renvoyer la position de la fin de la sélection
int getSelectionStart() Renvoyer la position du début de la sélection
String getText() Renvoyer le texte saisi
String getText(int, int) Renvoyer une portion du texte débutant à partir de la
position donnée par le premier paramètre et la
longueur donnée dans le second paramètre
bool isEditable() Renvoyer un booléen qui précise si le texte est
éditable ou non
void paste() Coller le contenu de la presse papier système dans le
composant
void select(int,int) Sélectionner une portion du texte dont les positions de
début et de fin sont fournies en paramètres
void Déplacer le curseur dans le texte à la position précisé
setCaretPosition(int) en paramètre
void setEditable(boolean) Permet de préciser si les données du composant sont
éditables ou non
void setSelectionEnd(int) Modifier la position de la fin de la sélection
void Modifier la position du début de la sélection
setSelectionStart(int)
void setText(String) Modifier le contenu du texte

o La classe JTextField
La classe javax.Swing.JTextField est un composant qui permet la saisie d'une seule ligne de
texte simple. Son modèle utilise un objet de type PlainDocument.
Exemple :
public static void main(String argv[]) {
JFrame f = new JFrame("ma fenetre");
f.setSize(300, 100);
JPanel pannel = new JPanel();
JTextField testField1 = new JTextField ("mon texte");
pannel.add(testField1);
f.getContentPane().add(pannel);
f.setVisible(true);
}
}

o La classe JPasswordField
La classe JPasswordField permet la saisie d'un texte dont tous les caractères saisis seront
affichés sous la forme d'un caractère particulier ('*' par défaut). Cette classe hérite de la classe
JTextField.
Exemple :
public static void main(String argv[]) {
JFrame f = new JFrame("ma fenetre");
f.setSize(300, 100);
JPanel pannel = new JPanel();
JPasswordField passwordField1 = new JPasswordField ("");
passwordField1.setPreferredSize(new Dimension(100,20 ));
pannel.add(passwordField1);
f.getContentPane().add(pannel);
f.setVisible(true);
}
La méthode setEchoChar(char) permet de préciser le caractère qui sera montré lors de la saisie.

Msci Student Ruphin NYAMI N.


Page 69
Il ne faut pas utiliser la méthode getText() qui est déclarée deprecated mais la méthode
getPassword() pour obtenir la valeur du texte saisi.
Exemple 2 : JPassWord
import java.awt.Dimension;
import java.awt.event.*;
import javax.swing.*;

public class EssaiPassWord implements ActionListener {


JPasswordField passwordField1 = null;
public static void main(String argv[]) {
EssaiPassWord jpf2 = new EssaiPassWord();
jpf2.init();
}

public void init() {


JFrame f = new JFrame("ma fenetre");
f.setSize(300, 100);
JPanel pannel = new JPanel();
passwordField1 = new JPasswordField("");
passwordField1.setPreferredSize(new Dimension(100, 20));
pannel.add(passwordField1);
JButton bouton1 = new JButton("Afficher");
bouton1.addActionListener(this);
pannel.add(bouton1);
f.getContentPane().add(pannel);
f.setVisible(true);
}

public void actionPerformed(ActionEvent e) {


System.out.println("texte saisie = " +
String.copyValueOf(passwordField1.getPassword()));
}
}

o La classe JFormattedTextField
Le JDK 1.4 propose la classe JFormattedTextField pour faciliter la création d'un composant de
saisie personnalisé. Cette classe hérite de la classe JTextField.

h) La classe EditorPane
Ce composant permet la saisie de texte riche multilignes. Ce type de texte peut contenir des
informations de mise en pages et de formatage. En standard, Swing propose le support des
formats RTF et HTML.
Exemple d’affichage de la page de faceBook dans ton application java :
import java.net.URL;
import javax.swing.*;
import javax.swing.event.*;

public class EditorPane1 {


public static void main(String[] args) {
final JEditorPane editeur;
JPanel pannel = new JPanel();
try {
editeur = new JEditorPane(new URL("http://facebook.com"));
editeur.setEditable(false);
editeur.addHyperlinkListener(new HyperlinkListener() {
public void hyperlinkUpdate(HyperlinkEvent e) {
if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {

Msci Student Ruphin NYAMI N.


Page 70
URL url = e.getURL();
if (url == null)
return;
try {
editeur.setPage(e.getURL());
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
});

pannel.add(editeur);
} catch (Exception e1) {
e1.printStackTrace();
}
JFrame f = new JFrame("ma fenetre");
f.setSize(500, 300);

f.getContentPane().add(pannel);
f.setVisible(true);

}
}

i) JLabel
Un JLabel permet d’afficher du texte ou une image. Un JLabel peut contenir plusieurs lignes et
il comprend les tags HTML. Le composant JLabel propose les mêmes fonctionnalités que les
intitulés AWT mais ils peuvent en plus contenir des icônes. Cette classe possède plusieurs
constructeurs :
Constructeurs Rôle
JLabel() Création d'une instance sans texte ni image
JLabel(Icon) Création d'une instance en précisant l'image
JLabel(Icon, Création d'une instance en précisant l'image
int) et l'alignement horizontal
JLabel(String) Création d'une instance en précisant le texte
JLabel(String, Création d'une instance en précisant le
Icon, int) texte, l'image et l'alignement horizontal
JLabel(String, Création d'une instance en précisant le texte
int) et l'alignement horizontal

Exemple :
public class TestJLabel1 {
public static void main(String argv[]) {
JFrame f = new JFrame("ma fenetre");
f.setSize(100,200);
JPanel pannel = new JPanel();
JLabel jLabel1 =new JLabel("Mon texte dans JLabel");
pannel.add(jLabel1);
ImageIcon icone = new ImageIcon("book.gif");
JLabel jLabel2 =new JLabel(icone);
pannel.add(jLabel2);
JLabel jLabel3 =new JLabel("Mon texte",icone,SwingConstants.LEFT);
pannel.add(jLabel3);

Msci Student Ruphin NYAMI N.


Page 71
f.getContentPane().add(pannel);
f.setVisible(true);
}
}

Quelques méthodes de JLabel

La classe JLabel définit plusieurs méthodes pour modifier l'apparence du composant :

Méthodes Rôle
setText() Permet d'initialiser ou de modifier le texte
affiché
setOpaque() Indique si le composant est transparent
(paramètre false) ou opaque (true)
setBackground() Indique la couleur de fond du
composant (setOpaque doit être à true)
setFont() Permet de préciser la police du texte
setForeGround() Permet de préciser la couleur du texte
setHorizontalAlignment() Permet de modifier l'alignement horizontal du
texte et de l'icône
setVerticalAlignment() Permet de modifier l'alignement vertical du
texte et de l'icône
setHorizontalTextAlignment() Permet de modifier l'alignement horizontal du
texte uniquement
setVerticalTextAlignment() Permet de modifier l'alignement vertical du
texte uniquement.
setIcon() Permet d'assigner une icône
setDisabledIcon() Permet de définir l'icône associée au JLabel
lorsqu'il est désactivé

L'alignement vertical par défaut d'un JLabel est centré. L'alignement horizontal par défaut est
soit à droite s'il ne contient que du texte, soit centré s'il contient une image avec ou sans texte.
Pour modifier cet alignement, il suffit d'utiliser les méthodes ci-dessus en utilisant des
constantes en paramètres : SwingConstants.LEFT, SwingConstants.CENTER,
SwingConstants.RIGHT, SwingConstants.TOP, SwingConstants.BOTTOM

Par défaut, un JLabel est transparent : son fond n'est pas dessiné. Pour le dessiner, il faut utiliser
la méthode setOpaque() :

public static void main(String argv[]) {


JFrame f = new JFrame("ma fenetre");
f.setSize(100,200);
JPanel pannel = new JPanel();
JLabel jLabel1 =new JLabel("Mon texte dans JLabel 1");
jLabel1.setBackground(Color.red);
pannel.add(jLabel1);
JLabel jLabel2 =new JLabel("Mon texte dans JLabel 2");
jLabel2.setBackground(Color.red);
jLabel2.setOpaque(true);
pannel.add(jLabel2);

Msci Student Ruphin NYAMI N.


Page 72
f.getContentPane().add(pannel);
f.setVisible(true);
}
1. JFileChooser

Un JFileChooser permet de sélectionner un fichier en parcourant l’arborescence du système de


fichier.
exemple
JFileChooser fc = new JFileChooser();
int returnVal = fc.showOpenDialog(aFrame);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File file = fc.getSelectedFile();
}

2. JProgressbar
Un JProgressBar permet d’afficher une barre de progression.
Quelques méthodes :
public JProgressBar();
public JProgressBar(int min, int max);
public void setValue(int i);

3. JTable
Les tableaux sont des composants qui permettent d'afficher des données de façon structurée.
Les tableaux sont composés de cellules. Les cellules sont encadrées de bordures noires et
contiennent les données dans le tableau d'Object et de String. Celles-ci peuvent être retrouvées
par leurs coordonnées (x, y) où x correspond au numéro de la ligne et y au numéro de la colonne
! Une cellule est donc l'intersection d'une ligne et d'une colonne. Afin de modifier une cellule,
il faut récupérer la ligne et la colonne auxquelles elle appartient.

Figure 3—exemple d'un Tableau

5.2.4. Positionnement des composants : Layout Manager


Pour placer des composants dans un container, Java propose une technique de Layout. Un
layout est une entité Java qui place les composants les uns par rapport aux autres.
Le layout s’occupe aussi de réorganiser les composants lorsque la taille du container varie. Il
y a plusieurs layout : BorderLayout, BoxLayout, CardLayout, FlowLayout,
GridLayout, GridBagLayout. Un layout n’est pas contenu dans un container, il gère
le positionnement.

Msci Student Ruphin NYAMI N.


Page 73
5.2.4.1. BorderLayout
Le BorderLayout sépare un container en cinq zones : NORTH, SOUTH, EAST, WEST et
CENTER. Lorsque l’on agrandit le container, le centre s'agrandit. Les autres zone prennent
uniquement l’espace qui leur est nécessaire.
Exemple :
Container contentPane = getContentPane();
contentPane.setLayout(new BorderLayout());
contentPane.add(new JButton("Button 1 (NORTH)"), BorderLayout.NORTH);

5.2.4.2. BoxLayout
Un BoxLayout permet d’empiler les composants du container (soit de verticalement, soit
horizontalement). Ce layout essaye de donner à chaque composant la place qu’il demande et il
est possible de rajouter des blocs invisibles. Il est possible de spécifier l’alignement des
composants (centre, gauche, droite)

5.2.4.3. CardLayout
Un CardLayout permet d’avoir plusieurs conteneurs les uns au-dessus des autres (comme un
jeux de cartes).
Exemple :
JPanel cards;
final static String BUTTONPANEL = "JPanel with JButtons";
final static String TEXTPANEL = "JPanel with JTextField";
cards = new JPanel();
cards.setLayout(new CardLayout());
cards.add(p1,BUTTONPANEL);
cards.add(p2,TEXTPANEL);

5.2.4.4. FlowLayout
Un FlowLayout permet de ranger les composants dans une ligne. Si l’espace est trop petit, une
autre ligne est créée. Le FlowLayout est le layout par défaut des JPanel
Exemple :
Container contentPane = getContentPane();
contentPane.setLayout(new FlowLayout());
contentPane.add(new JButton("Button 1"));
contentPane.add(new JButton("2"));
contentPane.add(new JButton("Button 3"));
contentPane.add(new JButton("Long-Named Button 4"));
contentPane.add(new JButton("Button 5"));

5.2.4.5. GridLayout

Un GridLayout permet de positionner les composants sur une grille.


Exemple :
Container contentPane = getContentPane();
contentPane.setLayout(new GridLayout(0,2));
contentPane.add(new JButton("Button 1"));
contentPane.add(new JButton("2"));
contentPane.add(new JButton("Button 3"));

Msci Student Ruphin NYAMI N.


Page 74
contentPane.add(new JButton("Long-Named Button 4"));
contentPane.add(new JButton("Button 5"));

5.2.4.6. GridBagLayout

Le GridBagLayout est le layout le plus complexe. Il place les composants sur une grille, mais
des composants peuvent être contenus dans plusieurs cases. Pour exprimer les propriétés des
composants dans la grille, on utilise un GridBagConstraints.
Un GridBasConstraints possède :
• gridx, gridy pour spécifier la position
• gridwidth, gridheight pour spécifier la place
• fill pour savoir comment se fait le remplissage

5.3. Les applications graphiques évoluées : Java fx


Java FX, initialement cr_e_e par SUN, a été intégrée à Java depuis la version 8. Java FX
propose :
- une API (des classes java) pour la gestion de graphiques, fenêtres
- un logiciel de cr_eation de fenêtres de dialogue `Scene Builder', générant des fichiers
FXML
- un composant de lecture de page web (WebView)
- un support `MultiTouch'
- utilisation de `PRISM' pour un accés direct à la carte graphique
- des composants pour la conception d'images 3D
- des liens vers des composants `Swing' (ancien mode de création d'interfaces graphiques)

Etude de Cas : Gestion Catalogue Produit


Application
 Créer une application, qui permet de gérer un catalogue de produits appartenant à des
catégories.
 Une catégorie est définie son identifiant, son nom et sa photo
 Un produit, appartenant à une catégorie, est définie par son identifiant, sa désignation, son
prix et sa photo
 Le service devra permettre les opérations suivantes :
- Ajouter une nouvelle catégorie
- Ajouter un nouveau produit
- Consulter toutes les catégories
- Consulter les produits d’une catégorie
- Consulter une catégorie
- Consulter un produit
- Consulter les produits dont la désignation contient unt mot clés
- Mettre à jour un produit
- Supprimer un produit
L’application Web se compose de trois couches :
- La couche Dao
- La couche métier
 Les entités Catégorie et Produit
 Une Interface ICatalogueMetier

Msci Student Ruphin NYAMI N.


Page 75
 Une implémentation de cette interface qui suppose que les produits et les
catégories sont stockés dans des collections de type HashMap, dans Access et
dans MySQL
- La couche présentation avec Swing ou Java FX au choix.

1ère étape : implémentation de couche metier.entites


a) La classse Catalogue.java
Suivant l’énoncé, la classe Catalogue doit être créée comme ceci :
package metier.entities;

public class Categorie{


private Long idCategorie;
private String nomCategorie;
private String photo;

public Long getIdCategorie() {return idCategorie;}


public void setIdCategorie(Long idCategorie) {
this.idCategorie = idCategorie;}
public String getNomCategorie() {return nomCategorie;}
public void setNomCategorie(String nomCategorie) {
this.nomCategorie = nomCategorie;}
public String getPhoto() {return photo;}
public void setPhoto(String photo) {this.photo = photo;}
public Categorie(Long idCategorie, String nomCategorie, String
photo) {super();this.idCategorie = idCategorie;this.nomCategorie =
nomCategorie;this.photo = photo;}
public Categorie() {super();}
@Override
public String toString() {
return "Categorie [idCategorie=" + idCategorie + ",
nomCategorie=" + nomCategorie + ", photo=" + photo + "]";}
}

b) La classe Produit.java
public class Produit {
private Long idProduit;
private String designation;
private double prix;
private String photo;
private Categorie categorie;
public Long getIdProduit() {return idProduit;}
public void setIdProduit(Long idProduit) {this.idProduit =
idProduit;}
public String getDesignation() {return designation;}
public void setDesignation(String designation) {
this.designation = designation;}
public double getPrix() {return prix;}
public void setPrix(double prix) {this.prix = prix;}
public String getPhoto() {return photo;}
public void setPhoto(String photo) {this.photo = photo;}
public Categorie getCategorie() {return categorie;}

Msci Student Ruphin NYAMI N.


Page 76
public void setCategorie(Categorie categorie) {
this.categorie = categorie;}
public Produit(Long idProduit, String designation, double
prix, String photo, Categorie categorie) {
super();
this.idProduit = idProduit;
this.designation = designation;
this.prix = prix;
this.photo = photo;
this.categorie = categorie;
}
public Produit() {super();}}

c) Déclaration de l’Interface ICatalogue.java


Dans cette interface, nous allons déclarer tous les méthodes de la gestion catalogue à
implémenter dans une autre classe.
package metier;
import java.util.List;
import metier.entities.Categorie;
import metier.entities.Produit;

public interface ICatalogue {


public Categorie addCategorie(Categorie cat);
public Produit addProdui(Produit p);
public List<Categorie> listeCategories();
public List<Produit> produitParCategorie(Long idCat);
public List<Produit> produitParMotCles(String mc);
public Categorie updateCategorie(Categorie c);
public List<Produit> listProduits();
public boolean deleteCategorie(Long idCat);
public boolean deleteProduit(Long idP);
public Produit updateProduit(Produit p);
public Categorie getCategorie(Long idCat);
public Produit getProduit(Long idP);
}

d) Implémentation de l’Interface ICatalogue


package metier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import metier.entities.Categorie;
import metier.entities.Produit;

public class CatalogueMetierImpl implements ICatalogue {


private HashMap<Long, Categorie> colCategories = new
HashMap<Long, Categorie>();
private HashMap<Long, Produit> colProduit = new
HashMap<Long, Produit>();

@Override
public Categorie addCategorie(Categorie cat) {

Msci Student Ruphin NYAMI N.


Page 77
colCategories.put(cat.getIdCategorie(),
cat);//L'ajout d'une catégorie dans la collectio
return cat;}
@Override
public Produit addProdui(Produit p) {
p.setCategorie(getCategorie(p.getCategorie().getIdCategorie()));//
l'objet produit a stocker, on lui passe la categorie
colProduit.put(p.getIdProduit(), p);
return p; }

@Override
public List<Categorie> listeCategories() {
return new ArrayList<Categorie>(colCategories.values());//super ici
prend la collection hashmap et on le retourne comme Arrayliste
}
@Override
public List<Produit> produitParCategorie(Long idCat) {
return new ArrayList<Produit>(colProduit.values());//Idem on vertie
la collection prduit et on le retourn coe liste
}
@Override
public List<Produit> produitParMotCles(String mc) {
List<Produit> lproduit = new ArrayList<Produit>();

for(Produit p:colProduit.values()){//faisons la recherche


if(p.getDesignation().contains(mc)){ lproduit.add(p); } }
return lproduit;}
@Override
public Categorie updateCategorie(Categorie c) {
colCategories.put(c.getIdCategorie(), c);
return c;
}
@Override
public List<Produit> listProduits() { return new
ArrayList<Produit>(colProduit.values());}

@Override
public boolean deleteCategorie(Long idCat) {
if(colCategories.get(idCat) != null){
colCategories.remove(idCat); return true; }else
throw new RuntimeException("Aucune clé de cette catégorie n'a
été trouvée dans le hashMap");
}

@Override
public boolean deleteProduit(Long idP) {
if(colProduit.get(idP) != null){
colProduit.remove(idP);
return true;
}else
throw new RuntimeException("Aucune clé de ce
Produit n'a été trouvée dans le hashMap");
}

@Override
public Produit updateProduit(Produit p) {

Msci Student Ruphin NYAMI N.


Page 78
colProduit.put(p.getIdProduit(), p);
return p;
}

@Override
public Categorie getCategorie(Long idCat) {
return colCategories.get(idCat);
}

@Override
public Produit getProduit(Long idP) {
return colProduit.get(idP);
}

public void initialiserCatalogue(){


addCategorie(new Categorie(1L, "Ordinateur",
"ordi.jpg"));
addCategorie(new Categorie(2L, "Imprimentes",
"printer.jpg"));
addCategorie(new Categorie(3L, "Scanner",
"scaner.jpg"));

//les produits maintenant


colProduit.put(1L,addProdui(new Produit(1L, "DELL
OPTIPLEX CEREO", 1200, "ordi1.jpg", getCategorie(1L))));
colProduit.put(2L,addProdui(new Produit(2L, "ASUS PC",
900, "ordi2.jpg", getCategorie(1L))));
colProduit.put(3L,addProdui(new Produit(3L, "Lenovo
NoteBook 65070", 800, "ordi3.jpg", getCategorie(1L))));
colProduit.put(4L,addProdui(new Produit(4L, "HP
PRINTER LASER JET 1010", 500, "primter1.jpg", getCategorie(2L))));
colProduit.put(5L,addProdui(new Produit(5L, "CANON
PIXMA", 1670, "im4.jpg", getCategorie(2L))));
colProduit.put(6L,addProdui(new Produit(6L, "SCAN
7729C", 1200, "SCAN3.jpg", getCategorie(3L))));
}
}

Application
 Créer un service RestFull qui permet de gérer un catalogue de produits appartenant à
des catégories.
 Une catégorie est définie son identifiant, son nom et sa photo
 Un produit, appartenant à une catégorie, est définie par son identifiant, sa désignation,
son prix et sa photo
 Le service devra permettre les opérations suivantes :
- Ajouter une nouvelle catégorie
- Ajouter un nouveau produit
- Consulter toutes les catégories
- Consulter les produits d’une catégories
- Consulter une catégorie
- Consulter un produit
- Consulter les produits dont la désignation contient unt mot clés
- Mettre à jour un produit

Msci Student Ruphin NYAMI N.


Page 79
- Supprimer un produit
L’application Web se compose de deux couches :
- La couche métier
 Les entités Catégorie et Produit
 Une Interface ICatalogueMetier
 Une implémentation de cette interface qui suppose que les produits et les
cétgories sont stockés dans des collections de type HashMap
- La couche service représenté par un service RestFull basé sur Jersey et
Tomcat

Msci Student Ruphin NYAMI N.


Page 80