Exercices simples sur les bases 
procédurales de Java – Solutions 
Solution de l’ex. 1 Conversion euros/franc 
Une solutio...
// On affiche la moyenne 
System.out.println("Moyenne : " + somme/(double)nbElts); 
} 
} 
Solution de l’ex. 3 Menu d’opéra...
sur les bases procédurales de Java – Solutions 
Solution de l’ex. 1 Table de multiplication 
Une solution possible est la ...
for(int i = 0; i < n; i++) { 
for(int j = 0; j <= i; j++) { 
System.out.print("*"); 
} 
System.out.println(""); 
} 
System...
/** 
* Classe polynomiale du 1er degre 
**/ 
class PolyLineaire { 
int a, b; // champs : coefficients de a*x + b 
// Const...
int a = Integer.parseInt(args[0]); 
int b = Integer.parseInt(args[1]); 
int x = Integer.parseInt(args[2]); 
// Creation d’...
} 
// methode 
int evaluer(int x) { 
return(a*x + b); 
} 
int evaluerCarre(int x) { 
int axPlusb = evaluer(x); 
28 Exercic...
void sort(InputOutputIntArray array) 
{ 
int[] a = array.getArray(); 
for (int i = a.length; --i >= 0; ) 
{ 
boolean swapp...
} catch(IOException e) { // Message d’erreur 
System.out.println("Entree invalide"); 
i--; 
} 
}// for() 
} 
void outputSc...
public class GraphApplet extends java.applet.Applet { 
double f(double x) { 
return (Math.cos(x/5) + Math.sin(x/7) + 2) * ...
} 
void dessinePiquet() { 
System.out.print(m_Name + " : "); 
for(int i = 0; i < m_nDiscs; i++) 
System.out.print(Anneaux[...
public static void main(String args[]) 
{ 
int nbDisques; 
if (args.length == 0) 
nbDisques = 3; 
else 
try { 
nbDisques =...
int ordre = sc.nextInt(); 
double coeffs[] = new double[ordre+1]; 
for(int i = 0; i < ordre+1; i++) { 
System.out.print("V...
} 
System.out.println("-1 (indice non trouve)"); 
return; 
} 
public static void main(String[] args) { 
Scanner sc = new S...
} 
public class PersonnelMain { 
public static void main(String[] args) { 
Personnel p1 = new Personnel(1, 12, 53432); 
Pe...
protected double partieReelle; 
protected double partieImaginaire; 
/* 
* Constructeurs 
*/ 
Complexe(double r, double i) ...
nbElts = n; 
tab = new int[nbElts][nbElts]; 
} 
public void afficher() { 
for (int i = 0; i < nbElts; i++) { 
for (int j =...
public void afficher() { 
for (int i = 0; i < nbElts; i++) { 
for (int j = 0; j < nbElts; j++) { 
tab[i][j].afficherSansCR...
étudiants – Solutions 
Solution de l’ex. 1 Classe Personne (constructeurs) 
Réponse à la question 1 
Classe PersonneMain1 ...
sage.diviserParDeux(); 
// Appel de la methode afficher 
sage.afficher(); System.out.println(""); 
sageBis.afficher(); Sys...
} 
} 
class Personne3 { 
String nom; 
int age; 
// Constructeur exhaustif 
Personne3(String leNom, int lAge) { 
nom = new ...
int noteMoyenne; 
boolean faineant; 
Etudiant3(String leNom, int lAge, 
int note, boolean poilAlaMain) { 
super(leNom, lAg...
System.out.println("Age : " + age); 
} 
void afficher(boolean compact) { 
if (compact == false) 
afficher(); 
else { 
Syst...
tabPers[i].afficher(true); // Affichage compact 
} 
} 
} 
Solution de l’ex. 4 Délégation d’affichage (Classes 
abstraites)...
public static void main(String[] args) { 
Personne6[] tabPers = new Personne6[5]; 
tabPers[0] = new Enseignant6("Nimbus", ...
nbComplexes--; 
} 
public Complexe1 multiplier(Complexe1 z) { 
double re = 0, im = 0; 
re = this.partieReelle * z.partieRe...
/* 
* Champs de la classe 
*/ 
protected double partieReelle; 
protected double partieImaginaire; 
/* 
* Constructeurs 
*/...
this(0, null); 
} 
for(int i = 0; i < tab.size(); i++) { 
System.out.println("tab[" + i + "]" + tab.get(i)); 
} 
Complexe ...
for (int i = index; i < nouvNbElts; i++) 
nouvDonnees[i] = get(i+1); 
Tableau nouvTableau = new Tableau(nouvNbElts, nouvDo...
} 
} 
Extrait de la classe ArrayList 
Pour comparaison, voici un extrait de la classe ArrayList du paquetage java.util 
(n...
public int size() { 
return size; 
} 
public boolean isEmpty() { 
return size == 0; 
} 
public boolean contains(Object ele...
public void add(int index, Object element) { 
if (index > size || index < 0) 
throw new IndexOutOfBoundsException( 
"Index...
tableaux, il aurait fallu également réaliser la copie profonde de ces derniers. 
Classe ObjetClonable, comportant la métho...
l’usage, cette méthode est censée réaliser une copie profonde de ses objets (par 
opposition à 
une copie superficielle, q...
}// fin de classe TableauClonable 
Interface TailleVariableClonable 
//Elle spécifie les méthodes add() et remove(). Notez...
Classe TableauComplexeDynClonable 
//Un tableau dynamique de ComplexeClonable. 
class TableauComplexeDynClonable extends 
...
System.out.println("Tab : " + t); 
} 
} 
Gestion locale de banque simple en 
Java – Solutions 
Solution de l’ex. 1 Gestion...
System.exit(1); 
} 
// Cercher une case libre pour le nouveau compte 
for (i = 0; i < allAccounts.length; i++) 
if (allAcc...
return balance; 
} 
/** Deposer le montant specifie su le compte dont on donne 
le nom */ 
public void deposit(String name...
BufferedReader stdin = new BufferedReader(new 
InputStreamReader(System.in)); 
String cmd = "nothing"; 
while(true) { 
Sys...
break; 
} 
else System.out.println("Action inconnue"); 
} 
}// while not quitted 
// Autres exceptions, erreurs de syntaxe...
while(true) { 
System.out.println("nVeuillez entrer une commande : n" + 
"open (ouverture de compte)n" + 
"close (cloture ...
String name = getName(stdin); String password = 
getPassword(stdin); 
ArrayList transactions = bank.getTransactionHistory(...
/** 
* Ouvre un compte avec le nom et le mot de passe specifie 
* Cette methode est synchronisee de facon qu’une seule 
th...
} 
/** Deposer le montant specifie su le compte dont on donne 
le nom */ 
public void deposit(String name, String password...
Classe FunnyMoney 
// Gestion simpliste de banque en local 
/** 
* Cette classe simple represente un montant monetaire. N’...
//Construct the application 
public SommeGraphiqueMain() { 
FrameSommeGraphique frame = new FrameSommeGraphique(); 
//Vali...
* use. If Jigloo is being used commercially (ie, by a 
corporation, 
* company or business for any purpose whatever) then ...
jDesktopPaneSomme.add(jLabelResultats); 
jLabelResultats.setText("Resultats"); 
jLabelResultats.setBounds(277, 6, 79, 30);...
}); 
} 
{ 
jButtonSommer = new JButton(); 
jDesktopPaneSomme.add(jButtonSommer); 
jButtonSommer.setText("Sommer"); 
jButto...
graphiques pour application bancaire – Solutions 
Solution de l’ex. 1 Conception d’une interface pour 
application bancair...
jMenuGUIBanque = new JMenuBar(); 
setJMenuBar(jMenuGUIBanque); 
jMenuGUIBanque.setPreferredSize(new java.awt.Dimension(390...
Classe GUIBankLocalServer 
import java.util.*; 
/** 
* Classe conteneur. Contient : 
* - FunnyMoney la monnaie utilisee 
*...
// Et l’enregsitrer 
accounts.put(name, acct); 
} 
/** 
* Cette methode utilitaire n’est pas une methode accessible 
de ma...
public FunnyMoney withdraw(String name, String password, 
FunnyMoney money) 
throws GUIBankingException { 
int amount = mo...
import javax.swing.JPanel; 
import java.awt.BorderLayout; 
import java.awt.event.ActionListener; 
import java.awt.event.Ac...
jPanelNomMotPasseDialog.setPreferredSize(new 
java.awt.Dimension(315, 200)); 
{ 
jLabelStrNom = new JLabel(); 
jPanelNomMo...
final java.awt.Component parent, 
final javax.swing.JPopupMenu menu) { 
parent.addMouseListener(new java.awt.event.MouseAd...
import java.awt.BorderLayout; 
import java.awt.event.ActionListener; 
import java.awt.event.ActionEvent; 
public class Ban...
final javax.swing.JPopupMenu menu) { 
parent.addMouseListener(new java.awt.event.MouseAdapter() { 
public void mousePresse...
{ 
// construct an instance of a thread and use the run method 
// from "this" applet 
runner = new Thread(this); 
runner....
int loopslot = 0; 
String dir; // Rep ou URL des images 
Thread kicker = null; // Activite animatrice 
int pause; // pause...
Solution de l’ex. 3 Une horloge avec affichage graphique 
import java.awt.*; 
import java.applet.*; 
import java.util.Date...
} 
} 
Exercices sur les threads autour 
d’une balle – Solutions 
Solution de l’ex. 1 Une balle rebondissante (utilisation ...
// 
public void setXY(int nPosX, int nPosY) { x = nPosX; y = 
nPosY; } 
public void setSize(int newSize) { size = newSize;...
/* 
* Initialisation de l’applet 
*/ 
public void init() { 
animationThread = new Thread(this, "Animation de balle"); 
the...
/* 
* Boucler indefiniment en appelant animer(), puis en se 
reposant 
*/ 
public void run() { 
while (true) { 
repaint();...
Corrige tp java
Corrige tp java
Corrige tp java
Corrige tp java
Corrige tp java
Corrige tp java
Corrige tp java
Corrige tp java
Corrige tp java
Corrige tp java
Corrige tp java
Corrige tp java
Corrige tp java
Corrige tp java
Corrige tp java
Corrige tp java
Corrige tp java
Corrige tp java
Corrige tp java
Corrige tp java
Corrige tp java
Corrige tp java
Corrige tp java
Corrige tp java
Corrige tp java
Corrige tp java
Corrige tp java
Corrige tp java
Corrige tp java
Corrige tp java
Corrige tp java
Corrige tp java
Corrige tp java
Corrige tp java
Corrige tp java
Prochain SlideShare
Chargement dans…5
×

Corrige tp java

6 867 vues

Publié le

cours java et tp

Publié dans : Logiciels
0 commentaire
3 j’aime
Statistiques
Remarques
  • Soyez le premier à commenter

Aucun téléchargement
Vues
Nombre de vues
6 867
Sur SlideShare
0
Issues des intégrations
0
Intégrations
4
Actions
Partages
0
Téléchargements
412
Commentaires
0
J’aime
3
Intégrations 0
Aucune incorporation

Aucune remarque pour cette diapositive

Corrige tp java

  1. 1. Exercices simples sur les bases procédurales de Java – Solutions Solution de l’ex. 1 Conversion euros/franc Une solution possible est la suivante : import java.util.*; public class ConversionMain { public static void main(String[] args) { // Objet Scanner pour les entrees clavier Scanner sc = new Scanner(System.in); // Requete faite a l’utilisateur System.out.print("Veuillez entrer un montant : "); // L’utilisateur entre un montant double x = sc.nextDouble(); // On affiche le resultat de la conversion System.out.println("Somme convertie en francs : " + x * 6.55957); } } Solution de l’ex. 2 Moyenne d’un tableau Une solution possible est la suivante : import java.util.*; public class MoyenneMain { public static void main(String[] args) { // Objet Scanner pour les entrees clavier Scanner sc = new Scanner(System.in); // Requete faite a l’utilisateur System.out.print("Veuillez entrer un nbre d’elts : "); // L’utilisateur entre une taille int nbElts = sc.nextInt(); // On cree un tableau double tab[] = new double[nbElts]; // Entree des valeurs du tableau for(int i = 0; i < nbElts; i++) { System.out.print("Veuillez entrer l’elt no " + i + " : "); tab[i] = sc.nextDouble(); } 14 Exercices de travaux pratiques Java // On calcule la somme des elts du tableau int somme = 0; for(int i = 0; i < nbElts; i++) { somme += tab[i]; }
  2. 2. // On affiche la moyenne System.out.println("Moyenne : " + somme/(double)nbElts); } } Solution de l’ex. 3 Menu d’opérations arithmétiques Une solution possible est la suivante : import java.util.*; public class ArithmetiqueMain { public static void main(String[] args) { // Objet Scanner pour les entrees clavier Scanner sc = new Scanner(System.in); // Menu utilisateur System.out.print("1 Somme de deux réelsn" + "2 Soustraction de deux réelsn" + "3 Multiplication de deux réelsn" + "4 Division de deux réelsn" + "5 Sortie du programmenn" + "Veuillez entrer votre choix : "); // L’utilisateur entre un choix int choix = sc.nextInt(); // Puis les deux reels System.out.print("Veuillez entrer le 1er réel : "); double x = sc.nextDouble(); System.out.print("Veuillez entrer le 2e réel : "); double y = sc.nextDouble(); // Realisation de l’operation double res = 0; switch(choix) { case 1 : res = x + y; break; case 2 : res = x - y; break; case 3 : res = x * y; break; case 4 : res = x / y; break; case 5 : System.exit(0); default : System.out.println("Choix incorrect"); System.exit(1); } // On affiche le resultat System.out.println("Resultat : " + res); } } Exercices simples supplémentaires
  3. 3. sur les bases procédurales de Java – Solutions Solution de l’ex. 1 Table de multiplication Une solution possible est la suivante : import java.util.*; public class TabMultMain { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.print("Veuillez entrer un entier : "); int n = sc.nextInt(); for(int i = 0; i < 10; i++) { System.out.print(n*i + " "); } System.out.println(""); } } Solution de l’ex. 2 Décomposition en base dix Une solution possible est la suivante : import java.util.Scanner; public class BaseDixMain { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = 1000; while (n < -999 || n > 999) { System.out.print("Veuillez entrer un entier à 3 chiffres n = sc.nextInt(); if (n < -999 || n > 999) continue; int c = n / 100; int d = (n - 100 * c) / 10; int u = n - 100 * c - 10 * d; System.out.print(c + "*10^2 + " + d + "*10 + " + u); } System.out.println(""); } } Solution de l’ex. 3 Etoiles Une solution possible est la suivante : import java.util.Scanner; public class EtoilesMain { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.print("Veuillez entrer un entier : "); int n = sc.nextInt();
  4. 4. for(int i = 0; i < n; i++) { for(int j = 0; j <= i; j++) { System.out.print("*"); } System.out.println(""); } System.out.println(""); } } Solution de l’ex. 4 Opérations élémentaires Une solution possible est la suivante : import java.util.Scanner; public class OperElemMain { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.print("Veuillez entrer un réel : "); double x = sc.nextDouble(); System.out.print("nVeuillez entrer un entier : "); int n = sc.nextInt(); System.out.println(x + "^2 = " + carre(x)); System.out.println(x + "^" + n + " = " + puissance(x, n)); System.out.println(n + "! = " + fact(n)); } public static double carre(double x) { return (x * x); } 20 Exercices de travaux pratiques Java public static double puissance(double x, int n) { double res = 1; for (int i = 0; i < n; i++) { res *= x; } return res; } public static int fact(int n) { if (n == 1) return 1; int res = n * fact(n - 1); return res; } } Exercices sur les bases procédurales de Java – Solutions Solution de l’ex. 1 Évaluation polynômiale simple Réponse à la première question import java.util.Scanner;
  5. 5. /** * Classe polynomiale du 1er degre **/ class PolyLineaire { int a, b; // champs : coefficients de a*x + b // Constructeur : initialisation des champs PolyLineaire(int a, int b) { this.a = a; this.b = b; } // methode int evaluer(int x) { return(a*x + b); } int evaluerCarre(int x) { int axPlusb = evaluer(x); return(axPlusb*axPlusb); } } /** * Ce programme affiche les carres au fur et a mesure que * l’utilisateur entre des valeurs de maniere interactive **/ public class PolyLineaireMainUn { public static void main(String[] args) { System.out.println("Veuillez entrer a, b et x"); // Creation d’un objet pour les entrees clavier Scanner entClav = new Scanner(System.in); // recuperation des arguments au format entier int a = entClav.nextInt(); int b = entClav.nextInt(); 26 Exercices de travaux pratiques Java int x = entClav.nextInt(); // Creation d’un objet de type PolyLineaire PolyLineaire p = new PolyLineaire(a, b); // Calcul et affichage du resultat System.out.println("(" + a + "*" + x + "+" + b + ")^2 = " + p.evaluerCarre(x)); } } Réponse à la deuxième question /** * Ce programme affiche les carres au fur et a mesure que * l’utilisateur entre des valeurs de maniere interactive **/ public class PolyLineaireMainDeux { public static void main(String[] args) { // test du nombre d’arguments if (args.length != 3) { System.out.println("Mauvais nombre d’arguments"); System.exit(1); } // recuperation des arguments au format entier
  6. 6. int a = Integer.parseInt(args[0]); int b = Integer.parseInt(args[1]); int x = Integer.parseInt(args[2]); // Creation d’un objet de type PolyLineaire PolyLineaire p = new PolyLineaire(a, b); // Calcul et affichage du resultat System.out.println("(" + a + "*" + x + "+" + b + ")^2 = " + p.evaluerCarre(x)); } } Réponse à la troisième question import java.util.Scanner; /** * Classe polynomiale du 1er degre **/ /** * Ce programme affiche les carres au fur et a mesure que * l’utilisateur entre des valeurs de maniere interactive **/ public class PolyLineaireMainTrois { public static void main(String[] args) { // Creation d’un objet pour les entrees clavier Scanner entClav = new Scanner(System.in); while(true) { System.out.println("Veuiilez entrer a, b et x ou quitter"); String s = entClav.next(); if (s.equals("quitter")) break; int a = Integer.parseInt(s); int b = entClav.nextInt(); int x = entClav.nextInt(); // Creation d’un objet de type PolyLineaire PolyLineaire p = new PolyLineaire(a, b); // Calcul et affichage du resultat System.out.println("(" + a + "*" + x + "+" + b + ")^2 = " + p.evaluerCarre(x)); } System.out.println("Sortie du programme"); } } Réponse à la première question utilisant la classe BufferedReader au lieu de Scanner import java.io.*; /** * Classe polynomiale du 1er degre **/ class PolyLineaireBuffRead { int a, b; // champs : coefficients de a*x + b // Constructeur : initialisation des champs PolyLineaireBuffRead(int a, int b) { this.a = a; this.b = b;
  7. 7. } // methode int evaluer(int x) { return(a*x + b); } int evaluerCarre(int x) { int axPlusb = evaluer(x); 28 Exercices de travaux pratiques Java return(axPlusb*axPlusb); } } /** * Ce programme affiche les carres au fur et a mesure que * l’utilisateur entre des valeurs de maniere interactive **/ public class PolyLineaireMainBuffRead { public static void main(String[] args) throws IOException { // On utilise un BufferedReader pour lire des lignes de texte // System.in est l’entree standard BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); // Boucle infinie for(;;) { System.out.println("Veuillez entrer a, b et x"); // Afficher une invite a l’utilisateur System.out.print("PolyLineaireInter > "); // Lire une ligne entree par l’utilisateur String line = in.readLine(); // Si l’on rencontre une fin de fichier, ou si l’utilisateur // entre "quit", on sort if ((line == null) || line.equals("quit")) break; // On essaie de formatter l’entree de l’utilisateur, // puis on calcule le carre String[] theArgs = line.split(" "); // decoupe la ligne selon " " try { int a = Integer.parseInt(theArgs[0]); int b = Integer.parseInt(theArgs[1]); int x = Integer.parseInt(theArgs[2]); PolyLineaireBuffRead p = new PolyLineaireBuffRead(a, b); System.out.println("(" + a + "*" + x + "+" + b + ")^2 = " + p.evaluerCarre(x)); } // Affichage d’un message d’erreur en cas de probleme catch(Exception e) { System.out.println("Entree Invalide"); } } } } Solution de l’ex. 2 Tri d’un tableau par bulle import java.io.*; class BubbleSortAlgorithm {
  8. 8. void sort(InputOutputIntArray array) { int[] a = array.getArray(); for (int i = a.length; --i >= 0; ) { boolean swapped = false; for (int j = 0; j < i; j++) { if (a[j] > a[j+1]) { int T = a[j]; a[j] = a[j+1]; a[j+1] = T; swapped = true; } } if (!swapped) return; } } } class InputOutputIntArray { int[] intArray; InputOutputIntArray(int nbElts) { intArray = new int[nbElts]; } int [] getArray() { return(intArray); } void inputKeyboard() { // On utilise un BufferedReader pour lire des lignes de texte // System.in est l’entree standard BufferedReader in = new BufferedReader( new InputStreamReader(System.in)); // Afficher une invite a l’utilisateur System.out.println("Entrez les elements du tableau "+ "ou q pour sortir "); for(int i = 0; i < intArray.length; i++) { try { System.out.print("Entrez l’element no " + (i+1) + " : "); // Lire une ligne entree par l’utilisateur String line = in.readLine(); // Si l’on rencontre une fin de fichier, // ou si l’utilisateur entre "quit", on sort if ((line == null) || line.equals("q")) break; // On essaie de formatter l’entree de l’utilisateur, // puis on remplit l’elt correspondant du tableau int elt = Integer.parseInt(line); intArray[i] = elt;
  9. 9. } catch(IOException e) { // Message d’erreur System.out.println("Entree invalide"); i--; } }// for() } void outputScreen(String message) { System.out.println(message); for(int i = 0; i < intArray.length; i++) { System.out.print("t[" + i + "] " + intArray[i] + " "); } System.out.println("nn"); } } public class BubbleSortText { int[] arrayToSort; public static void main(String[] args) throws IOException { int nbElts; // Traitement des arguments if (args.length < 1) nbElts = 10; else nbElts = Integer.parseInt(args[0]); BubbleSortAlgorithm algorithm = new BubbleSortAlgorithm(); InputOutputIntArray arrayToSort = new InputOutputIntArray(nbElts); // Entree au clavier arrayToSort.inputKeyboard(); // Tri algorithm.sort(arrayToSort); // Affichage du resultat arrayToSort.outputScreen("nnVoici le tableau trie "); } } Solution de l’ex. 3 Affichage du graphe d’une fonction Portion de code HTML associée à l’applet <HTML> <HEAD> </HEAD> <BODY BGCOLOR="000000"> <CENTER> <APPLET code = "GrahApplet.class" width = "500" height = "300" > </APPLET> </CENTER> </BODY> </HTML> Solution pour le source java import java.awt.Graphics;
  10. 10. public class GraphApplet extends java.applet.Applet { double f(double x) { return (Math.cos(x/5) + Math.sin(x/7) + 2) * getSize().height / 4; } public void paint(Graphics g) { for (int x = 0 ; x < getSize().width ; x++) { g.drawLine(x, (int)f(x), x + 1, (int)f(x + 1)); } } public String getAppletInfo() { return "Dessine le graphe d’une fonction de type sinusiodal."; } } Exercices complémentaires sur les bases procédurales Java – Solutions Solution de l’ex. 1 Les tours de Hanoï class Piquet { int m_nDiscs; int Anneaux[]; String m_Name; Piquet(String s, int maxPiquets) { m_Name = s; m_nDiscs = 0; Anneaux = new int[maxPiquets]; } void viderPiquet() { m_nDiscs = 0; } void remplirPiquet(int i) { m_nDiscs = i; for(int j = 0; j < m_nDiscs; j++) { Anneaux[j] = j; } } int popAnneau() { int ann = Anneaux[m_nDiscs - 1]; m_nDiscs--; return ann; } void pushAnneau(int ann) { m_nDiscs++; Anneaux[m_nDiscs - 1] = ann; } String nom() { return m_Name;
  11. 11. } void dessinePiquet() { System.out.print(m_Name + " : "); for(int i = 0; i < m_nDiscs; i++) System.out.print(Anneaux[i] + " "); System.out.println(" "); } } class JeuHanoi { int N; Piquet A, B, C; public JeuHanoi(int NbDisques) { N = NbDisques; A = new Piquet("Gauche", N); B = new Piquet("Milieu", N); C = new Piquet("Droit", N); A.remplirPiquet(N); B.viderPiquet(); C.viderPiquet(); dessinerJeu(); deplacerTour(N, A, B, C); } public void deplacerTour(int i, Piquet piqA, Piquet piqB, Piquet piqC) { if(i == 0) { return; } else { deplacerTour(i - 1, piqA, piqC, piqB); deplacerAnneau(piqA, piqB); deplacerTour(i - 1, piqC, piqB, piqA); return; } } public void deplacerAnneau(Piquet piq, Piquet piqA) { int anneau = piq.popAnneau(); piqA.pushAnneau(anneau); dessinerJeu(); } public void dessinerJeu() { A.dessinePiquet(); 36 Exercices de travaux pratiques Java B.dessinePiquet(); C.dessinePiquet(); System.out.println(" "); } } public class HanoiMain {
  12. 12. public static void main(String args[]) { int nbDisques; if (args.length == 0) nbDisques = 3; else try { nbDisques = Integer.parseInt(args[0]); } catch (NumberFormatException e) { nbDisques = 3; } new JeuHanoi(nbDisques); } } Solution de l’ex. 2 Évaluation de polynôme par le schéma de Horner import java.util.Scanner; /** * Evaluation de polynomes par la methode de Horner */ class Horner { double a[]; // coefficients du polynome int N; // ordre du polynome public Horner(int nouvN, double nouvA[]) { N = nouvN; a = new double[N]; for(int i = 0; i < N; i++) { a[i] = nouvA[i]; } } double evalBrute(double x) { double resultat = 0; for(int i = 0; i < N; i++) { resultat += a[i]*Math.pow(x, (double)i); } return resultat; } double evalHorner(double x) { double b[] = new double[N+1]; int i; i = N-2; b[i+1] = a[N-1]; while(i >= 0) { i--; b[i+1] = b[i+2]*x + a[i+1]; } return b[0]; } public static void main(String[] args) { Scanner sc = new Scanner(System.in); double eps = 1e-14; System.out.print("Veuillez entrer l’ordre du polynome ");
  13. 13. int ordre = sc.nextInt(); double coeffs[] = new double[ordre+1]; for(int i = 0; i < ordre+1; i++) { System.out.print("Veuillez entrer le coeff no " + i + " "); coeffs[i] = sc.nextDouble(); } Horner h = new Horner(ordre+1, coeffs); System.out.print("Veuillez entrer x "); double x = sc.nextDouble(); double resBrute = h.evalBrute(x); double resHorner = h.evalHorner(x); System.out.print("Evaluation de p(x) = "); for(int i = 0; i < ordre+1; i++) { System.out.print(h.a[i] + "*x^" + i + " + "); } System.out.print("n en x = " + x); double Pb = h.evalBrute(x); double Ph = h.evalHorner(x); System.out.println("eval Brute --> Pb(" + x + ")=" + Pb); System.out.println("eval Horner --> Ph(" + x + ")=" + Ph); System.out.println("test --> |Pb(x)-Ph(x)| < 1e-14 : " + (Math.abs(Ph-Pb) < eps) ); } } Exercices d’introduction orientée objet en Java : manipulations de classes – Solutions Solution de l’ex. 1 Classe Tableau import java.util.*; public class Tableau { int[] tab; public Tableau(int n1, int n2, int n3, int n4) { tab = new int[4]; tab[0] = n1; tab[1] = n2; tab[2] = n3; tab[3] = n4; } public void trouverZero() { for (int i = 0; i < tab.length; i++) { if (tab[i] == 0) { System.out.println("tab[" + i + "] == 0"); return; }
  14. 14. } System.out.println("-1 (indice non trouve)"); return; } public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.print("Veuillez entrer l’entier 1 : "); int n1 = sc.nextInt(); System.out.print("Veuillez entrer l’entier 2 : "); int n2 = sc.nextInt(); System.out.print("Veuillez entrer l’entier 3 : "); int n3 = sc.nextInt(); System.out.print("Veuillez entrer l’entier 4 : "); int n4 = sc.nextInt(); Tableau t = new Tableau(n1, n2, n3, n4); t.trouverZero(); } } Solution de l’ex. 2 Variante de la classe Tableau import java.util.Scanner; class TableauBis { int[] tab; public TableauBis(int n1, int n2, int n3, int n4) { tab = new int[4]; tab[0] = n1; tab[1] = n2; tab[2] = n3; tab[3] = n4; } public int trouverZero() { for (int i = 0; i < tab.length; i++) { if (tab[i] == 0) { return i; } } return -1; } } public class TableauBisMain { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.print("Veuillez entrer l’entier 1 : "); int n1 = sc.nextInt(); System.out.print("Veuillez entrer l’entier 2 : "); int n2 = sc.nextInt(); System.out.print("Veuillez entrer l’entier 3 : "); int n3 = sc.nextInt(); System.out.print("Veuillez entrer l’entier 4 : "); int n4 = sc.nextInt(); TableauBis t = new TableauBis(n1, n2, n3, n4); int ind = t.trouverZero(); System.out.print("Indice trouve : " + ind); }
  15. 15. } public class PersonnelMain { public static void main(String[] args) { Personnel p1 = new Personnel(1, 12, 53432); Personnel p2 = new Personnel(2, 24, 55438); p1.printPersonnel(); p2.printPersonnel(); p1.setIdent(44); p2.setPosteTel(56787); p1.printPersonnel(); p2.printPersonnel(); } } class Personnel { int genre; int ident; int posteTel; public Personnel(int g, int id, int pt) { if (g != 1 && g != 2) genre = 1; else genre = g; ident = id; posteTel = pt; } public int getGenre() { return genre; } public int getIdent() { return ident; } public int getPosteTel() { return posteTel; } public void setIdent(int newIdent) { ident = newIdent; } public void setPosteTel(int newPosteTel) { posteTel = newPosteTel; } public void printPersonnel() { System.out.println("genre : " + genre + " identifiant : " + ident + " poste telephonique : " + posteTel); } } Solution de l’ex. 4 Classe Complexe public class Complexe { /* * Champs de la classe */
  16. 16. protected double partieReelle; protected double partieImaginaire; /* * Constructeurs */ Complexe(double r, double i) { partieReelle = r; partieImaginaire = i; } Complexe() { this(0, 0); } Complexe(Complexe z) { this(z.partieReelle, z.partieImaginaire); } public Complexe ajouter(Complexe z) { double re = 0, im = 0; re = this.partieReelle + z.partieReelle; im = this.partieReelle + z.partieImaginaire; Complexe somme = new Complexe(re, im); return somme; } public void afficher() { System.out.println("(" + partieReelle + ", " + partieImaginaire public void afficherSansCR() { System.out.print("(" + partieReelle + ", " + partieImaginaire + } /* public static void main(String[] args) { Complexe c1 = new Complexe(1, 1); Complexe c2 = new Complexe(7, 6); Complexe c3 = c1.ajouter(c2); c1.afficher(); c2.afficher(); c3.afficher(); } */ }// fin de la classe Complexe Solution de l’ex. 5 Classe Matrice public class MatriceCarree { int[][] tab; int nbElts; public MatriceCarree(int n, int[] elts) { nbElts = n; tab = new int[nbElts][nbElts]; for (int i = 0; i < nbElts; i++) { for (int j = 0; j < nbElts; j++) { tab[i][j] = elts[i * nbElts + j]; } } } public MatriceCarree(int n) {
  17. 17. nbElts = n; tab = new int[nbElts][nbElts]; } public void afficher() { for (int i = 0; i < nbElts; i++) { for (int j = 0; j < nbElts; j++) { System.out.print(tab[i][j] + "t"); } System.out.println(""); } System.out.println(""); } public MatriceCarree ajouter(MatriceCarree m) { MatriceCarree r = new MatriceCarree(nbElts); for (int i = 0; i < nbElts; i++) { for (int j = 0; j < nbElts; j++) { r.tab[i][j] = tab[i][j] + m.tab[i][j]; } } return r; } public static void main(String[] args) { int[] elts1 = new int[4]; int[] elts2 = new int[4]; for (int i = 0; i < 4; i++) { elts1[i] = 2 * i; elts2[i] = 7 * i; } MatriceCarree m1 = new MatriceCarree(2, elts1); MatriceCarree m2 = new MatriceCarree(2, elts2); MatriceCarree m3 = m1.ajouter(m2); m1.afficher(); m2.afficher(); m3.afficher(); } } Solution de l’ex. 6 Matrice de complexes public class MatriceCarreeComplexe { Complexe[][] tab; int nbElts; public MatriceCarreeComplexe(int n, Complexe[] elts) { nbElts = n; tab = new Complexe[nbElts][nbElts]; for (int i = 0; i < nbElts; i++) { for (int j = 0; j < nbElts; j++) { tab[i][j] = new Complexe(elts[i * nbElts + j]); } } } public MatriceCarreeComplexe(int n) { nbElts = n; tab = new Complexe[nbElts][nbElts]; }
  18. 18. public void afficher() { for (int i = 0; i < nbElts; i++) { for (int j = 0; j < nbElts; j++) { tab[i][j].afficherSansCR(); System.out.print("t"); } System.out.println(""); } System.out.println(""); } public MatriceCarreeComplexe ajouter(MatriceCarreeComplexe m) { MatriceCarreeComplexe r = new MatriceCarreeComplexe(nbElts); for (int i = 0; i < nbElts; i++) { for (int j = 0; j < nbElts; j++) { r.tab[i][j] = tab[i][j].ajouter(m.tab[i][j]); } } return r; } public static void main(String[] args) { Complexe[] elts1 = new Complexe[4]; Complexe[] elts2 = new Complexe[4]; for (int i = 0; i < 4; i++) { elts1[i] = new Complexe(i, 2 * i); elts2[i] = new Complexe(3 * i, 5 * i); } MatriceCarreeComplexe m1 = new MatriceCarreeComplexe(2, elts1); MatriceCarreeComplexe m2 = new MatriceCarreeComplexe(2, elts2); MatriceCarreeComplexe m3 = m1.ajouter(m2); m1.afficher(); m2.afficher(); m3.afficher(); } } Exercices d’introduction orientée objet en Java : personnes, enseignants et
  19. 19. étudiants – Solutions Solution de l’ex. 1 Classe Personne (constructeurs) Réponse à la question 1 Classe PersonneMain1 public class PersonneMain1 { public static void main(String[] args) { // Creation d’une instance de Personne1 Personne1 sage = new Personne1("Agecanonix", 80); // Appel de la methode afficher sage.afficher(); } } Classe Personne1 class Personne1 { String nom; int age; // Constructeur exhaustif Personne1(String leNom, int lAge) { nom = new String(leNom); age = lAge; } void afficher() { System.out.println("Nom : " + nom); System.out.println("Age : " + age); } } Notez que dans le constructeur de Personne1, l’initialisation du champ nom a été réalisée par nom = new String(leNom) ; et non par nom = leNom ; // sachant que la dernière ligne ne fait que copier les références alors que la première effectue une réelle duplication de la chaîne. Il se trouve que sont intégrés au sein du langage des mécanismes liés au ramasse miettes qui ne libèrent la mémoire que lorsqu’il n’y a plus de référence. Mais attention, lorsqu’on ne copie que les références, on accède à chaque fois au même objet. Réponse à la question 2 Classe PersonneMain2 public class PersonneMain2 { public static void main(String[] args) { double[] mesComptes = new double[2]; mesComptes[0] = 100; mesComptes[1] = 92; // Creation de deux instances de Personne2 Personne2 sage = new Personne2("Agecanonix", 80, mesComptes); Personne2 sageBis = new Personne2("Agecanonix", 80, mesComptes);
  20. 20. sage.diviserParDeux(); // Appel de la methode afficher sage.afficher(); System.out.println(""); sageBis.afficher(); System.out.println(""); } } Classe Personne2 class Personne2 { String nom; int age; double[] comptes; // Constructeur exhaustif Personne2(String leNom, int lAge, double[] lesComptes) { // La ligne suivante est a proscrire, quoiqu’il soit // difficile de s’en rendre compte // nom = leNom; // La bonne maniere de faire est : nom = new String(leNom); age = lAge; // La ligne suivante est a proscrire // nombres = lesNombres; // La bonne maniere de faire est : comptes = new double[lesComptes.length]; for(int i = 0; i < comptes.length; i++) { comptes[i] = lesComptes[i]; } } void diviserParDeux() { for(int i = 0; i < comptes.length; i++) { comptes[i] /= 2.0; } } void afficher() { System.out.println("Nom : " + nom); System.out.println("Age : " + age); for(int i = 0; i < comptes.length; i++) { System.out.println("Compte no " + i + " : " + comptes[i]); } } } Réponse à la question 3 public class PersonneMain3 { public static void main(String[] args) { double[] mesNombres = {100, 92}; // Creation de 3 instances de Personne4 Personne3 sage = new Personne3("Agecanonix", 80); Personne3 intrepide = new Personne3(); Personne3 humain = new Personne3(intrepide); // Appel de la methode afficher sage.afficher(); System.out.println(""); intrepide.afficher(); System.out.println(""); humain.afficher(); System.out.println("");
  21. 21. } } class Personne3 { String nom; int age; // Constructeur exhaustif Personne3(String leNom, int lAge) { nom = new String(leNom); age = lAge; } // Constructeur par defaut Personne3() { this("Asterix", 30); } // Constructeur de recopie Personne3(Personne3 p) { nom = new String(p.nom); age = p.age; } void afficher() { System.out.println("Nom : " + nom); System.out.println("Age : " + age); } } Solution de l’ex. 2 Classes Enseignants et étudiants (Héritage) Réponse à la question 1 Classe ProfEleveMain3 public class ProfEleveMain3 { public static void main(String[] args) { Personne3 reveur = new Personne3("Nimbus", 45); Enseignant3 prof = new Enseignant3("Nimbus", 45, 150, true); Etudiant3 eleve = new Etudiant3("Soupaloigonycrouton", 20, 5, true); reveur.afficher(); System.out.println(""); prof.afficher(); System.out.println(""); eleve.afficher(); System.out.println(""); } } Classe Enseignant3 class Enseignant3 extends Personne3 { int nbHeuresCours; boolean grincheux; Enseignant3(String leNom, int lAge, int heures, boolean ouin) { super(leNom, lAge); nbHeuresCours = heures; grincheux = ouin; } } Classe Etudiant3 class Etudiant3 extends Personne3 {
  22. 22. int noteMoyenne; boolean faineant; Etudiant3(String leNom, int lAge, int note, boolean poilAlaMain) { super(leNom, lAge); noteMoyenne = note; faineant = poilAlaMain; } } Réponse à la question 2 public class ProfEleveMain4 { public static void main(String[] args) { Personne3[] tabPers = new Personne3[5]; tabPers[0] = new Enseignant3("Nimbus", 45, 150, true); tabPers[1] = new Enseignant3("Tournesol", 55, 270, false); tabPers[2] = new Etudiant3("Gauss", 21, 22, false); tabPers[3] = new Etudiant3("GrosZero", 27, 3, true); tabPers[4] = new Etudiant3("Gaston", 28, 5, false); for(int i = 0; i < 5; i++) { tabPers[i].afficher(); System.out.print("Statut : "); if (tabPers[i] instanceof Enseignant3) System.out.println("Enseignant"); else if (tabPers[i] instanceof Etudiant3) System.out.println("Etudiant"); else System.out.println("Inconnu"); System.out.println(""); } } } Solution de l’ex. 3 Différents affichages (Surcharge et redéfinition) Réponse à la question 1 class Personne5 { String nom; int age; // Constructeur exhaustif Personne5(String leNom, int lAge) { nom = new String(leNom); age = lAge; } // Constructeur par defaut Personne5() { this("Asterix", 30); } // Constructeur de recopie Personne5(Personne5 p) { nom = new String(p.nom); age = p.age; } void afficher() { System.out.println("Nom : " + nom);
  23. 23. System.out.println("Age : " + age); } void afficher(boolean compact) { if (compact == false) afficher(); else { System.out.print("[" + nom + ", " + age + "]"); } } } Réponse à la question 2 class Enseignant5 extends Personne5 { int nbHeuresCours; boolean grincheux; Enseignant5(String leNom, int lAge, int heures, boolean ouin) { super(leNom, lAge); nbHeuresCours = heures; grincheux = ouin; } void afficher() { super.afficher(); System.out.println("Enseignantn"); } } Réponse à la question 3 Classe Etudiant5 class Etudiant5 extends Personne5 { double noteMoyenne; boolean faineant; Etudiant5(String leNom, int lAge, int moyenne, boolean poilAlaMain) { super(leNom, lAge); noteMoyenne = moyenne; faineant = poilAlaMain; } void afficher() { super.afficher(); System.out.println("Etudiantn"); } } Classe ProfEleveMain5 public class ProfEleveMain5 { public static void main(String[] args) { Personne5[] tabPers = new Personne5[5]; tabPers[0] = new Enseignant5("Nimbus", 45, 150, true); tabPers[1] = new Enseignant5("Tournesol", 55, 270, false); tabPers[2] = new Etudiant5("Gauss", 21, 22, false); tabPers[3] = new Etudiant5("GrosZero", 27, 3, true); tabPers[4] = new Etudiant5("Gaston", 28, 5, false); for(int i = 0; i < 5; i++) {
  24. 24. tabPers[i].afficher(true); // Affichage compact } } } Solution de l’ex. 4 Délégation d’affichage (Classes abstraites) Classe Personne6 abstract class Personne6 { String nom; int age; // Constructeur exhaustif Personne6(String leNom, int lAge) { nom = new String(leNom); age = lAge; } // Affichage du type delegue aux sous classes abstract void afficherType(); void afficher() { System.out.println("Nom : " + nom); System.out.println("Age : " + age); afficherType(); } } Classe Enseignant6 class Enseignant6 extends Personne6 { int nbHeuresCours; boolean grincheux; Enseignant6(String leNom, int lAge, int heures, boolean ouin) { super(leNom, lAge); nbHeuresCours = heures; grincheux = ouin; } void afficherType() { System.out.println("Enseignant"); } } Classe Etudiant6 class Etudiant6 extends Personne6 { int noteMoyenne; boolean faineant; Etudiant6(String leNom, int lAge, int note, boolean poilAlaMain) { super(leNom, lAge); noteMoyenne = note; faineant = poilAlaMain; } void afficherType() { System.out.println("Etudiant"); } } Classe ProfEleveMain6 public class ProfEleveMain6 {
  25. 25. public static void main(String[] args) { Personne6[] tabPers = new Personne6[5]; tabPers[0] = new Enseignant6("Nimbus", 45, 50, true); tabPers[1] = new Enseignant6("Tournesol", 55, 292, false); tabPers[2] = new Etudiant6("Gauss", 21, 22, false); tabPers[3] = new Etudiant6("GrosZero", 27, 1, true); tabPers[4] = new Etudiant6("Gaston", 28, 4, false); for(int i = 0; i < 5; i++) { tabPers[i].afficher(); } } } Exercices de base orientée objet Java autour de complexes – Solutions Solution de l’ex. 1 Première manipulations de complexes (création de classes, constructeurs, méthodes et champs statiques) Voici la réponse aux différentes questions : Classe Complexe class Complexe1 { /* * Champs de la classe */ protected double partieReelle; protected double partieImaginaire; private static int nbComplexes = 0; /* * Constructeurs */ Complexe1(double r, double i) { partieReelle = r; partieImaginaire = i; nbComplexes++; } Complexe1() { this(0, 0); } Complexe1(Complexe1 z) { this(z.partieReelle, z.partieImaginaire); } public String toString() { return ("[" + nbComplexes + "](" + Double.toString(partieReelle) + ", " + Double.toString(partieImaginaire) + ")"); } // methode appelee a la liberation memoire d’un complexe // on decremente le compteur d’objets protected void finalize() { System.out.println("Morituri " + this);
  26. 26. nbComplexes--; } public Complexe1 multiplier(Complexe1 z) { double re = 0, im = 0; re = this.partieReelle * z.partieReelle - this.partieImaginaire * z.partieImaginaire; im = this.partieReelle * z.partieImaginaire + this.partieImaginaire * z.partieReelle; Complexe1 produit = new Complexe1(re, im); return produit; } public static Complexe1 racNiemeUnite(int n) { double re = 0, im = 0, phase = 0; phase = (2*Math.PI)/n; re = Math.cos(phase); im = Math.sin(phase); // renvoi avec creation d’instance implicite return(new Complexe1(re, im)); } }// fin de la classe Complexe Classe ComplexeMain public class ComplexeMain1 { public static void main(String[] args) { Complexe1 resultat = null; switch(args.length) { case 1 : int n = Integer.parseInt(args[0]); resultat = Complexe1.racNiemeUnite(n); break; case 4 : double re1 = Double.parseDouble(args[0]); double im1 = Double.parseDouble(args[1]); double re2 = Double.parseDouble(args[2]); double im2 = Double.parseDouble(args[3]); Complexe1 z1 = new Complexe1(re1, im1); Complexe1 z2 = new Complexe1(re2, im2); resultat = z1.multiplier(z2); // On libere la memoire en dereferencant les 2 objets // intermediaires puis en appelant le ramasse-miettes z1 = null; z2 = null; System.gc(); break; default : System.out.println("1 ou 4 parametres"); System.exit(1); } System.out.println("Resultat : " + resultat); } }// fin de la classe ComplexeMain Solution de l’ex. 2 Tableaux génériques (tableaux) Voici la réponse aux différentes questions : Classe Complexe class Complexe {
  27. 27. /* * Champs de la classe */ protected double partieReelle; protected double partieImaginaire; /* * Constructeurs */ Complexe(double r, double i) { partieReelle = r; partieImaginaire = i; } Complexe() { this(0, 0); } Complexe(Complexe z) { this(z.partieReelle, z.partieImaginaire); } public String toString() { return ("(" + Double.toString(partieReelle) + ", " + Double.toString(partieImaginaire) + ")"); } public boolean equals(Complexe z) { return (this.partieReelle == z.partieReelle && this.partieImaginaire == z.partieImaginaire); } public void change(double nouvPReelle, double nouvPImag) { partieReelle = nouvPReelle; partieImaginaire = nouvPImag; } public Complexe multiplier(Complexe z) { double re = 0, im = 0; re = this.partieReelle * z.partieReelle - this.partieImaginaire * z.partieImaginaire; im = this.partieReelle * z.partieImaginaire + this.partieImaginaire * z.partieReelle; Complexe produit = new Complexe(re, im); return produit; } }// fin de la classe Complexe Classe Tableau un tableau d’objets (de type Objet). class Tableau { private Object[] donnees = null; private int nbElts; public Tableau(int nb, Object[] tabObjets) { nbElts = nb; donnees = tabObjets; } public Tableau(Tableau t) { this(t.nbElts, t.donnees); } public Tableau() {
  28. 28. this(0, null); } for(int i = 0; i < tab.size(); i++) { System.out.println("tab[" + i + "]" + tab.get(i)); } Complexe cplxeBis = new Complexe(5, 5); Tableau tabBis = new Tableau(tab); tabBis.set(2, cplxeBis); for(int i = 0; i < tab.size(); i++) { System.out.print("tab[" + i + "]" + tab.get(i)); System.out.println(" -- tabBis[" + i + "]" + tabBis.get(i)); } } } Solution de l’ex. 3 Tableaux dynamiques (interfaces, polymorphisme) Solution standard Interface TailleVariable // qui spécifie les méthodes add() et remove(). interface TailleVariable { public void add(int i, Object elt); public Object remove(int index); } Classe TableauDynamique qui implante les méthodes add() et remove(). class TableauDynamique extends Tableau implements TailleVariable { public TableauDynamique(int nb, Object[] tabObjets) { super(nb, tabObjets); } public void add(int index, Object elt) { // allocation d’un nouveau tableau de references int nouvNbElts = size() + 1; Object[] nouvDonnees = new Object[nouvNbElts]; // remplissage du tableau elargi for (int i = 0; i < index; i++) nouvDonnees[i] = get(i); nouvDonnees[index] = elt; for (int i = index+1; i < nouvNbElts; i++) nouvDonnees[i] = get(i-1); Tableau nouvTableau = new Tableau(nouvNbElts, nouvDonnees); muer(nouvTableau); } public Object remove(int index) { Object ejecte = null; // allocation d’un nouveau tableau de references int nouvNbElts = size() - 1; Object[] nouvDonnees = new Object[nouvNbElts]; // remplissage du tableau elargi for (int i = 0; i < index; i++) nouvDonnees[i] = get(i); ejecte = get(index);
  29. 29. for (int i = index; i < nouvNbElts; i++) nouvDonnees[i] = get(i+1); Tableau nouvTableau = new Tableau(nouvNbElts, nouvDonnees); muer(nouvTableau); return ejecte; } } Classe TableauComplexeDyn Un tableau dynamique de Complexe. class TableauComplexeDyn extends TableauDynamique { TableauComplexeDyn(int nb, double[] tabRe, double[] tabIm) { super(nb, new Complexe[nb]); for(int i = 0; i < size(); i++) set(i, new Complexe(tabRe[i], tabIm[i])); } public void add(int index, Object elt) { if ((elt instanceof Complexe) == false) System.out.println("Attention, vous ajouter un non complexe : "" + elt + "" a l’indice " + index); super.add(index, elt); } public String toString() { StringBuffer s = new StringBuffer("n"); for(int i = 0; i < size(); i++) s.append(i + ": " + get(i).toString() + "n"); return s.toString(); } } Classe TableauComplexeDynMain La classe contenant le main(). public class TableauComplexeDynMain { public static void main(String[] args) { double[] tabPartRe, tabPartIm; int nbEltsTab = 0; if (args.length < 1) nbEltsTab = 5; else nbEltsTab = Integer.parseInt(args[0]); tabPartRe = new double[nbEltsTab]; tabPartIm = new double[nbEltsTab]; for (int i = 0; i < nbEltsTab; i++) { tabPartRe[i] = Math.random(); tabPartIm[i] = Math.random(); } TableauComplexeDyn t = new TableauComplexeDyn(nbEltsTab, tabPartRe, tabPartIm); System.out.println("Tab : " + t); t.add(4, new Complexe(2, 2)); t.add(4, new Integer(2)); t.add(3, new String("L’homme regarde la fleur, la fleur sourit.")); System.out.println("Tab : " + t);
  30. 30. } } Extrait de la classe ArrayList Pour comparaison, voici un extrait de la classe ArrayList du paquetage java.util (n’ont été retirées de cet extrait que les méthodes les moins importantes). On notera que les méthodes set() et get() sont, dans l’esprit, identiques. On notera également la présence d’une méthode clone() qui effectue une copie superficielle (elle copie les différents éléments du tableau interne elementData ; si les éléments stockés sont des types primitifs, une copie indépendante est réalisée ; si les éléments stockés sont des références à des objets, seules les références sont copiées). Extrait de la classe java.util.ArrayList /* * @(#)ArrayList.java 1.36 01/12/03 * Copyright 2002 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package java.util; public class ArrayList extends AbstractList implements List, RandomAccess, Cloneable, java.io.Serializable { private transient Object elementData[]; private int size; public ArrayList(int initialCapacity) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); this.elementData = new Object[initialCapacity]; } public ArrayList() { this(10); } public void ensureCapacity(int minCapacity) { modCount++; int oldCapacity = elementData.length; if (minCapacity > oldCapacity) { Object oldData[] = elementData; int newCapacity = (oldCapacity * 3)/2 + 1; if (newCapacity < minCapacity) newCapacity = minCapacity; elementData = new Object[newCapacity]; System.arraycopy(oldData, 0, elementData, 0, size); } }
  31. 31. public int size() { return size; } public boolean isEmpty() { return size == 0; } public boolean contains(Object elem) { return indexOf(elem) >= 0; } public int indexOf(Object elem) { if (elem == null) { for (int i = 0; i < size; i++) if (elementData[i]==null) return i; } else { for (int i = 0; i < size; i++) if (elem.equals(elementData[i])) return i; } return -1; } public Object clone() { try { ArrayList v = (ArrayList)super.clone(); v.elementData = new Object[size]; System.arraycopy(elementData, 0, v.elementData, 0, size); v.modCount = 0; return v; } catch (CloneNotSupportedException e) { // this shouldn’t happen, since we are Cloneable throw new InternalError(); } } public Object[] toArray() { Object[] result = new Object[size]; System.arraycopy(elementData, 0, result, 0, size); return result; } // Positional Access Operations public Object get(int index) { RangeCheck(index); return elementData[index]; } public Object set(int index, Object element) { RangeCheck(index); Object oldValue = elementData[index]; elementData[index] = element; return oldValue; } public boolean add(Object o) { ensureCapacity(size + 1); // Increments modCount!! elementData[size++] = o; return true; }
  32. 32. public void add(int index, Object element) { if (index > size || index < 0) throw new IndexOutOfBoundsException( "Index: "+index+", Size: "+size); ensureCapacity(size+1); // Increments modCount!! System.arraycopy(elementData, index, elementData, index + 1, size - index); elementData[index] = element; size++; } public Object remove(int index) { RangeCheck(index); modCount++; Object oldValue = elementData[index]; int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // Let gc do its work return oldValue; } public void clear() { modCount++; // Let gc do its work for (int i = 0; i < size; i++) elementData[i] = null; size = 0; } private void RangeCheck(int index) { if (index >= size || index < 0) throw new IndexOutOfBoundsException( "Index: "+index+", Size: "+size); } } Solution avec copie profonde par clonage d’objets Voici maintenant une solution réalisant une copie profonde en se servant de la méthode clone() de Object. Pour cloner un objet, il faut au préalable que ce dernier implante l’interface Cloneable. La solution retenue ici est que la classe Tableau (nommée ci-dessous TableauClonable) implante cette interface. Les objets potentiels d’un tel tableau dérivent eux de ObjetClonable dont la seule fonction est, au travers de sa méthode clone(), d’appeler la méthode clone() d’Object. Cette dernière effectue une copie de références. Notez que la redéfinition de clone() au sein de ComplexeClonable se contente d’appeler la méthode clone() de la classe ObjetClonable, c’est-à-dire clone() d’Object. Ceci est suffisant, car les champs de Complexe sont tous des types primitifs. S’il y avait eu des références à des objets ou des
  33. 33. tableaux, il aurait fallu également réaliser la copie profonde de ces derniers. Classe ObjetClonable, comportant la méthode clone() C’est cette classe dont devront hériter les objets à cloner : class ObjetClonable { protected Object clone() throws CloneNotSupportedException { return super.clone(); } } Classe ComplexeClonable L’objet complexe que l’on peut cloner : class ComplexeClonable extends ObjetClonable { /* * Champs de la classe */ protected double partieReelle; protected double partieImaginaire; /* * Constructeurs */ ComplexeClonable(double r, double i) { partieReelle = r; partieImaginaire = i; } ComplexeClonable() { this(0, 0); } ComplexeClonable(ComplexeClonable z) { this(z.partieReelle, z.partieImaginaire); } public String toString() { return ("(" + Double.toString(partieReelle) + ", " + Double.toString(partieImaginaire) + ")"); } public boolean equals(ComplexeClonable z) { return (this.partieReelle == z.partieReelle && this.partieImaginaire == z.partieImaginaire); } public ComplexeClonable multiplier(ComplexeClonable z) { double re = 0, im = 0; re = this.partieReelle * z.partieReelle - this.partieImaginaire * z.partieImaginaire; im = this.partieReelle * z.partieImaginaire + this.partieImaginaire * z.partieReelle; ComplexeClonable produit = new ComplexeClonable(re, im); return produit; } protected Object clone() throws CloneNotSupportedException { return super.clone(); } }// fin de la classe ComplexeClonable La classe TableauClonable, Un tableau d’objets clonable (de type ObjetClonable). Il implante l’interface java Cloneable qui impose de redéfinir la méthode clone(). Selon
  34. 34. l’usage, cette méthode est censée réaliser une copie profonde de ses objets (par opposition à une copie superficielle, qui ne copie que les références). class TableauClonable implements Cloneable { private ObjetClonable[] donnees = null; private int nbElts; public TableauClonable(int nb, ObjetClonable[] tabObjets) { nbElts = nb; donnees = tabObjets; } public TableauClonable(TableauClonable t) { this(t.nbElts, t.donnees); } public TableauClonable() { this(0, null); } protected Object clone() throws CloneNotSupportedException { TableauClonable theClone = null; try { theClone = (TableauClonable)super.clone(); ObjetClonable[] tab = theClone.donnees; for (int i = 0; i < tab.length; i++) { ObjetClonable o = donnees[i]; tab[i] = (ObjetClonable)o.clone(); } } catch (CloneNotSupportedException e) { System.err.println(e.getMessage()); } return theClone; } int size() { return nbElts; } public int indexOf(ObjetClonable elt) { for (int i = 0; i < size(); i++) if (get(i).equals(elt)) return i; return -1; } ObjetClonable get(int index) { return donnees[index]; } ObjetClonable set(int index, ObjetClonable element) { ObjetClonable vieux = donnees[index]; donnees[index] = element; return vieux; } protected void muer(TableauClonable nouv) { ObjetClonable[] vieux = donnees; donnees = nouv.donnees; nbElts = nouv.nbElts; vieux = null; }
  35. 35. }// fin de classe TableauClonable Interface TailleVariableClonable //Elle spécifie les méthodes add() et remove(). Notez que remove() renvoie une référence //de type ObjetClonable. interface TailleVariableClonable { public void add(int i, Object elt); public ObjetClonable remove(int index); } Classe TableauDynamiqueClonable Elle implante les méthodes add() et remove(). class TableauDynamiqueClonable extends TableauClonable implements TailleVariableClonable { public TableauDynamiqueClonable(int nb, ObjetClonable[] tabObjets) { super(nb, tabObjets); } public void add(int index, Object elt) { if ((elt instanceof ObjetClonable) == false) { System.out.println("Ajount de l’objet "" + elt + "" ne derivant pas d’ObjetClonable impossible "); return; } // allocation d’un nouveau tableau de references int nouvNbElts = size() + 1; ObjetClonable[] nouvDonnees = new ObjetClonable[nouvNbElts]; // remplissage du tableau elargi for (int i = 0; i < index; i++) nouvDonnees[i] = get(i); nouvDonnees[index] = (ObjetClonable) elt; for (int i = index + 1; i < nouvNbElts; i++) nouvDonnees[i] = get(i - 1); TableauClonable nouvTableau = new TableauClonable(nouvNbElts, nouvDonnees); muer(nouvTableau); } public ObjetClonable remove(int index) { ObjetClonable ejecte = null; // allocation d’un nouveau tableau de references int nouvNbElts = size() - 1; ObjetClonable[] nouvDonnees = new ObjetClonable[nouvNbElts]; // remplissage du tableau elargi for (int i = 0; i < index; i++) nouvDonnees[i] = get(i); ejecte = get(index); for (int i = index-1; i < nouvNbElts; i++) nouvDonnees[i] = get(i+1); TableauClonable nouvTableau = new TableauClonable(nouvNbElts, nouvDonnees); muer(nouvTableau); return ejecte; } }
  36. 36. Classe TableauComplexeDynClonable //Un tableau dynamique de ComplexeClonable. class TableauComplexeDynClonable extends TableauDynamiqueClonable { TableauComplexeDynClonable(int nb, double[] tabRe, double[] tabIm) { super(nb, new ComplexeClonable[nb]); for(int i = 0; i < size(); i++) set(i, new ComplexeClonable(tabRe[i], tabIm[i])); } public void add(int index, Object elt) { if ((elt instanceof ComplexeClonable) == false) System.out.println("Attention, vous ajoutez un non complexe : "" + elt + "" a l’indice " + index); try { super.add(index, (ObjetClonable)elt); } catch (ClassCastException e) { System.out.println("Une exception devrait être générée, " + " l’objet ajouté n’implante pas ObjetClonable"); } } public String toString() { StringBuffer s = new StringBuffer("n"); for(int i = 0; i < size(); i++) s.append(i + ": " + get(i).toString() + "n"); return s.toString(); } } Classe TableauComplexeDynClonableMain La classe contenant le main(). public class TableauComplexeDynClonableMain { public static void main(String[] args) { double[] tabPartRe, tabPartIm; int nbEltsTab = 0; if (args.length < 1) nbEltsTab = 5; else nbEltsTab = Integer.parseInt(args[0]); tabPartRe = new double[nbEltsTab]; tabPartIm = new double[nbEltsTab]; for (int i = 0; i < nbEltsTab; i++) { tabPartRe[i] = Math.random(); tabPartIm[i] = Math.random(); } TableauComplexeDynClonable t = new TableauComplexeDynClonable(nbEltsTab, tabPartRe, tabPartIm); System.out.println("Tab : " + t); t.add(4, new ComplexeClonable(2, 2)); t.add(4, new Integer(2)); t.add(3, new String("L’homme regarde la fleur, la fleur sourit."));
  37. 37. System.out.println("Tab : " + t); } } Gestion locale de banque simple en Java – Solutions Solution de l’ex. 1 Gestion simple de banque : solution locale Une solution possible, avec un tableau pour stocker les comptes, est la suivante : // Gestion simpliste de banque en local import java.io.*; /** * Classe conteneur. Contient : * - Client le client * - Server la banque **/ /** * Classe imbriquee pour stocker les donnees d’un compte bancaire **/ class SimpleAccount { String name; String password; // mot de passe int balance; // solde du compte SimpleAccount(String name, String password) { this.name = name; this.password = password; this.balance = 0; } } /** * Serveur bancaire simpliste realise en local **/ class SimpleBankLocalServer { /** * Cette table stocke tous les comptes ouverts **/ SimpleAccount allAccounts[] = new SimpleAccount[100]; /** * Ouvre un compte avec le nom et le mot de passe specifie **/ public void openAccount(String name, String password) { // Verifier s’il exsite deja un compte ayant ce nom int i; for (i = 0; i < allAccounts.length; i++) if (allAccounts[i] != null && ((allAccounts[i]).name).equals(name) == System.out.println("Le compte existe deja.");
  38. 38. System.exit(1); } // Cercher une case libre pour le nouveau compte for (i = 0; i < allAccounts.length; i++) if (allAccounts[i] == null) break; if (i == allAccounts.length) { System.out.println("Tableau des comptes plein !"); System.out.flush(); System.exit(2); } // S’il n’existe pas, le creer SimpleAccount acct = new SimpleAccount(name, password); // Et l’enregsitrer allAccounts[i] = acct; } /** * Cette methode utilitaire renvoie l’indice de l’objet Account dans * le tableau des comptes **/ public int verify(String name, String password) { boolean nonExistant = true; SimpleAccount acct = null; int accIndex = 0; for (accIndex = 0; accIndex < allAccounts.length; accIndex++) { acct = allAccounts[accIndex]; if (acct != null && (acct.name).equals(name) == true) { nonExistant = false; break; } } if (nonExistant == true ) { System.out.println("Compte inexistant"); System.out.flush(); System.exit(3); } if (!password.equals(acct.password)) { System.out.println("Mot de passe invalide"); System.out.flush(); System.exit(4); } return accIndex; } /** * Ferme le compte dont on donne le nom. Methode synchronisee **/ public int closeAccount(String name, String password) { SimpleAccount acct = null; int index = verify(name, password); acct = allAccounts[index]; int balance = acct.balance; acct.balance = 0; allAccounts[index] = null;
  39. 39. return balance; } /** Deposer le montant specifie su le compte dont on donne le nom */ public void deposit(String name, String password, int money) { int index = verify(name, password); SimpleAccount acct = allAccounts[index]; acct.balance += money; } /** Effectue un retrait d’un montant specifie */ public int withdraw(String name, String password, int amount) { int index = verify(name, password); SimpleAccount acct = allAccounts[index]; if (acct.balance < amount) System.out.println("Solde insuffisant"); acct.balance -= amount; return amount; } /** Renvoie le solde du compte dont on donne le nom */ public int getBalance(String name, String password) { int index = verify(name, password); SimpleAccount acct = allAccounts[index]; return acct.balance; } }// class Server /** * Client simple interagissant avec un serveur **/ public class SimpleBankLocal { public static String getName(BufferedReader in) { String name = null; try { System.out.println("Veuillez entrer le nom du compte : "); name = new String(in.readLine().toLowerCase()); } catch (IOException e) { System.err.println("Erreur en readLine()"); } return name; } public static String getPassword(BufferedReader in) { String password = null; try { System.out.println("Veuillez entrer le mot de passe : "); password = new String(in.readLine().toLowerCase()); } catch (IOException e) { System.err.println("Erreur en readLine()"); } return password; } public static void main(String[] args) { try { SimpleBankLocalServer bank = new SimpleBankLocalServer();
  40. 40. BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); String cmd = "nothing"; while(true) { System.out.println("nVeuillez entrer une commande : n" + "open (ouverture de compte)n" + "close (cloture de compte)n" + "deposit (depot sur le compte)n" + "withdraw (retrait sur le compte)n" + "balance (solde du compte)n" + "quit (sortie du programme)n"); // Convertir la commande utilisateur en minuscules cmd = stdin.readLine().toLowerCase(); // Differentes actions possibles if (cmd.equals("open")) { // ouverture de compte String name = getName(stdin); String password = getPassword(stdin); bank.openAccount(name, password); System.out.println("Account opened."); } else if (cmd.equals("close")) { // fermeture de compte String name = getName(stdin); String password = getPassword(stdin); int money = bank.closeAccount(name, password); System.out.println(money + " pieces vous sont rendues."); System.out.println("Au revoir."); } else if (cmd.equals("deposit")) { // depot d’argent String name = getName(stdin); String password = getPassword(stdin); System.out.println("Veuillez entrer le montant : "); String amount = new String(stdin.readLine().toLowerCase()); int money = Integer.parseInt(amount); bank.deposit(name, password, money); System.out.println("Depot de " + money + " pieces."); } else if (cmd.equals("withdraw")) { // retarait d’argent String name = getName(stdin); String password = getPassword(stdin); System.out.println("Veuillez entrer le montant : "); String amount = new String(stdin.readLine().toLowerCase()); int money = bank.withdraw(name, password, Integer.parseInt(amount)); System.out.println("Retrait de " + money + " pieces."); } else if (cmd.equals("balance")) { // solde du compte String name = getName(stdin); String password = getPassword(stdin); int amt = bank.getBalance(name, password); System.out.println("Vous avez "+amt+" de pieces a cette banque."); } else if (cmd.equals("quit")) { // break System.out.println("Au revoirn");
  41. 41. break; } else System.out.println("Action inconnue"); } }// while not quitted // Autres exceptions, erreurs de syntaxe, affichage d’utilisation catch (Exception e) { System.err.println(e); System.err.println("Utilisation : java BankLocal"); } } }// class Client Solution de l’ex. 2 Gestion simple de banque : compléments Une solution possible, avec une HashMap pour stocker les comptes, est la suivante : Classe BankLocal // Gestion simpliste de banque en local import java.util.*; import java.io.*; /** * Client simple interagissant avec un serveur **/ public class BankLocal { public static String getName(BufferedReader in) { String name = null; try { System.out.println("Veuillez entrer le nom du compte : "); name = new String(in.readLine().toLowerCase()); } catch (IOException e) { System.err.println("Erreur en readLine()"); } return name; } public static String getPassword(BufferedReader in) { String password = null; try { System.out.println("Veuillez entrer le mot de passe : "); password = new String(in.readLine().toLowerCase()); } catch (IOException e) { System.err.println("Erreur en readLine()"); } return password; } public static void main(String[] args) { try { BankLocalServer bank = new BankLocalServer(); BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); String cmd = "nothing";
  42. 42. while(true) { System.out.println("nVeuillez entrer une commande : n" + "open (ouverture de compte)n" + "close (cloture de compte)n" + "deposit (depot sur le compte)n" + "withdraw (retrait sur le compte)n" + "balance (solde du compte)n" + "history (historique des transactions)n" + "quit (sortie du programme)n"); // Convertir la commande utilisateur en minuscules cmd = stdin.readLine().toLowerCase(); // Differentes actions possibles if (cmd.equals("open")) { // ouverture de compte String name = getName(stdin); String password = getPassword(stdin); bank.openAccount(name, password); System.out.println("Account opened."); } else if (cmd.equals("close")) { // fermeture de compte String name = getName(stdin); String password = getPassword(stdin); FunnyMoney money = bank.closeAccount(name, password); System.out.println(money.amount+" pieces vous sont rendues."); System.out.println("Au revoir."); } else if (cmd.equals("deposit")) { // depot d’argent String name = getName(stdin); String password = getPassword(stdin); System.out.println("Veuillez entrer le montant : "); String amount = new String(stdin.readLine().toLowerCase()); FunnyMoney money = new FunnyMoney(Integer.parseInt(amount)); bank.deposit(name, password, money); System.out.println("Depot de " + money.amount + " pieces."); } else if (cmd.equals("withdraw")) { // retarait d’argent String name = getName(stdin); String password = getPassword(stdin); System.out.println("Veuillez entrer le montant : "); String amount = new String(stdin.readLine().toLowerCase()); FunnyMoney money = bank.withdraw(name, password, Integer.parseInt(amount)); System.out.println("Retrait de " + money.amount + " pieces."); } else if (cmd.equals("balance")) { // solde du compte String name = getName(stdin); String password = getPassword(stdin); int amt = bank.getBalance(name, password); System.out.println("Vous avez "+amt+" de pieces a cette banque."); } else if (cmd.equals("history")) { // historique des transactions
  43. 43. String name = getName(stdin); String password = getPassword(stdin); ArrayList transactions = bank.getTransactionHistory(name, password); for(int i = 0; i < transactions.size(); i++) System.out.println(transactions.get(i)); } else if (cmd.equals("quit")) { // break System.out.println("Au revoirn"); break; } else System.out.println("Action inconnue"); } }// while not quitted // Gestion des exceptions banacires catch (BankingException e) { System.err.println(e.getMessage()); } // Autres exceptions, erreurs de syntaxe, affichage d’utilisation catch (Exception e) { System.err.println(e); System.err.println("Utilisation : java BankLocal"); } } }// class Client Classe BankLocalServer // Gestion simpliste de banque en local import java.util.*; /** * Classe stockant les donnees d’un compte bancaire **/ class Account { String password; // mot de passe int balance; // solde du compte ArrayList transactions = new ArrayList(); // historique des transactions Account(String password) { this.password = password; this.balance = 0; transactions.add("Compte ouvert le " + new Date()); } } /** * Serveur bancaire simpliste realise en local **/ class BankLocalServer { /** * Cette table de hachage stocke tous les comptes ouverts et relie * chaque noms de compte a l’objet Account correspondant **/ HashMap accounts = new HashMap();
  44. 44. /** * Ouvre un compte avec le nom et le mot de passe specifie * Cette methode est synchronisee de facon qu’une seule thread * ne modifie a la fois la table des comptes. **/ public synchronized void openAccount(String name, String password) throws BankingException { // Verifier s’il exsite deja un compte ayant ce nom if (accounts.get(name) != null) throw new BankingException("Le compte existe deja."); // S’il n’existe pas, le creer Account acct = new Account(password); // Et l’enregsitrer accounts.put(name, acct); } /** * Cette methode utilitaire n’est pas une methode accessible de maniere * distante. Etant donnes un nom et un mot de passe, verifie s’il existe * un compte correspondant. Si oui, renvoie l’objet Account. Sinon, * leve une exception. **/ public Account verify(String name, String password) throws BankingException { synchronized(accounts) { Account acct = (Account)accounts.get(name); if (acct == null) throw new BankingException("Compte inexistant"); if (!password.equals(acct.password)) throw new BankingException("Mot de passe invalide"); return acct; } } /** * Ferme le compte dont on donne le nom. Methode synchronisee **/ public synchronized FunnyMoney closeAccount(String name, String password) throws BankingException { Account acct; acct = verify(name, password); accounts.remove(name); // Avant de changer le solde ou effectuer une transaction sur un compte, // il faut d’abord acquerir un verrou sur ce compte synchronized (acct) { int balance = acct.balance; acct.balance = 0; return new FunnyMoney(balance); }
  45. 45. } /** Deposer le montant specifie su le compte dont on donne le nom */ public void deposit(String name, String password, FunnyMoney money) throws BankingException { Account acct = verify(name, password); synchronized(acct) { acct.balance += money.amount; acct.transactions.add(money.amount + " pieces deposees le " + new Date()); } } /** Effectue un retrait d’un montant specifie */ public FunnyMoney withdraw(String name, String password, int amount) throws BankingException { Account acct = verify(name, password); synchronized(acct) { if (acct.balance < amount) throw new BankingException("Solde insuffisant"); acct.balance -= amount; acct.transactions.add("Retrait de " + amount + " le "+new Date()); return new FunnyMoney(amount); } } /** Renvoie le solde du compte dont on donne le nom */ public int getBalance(String name, String password) throws BankingException { Account acct = verify(name, password); synchronized(acct) { return acct.balance; } } /** * Renvoie un vecteur de String contenant l’historique pour * le compte dont on donne le nom **/ public ArrayList getTransactionHistory(String name, String password) throws BankingException { Account acct = verify(name, password); synchronized(acct) { return acct.transactions; } } }// class Server Classe BankingException // Gestion simpliste de banque en local /** * Type d’exception bancaire, comme "Solde insuffisant" ou "Mot de passe invalide" **/ class BankingException extends Exception { public BankingException(String msg) { super(msg); } }
  46. 46. Classe FunnyMoney // Gestion simpliste de banque en local /** * Cette classe simple represente un montant monetaire. N’est qu’un emballage * d’un entier. **/ class FunnyMoney { public int amount; public FunnyMoney(int amount) { this.amount = amount; } } Conception d’interfaces graphiques et entrées-sorties Exercices d’introduction à la conception d’interfaces graphiques sous Eclipse – Solutions Solution de l’ex. 1 Somme d’entiers Classe SommeGraphiqueMain enrobant la méthode main() import javax.swing.UIManager; import java.awt.*; public class SommeGraphiqueMain { boolean packFrame = false;
  47. 47. //Construct the application public SommeGraphiqueMain() { FrameSommeGraphique frame = new FrameSommeGraphique(); //Validate frames that have preset sizes //Pack frames that have useful preferred size info, e.g. from their layout if (packFrame) { frame.pack(); } else { frame.validate(); } //Center the window Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); Dimension frameSize = frame.getSize(); if (frameSize.height > screenSize.height) { frameSize.height = screenSize.height; } if (frameSize.width > screenSize.width) { frameSize.width = screenSize.width; } frame.setLocation((screenSize.width - frameSize.width) / 2, (screenSize.height frame.setVisible(true); } //Main method public static void main(String[] args) { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClass Name()); } catch(Exception e) { e.printStackTrace(); } new SommeGraphiqueMain(); } } Classe JFrameSomme import javax.swing.WindowConstants; import javax.swing.JDesktopPane; import java.awt.BorderLayout; import javax.swing.JLabel; import javax.swing.border.BevelBorder; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.border.LineBorder; import javax.swing.BorderFactory; import javax.swing.JTextField; /** * This code was generated using CloudGarden’s Jigloo * SWT/Swing GUI Builder, which is free for non-commercial
  48. 48. * use. If Jigloo is being used commercially (ie, by a corporation, * company or business for any purpose whatever) then you * should purchase a license for each developer using Jigloo. * Please visit www.cloudgarden.com for details. * Use of Jigloo implies acceptance of these licensing terms. * ************************************* * A COMMERCIAL LICENSE HAS NOT BEEN PURCHASED * for this machine, so Jigloo or this code cannot be used legally * for any corporate or commercial purpose. * ************************************* */ public class JFrameSomme extends javax.swing.JFrame { private JDesktopPane jDesktopPaneSomme; private JLabel jLabelNombres; private JLabel jLabelResultats; private JLabel jLabelNombreNo2; private JTextField jTextFieldNombreNo1; private JButton jButtonQuitter; private JButton jButtonSommer; private JLabel jLabelValeurResultat; private JLabel jLabelSomme; private JTextField jTextFieldNombreNo2; private JLabel jLabelNombreNo1; /** * Auto-generated main method to display this JFrame */ public static void main(String[] args) { JFrameSomme inst = new JFrameSomme(); inst.setVisible(true); } public JFrameSomme() { super(); initGUI(); } private void initGUI() { try { this.setSize(400, 300); setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); this.getContentPane().setBackground(new java.awt.Color(128,128,128)); { jDesktopPaneSomme = new JDesktopPane(); this.getContentPane().add(jDesktopPaneSomme, BorderLayout.jDesktopPaneSomme.setBorder(BorderFactory.creat eEtchedBorder({ jLabelNombres = new JLabel(); jDesktopPaneSomme.add(jLabelNombres); jLabelNombres.setText("Nombres"); jLabelNombres.setBounds(73, 9, 73, 30); jLabelNombres.setFont(new java.awt.Font("} { jLabelResultats = new JLabel();
  49. 49. jDesktopPaneSomme.add(jLabelResultats); jLabelResultats.setText("Resultats"); jLabelResultats.setBounds(277, 6, 79, 30); jLabelResultats.setFont(new java.awt.Font("} { jLabelNombreNo1 = new JLabel(); jDesktopPaneSomme.add(jLabelNombreNo1); jLabelNombreNo1.setText("NombreNo1"); jLabelNombreNo1.setBounds(73, 72, 76, 30); } { jLabelNombreNo2 = new JLabel(); jDesktopPaneSomme.add(jLabelNombreNo2); jLabelNombreNo2.setText("NombreNo2"); jLabelNombreNo2.setBounds(73, 114, 79, 30); } { jTextFieldNombreNo1 = new JTextField(); jDesktopPaneSomme.add(jTextFieldNombreNo1); jTextFieldNombreNo1.setText(" "); jTextFieldNombreNo1.setBounds(165, 72, 60, 30); } { jTextFieldNombreNo2 = new JTextField(); jDesktopPaneSomme.add(jTextFieldNombreNo2); jTextFieldNombreNo2.setText(" "); jTextFieldNombreNo2.setBounds(165, 114, 60, 30); } { jLabelSomme = new JLabel(); jDesktopPaneSomme.add(jLabelSomme); jLabelSomme.setText("Somme"); jLabelSomme.setBounds(165, 160, 60, 30); jLabelSomme.setFont(new java.awt.Font("Dialog",1,14)); } { jLabelValeurResultat = new JLabel(); jDesktopPaneSomme.add(jLabelValeurResultat); jLabelValeurResultat.setText(" "); jLabelValeurResultat.setBounds(277, 163, 60, 30); jLabelValeurResultat.setBackground(new java.awt.Color(192,192,192)); jLabelValeurResultat.setBorder(new LineBorder(new java.awt.Color(0,0,0), 1, false)); } { jButtonQuitter = new JButton(); jDesktopPaneSomme.add(jButtonQuitter); jButtonQuitter.setText("Quitter"); jButtonQuitter.setBounds(23, 218, 77, 30); jButtonQuitter.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { System.exit(0); }
  50. 50. }); } { jButtonSommer = new JButton(); jDesktopPaneSomme.add(jButtonSommer); jButtonSommer.setText("Sommer"); jButtonSommer.setBounds(278, 218, 85, 30); jButtonSommer.addActionListener(new ActionListener() public void actionPerformed(ActionEvent String texteSomme = "Idéfini"; int somme = 0; String chaineUn = jTextFieldNombreNo1.String chaineUnNettoyee = chaineUn.String chaineDeux = jTextFieldNombreNo2.String chaineDeuxNettoyee = try { int nombreUn = Integer.parseInt(int nombreDeux = Integer.parseInt(somme = nombreUn + nombreDeux; texteSomme = Integer.toString(jLabelValeurResultat.setText(jTextFieldNomb reNo1.setText(""); jTextFieldNombreNo2.setText(""); } catch (NumberFormatException jTextFieldNombreNo1.jTextFieldNombreNo2.jLabelValeurResultat .return; } } }); } } } catch (Exception e) { e.printStackTrace(); } } /** * Auto-generated method for setting the popup menu for a component */ private void setComponentPopupMenu( final java.awt.Component parent, final javax.swing.JPopupMenu menu) { parent.addMouseListener(new java.awt.event.MouseAdapter() { public void mousePressed(java.awt.event.MouseEvent e) { if (e.isPopupTrigger()) menu.show(parent, e.getX(), e.getY()); } public void mouseReleased(java.awt.event.MouseEvent e) { if (e.isPopupTrigger()) menu.show(parent, e.getX(), e.getY()); } }); } } Exercice de conception d’interfaces
  51. 51. graphiques pour application bancaire – Solutions Solution de l’ex. 1 Conception d’une interface pour application bancaire simple Interface graphique Classe GUIBanqueFrame import javax.swing.WindowConstants; /** * This code was generated using CloudGarden’s Jigloo * SWT/Swing GUI Builder, which is free for non-commercial * use. If Jigloo is being used commercially (ie, by a corporation, * company or business for any purpose whatever) then you * should purchase a license for each developer using Jigloo. * Please visit www.cloudgarden.com for details. * Use of Jigloo implies acceptance of these licensing terms. * ************************************* * A COMMERCIAL LICENSE HAS NOT BEEN PURCHASED * for this machine, so Jigloo or this code cannot be used legally * for any corporate or commercial purpose. * ************************************* */ import javax.swing.JMenuBar; import javax.swing.JMenu; import javax.swing.JMenuItem; public class GUIBanqueFrame extends javax.swing.JFrame { private JMenuBar jMenuGUIBanque; private JMenu jMenuFichier; private JMenuItem jMenuOperationsItemSolde; private JMenuItem jMenuOperationsItemHistorique; private JMenuItem jMenuOperationsItemRetrait; private JMenuItem jMenuOperationsItemDepot; private JMenuItem jMenuOperationsItemFermer; private JMenuItem jMenuOperationsItemOuvrir; private JMenuItem jMenuFichierItemQuitter; private JMenu jMenuOperations; /** * Auto-generated main method to display this JFrame */ public static void main(String[] args) { GUIBanqueFrame inst = new GUIBanqueFrame(); inst.setVisible(true); } public GUIBanqueFrame() { super(); initGUI(); } private void initGUI() { try { setSize(400, 300); setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); {
  52. 52. jMenuGUIBanque = new JMenuBar(); setJMenuBar(jMenuGUIBanque); jMenuGUIBanque.setPreferredSize(new java.awt.Dimension(390, 18)); { jMenuFichier = new JMenu(); jMenuGUIBanque.add(jMenuFichier); jMenuFichier.setText("Fichier"); { jMenuFichierItemQuitter = new JMenuItem(); jMenuFichier.add(jMenuFichierItemQuitter); jMenuFichierItemQuitter.setText(" } } { jMenuOperations = new JMenu(); jMenuGUIBanque.add(jMenuOperations); jMenuOperations.setText("Operations"); { jMenuOperationsItemOuvrir = new jMenuOperations.add(jMenuOperat jMenuOperationsItemOuvrir.setTex } { jMenuOperationsItemFermer = new jMenuOperations.add(jMenuOperati jMenuOperationsItemFermer.setTex } { jMenuOperationsItemSolde = new J jMenuOperations.add(jMenuOperationsItemSolde); jMenuOperationsItemSolde.setText("} { jMenuOperationsItemDepot = new JMenuItem(); jMenuOperations.add(jMenuOperationsItemDepot); jMenuOperationsItemDepot.setText("} { jMenuOperationsItemRetrait = new jMenuOperations.add(jMenuOperationsItemRetrait); jMenuOperationsItemRetrait .setText("Retrait d’un compte"); } { jMenuOperationsItemHistorique = jMenuOperations.add(jMenuOperationsItemHistorique); jMenuOperationsItemHistorique .setText("Historique d’un } } } } catch (Exception e) { e.printStackTrace(); } } }
  53. 53. Classe GUIBankLocalServer import java.util.*; /** * Classe conteneur. Contient : * - FunnyMoney la monnaie utilisee * - BankingException une exception bancaire * - Server la banque **/ /** * Cette classe simple represente un montant monetaire. N’est qu’un emballage * d’un entier. **/ class FunnyMoney { public int amount; public FunnyMoney(int amount) { this.amount = amount; } } public class GUIBankLocalServer { /** * Classe imbriquee pour stocker les donnees d’un compte bancaire **/ class Account { String password; // mot de passe int balance; // solde du compte ArrayList transactions = new ArrayList(); // historique des transactions Account(String password) { this.password = password; this.balance = 0; transactions.add("Compte ouvert le " + new Date()); } } /** * Cette table de hachage stocke tous les comptes ouverts et relie * chaque noms de compte a l’objet Account correspondant **/ HashMap accounts = new HashMap(); /** * Ouvre un compte avec le nom et le mot de passe specifie * Cette methode est synchronisee de facon qu’une seule thread * ne modifie a la fois la table des comptes. **/ public synchronized void openAccount(String name, String password) throws GUIBankingException { // Verifier s’il exsite deja un compte ayant ce nom if (accounts.get(name) != null) throw new GUIBankingException("Le compte existe deja."); // S’il n’existe pas, le creer Account acct = new Account(password);
  54. 54. // Et l’enregsitrer accounts.put(name, acct); } /** * Cette methode utilitaire n’est pas une methode accessible de maniere * distante. Etant donnes un nom et un mot de passe, verifie s’il existe * un compte correspondant. Si oui, renvoie l’objet Account. Sinon, * leve une exception. **/ public Account verify(String name, String password) throws GUIBankingException { synchronized(accounts) { Account acct = (Account)accounts.get(name); if (acct == null) throw new GUIBankingException("Compte inexistant"); if (!password.equals(acct.password)) throw new GUIBankingException("Mot de passe invalide"); return acct; } } /** * Ferme le compte dont on donne le nom. Methode synchronisee **/ public synchronized FunnyMoney closeAccount(String name, String password) throws GUIBankingException { Account acct; acct = verify(name, password); accounts.remove(name); // Avant de changer le solde ou effectuer une transaction sur un compte, // il faut d’abord acquerir un verrou sur ce compte synchronized (acct) { int balance = acct.balance; acct.balance = 0; return new FunnyMoney(balance); } } /** Deposer le montant specifie su le compte dont on donne le nom */ public void deposit(String name, String password, FunnyMoney money) throws GUIBankingException { Account acct = verify(name, password); synchronized(acct) { acct.balance += money.amount; acct.transactions.add(money.amount + " pieces deposees le " + new Date()); } } /** Effectue un retrait d’un montant specifie */
  55. 55. public FunnyMoney withdraw(String name, String password, FunnyMoney money) throws GUIBankingException { int amount = money.amount; Account acct = verify(name, password); synchronized(acct) { if (acct.balance < amount) throw new GUIBankingException("Solde insuffisant"); acct.balance -= amount; acct.transactions.add("Retrait de " + amount + " le "+new Date()); return new FunnyMoney(amount); } } /** Renvoie le solde du compte dont on donne le nom */ public FunnyMoney getBalance(String name, String password) throws GUIBankingException { Account acct = verify(name, password); synchronized(acct) { return new FunnyMoney(acct.balance); } } /** * Renvoie un vecteur de String contenant l’historique pour * le compte dont on donne le nom **/ public ArrayList getTransactionHistory(String name, String password) throws GUIBankingException { Account acct = verify(name, password); synchronized(acct) { return acct.transactions; } } } Fenêtres de dialogue Classe NomMotPasseDialog import javax.swing.JFrame; /** * This code was generated using CloudGarden’s Jigloo * SWT/Swing GUI Builder, which is free for non-commercial * use. If Jigloo is being used commercially (ie, by a corporation, * company or business for any purpose whatever) then you * should purchase a license for each developer using Jigloo. * Please visit www.cloudgarden.com for details. * Use of Jigloo implies acceptance of these licensing terms. * ************************************* * A COMMERCIAL LICENSE HAS NOT BEEN PURCHASED * for this machine, so Jigloo or this code cannot be used legally * for any corporate or commercial purpose. * ************************************* */ import javax.swing.JLabel; import javax.swing.JButton; import javax.swing.JTextField;
  56. 56. import javax.swing.JPanel; import java.awt.BorderLayout; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; public class NomMotPasseDialog extends javax.swing.JDialog { private JPanel jPanelNomMotPasseDialog; private JLabel jLabelStrNom; private JButton jButtonOK; private JTextField jTextFieldMontant; private JTextField jTextFieldMotDePasse; private JTextField jTextFieldNom; private JLabel jLabelStrMontant; private JLabel jLabelStrMotDePasse; protected String name = null; protected String password = null; protected int montant = -1; public NomMotPasseDialog(JFrame frame, boolean modal) { super(frame, modal); initGUI(); } void actionPerformedNomPass(ActionEvent e) { name = new String(jTextFieldNom.getText().trim()); password = new String(jTextFieldMotDePasse.getText().trim()); if (jTextFieldMontant.isVisible()) { montant = Integer.parseInt(jTextFieldMontant.getText().trim()); jTextFieldMontant.setText(""); } jTextFieldNom.setText(""); jTextFieldMotDePasse.setText(""); this.setVisible(false); } public void partialShow() { this.jLabelStrMontant.setVisible(false); this.jTextFieldMontant.setVisible(false); this.setVisible(true); this.jLabelStrMontant.setVisible(true); this.jTextFieldMontant.setVisible(true); } public String getName() { return name; } public String getPassword() { return password; } public FunnyMoney getAmount() { return new FunnyMoney(montant); } private void initGUI() { try { setSize(400, 300); { jPanelNomMotPasseDialog = new JPanel(); this.getContentPane().add( jPanelNomMotPasseDialog, BorderLayout.CENTER); jPanelNomMotPasseDialog.setLayout(null);
  57. 57. jPanelNomMotPasseDialog.setPreferredSize(new java.awt.Dimension(315, 200)); { jLabelStrNom = new JLabel(); jPanelNomMotPasseDialog.add(jLabelStrNom); jLabelStrNom.setText("Nom"); jLabelStrNom.setBounds(43, 31, 60, 30); } { jLabelStrMotDePasse = new JLabel(); jPanelNomMotPasseDialog.add(jLabelStrMotDePasse); jLabelStrMotDePasse.setText("Mot de passe"); jLabelStrMotDePasse.setBounds(43, 71, 93, 30); } { jLabelStrMontant = new JLabel(); jPanelNomMotPasseDialog.add(jLabelStrMontant); jLabelStrMontant.setText("Montant"); jLabelStrMontant.setBounds(43, 114, 60, 30); } { jTextFieldNom = new JTextField(); jPanelNomMotPasseDialog.add(jTextFieldNom); jTextFieldNom.setText(" "); jTextFieldNom.setBounds(141, 31, 60, 30); } { jTextFieldMotDePasse = new JTextField(); jPanelNomMotPasseDialog.add(jTextFieldMo jTextFieldMotDePasse.setText(" jTextFieldMotDePasse.setBounds(141, 71, } { jTextFieldMontant = new JTextField(); jPanelNomMotPasseDialog.add(jTextFieldMontant); jTextFieldMontant.setText(" jTextFieldMontant.setBounds(141, 114, 60, } { jButtonOK = new JButton(); jPanelNomMotPasseDialog.add(jButtonOK); jButtonOK.setText("OK"); jButtonOK.setBounds(267, 184, 60, 30); jButtonOK.addActionListener(new ActionListener() public void actionPerformed(ActionEvent actionPerformedNomPass(evt); }); } } } catch (Exception e) { e.printStackTrace(); } } /** * Auto-generated method for setting the popup menu for a component */ private void setComponentPopupMenu(
  58. 58. final java.awt.Component parent, final javax.swing.JPopupMenu menu) { parent.addMouseListener(new java.awt.event.MouseAdapter() { public void mousePressed(java.awt.event.MouseEvent e) { if (e.isPopupTrigger()) menu.show(parent, e.getX(), e.getY()); } public void mouseReleased(java.awt.event.MouseEvent e) { if (e.isPopupTrigger()) menu.show(parent, e.getX(), e.getY()); } }); } } Classe GUIBankingException /** * Type d’exception bancaire, comme "Solde insuffisant" ou "Mot de passe invalide" **/ public class GUIBankingException extends Exception { static BankingExceptionDialog dialog = new BankingExceptionDialog(null, true); protected String message; public GUIBankingException(String msg) { message = msg; } public String getMessage() { return message; } public void showErrorMessage(String msg) { dialog.setMessage(msg); dialog.setVisible(true); } } Classe BankingExceptionDialog import javax.swing.JFrame; /** * This code was generated using CloudGarden’s Jigloo * SWT/Swing GUI Builder, which is free for non-commercial * use. If Jigloo is being used commercially (ie, by a corporation, * company or business for any purpose whatever) then you * should purchase a license for each developer using Jigloo. * Please visit www.cloudgarden.com for details. * Use of Jigloo implies acceptance of these licensing terms. * ************************************* * A COMMERCIAL LICENSE HAS NOT BEEN PURCHASED * for this machine, so Jigloo or this code cannot be used legally * for any corporate or commercial purpose. * ************************************* */ import javax.swing.JPanel; import javax.swing.JLabel; import javax.swing.JButton;
  59. 59. import java.awt.BorderLayout; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; public class BankingExceptionDialog extends javax.swing.JDialog { private JPanel jPanelBankingExceptionDialog; private JButton jButtonOK; private JLabel jLabelMessageErreur; public BankingExceptionDialog(JFrame frame, boolean modal) { super(frame, modal); initGUI(); } void actionPerformedOK(ActionEvent e) { this.setVisible(false); } public void setMessage(String m) { jLabelMessageErreur.setText(m); } private void initGUI() { try { setSize(400, 300); { jPanelBankingExceptionDialog = new JPanel(); this.getContentPane().add( jPanelBankingExceptionDialog, BorderLayout.CENTER); jPanelBankingExceptionDialog.setLayout(null); { jLabelMessageErreur = new JLabel(); jPanelBankingExceptionDialog.add(jLabelMessageErreur); jLabelMessageErreur.setText(" "); jLabelMessageErreur.setBounds(47, 52, 303, } { jButtonOK = new JButton(); jPanelBankingExceptionDialog.add(jButtonOK); jButtonOK.setText("OK"); jButtonOK.setBounds(162, 197, 60, 30); jButtonOK.addActionListener(new ActionListener() public void actionPerformed(ActionEvent actionPerformedOK(evt); } }); } } } catch (Exception e) { e.printStackTrace(); } } /** * Auto-generated method for setting the popup menu for a component */ private void setComponentPopupMenu( final java.awt.Component parent,
  60. 60. final javax.swing.JPopupMenu menu) { parent.addMouseListener(new java.awt.event.MouseAdapter() { public void mousePressed(java.awt.event.MouseEvent e) { if (e.isPopupTrigger()) menu.show(parent, e.getX(), e.getY()); } public void mouseReleased(java.awt.event.MouseEvent e) { if (e.isPopupTrigger()) menu.show(parent, e.getX(), e.getY()); } }); } } Gestion de threads et programmation concurrente Exercices d’introduction aux activités (threads) Java – Solutions Solution de l’ex. 1 Une horloge simpliste /* A class with one thread, implementing a Digital Clock */ import java.awt.Graphics; import java.awt.Font; import java.util.Date; public class DigitalThread extends java.applet.Applet implements Runnable { Font theFont = new Font("TimesRoman",Font.BOLD,24); Date theDate; Thread runner; // override the applet start method public void start() { if (runner == null);
  61. 61. { // construct an instance of a thread and use the run method // from "this" applet runner = new Thread(this); runner.start(); // call the thread start method } } // override the applet stop method public void stop() { if (runner != null) { runner.stop(); // call the thread stop method runner = null; } } // provide a method run to be the body of the thread // this method required by the runnable interface public void run() { while (true) { theDate = new Date(); // this method will call applet method update, // which will call paint below repaint(); // current thread will sleep for 1 second try { Thread.sleep(1000); } catch (InterruptedException e) { } } } // provide the applet paint method public void paint(Graphics g) { g.setFont(theFont); g.drawString(theDate.toString(),10,50); } } Solution de l’ex. 2 Affichage d’une série d’images : Duke fait la roue import java.io.InputStream; import java.applet.Applet; import java.awt.*; import java.net.*; /** * Une applet simple pour jouer en bocle une serie d’images, * le tag "img" indique que suite d’images doit etre jouee * */ public class TDuke extends Applet implements Runnable { /** * The current loop slot. */
  62. 62. int loopslot = 0; String dir; // Rep ou URL des images Thread kicker = null; // Activite animatrice int pause; // pause entre les images int offset; int off; int speed; int nimgs; Image imgs[]; // tableau des images int maxWidth; public void run() { dir = "ImagesTumbleDuke"; nimgs = 16; setBackground(Color.gray); Thread.currentThread().setPriority(Thread.NORM_PRIORITY-1); imgs = new Image[nimgs]; for (int i = 1; i < nimgs; i++) { imgs[i] = getImage(getDocumentBase(), dir + "/T" + i + ".gif"); } Dimension d = getSize(); while (kicker != null) { if (++loopslot >= nimgs) { loopslot = 0; } repaint(); try { Thread.sleep(300); } catch (InterruptedException e) { break; } }// while (kicker != null) } public void paint(Graphics g) { if ((imgs != null) && (loopslot < nimgs) && (imgs[loopslot] != null)) { g.drawImage(imgs[loopslot], 0, 0, this); } } public void start() { if (kicker == null) { kicker = new Thread(this); kicker.start(); } } public void stop() { if (kicker != null) { kicker.stop(); kicker = null; } } }
  63. 63. Solution de l’ex. 3 Une horloge avec affichage graphique import java.awt.*; import java.applet.*; import java.util.Date; public class GraphicClock extends Applet implements Runnable { Thread myThread; public void init() { } public void start() { myThread = new Thread(this); myThread.start(); } Date date; int hours, minutes, seconds, clockHours, clockMinutes, clockSeconds; String time; public void run() { for (;;) { // Prendre la date et l’heure systeme date = new Date(); hours = date.getHours(); // Conversion des heures, minutes, secondes en degres // (de 0 a 360) // Le signe - est necessaire a cause de fillArc() clockHours = -(hours>=12 ? hours - 12 : hours) * 30; minutes = date.getMinutes(); clockMinutes = -minutes * 6; seconds = date.getSeconds(); clockSeconds = -seconds * 6; time = "" + hours + ":" + minutes + ":" + seconds; repaint(); try { myThread.sleep(1000); } catch (InterruptedException e) {} } } public void stop() { if (myThread!= null) { myThread.stop(); myThread = null; } } public void paint(Graphics g) { g.setColor(Color.blue); g.fillArc(10,10,100,100,90,clockSeconds); g.setColor(Color.red); g.fillArc(20,20,80,80,90,clockMinutes); g.setColor(Color.yellow); g.fillArc(30,30,60,60,90,clockHours); g.setColor(Color.blue); g.drawString(time,40, 125);
  64. 64. } } Exercices sur les threads autour d’une balle – Solutions Solution de l’ex. 1 Une balle rebondissante (utilisation d’activité ou thread) Voici le bout de code HTML pour lancer l’applet à partir d’un navigateur : <APPLET CODE="BallField.class" WIDTH=300 HEIGHT=300></APPLET> Voici le code Java de la classe Ball, archétype d’une balle en mouvement. Notez que la balle elle-même n’est pas responsable de son mouvement. Elle est animée par la classe BallField dont le code est fourni ensuite. Cette architecture est de type maître/esclave, le maître étant ici BallField. Un autre type d’architecture est celle de type purement distribuée, où les balles sont chacune responsables de leur propre animation. Concrètement, cela impliquerait que chaque balle implante Runnable, alors qu’ici seul BallField implante Runnable. Un autre remarque cruciale : remarquez bien que l’accès à chaque champ ne peut (quasiment) se faire qu’au travers d’une méthode, que ce soit pour l’obtention d’une valeur ou la modification d’une valeur d’un champ. Code de Ball // // Ball : Disque en mouvement // import java.awt.*; public class Ball { protected int x, y; // position de la balle protected int size; // diametre de la balle protected int dx, dy; // vecteur deplacement protected int dt; // intervalle entre 2 affichages protected Color color; // couleur protected Color backgroundColor; // couleur du fond public Ball (int Xpos, int Ypos, int diameter, Color backColor) { x = Xpos; y = Ypos; size = diameter; dx = 0; dy = 0; dt = 0; // Initialemetnt inerte color = Color.red; // Initialement rouge backgroundColor = backColor; } // methodes fixant des attributs
  65. 65. // public void setXY(int nPosX, int nPosY) { x = nPosX; y = nPosY; } public void setSize(int newSize) { size = newSize; } public void setDxDy (int ndx, int ndy) { dx = ndx; dy = ndy; } public void setDt (int ndt) { dt = ndt; } public void setColor (Color newColor) { color = newColor; } // methodes accedant aux attributs (accesseurs) // public int getX() { return x; } public int getY() { return y; } public int getSize() { return size; } public int getDx() { return dx; } public int getDy() { return dy; } public int getDt() { return dt; } public Color getColor() { return color; } // methodes modifiant des attributs // public void move() { x += dx; y += dy; } // Afficher la balle a sa position courante // public void paint(Graphics g) { // Astuce : pour eviter de voir un croissant rouge derriere la balle, // on dessine une balle en couleur de fond a l’endroit // precedent (c.a.d. aux coordonnees -dx, -dy) g.setColor(backgroundColor); g.fillOval(x-(size/2)-dx, y-(size/2)-dy, size, size); // Affichage proprement dit de la balle g.setColor(color); g.fillOval(x-(size/2), y-(size/2), size, size); } // Traiter le rebond sur les bords // public void xBounce() { dx = -dx; } public void yBounce() { dy = -dy; } }// public class Ball Code de BallField Elle anime la balle précédente. import java.applet.*; import java.awt.*; /* * Terrain a balle : responsable de lŠanimation de la balle */ public class BallField extends Applet implements Runnable { int x = 150, y = 50, size = 50; // position et rayon de la balle int dx = 11, dy = 7; // trajectoire de la balle int dt = 90; // nbre de ms entre 2 affichages Thread animationThread = null; // thread pour l’animation Ball theBall = null; volatile boolean stopped=true;
  66. 66. /* * Initialisation de l’applet */ public void init() { animationThread = new Thread(this, "Animation de balle"); theBall = new Ball(x, y, size, Color.black); theBall.setDxDy(dx, dy); theBall.setDt(dt); // Fixer la couleur de fond ; cf. paint() de Ball setBackground(Color.black); } /* * Bouger, faire rebondir la balle et demander de redessiner. */ public void paint(Graphics g) { Dimension d = getSize(); int x, y, dx, dy, r; // position, direction et rayon de la balle // Initialisations x = theBall.getX(); y = theBall.getY(); dx = theBall.getDx(); dy = theBall.getDy(); r = theBall.getSize() / 2; // On rebondit si l’on a heurte un cote if ((x - r + dx < 0) || (x + r + dx > d.width)) { theBall.xBounce(); } if ((y - r + dy < 0) || (y + r + dy > d.height)) { theBall.yBounce(); } // Bouger la balle theBall.move(); // Demander au navigateur d’appeler la methode paint() pour // afficher la balle a sa nouvelle position theBall.paint(g); } /* * Demarrer l’activite lorsque le navigateur demarre l’applet */ public void start() { if (!animationThread.isAlive()) { animationThread.start(); } synchronized(this){ stopped=false; notify(); } }// start() /* * Arreter l’activite lorsque le navigateur interromp lŠapplet */ public void stop() { synchronized(this){ stopped=true; } }
  67. 67. /* * Boucler indefiniment en appelant animer(), puis en se reposant */ public void run() { while (true) { repaint(); try { synchronized(this){ while(stopped){ wait(); } } Thread.sleep(theBall.getDt()); } catch (InterruptedException e) { break; } } }// run() }// class BallField On notera que dans la solution précédente, l’on utilise une variable de condition bolléenne stopped utilisée dans run() et modifiée dans start() et dans stop(). Un wait() dans run() déclenché par la condition stopped == true est associé à un notify() dans start(). Code de BallDoubleBuffering Nous donnons ici une solution au problème de clignotement de l’affichage qui apparaît habituellement. Cette technique, dite du double buffering, consiste à écrire les modifications d’affichage dans un plan mémoire (et non directement à l’écran), puis, une fois que l’ensemble de la fenêtre à afficher est prête, à affectuer l’affichage d’un coup. // This example is from _Java Examples in a Nutshell_. (http://www.oreilly.com) // Copyright (c) 1997 by David Flanagan // This example is provided WITHOUT ANY WARRANTY either expressed or implied. // You may study, use, modify, and distribute it for non-commercial purposes. // For any commercial use, see http://www.davidflanagan.com/javaexamples import java.applet.*; import java.awt.*; /** * An applet that displays a simple animation using double-buffering * and clipping **/ public class BallDoubleBuffering extends Applet implements Runnable { int x = 150, y = 100, r=20; // Position and radius of the circle

×