Master 2 Pro E-Comm
Université de Bourgogne IGA Casablanca Maroc
Responsable Pr J.J. CHABRIER
Cours Java
Plan du cours
„ Pratique de la programmation Java
„ Créer des Objets, types d’objets simples
„ Classes et héritage
„ Interfaces et packages
„ Gestion d’erreurs et d’exceptions, E/S
„ Applets, multithreading
„ Interface homme-machine : awt, swing
„ Exemples de programmes Java
Partie 1
Pratique de la programmation Java (compilation, exécution, etc.)
Compiler et exécuter un
programme Java en mode console
„ Rajouter dans la variable système PATH le chemin vers
„ C:\Program Files\Java\jdk1.5.0_01\bin
„ /usr/local/java/jdk1.5.0_01/bin
„ Compiler une classe Java
„ javac MaClasse.java
„ Exécuter une classe :
„ java MaClasse
„ Tester une applet :
„ appletviewer MonApplet.html
Générer la documentation technique avec javadoc
„ Générer la documentation technique
„ javadoc –d docu *.java
„ Les commentaires /** */ apparaissent dans la documentation. Reconnus si placé immédiatement avant décalaration de classe, interface, champ ou méthode
„ Les commentaires utilisent les balises HTML
„ Les commentaires peuvent contenir des "tag"
„ @author, @see , @param, @return, @version,
@throw
Partie 2
Créer des objets,
types d’objets simples
Créer des objets
Nom de l'objet
Nom de la classe Nom du constructeur
Rectangle rect = new Rectangle(10,20);
Créer une référence d'un
objet de type Rectangle Instancier un objet de type Rectangle
Variables membres et méthodes
„ D'instances :
„ Propres à un objet
„ L'objet doit être instancié
„ Une méthode d'instances accèdeà toutes les variables et méthodes d'instance ou pas
„ "this" a un sens
„ De classe
„ Dites statiques
„ Communes à toute la classe
„ Une méthode de classe accède uniquement aux variables et méthodes de classe
Utiliser les variables membres et les méthodes
„
Accès aux variables et méthodes d'un objet : l'objet doit être instancié
„ rect.aire()
„
Accès aux variables et méthodes statiques d'une objet :
„ NomClasse.nomMethode();
„ Nul besoin d'un objet instancié
Classe Character
„ Type élementaire "char" et classe "Character"
„ Support unicode (16 bits, toutes les langues)
„ Quelques méthodes utiles:
„ Constructeur
„ Character a = new Character('a');
„ Comparaison
„ a.compareTo(b)
„ Conversion vers char
„ charValue()
„ Test si majuscule
„ isUpperCase()
Classe String et StringBuffer
„
String utilisée si chaîne non modifiable StringBuffer si on compte modifier la chaîne
„
Méthodes intéressantes:
„ valueOf(), toString(), split(), substring(), getCharAt(), setCharAt()
Les tableaux
„ Déclaration tableau d'entiers
„ int[] tab = new int[10];
„ tab[3] = 5;
„ Déclaration tableau d'objets
„ MaClasse[] otab = new MaClasse[10];
„ Attention otab[i] est une référence àun objet de type MaClasse. Il faut instancier cet objet avant de l'utiliser. Otab[i] = new MaClasse();
Les tableaux, complément
„ Tableau de tableau
„ int[][] matrice = new int[10][5];
„ Initialiser un tableau
„ String[] jeux = {"Doom","StarTrek","Backgamon"};
„ String[][] films ={{"Terminator","Starwars"},
{"Casablanca","Mari pour ma femme","Anges ne volent pas à Casablanca"}}; //lignes de longueurs variables
„ Récupérer la longueur d'un tableau
„ l = tab.length;// Attention, pas de parenthèse finale
„ films[0].length vaut 2 et films[1].length égal à 3
Partie 3
Classes et héritage
Créer une classe
Déclarer une classe
Public abstract final class MaClasseextends ClasseMere implements Interface1, Interface2
{
} // corps de la classe
Public : classe accessible par toutes les classes Abstract : classe ne peut être instanciée
Final : classe ne peut avoir des classes filles Extends : indique la classe mère
Implements : spécifie les interfaces implémentées Seul mot-clef obilgatoire : class
Déclarer une variable membre
Public Private
Protectedstatic final transcient volatile type nom = initialisation;
Public : accessible par tout le monde
Private : accessible àl’intérieur de la classe Protected : accessible par les classes filles Static : variable de classe
Final : constante non modifiable
Transcient : utilisé pour la sérialisation d’objets Volatile : peutêtre modifiée par un autre processus Une variable qui n’est ni public, ni private ni protected
Est accessible pour le package et pour la classe où elle est définie
Protée d’une variable
Public class MaClasse{ public int a;
protected b;
private int c;
Visible partout
Visibleàl’intérieur de la classe et pour les classes filles
public MaClasse (int a, int b,int c){ this.a = a;
this.b = b;
Visibleàl’intérieur de la classe
} super.c c; Paramètres du même nom que des variables membres et cachent celles-ci.
void uneMethode { double d;
Visibleàl’intérieur de la méthode et détruite après la fin d’exécution de la fonction
} } this : Référence prédéfinie vers l’objet courant super : référence vers la classe mère
Déclaration d’une méthode
On peut déclarer plusieurs méthodes avec le même nom mais des paramètres différents.
Méthodes et classes abstractes
„ Méthode abstraite : prototype défini mais pas le corps de la méthode.
„ Classe abstraite : au moins une méthode est abstraite.
„ On ne peut pas instancier une classe abstraite.
„ Une sous-classe doit définir toutes les
méthodes abstraites de sa classe mère, sinon elle doit être également abstraite.
Méthodes et classes finales
„
Classe finale : ne peut être sous- classée.
„
Méthode finale :ne peut être redéfinie dans une classe fille.
„
Variable membre finale : constante.
Partie 4
Interfaces et packages
Une interface c'est quoi ?
„ Définition : une classe où toutes les méthodes sont abstraites.
„ Une interface peut définir des constantes (final).
„ Une interface est un contrat que toute classe qui l'implémente doit remplir.
„ Attention une interface ne peut changer sans remettre en cause toutes les classes qui
l'implémentent.
„ Une classe peut implémenter plusieurs interfaces.
Différence interface/classe abstraite
„ Une interface ne peut implémenter de méthode. Une classe abstraite peut le faire.
„ Une classe peut implémenter plusieurs interfaces mais a une seule classe mère.
„ Une interface n'est pas liée à une hiérarchie de classes. Plusieurs classes indépendantes peuvent implémenter la m me interface.
Déclaration et usage
public MonApplet extends Appletimplements ActionListener {
… }
Nom de l'interface implémentée
Un package c'est quoi ?
„
Un package est un ensemble de classes remplissant des fonctions similaires et fournissant un espace de nommage propre.
„
Toutes les classes ou interfaces appartenant à un même package commencent par la déclaration
„ package nom_package;
Nommer un package
„ Deux classes ayant le même nom et se trouvant dans des packages différents ne posent pas de problème.
„ Pour garantir l'unicité de nommage des packages on utilise le nom de domaines inversé :
„ ma.iga.monpackage
„ Attention la structure des répertoires doit correspondre au nom du package
„ ma/iga/monpackage/
Usage des classes définies dans les packages
„ Référence totale:
„ nompackage.NomClasse obj;
„ Clause import, 2 manières:
„ Importer uniquement la classe :
„ import monpackage.NomClasse; NomClasse obj;
„ Importer tout le package :
„ import monpackage.*; NomClasse obj ;
„ Les packages et les classes sont recherchés soit dans le répertoire courant soit dans les répertoires et fichiers zip cités dans la variable CLASSPATH
Partie 5
Gestion d’erreurs et d’exceptions, Entrées/Sorties
Définitions
„ On appelle "exception" un événement qui a lieu dans un programme perturbant son bon fonctionnement
„ Les exceptions sont le lot quotidien des programmeurs. On doit les gérer.
„ Exemple : pb réseau, E/S
„ On réserve le mot "error" aux erreurs graves plus profondes au niveau du système
provoquant l'arrêt du programme
Obligation de gérer certaines exceptions potentielles
Un problème/ …
InputFile.java:11: Exception java.io.FileNotFoundException must be caught, or it must be declared in the throws clause of this method.
in = new FileReader(filename);
^
Try {
… et sa solution:
…
} catch (FileNotFoundException e) {
System.out.println("Erreur : " + e);
}
Intérêt d'utiliser des exceptions
„
Séparation code de gestion d'erreur du code "normal"
„
Propagation de l'exception à travers la pile d'appel
„
Grouper la gestion d'erreurs par type.
Séparation code normal/exception
Try {
// ici le code "normal"
} catch (FileNotFoundException e) {
// et là le traitement exceptionnel }
Propagation d'erreur à travers la pile
method1 { try {
call method2;
} catch (exception) { doErrorProcessing;
Gère l'exception
} }
method2 throws exception { call method3;
}
method3 throws exception { call readFile;
}
Propage l'exception l'exception mais ne la gère pas
Provoque l'exception mais ne la gère pas
Grouper les erreurs par type
Try {
// ici le code à surveiller
} catch (InvalidIndexException e) { // traiter index hors plage
} catch (ArrayException e) {
// ici un traitement plus général
} catch (Exception e) {
// traitement le plus général }
Block finally
Le bloc finally est exécutédans tous les cas même si l'erreur n'a pas eu lieu :
public void writeList() { PrintWriter out = null;
try {
System.out.println("Entering try statement");
out = new PrintWriter(new FileWriter("OutFile.txt"));
for (int i = 0; i < size; i++)
out.println("Value at: " + i + " = " + victor.elementAt(i));
} catch (ArrayIndexOutOfBoundsException e) {
System.err.println("Caught ArrayIndexOutOfBoundsException: " + e.getMessage());
•Utile pour traitement de nettoyage avant de passer la main
} catch (IOException e) {
System.err.println("Caught IOException: " + e.getMessage());
} finally { if (out != null) {
System.out.println("Closing PrintWriter");
out.close();
} else {
System.out.println("PrintWriter not open");
•Evite les répétitions de code
} } }
Propager / provoquer une exception
Propager : throws
public Object pop() throws EmptyStackException { Object obj;
Provoquer : throw
if (size == 0)
throw new EmptyStackException();
}
obj = objectAt(size - 1);
setObjectAt(size - 1, null);
size--;
return obj;
On peut définir sa propre classe d'exception Àcondition qu'elle hérite de Throwable ou de l'une de ses filles
La hiérarchie d'exceptions
Provoquées par la JVM
Provoqués par les erreurs profondes du système
Seule classeà"subclasser"
par le programmeur
Les entrées/sortie
Lecture Ouvrir un stream
Tant que encore information lire information
Fin tan que Fermer stream
Ecriture Ouvrir un stream
Tant que encore information écrire information Fin tan que Fermer stream
"Character" streams : L/E de
caractères Unicode
"Byte streams" : L/E de fichiers binaires quelconques.
Utilisation des fichiers
import java.io.*;
public class Copy {
public static void main(String[] args) throws IOException { File inputFile = new File("farrago.txt");
File outputFile = new File("outagain.txt");
FileReader in = new FileReader(inputFile);
FileWriter out = new FileWriter(outputFile);
int c;
while ((c = in.read()) != -1) out.write(c);
} }
in.close();
out.close();
Aperçu sur JDBC
import java.sql.*;
import java.util.*;
class Bdd {
public static void main(String[] ch) { try {
Connection con = DriverManager.getConnection( "jdbc:odbc:undsn");
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM valeurs ");
while (rs.next()) {
int x = rs.getInt("code");
String s = rs.getString("valeur");
System.out.println("code=" + x + " valeur=" + s);
} // while
} catch (SQLException e){
System.out.println("pb jdbc " + e);
} } // main } // Bdd
Partie 6
Applets, multithreading
Créer une applet
import java.applet.Applet;
import java.awt.Graphics;
public class MonApplet extends Applet { StringBuffer s;
public void paint(Graphics g) { g.drawString(s.toString(),10,10); } public void init () { s.append("initialisation…"); repaint();}
public void start () { s.append("démarrer…"); repaint();}
public void stop () { s.append("arrêter…"); repaint();}
Public boolean mouseDown(Event e, int x, int y) { s.append("click("+x,","+y+")…");
} }
<html><body>
<applet code="MonApplet.class" width=300 height=200>
</applet></body></html>
Ce qu'une Applet ne peut pas faire
„ Charger une librairie ou définir des méthodes native
„ Lire ou écrire des fichiers ordinaires dans l'ordinateur qui l'exécute
„ Etablir des connexions réseaux sauf vers le serveur d'où elle a été chargée
„ Démarrer un programme sur la machine qui l'exécute.
„ Lire certaines proriétés du système
„ Les fenêtres crées par une applet ont un look différent des autres
Interaction Applet/Navigateur
„
Afficher un message dans la barre de status du navigateur
„ showStatus("ceci est un message");
„
Fonction
„ AppletContext getAppletContext()
Méthodes de AppletContext
„
Afficher un document dans le navigateur
„ public void showDocument(java.net.URLurl) public void showDocument(java.net.URLurl, String targetWindow)
„ targetWindow : "_blank", "nom-fenetre", "_parent", "_top"
„
Récupérer une référence d'une autre applet
„ Applet getApplet(String nom-applet);
„ Le nom de l'applet est celui désigné dans la balise html <applet code="…" name="…">
Autres interactions Applet/Environnement
„ Jouer des fichier multimédia
„ AudioClip getAudioClip(URL url);
„ Récupérer une image
„ Image getImage(URL url);
„ Spécifier des paramètres HTML
„ <applet code="MaClasse.class">
„ <Param name="LARGEUR" value="10">
„ </applet>
„ Récupérer un paramètre HTML
„ String getParameter(String nom-parametre);
Multi-threading
• Un thread est un sous-processus s'exécutant en parallèle avec d'autres threads
• Permet le traitement en arrière plan des traitements longs ou coûteux en temps machine
• Attention aux accès concurrents
• Peutêtre implémentéde deux façons:
• En subclassant la classe Thread
• En implémentant l'interface runnable
"Subclasser" la classe Thread
public class UneTache extends Thread { public UneTache(String nom) {
super(nom);
}
public void run() {
for(int i=0; i<10; i++)
System.out.println(this.getName() + " : i=" + i);
}
}
public class Principal {
public static void main(String[] s) {
UneTache t1 = new UneTache("tâche t1");
UneTache t2 = new UneTache("tâche t2");
}
}
t1.start();
t2.start();
Implémenter l'interface Runnable
public class Tache implements Runnable{
public void go (String nom) {
Thread t = new Thread (this,nom);
t.start();
}
public void run() {
for(int i=0; i<10; i++)
System.out.println(Thread.currentThread().getName() +
" : i=" + i);
}
}
public class Multitaches {
static Tache t = new Tache();
public static void main(String[] s) { t.go("tache t1");
t.go("tache t2");
}
}
Multithreading dans une applet
import java.applet.Applet;
import java.awt.*;
Import java.event.*;
public class Animation extends Applet implements Runnable{
private Thread t;
private int offset = 0;
private int n=0;
public void start() {
t = new Thread(this);
t.start();
}
public void stop() { t=null;
}
Multithreading applet (suite)
public void run() {
String msg = new String("thread " + ++n + " démarré!");
showStatus(msg);
System.out.println(msg);
while(t == Thread.currentThread()) { try{
int large = Integer.parseInt(getParameter("LARGEUR"));
offset = (offset + 5) % large;
Thread.sleep(100);
repaint();
} catch (InterruptedException e) { } catch (NumberFormatException e) { }
}
}
public void paint(Graphics g) { Rectangle rect = getBounds();
g.clearRect(rect.x,rect.y,rect.width,rect.height);
g.drawString("Salamou alykoum ,alykoum salam !",offset,10);
}
} // class Animation
Multi-threading : attention aux conflits si mise à jour concurrente
class Banque {
public static void main(String[] s) { Compte cmpt = new Compte();
Virement vir = new Virement(cmpt);
Cheque chq = new Cheque(cmpt);
System.out.println("Solde initial = " + cmpt.getSolde());
vir.start();
try{
Thread.sleep(3000);
} catch (InterruptedException e) { }
chq.start();
while(cmpt.nThread < 2 );
System.out.println("Solde final = " + cmpt.getSolde());
} }
•On crée un compte
•On crée un objet virement et un objet Cheque qui, tous les deux, vont mettreàjour le compte crée
•On introduit un délai d'attente de 3 secondes pour s'assurer que les deux threads Virement et Cheque se déroulent l'un après l'autre
•Si on supprime ce délai de 3 secondes les deux threads seront en concurrence.
Conflits des threads (suite)
class Compte {
private int solde = 0;
public int nThread = 0;
public synchronized void crediter(String nom, int montant) { int val = 0;
val = solde;
val += montant;
try {
Thread.sleep(100);
} catch (InterruptedException e) { }
solde = val;
System.out.println(nom + " : " + solde);
}
}
public int getSolde() { return solde;}
•Le compte crée l'est avec un solde initial nul
•La classe Compte offre la méthode "créditer"
•Le passage par une variable locale et le délai de 0,1s ont pour but
Conflits des threads (suite)
class Virement extends Thread { private Compte cmpt;
public Virement(Compte cmpt) { super("virement");
this.cmpt = cmpt;
}
public void run() {
System.out.println("virement, solde trouvé = " + cmpt.getSolde());
for(int i=0; i<10; i++) cmpt.crediter("virement",100);
cmpt.nThread++;
Aussi bien le thread Cheque que Virement vont créditer le compte de 10 fois 100 DH, }
}
class Cheque extends Thread { private Compte cmpt;
public Cheque(Compte cmpt) { super("cheque");
this.cmpt = cmpt;
soit chaque thread rajoute 1000 DH au solde du compte }
public void run() {
System.out.println("cheque, solde trouvé = " + cmpt.getSolde());
for(int i=0; i<10; i++) cmpt.crediter("virement",100);
cmpt.nThread++;
} }
Conflits des threads, un problème et sa solution
„ Si les deux threads Cheque et Virement s'exécutent l'un après l'autre
„ Solde final : résultat correct : 2000 DH
„ Si les deux threads s'exécutent simultanéments
„ Solde final : résultat erroné :1200 DH ou 1100 DH.
Certaines transactions sont perdues.
„ Solution : synchroniser les deux processus en créant une "section critique"
public synchronized void crediter(String nom, int montant) { au lieu de :
public void crediter(String nom, int montant) {
Partie 7
Interface homme-machine : awt et swing
awt versus JFC/Swing
„ awt plus ancien donc plus supporté par les navigateurs web
„ JFC : Java Foundation Class, Swing : nom de code de la librairie
„ JFC/Swing plus performant et plus riche
„ Préférer awt pour des applications internet et swing pour l'intranet
„ Packages correspondants
„ import java.awt.*;
„ import javax.swing.*;
Awt : créer une fenêtre simple avec quelques widgets
import java.awt.*;
class Appli {
public static void main(String[] ch) { Frame fen = new Frame();
fen.setBounds(10,10,400,300);
Label libel1 = new Label("Nom :");
Label libel2 = new Label("Prénom :");
TextField nom = new TextField();
TextField prenom = new TextField();
Button valid = new Button("Valider");
Button quit = new Button("Quitter");
fen.setLayout(new FlowLayout());
fen.add(libel1);
fen.add(nom);
fen.add(libel2);
fen.add(prenom);
fen.add(valid);
fen.add(quit);
fen.setVisible(true);
Déclarer une fenêtre et spécifier sa position et ses dimensions
(x,y,largeur,hauteur)
x y
Déclarer les widgets (éléments de l'interface graphiques) qui vont être insérés dans la fenêtre
Choisir le type de positionnement des widgets dans la fenêtre
Insérer les widgets dans la fenêtre
} }
Rendre la fenêtre visible
Traiter l'événement click de souris avec awt
import java.awt.*;
import java.awt.event.*;
import java.util.*;
Classe Ecouteur implémente l'interface ActionListener
(écoute des boutons) class Ecouteur extends Appli2 implements ActionListener,WindowListener {
public void actionPerformed(ActionEvent e) { if(e.getActionCommand().equals("Quitter")){
System.exit(0);
}
} else if(e.getActionCommand().equals("Valider")){
// traitement bouton valider }
Classe Ecouteur implémente l'interface WindowListener
(fermeture de fenêtre)
public void windowClosing(WindowEvent e) { if(e.getWindow() instanceof Dialog) {
e.getWindow().dispose();
}
} else { }
System.exit(0);
public void windowDeactivated(WindowEvent e) {}
public void windowActivated(WindowEvent e) {}
public void windowClosed(WindowEvent e) {}
public void windowOpened(WindowEvent e) {}
public void windowIconified(WindowEvent e) {}
public void windowDeiconified(WindowEvent e) {}
}
Ecouteur ecoute = new Ecouteur();
valid.addActionListener(ecoute);
quit.addActionListener(ecoute);
fen.addWindowListener(ecoute);
Divers types de "Layout"
„ Un "layout" est la manière dont les objets sont diposésàl'intérieur d'un conteneur (fenêtre, boite de dialogue, etc.)
„ Si non utilisé, on positionne manuellement les widgetsàl'aide de setBounds (x,y,largeur,hauteur)
„ Quelques "layout" classiques
„ FlowLayout() : les widgets sont mis les unsàla suite des autres selon leurs tailles et celles du conteneur
„ GridLayout(lignes,colonnes) : widgets disposés sous formes de lignes et colonnes.
„ BorderLayout() : attacher un widgetàun bord (NORTH, SOUTH, EAST, WEST) ou au centre (CENTER), utile pour "coller" une zoneàun bord même quand la fenêtre est redimensionnée.
„ Layout par défaut pour divers types de conteneurs :
„ Frame (BorderLayout), Dialog (BorderLayout), Applet(celui de Panelà savoir FlowLayout), Window (BorderLayout)
Quelques widgets disponibles pour awt
„ Button : bouton
„ Canvas: zone de dessin dans un écran
„ CheckBox: cases àcocher
„ Dialog: boite de dialogue
„ FileDialog: boite pour sélectionner un fichier
„ Frame : fenêtre avec cadre
„ Image: zone pour afficher une image gif, jpeg, etc.
„ Label: libellé
„ List: choix dans une liste
„ MenuBar et Menu: pou créer un menu
„ Panel : un conteneur simple pouvant contenir d'autres composants ou d'autres panels.
„ TextArea et TextField: zones de texte.
„ Window: fenêtre sans bordure ni menu
Quelques widgets disponibles pour swing
„ Japplet
„ JButton
„ JCheckBox
„ JDialog
„
JFileChooser
„ Jframe
„ Jlabel
„ Jlist
„ JMenuBar
„ JMenu
„ JPanel
„
JPasswordField
„ Jtable
„ TextArea
„ TextField
„ JToolBar
„ Jtree
„ Jwindow
„ Timer
Exemples de programmes Java fournis en annexe (1/3)
„ Affichage: classe permettant de multiplier deux matrices et d'afficher le résultat dans une fenêtre graphique
„ Animation: Applet d'animation d'un texte en le faisant défilerà l'écran
„ Appli: Exemple d'affichage d'une fenêtre sans traitement d'événements
„ Appli2: Exemple d'affichage d'une fenêtre avec quelques widgets en utilisant awt
„ Banque: Classe pour tester les conflits d'accès de deux threads concurrents
„ Bdd: exemple simple d'utilisation de JDBC
„ Cheque: thread concurent avec le thread Virement
„ Compte:Exemple utilisépour le test des threads concurrents
„ Essai2: classe utilisant JFC/Swing
Exemples de programmes Java fournis en annexe (2/3)
„ Exemple: test du traitement d'une exception
„ Frm2Awt: classe pour transformer unécran défini avec VB (.frm) en une classe Java. On doit préciser le nom du fichier .frm en paramètre de la ligne de commande
„ Matrice: Exemple de calcul matriciel avec affichage graphique des matrices
„ MonApplet: Exemple d'applets avec gestion desévénements bouton et fermeture fenêtre
„ MonApplet2 :Une Applet utilisant une sous-fenêtre avec bouton plus un calcul de date
„ MonGregorien :Analyse d'une chaîne date pour la transformer en type Calendrier Grégorien
„ Multitaches :Programme de test de processus multi-tâches
„ Principal :Programme de test de multithreading
Exemples de programmes Java fournis en annexe (3/3)
„ Exemple :multi-threading utilisant l'interface Runnable
„ UneMatrice :Classe matrice, saisie, affichage et multiplication de matrices
„ UneTache :multi-threading en utilisant l'extension de la classe Thread
„ Vb2Java :classe (inachevée) en vue de restrusturer Frm2Awt en packages avec interface et classes spécialisées par type de contrôle àconvertir
„ Virement : Thread concurrent du thread Cheque
Annexes
„
Codes sources de toutes les classes citées dans les exemples précédents
„