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. // 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. 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. 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. /**
* 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. 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. }
// 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. 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. } 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. 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. }
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. 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. 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. }
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. }
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. 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. 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. 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. é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. 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. }
}
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. 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. 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. 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. 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. 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. /*
* 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. 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. 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. }
}
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. 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. 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. 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. 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. }// 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. 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. 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. 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. 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. 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. 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. 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. 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. /**
* 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. }
/** 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. 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. //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. * 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();
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. 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. 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. 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. // 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. 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. 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. 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. 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. 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. 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. {
// 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. 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. 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. }
}
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. //
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. /*
* 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. /*
* 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