init
This commit is contained in:
commit
e907d221c2
13
TP01/CycleVie.java
Normal file
13
TP01/CycleVie.java
Normal file
|
@ -0,0 +1,13 @@
|
|||
/** Illustrer le ramasse-miettes de Java.
|
||||
* @author Xavier Crégut
|
||||
* @version 1.4
|
||||
*/
|
||||
public class CycleVie {
|
||||
|
||||
public static void main(String[] args) {
|
||||
for (int i = 0; i < 100_000; i++) {
|
||||
Point p = new Point(i, i);
|
||||
}
|
||||
System.out.println("Fini !");
|
||||
}
|
||||
}
|
91
TP01/ExempleComprendre.java
Normal file
91
TP01/ExempleComprendre.java
Normal file
|
@ -0,0 +1,91 @@
|
|||
/** Comprendre les objets et les poignées sur la classe Point.
|
||||
* @author Xavier Crégut
|
||||
* @version 1.6
|
||||
*/
|
||||
public class ExempleComprendre {
|
||||
|
||||
/** Afficher un point précédé d'un texte.
|
||||
* @param texte le texte à afficher
|
||||
* @param p le point à afficher
|
||||
*/
|
||||
public static void afficher(String texte, Point p) {
|
||||
System.out.print(texte + " = ");
|
||||
p.afficher();
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
/** Méthode principale */
|
||||
public static void main(String[] args) {
|
||||
// Créer et afficher un point p1
|
||||
Point p1; // déclarer une poignée sur un Point
|
||||
p1 = new Point(3, 4); // créer un point et l'attacher à p1
|
||||
// On peut écrire les deux instructions précédentes sur la
|
||||
// même ligne. Ceci évite d'oublier d'initialiser une
|
||||
// poignée.
|
||||
afficher("p1", p1);
|
||||
|
||||
// Créer et afficher un point p2
|
||||
Point p2 = new Point(0, 0); // On déclare des poignées et on
|
||||
// crée des objets quand on veut.
|
||||
afficher("p2", p2);
|
||||
|
||||
// Afficher la distance entre p1 et p2
|
||||
double d = p1.distance(p2);
|
||||
System.out.println("Distance de p1 à p2 : " + d);
|
||||
|
||||
// Translater p1
|
||||
System.out.println("> p1.translater(6, -2);");
|
||||
p1.translater(6, -2);
|
||||
afficher("p1", p1); // Qu'est ce qui est affiché ?
|
||||
|
||||
// Changer l'abscisse de p1 et afficher p1
|
||||
System.out.println("> p1.setX(0);");
|
||||
p1.setX(0);
|
||||
afficher("p1", p1); // Qu'est ce qui est affiché ?
|
||||
|
||||
// Changer l'ordonnée de p1 et afficher p1
|
||||
System.out.println("> p1.setY(10);");
|
||||
p1.setY(10);
|
||||
afficher("p1", p1);
|
||||
// Dessiner l'état de la mémoire
|
||||
// Prendre une nouvelle poignée sur p1
|
||||
System.out.println("> Point p3 = p1;");
|
||||
Point p3 = p1;
|
||||
afficher("p3", p3); // Qu'est ce qui est affiché ?
|
||||
afficher("p1", p1); // Qu'est ce qui est affiché ?
|
||||
|
||||
// Déplacer p3
|
||||
System.out.println("> p3.translater(100, 100);");
|
||||
p3.translater(100, 100);
|
||||
afficher("p3", p3); // Qu'est ce qui est affiché ?
|
||||
|
||||
// Afficher p1
|
||||
afficher("p1", p1); // Qu'est ce qui est affiché ?
|
||||
|
||||
// Dessiner l'état de la mémoire
|
||||
// Affectations entre poignées
|
||||
System.out.println("> p3 = new Point(123, 321);");
|
||||
p3 = new Point(123, 321);
|
||||
afficher("p3", p3); // Qu'est ce qui est affiché ?
|
||||
afficher("p1", p1); // Qu'est ce qui est affiché ?
|
||||
|
||||
System.out.println("> p1 = p2 = p3;");
|
||||
p1 = p2 = p3;
|
||||
// Dessiner l'état de la mémoire
|
||||
afficher("p1", p1); // Qu'est ce qui est affiché ?
|
||||
afficher("p2", p2); // Qu'est ce qui est affiché ?
|
||||
afficher("p3", p3); // Qu'est ce qui est affiché ?
|
||||
|
||||
// p1, p2 et p3 sont-ils des points différents ?
|
||||
System.out.println("> p1.translater(-123, -321);");
|
||||
p1.translater(-123, -321);
|
||||
afficher("p1", p1); // Qu'est ce qui est affiché ?
|
||||
afficher("p2", p2); // Qu'est ce qui est affiché ?
|
||||
afficher("p3", p3); // Qu'est ce qui est affiché ?
|
||||
|
||||
d = new Point(5, 5).distance(new Point(8, 1));
|
||||
System.out.println("d = " + d);
|
||||
|
||||
// Combien y a-t-il de points accessibles ?
|
||||
}
|
||||
}
|
108
TP01/ExempleComprendreTutor.java
Normal file
108
TP01/ExempleComprendreTutor.java
Normal file
|
@ -0,0 +1,108 @@
|
|||
class MonPoint {
|
||||
|
||||
public MonPoint(double vx, double vy) {
|
||||
this.x = vx;
|
||||
this.y = vy;
|
||||
}
|
||||
|
||||
public double getX() {
|
||||
return this.x;
|
||||
}
|
||||
|
||||
public double getY() {
|
||||
return this.y;
|
||||
}
|
||||
|
||||
public void setX(double vx) {
|
||||
this.x = vx;
|
||||
}
|
||||
|
||||
public void setY(double vy) {
|
||||
this.y = vy;
|
||||
}
|
||||
|
||||
public void afficher() {
|
||||
System.out.print("(" + this.x + ", " + this.y + ")");
|
||||
}
|
||||
|
||||
public double distance(MonPoint autre) {
|
||||
return Math.sqrt(Math.pow(autre.x - this.x, 2)
|
||||
+ Math.pow(autre.y - this.y, 2));
|
||||
}
|
||||
|
||||
public void translater(double dx, double dy) {
|
||||
this.x += dx;
|
||||
this.y += dy;
|
||||
}
|
||||
|
||||
private double x;
|
||||
private double y;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public class ExempleComprendreTutor {
|
||||
|
||||
public static void afficher(String texte, MonPoint p) {
|
||||
System.out.print(texte + " = ");
|
||||
p.afficher();
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
MonPoint p1;
|
||||
p1 = new MonPoint(3, 4);
|
||||
afficher("p1", p1);
|
||||
|
||||
MonPoint p2 = new MonPoint(0, 0);
|
||||
afficher("p2", p2);
|
||||
|
||||
double d = p1.distance(p2);
|
||||
System.out.println("Distance de p1 à p2 : " + d);
|
||||
|
||||
System.out.println("> p1.translater(6, -2);");
|
||||
p1.translater(6, -2);
|
||||
afficher("p1", p1); // Qu'est ce qui est affiché ?
|
||||
|
||||
System.out.println("> p1.setX(0);");
|
||||
p1.setX(0);
|
||||
afficher("p1", p1); // Qu'est ce qui est affiché ?
|
||||
|
||||
System.out.println("> p1.setY(10);");
|
||||
p1.setY(10);
|
||||
afficher("p1", p1);
|
||||
|
||||
System.out.println("> MonPoint p3 = p1;");
|
||||
MonPoint p3 = p1;
|
||||
afficher("p3", p3);
|
||||
afficher("p1", p1);
|
||||
|
||||
System.out.println("> p3.translater(100, 100);");
|
||||
p3.translater(100, 100);
|
||||
afficher("p3", p3);
|
||||
|
||||
afficher("p1", p1);
|
||||
|
||||
System.out.println("> p3 = new MonPoint(123, 321);");
|
||||
p3 = new MonPoint(123, 321);
|
||||
afficher("p3", p3);
|
||||
afficher("p1", p1);
|
||||
|
||||
System.out.println("> p1 = p2 = p3;");
|
||||
p1 = p2 = p3;
|
||||
afficher("p1", p1);
|
||||
afficher("p2", p2);
|
||||
afficher("p3", p3);
|
||||
|
||||
System.out.println("> p1.translater(-123, -321);");
|
||||
p1.translater(-123, -321);
|
||||
afficher("p1", p1);
|
||||
afficher("p2", p2);
|
||||
afficher("p3", p3);
|
||||
|
||||
d = new MonPoint(5, 5).distance(new MonPoint(8, 1));
|
||||
System.out.println("d = " + d);
|
||||
}
|
||||
|
||||
}
|
17
TP01/ExempleErreur.java
Normal file
17
TP01/ExempleErreur.java
Normal file
|
@ -0,0 +1,17 @@
|
|||
/** Une erreur à la compilation !
|
||||
* Pourquoi ?
|
||||
* @author Xavier Crégut
|
||||
* @version 1.3
|
||||
*/
|
||||
public class ExempleErreur {
|
||||
|
||||
/** Méthode principale */
|
||||
public static void main(String[] args) {
|
||||
Point p1 = new Point(0, 0);
|
||||
p1.setX(1);
|
||||
p1.setY(2);
|
||||
p1.afficher();
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
}
|
115
TP01/Point.java
Normal file
115
TP01/Point.java
Normal file
|
@ -0,0 +1,115 @@
|
|||
import java.awt.Color;
|
||||
|
||||
/** Point modélise un point géométrique dans un plan équipé d'un
|
||||
* repère cartésien. Un point peut être affiché et translaté.
|
||||
* Sa distance par rapport à un autre point peut être obtenue.
|
||||
*
|
||||
* @author Xavier Crégut <Prénom.Nom@enseeiht.fr>
|
||||
*/
|
||||
public class Point {
|
||||
/** Construire un point à partir de son abscisse et de son ordonnée.
|
||||
* @param vx abscisse
|
||||
* @param vy ordonnée
|
||||
*/
|
||||
public Point(double vx, double vy) {
|
||||
System.out.println("CONSTRUCTEUR Point(" + vx + ", " + vy + ")");
|
||||
this.x = vx;
|
||||
this.y = vy;
|
||||
this.couleur = Color.green;
|
||||
}
|
||||
|
||||
/** Obtenir l'abscisse du point.
|
||||
* @return abscisse du point
|
||||
*/
|
||||
public double getX() {
|
||||
return this.x;
|
||||
}
|
||||
|
||||
/** Obtenir l'ordonnée du point.
|
||||
* @return ordonnée du point
|
||||
*/
|
||||
public double getY() {
|
||||
return this.y;
|
||||
}
|
||||
|
||||
/** Changer l'abscisse du point.
|
||||
* @param vx nouvelle abscisse
|
||||
*/
|
||||
public void setX(double vx) {
|
||||
this.x = vx;
|
||||
}
|
||||
|
||||
/** Changer l'ordonnée du point.
|
||||
* @param vy nouvelle ordonnée
|
||||
*/
|
||||
public void setY(double vy) {
|
||||
this.y = vy;
|
||||
}
|
||||
|
||||
/** Afficher le point. */
|
||||
public void afficher() {
|
||||
System.out.print("(" + this.x + ", " + this.y + ")");
|
||||
}
|
||||
|
||||
/** Distance par rapport à un autre point.
|
||||
* @param autre l'autre point
|
||||
* @return distance entre this et autre
|
||||
*/
|
||||
public double distance(Point autre) {
|
||||
return Math.sqrt(Math.pow(autre.x - this.x, 2)
|
||||
+ Math.pow(autre.y - this.y, 2));
|
||||
}
|
||||
|
||||
/** Translater le point.
|
||||
* @param dx déplacement suivant l'axe des X
|
||||
* @param dy déplacement suivant l'axe des Y
|
||||
*/
|
||||
public void translater(double dx, double dy) {
|
||||
this.x += dx;
|
||||
this.y += dy;
|
||||
}
|
||||
|
||||
// Gestion de la couleur
|
||||
|
||||
/** Obtenir la couleur du point.
|
||||
* @return la couleur du point
|
||||
*/
|
||||
public Color getCouleur() {
|
||||
return this.couleur;
|
||||
}
|
||||
|
||||
/** Changer la couleur du point.
|
||||
* @param nouvelleCouleur nouvelle couleur
|
||||
*/
|
||||
public void setCouleur(Color nouvelleCouleur) {
|
||||
this.couleur = nouvelleCouleur;
|
||||
}
|
||||
|
||||
// La méthode finalize est appelée avant que le récupérateur de
|
||||
// mémoire ne détruise l'objet. Attention toutefois, on ne sait
|
||||
// pas quand ces ressources seront libérées et il est donc
|
||||
// dangereux de s'appuyer sur ce mécanisme pour libérer des
|
||||
// ressources qui sont en nombre limité.
|
||||
//
|
||||
// D'autre part, pour être sûr que les méthodes << finalize >>
|
||||
// sont appelées avant la fermeture de Java, il faut appeler la
|
||||
// méthode statique :
|
||||
// System.runFinalizersOnExit(true)
|
||||
//
|
||||
protected void finalize() {
|
||||
System.out.print("DESTRUCTION du point : ");
|
||||
this.afficher();
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
// Représentation interne d'un point
|
||||
// ---------------------------------
|
||||
|
||||
// Remarque : en Java, il est conseillé (convention de programmation)
|
||||
// de mettre les attributs au début de la classe.
|
||||
|
||||
private double x; // abscisse
|
||||
private double y; // ordonnée
|
||||
private Color couleur; // couleur du point
|
||||
|
||||
}
|
67
TP01/Schema.java
Normal file
67
TP01/Schema.java
Normal file
|
@ -0,0 +1,67 @@
|
|||
/** Un Schéma est défini pas trois points qui constituent ses
|
||||
* sommets. Un Schéma peut être affiché et translaté.
|
||||
*
|
||||
* @author
|
||||
* @version 1.9
|
||||
*/
|
||||
public class Schema {
|
||||
|
||||
private Segment s1;
|
||||
private Segment s2;
|
||||
private Segment s3;
|
||||
private Point barycentre;
|
||||
|
||||
/** Construire un Schéma à partir de ses trois sommets.
|
||||
* @param s1 le premier point du schéma
|
||||
* @param s2 le deuxième point du schéma
|
||||
* @param s3 le troisème point du schéma
|
||||
*/
|
||||
public Schema(Point p1, Point p2, Point p3) {
|
||||
this.s1 = new Segment(p1, p2);
|
||||
this.s2 = new Segment(p2, p3);
|
||||
this.s3 = new Segment(p3, p1);
|
||||
this.barycentre = calcul_barycentre(p1, p2, p3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calcul le barycentre à partir de trois points
|
||||
* @param p1
|
||||
* @param p2
|
||||
* @param p3
|
||||
* @return le barycentre de trois points
|
||||
*/
|
||||
private static Point calcul_barycentre(Point p1, Point p2, Point p3) {
|
||||
return new Point(
|
||||
(p1.getX() + p2.getX() + p3.getX())/3,
|
||||
(p1.getY() + p2.getY() + p3.getY())/3 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Translater le schéma.
|
||||
*
|
||||
* @param dx déplacement suivant l'axe des X
|
||||
* @param dy déplacement suivant l'axe des Y
|
||||
*/
|
||||
public void translater(double dx, double dy) {
|
||||
this.s1.getExtremite(1).translater(dx, dy);
|
||||
this.s2.getExtremite(1).translater(dx, dy);
|
||||
this.s3.getExtremite(1).translater(dx, dy);
|
||||
this.barycentre.translater(dx, dy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Afficher le schéma
|
||||
*/
|
||||
public void afficher() {
|
||||
|
||||
System.out.print("[ ");
|
||||
this.s1.getExtremite(1).afficher();
|
||||
System.out.print(" - ");
|
||||
this.s2.getExtremite(1).afficher();
|
||||
System.out.print(" - ");
|
||||
this.s3.getExtremite(1).afficher();
|
||||
System.out.print(" ], barycentre: ");
|
||||
this.barycentre.afficher();
|
||||
}
|
||||
|
||||
}
|
81
TP01/Segment.java
Normal file
81
TP01/Segment.java
Normal file
|
@ -0,0 +1,81 @@
|
|||
import java.awt.Color;
|
||||
|
||||
/** Un segment est défini pas ses deux points qui constituent ses
|
||||
* extrémités. Un segment peut être affiché et translaté.
|
||||
*
|
||||
* @author Xavier Crégut
|
||||
* @version 1.9
|
||||
*/
|
||||
public class Segment {
|
||||
|
||||
private Point extremite1;
|
||||
private Point extremite2;
|
||||
private Color couleur;
|
||||
|
||||
/** Construire un Segment à partir de ses deux points extrémités.
|
||||
* @param ext1 le premier point extrémité
|
||||
* @param ext2 le deuxième point extrémité
|
||||
*/
|
||||
public Segment(Point ext1, Point ext2) {
|
||||
this.extremite1 = ext1;
|
||||
this.extremite2 = ext2;
|
||||
this.couleur = Color.green;
|
||||
}
|
||||
|
||||
/** Translater le segment.
|
||||
* @param dx déplacement suivant l'axe des X
|
||||
* @param dy déplacement suivant l'axe des Y
|
||||
*/
|
||||
public void translater(double dx, double dy) {
|
||||
// System.err.println("Segment.translater(double, double) non implantée");
|
||||
this.extremite1.translater(dx, dy);
|
||||
this.extremite2.translater(dx, dy);
|
||||
}
|
||||
|
||||
/** Obtenir la longueur du segment.
|
||||
* @return la longueur du segment
|
||||
*/
|
||||
public double longueur() {
|
||||
// System.err.println("Segment.longueur() non implantée");
|
||||
return Math.sqrt(
|
||||
Math.pow(this.extremite1.getY() - this.extremite2.getY(), 2)
|
||||
+ Math.pow(this.extremite1.getX() - this.extremite2.getX(), 2));
|
||||
}
|
||||
|
||||
/** Afficher le segment. Le segment est affiché sous la forme :
|
||||
* <PRE>
|
||||
* [extremite1-extremite2]
|
||||
* </PRE>
|
||||
*/
|
||||
public void afficher() {
|
||||
// System.err.println("Segment.afficher() non implantée");
|
||||
System.out.print("[ ");
|
||||
this.extremite1.afficher();
|
||||
System.out.print(" - ");
|
||||
this.extremite2.afficher();
|
||||
System.out.print(" ]");
|
||||
}
|
||||
|
||||
/** Obtenir la couleur du segment.
|
||||
* @return la couleur du segment
|
||||
*/
|
||||
public Color getCouleur() {
|
||||
return this.couleur;
|
||||
}
|
||||
|
||||
/** Changer la couleur du segment.
|
||||
* @param nouvelleCouleur nouvelle couleur
|
||||
*/
|
||||
public void setCouleur(Color nouvelleCouleur) {
|
||||
this.couleur = nouvelleCouleur;
|
||||
}
|
||||
|
||||
public Point getExtremite(int id) {
|
||||
if (id == 1) {
|
||||
return this.extremite1;
|
||||
} else {
|
||||
return this.extremite2;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
45
TP01/TestSchema.java
Normal file
45
TP01/TestSchema.java
Normal file
|
@ -0,0 +1,45 @@
|
|||
/** Programme de test de la classe Schéma.
|
||||
* @author
|
||||
* @version 1.4
|
||||
*/
|
||||
public class TestSchema {
|
||||
|
||||
public static void main(String[] args) {
|
||||
// Créer trois points et un schéma à partir de ces points
|
||||
Point p1 = new Point(3, 2);
|
||||
Point p2 = new Point(11, 4);
|
||||
Point p3 = new Point(6, 9);
|
||||
Schema s = new Schema(p1, p2, p3);
|
||||
|
||||
// Afficher le schéma
|
||||
System.out.println("s = "); s.afficher(); System.out.println();
|
||||
|
||||
// Translater le segment
|
||||
System.out.println("> s.translater(10, 100);");
|
||||
s.translater(10, 100);
|
||||
|
||||
// Afficher le schéma
|
||||
System.out.println("s = "); s.afficher(); System.out.println();
|
||||
|
||||
// vérif
|
||||
if (p1.getX() != 13) {
|
||||
System.out.println("ERREUR pour translater p1.x !");
|
||||
}
|
||||
if (p1.getY() != 102) {
|
||||
System.out.println("ERREUR pour translater p1.y !");
|
||||
}
|
||||
if (p2.getX() != 21) {
|
||||
System.out.println("ERREUR pour translater p2.x !");
|
||||
}
|
||||
if (p2.getY() != 104) {
|
||||
System.out.println("ERREUR pour translater p2.y !");
|
||||
}
|
||||
if (p3.getX() != 16) {
|
||||
System.out.println("ERREUR pour translater p3.x !");
|
||||
}
|
||||
if (p3.getY() != 109) {
|
||||
System.out.println("ERREUR pour translater p3.y !");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
47
TP01/TestSegment.java
Normal file
47
TP01/TestSegment.java
Normal file
|
@ -0,0 +1,47 @@
|
|||
/** Programme de test de la classe Segment.
|
||||
* @author Xavier Crégut
|
||||
* @version 1.4
|
||||
*/
|
||||
public class TestSegment {
|
||||
|
||||
public static void main(String[] args) {
|
||||
// Créer deux points et un segment à partir de ces points
|
||||
Point p1 = new Point(0, 0);
|
||||
Point p2 = new Point(3, 4);
|
||||
Segment s = new Segment(p1, p2);
|
||||
|
||||
// Afficher le segment
|
||||
System.out.print("s = "); s.afficher(); System.out.println();
|
||||
|
||||
// Afficher la longueur du segment
|
||||
System.out.println("longueur de s = " + s.longueur());
|
||||
if (s.longueur() != 5) {
|
||||
System.out.println("ERREUR : la longueur devrait être 5 !");
|
||||
}
|
||||
|
||||
// Translater le segment
|
||||
System.out.println("> s.translater(10, 100);");
|
||||
s.translater(10, 100);
|
||||
if (p1.getX() != 10) {
|
||||
System.out.println("ERREUR pour translater extrémité1.x !");
|
||||
}
|
||||
if (p1.getY() != 100) {
|
||||
System.out.println("ERREUR pour translater extrémité1.y !");
|
||||
}
|
||||
if (p2.getX() != 13) {
|
||||
System.out.println("ERREUR pour translater extrémité2.x !");
|
||||
}
|
||||
if (p2.getY() != 104) {
|
||||
System.out.println("ERREUR pour translater extrémité2.y !");
|
||||
}
|
||||
|
||||
// Afficher le segment
|
||||
System.out.print("s = "); s.afficher(); System.out.println();
|
||||
|
||||
// Afficher la longueur du segment
|
||||
System.out.println("longueur de s = " + s.longueur());
|
||||
if (s.longueur() != 5) {
|
||||
System.out.println("ERREUR : la longueur devrait être 5 !");
|
||||
}
|
||||
}
|
||||
}
|
BIN
TP01/to-1sn-2020-tp-01-sujet.pdf
Normal file
BIN
TP01/to-1sn-2020-tp-01-sujet.pdf
Normal file
Binary file not shown.
13
TP02/.vscode/settings.json
vendored
Normal file
13
TP02/.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"java.project.referencedLibraries": [
|
||||
"lib/**/*.jar",
|
||||
"/usr/share/java/hamcrest-core.jar",
|
||||
"/usr/share/java/junit.jar"
|
||||
],
|
||||
"files.exclude": {
|
||||
"**/.classpath": true,
|
||||
"**/.project": true,
|
||||
"**/.settings": true,
|
||||
"**/.factorypath": true
|
||||
}
|
||||
}
|
117
TP02/Point.java
Normal file
117
TP02/Point.java
Normal file
|
@ -0,0 +1,117 @@
|
|||
import java.awt.Color;
|
||||
|
||||
/** Point modélise un point géométrique dans un plan équipé d'un
|
||||
* repère cartésien. Un point peut être affiché et translaté.
|
||||
* Sa distance par rapport à un autre point peut être obtenue.
|
||||
*
|
||||
* @author Xavier Crégut <Prénom.Nom@enseeiht.fr>
|
||||
*/
|
||||
public class Point {
|
||||
/** Construire un point à partir de son abscisse et de son ordonnée.
|
||||
* @param vx abscisse
|
||||
* @param vy ordonnée
|
||||
*/
|
||||
public Point(double vx, double vy) {
|
||||
// System.out.println("CONSTRUCTEUR Point(" + vx + ", " + vy + ")");
|
||||
this.x = vx;
|
||||
this.y = vy;
|
||||
this.couleur = Color.green;
|
||||
}
|
||||
|
||||
/** Obtenir l'abscisse du point.
|
||||
* @return abscisse du point
|
||||
*/
|
||||
public double getX() {
|
||||
return this.x;
|
||||
}
|
||||
|
||||
/** Obtenir l'ordonnée du point.
|
||||
* @return ordonnée du point
|
||||
*/
|
||||
public double getY() {
|
||||
return this.y;
|
||||
}
|
||||
|
||||
/** Changer l'abscisse du point.
|
||||
* @param vx nouvelle abscisse
|
||||
*/
|
||||
public void setX(double vx) {
|
||||
this.x = vx;
|
||||
}
|
||||
|
||||
/** Changer l'ordonnée du point.
|
||||
* @param vy nouvelle ordonnée
|
||||
*/
|
||||
public void setY(double vy) {
|
||||
this.y = vy;
|
||||
}
|
||||
|
||||
/** Afficher le point. */
|
||||
public void afficher() {
|
||||
System.out.print("(" + this.x + ", " + this.y + ")");
|
||||
}
|
||||
|
||||
/** Distance par rapport à un autre point.
|
||||
* @param autre l'autre point
|
||||
* @return distance entre this et autre
|
||||
*/
|
||||
public double distance(Point autre) {
|
||||
return Math.sqrt(Math.pow(autre.x - this.x, 2)
|
||||
+ Math.pow(autre.y - this.y, 2));
|
||||
}
|
||||
|
||||
/** Translater le point.
|
||||
* @param dx déplacement suivant l'axe des X
|
||||
* @param dy déplacement suivant l'axe des Y
|
||||
*/
|
||||
public void translater(double dx, double dy) {
|
||||
this.x += dx;
|
||||
this.y += dy;
|
||||
}
|
||||
|
||||
// Gestion de la couleur
|
||||
|
||||
/** Obtenir la couleur du point.
|
||||
* @return la couleur du point
|
||||
*/
|
||||
public Color getCouleur() {
|
||||
return this.couleur;
|
||||
}
|
||||
|
||||
/** Changer la couleur du point.
|
||||
* @param nouvelleCouleur nouvelle couleur
|
||||
*/
|
||||
public void setCouleur(Color nouvelleCouleur) {
|
||||
this.couleur = nouvelleCouleur;
|
||||
}
|
||||
|
||||
/*
|
||||
// La méthode finalize est appelée avant que le récupérateur de
|
||||
// mémoire ne détruise l'objet. Attention toutefois, on ne sait
|
||||
// pas quand ces ressources seront libérées et il est donc
|
||||
// dangereux de s'appuyer sur ce mécanisme pour libérer des
|
||||
// ressources qui sont en nombre limité.
|
||||
//
|
||||
// D'autre part, pour être sûr que les méthodes << finalize >>
|
||||
// sont appelées avant la fermeture de Java, il faut appeler la
|
||||
// méthode statique :
|
||||
// System.runFinalizersOnExit(true)
|
||||
//
|
||||
protected void finalize() {
|
||||
System.out.print("DESTRUCTION du point : ");
|
||||
this.afficher();
|
||||
System.out.println();
|
||||
}
|
||||
*/
|
||||
|
||||
// Représentation interne d'un point
|
||||
// ---------------------------------
|
||||
|
||||
// Remarque : en Java, il est conseillé (convention de programmation)
|
||||
// de mettre les attributs au début de la classe.
|
||||
|
||||
private double x; // abscisse
|
||||
private double y; // ordonnée
|
||||
private Color couleur; // couleur du point
|
||||
|
||||
}
|
101
TP02/PointTest.java
Normal file
101
TP02/PointTest.java
Normal file
|
@ -0,0 +1,101 @@
|
|||
import org.junit.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
/** Programme de test de la classe Point.
|
||||
* @author Xavier Crégut
|
||||
* @version 1.11
|
||||
*/
|
||||
public class PointTest {
|
||||
|
||||
public static final double EPSILON = 1e-6;
|
||||
// précision pour la comparaison entre réels.
|
||||
|
||||
private Point p1;
|
||||
private Point p2;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
p1 = new Point(1, 2);
|
||||
p2 = new Point(4, -2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitialisation() {
|
||||
assertTrue(p1 != null);
|
||||
assertTrue(p2 != null);
|
||||
assertTrue(p1.getX() == 1);
|
||||
assertTrue(p1.getY() == 2);
|
||||
assertTrue(p2.getX() == 4);
|
||||
assertTrue(p2.getY() == -2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitialisationMieux() {
|
||||
assertNotNull(p1);
|
||||
assertNotNull(p2);
|
||||
// Remarque : faire un test d'égalité sur des réels est à éviter
|
||||
// à cause des erreurs d'arrondi. En conséquence, il faut
|
||||
// vérifier que les deux nombres sont égaux à EPSILON près.
|
||||
// C'est ce que fait assertEquals(attendu, réel, précision)
|
||||
assertEquals(1.0, p1.getX(), EPSILON);
|
||||
assertEquals(2.0, p1.getY(), EPSILON);
|
||||
assertEquals(4.0, p2.getX(), EPSILON);
|
||||
assertEquals(-2.0, p2.getY(), EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetX() {
|
||||
p1.setX(10);
|
||||
assertEquals(10.0, p1.getX(), EPSILON);
|
||||
p1.setX(-5);
|
||||
assertEquals(-5.0, p1.getX(), EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetY() {
|
||||
p1.setY(10);
|
||||
assertEquals(10.0, p1.getY(), EPSILON);
|
||||
p1.setY(-5);
|
||||
assertEquals(-5.0, p1.getY(), EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDistance() {
|
||||
assertEquals(0.0, p1.distance(p1), EPSILON);
|
||||
assertEquals(0.0, p2.distance(p2), EPSILON);
|
||||
assertEquals(5.0, p1.distance(p2), EPSILON);
|
||||
assertEquals(5.0, p2.distance(p1), EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTranslater1() {
|
||||
p1.translater(2, 4);
|
||||
assertEquals(3.0, p1.getX(), EPSILON);
|
||||
assertEquals(6.0, p1.getY(), EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTranslater2() {
|
||||
p2.translater(-2, -4);
|
||||
assertEquals(2.0, p2.getX(), EPSILON);
|
||||
assertEquals(-6.0, p2.getY(), EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCouleur() {
|
||||
assertEquals(p1.getCouleur(), Color.GREEN);
|
||||
assertEquals(p2.getCouleur(), Color.GREEN);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetCouleur() {
|
||||
p1.setCouleur(Color.RED);
|
||||
p2.setCouleur(Color.BLUE);
|
||||
assertEquals(p1.getCouleur(), Color.RED);
|
||||
assertEquals(p2.getCouleur(), Color.BLUE);
|
||||
}
|
||||
|
||||
|
||||
}
|
BIN
TP02/to-1sn-2020-tp-02-sujet.pdf
Normal file
BIN
TP02/to-1sn-2020-tp-02-sujet.pdf
Normal file
Binary file not shown.
0
TP03/PAS_DE_FICHIERS_FOURNIS
Normal file
0
TP03/PAS_DE_FICHIERS_FOURNIS
Normal file
6
TP04/.vscode/settings.json
vendored
Normal file
6
TP04/.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"java.project.referencedLibraries": [
|
||||
"lib/**/*.jar",
|
||||
"afficheur.jar"
|
||||
]
|
||||
}
|
46
TP04/AfficheurTexte.java
Normal file
46
TP04/AfficheurTexte.java
Normal file
|
@ -0,0 +1,46 @@
|
|||
import afficheur.Afficheur;
|
||||
|
||||
public class AfficheurTexte implements Afficheur {
|
||||
|
||||
public void dessinerPoint(double x, double y, java.awt.Color c) {
|
||||
System.out.println("Point {");
|
||||
System.out.printf(" x = %f\n", x);
|
||||
System.out.printf(" y = %f\n", y);
|
||||
System.out.print( " couleur = ");
|
||||
System.out.println(c);
|
||||
System.out.println("}");
|
||||
}
|
||||
|
||||
public void dessinerLigne(double x1, double y1, double x2, double y2, java.awt.Color c) {
|
||||
System.out.println("Ligne {");
|
||||
System.out.printf(" x1 = %f\n", x1);
|
||||
System.out.printf(" y1 = %f\n", y1);
|
||||
System.out.printf(" x2 = %f\n", x2);
|
||||
System.out.printf(" y2 = %f\n", y2);
|
||||
System.out.print( " couleur = ");
|
||||
System.out.println(c);
|
||||
System.out.println("}");
|
||||
}
|
||||
|
||||
public void dessinerCercle(double x, double y, double rayon, java.awt.Color c) {
|
||||
System.out.println("Cercle {");
|
||||
System.out.printf(" centre_x = %f\n", x);
|
||||
System.out.printf(" centre_y = %f\n", y);
|
||||
System.out.printf(" rayon = %f\n", rayon);
|
||||
System.out.print( " couleur = ");
|
||||
System.out.println(c);
|
||||
System.out.println("}");
|
||||
}
|
||||
|
||||
public void dessinerTexte(double x, double y, java.lang.String texte, java.awt.Color c) {
|
||||
System.out.println("Texte {");
|
||||
System.out.printf(" x = %f\n", x);
|
||||
System.out.printf(" y = %f\n", y);
|
||||
System.out.printf(" valeur = %s\n", texte);
|
||||
System.out.print( " couleur = ");
|
||||
System.out.println(c);
|
||||
System.out.println("}");
|
||||
}
|
||||
|
||||
}
|
||||
|
31
TP04/ExempleEcran.java
Normal file
31
TP04/ExempleEcran.java
Normal file
|
@ -0,0 +1,31 @@
|
|||
import afficheur.AfficheurSVG;
|
||||
import afficheur.Ecran;
|
||||
import java.awt.Color;
|
||||
|
||||
/**
|
||||
* Exemple d'utilisation de la classe Ecran.
|
||||
*/
|
||||
class ExempleEcran {
|
||||
|
||||
public static void main(String[] args) {
|
||||
// Construire un écran
|
||||
// AfficheurTexte monEcran = new AfficheurTexte();
|
||||
Ecran monEcran = new Ecran("ExempleEcran", 400, 250, 15);
|
||||
|
||||
// Dessiner les axes
|
||||
monEcran.dessinerAxes();
|
||||
|
||||
// Dessiner un point vert de coordonnées (1, 2)
|
||||
monEcran.dessinerPoint(1, 2, Color.GREEN);
|
||||
|
||||
// Dessiner un segment rouge d'extrémités (6, 2) et (11, 9)
|
||||
monEcran.dessinerLigne(6, 2, 11, 9, Color.RED);
|
||||
|
||||
// Dessiner un cercle jaune de centre (4, 3) et rayon 2.5
|
||||
monEcran.dessinerCercle(4, 3, 2.5, Color.YELLOW);
|
||||
|
||||
// Dessiner le texte "Premier dessin" en bleu à la position (1, -2)
|
||||
monEcran.dessinerTexte(1, -2, "Premier dessin", Color.BLUE);
|
||||
}
|
||||
|
||||
}
|
70
TP04/ExempleSchema1.java
Normal file
70
TP04/ExempleSchema1.java
Normal file
|
@ -0,0 +1,70 @@
|
|||
import afficheur.AfficheurSVG;
|
||||
import java.awt.Color;
|
||||
|
||||
/** Construire le schéma proposé dans le sujet de TP avec des points,
|
||||
* et des segments.
|
||||
*
|
||||
* @author Xavier Crégut
|
||||
* @version $Revision: 1.7 $
|
||||
*/
|
||||
public class ExempleSchema1 {
|
||||
|
||||
/** Construire le schéma et le manipuler.
|
||||
* Le schéma est affiché.
|
||||
* @param args les arguments de la ligne de commande
|
||||
*/
|
||||
public static void main(String[] args)
|
||||
{
|
||||
// Créer les trois segments
|
||||
Point p1 = new Point(3, 2);
|
||||
Point p2 = new Point(6, 9);
|
||||
Point p3 = new Point(11, 4);
|
||||
Segment s12 = new Segment(p1, p2);
|
||||
Segment s23 = new Segment(p2, p3);
|
||||
Segment s31 = new Segment(p3, p1);
|
||||
|
||||
// Créer le barycentre
|
||||
double sx = p1.getX() + p2.getX() + p3.getX();
|
||||
double sy = p1.getY() + p2.getY() + p3.getY();
|
||||
Point barycentre = new Point(sx / 3, sy / 3);
|
||||
|
||||
// Afficher le schéma
|
||||
System.out.println("Le schéma est composé de : ");
|
||||
s12.afficher(); System.out.println();
|
||||
s23.afficher(); System.out.println();
|
||||
s31.afficher(); System.out.println();
|
||||
barycentre.afficher(); System.out.println();
|
||||
|
||||
// Construire un écran
|
||||
// AfficheurSVG monEcran = new AfficheurSVG("ExempleSchema1", "schemaSVG", 600, 400);
|
||||
AfficheurTexte monEcran = new AfficheurTexte();
|
||||
|
||||
// Dessiner sur l'écran
|
||||
s12.dessiner(monEcran);
|
||||
s23.dessiner(monEcran);
|
||||
s31.dessiner(monEcran);
|
||||
barycentre.dessiner(monEcran);
|
||||
|
||||
// Translater le schéma
|
||||
s12.translater(4, -3);
|
||||
s23.translater(4, -3);
|
||||
s31.translater(4, -3);
|
||||
barycentre.translater(4, -3);
|
||||
|
||||
// Redessiner sur l'écran
|
||||
s12.dessiner(monEcran);
|
||||
s23.dessiner(monEcran);
|
||||
s31.dessiner(monEcran);
|
||||
barycentre.dessiner(monEcran);
|
||||
|
||||
// Dessiner les axes
|
||||
// monEcran.dessinerAxes();
|
||||
|
||||
// // Afficher le dessin
|
||||
// monEcran.ecrire();
|
||||
|
||||
// // Écrire le dessin SVG dans un fichier
|
||||
// monEcran.ecrire("schema.svg");
|
||||
}
|
||||
|
||||
}
|
100
TP04/Point.java
Normal file
100
TP04/Point.java
Normal file
|
@ -0,0 +1,100 @@
|
|||
import java.awt.Color;
|
||||
import afficheur.Afficheur;
|
||||
|
||||
/** Point modélise un point géométrique dans un plan équipé d'un
|
||||
* repère cartésien. Un point peut être affiché et translaté.
|
||||
* Sa distance par rapport à un autre point peut être obtenue.
|
||||
*
|
||||
* @author Xavier Crégut <Prénom.Nom@enseeiht.fr>
|
||||
*/
|
||||
public class Point {
|
||||
private double x; // abscisse
|
||||
private double y; // ordonnée
|
||||
private Color couleur; // couleur du point
|
||||
|
||||
/** Construire un point à partir de son abscisse et de son ordonnée.
|
||||
* @param vx abscisse
|
||||
* @param vy ordonnée
|
||||
*/
|
||||
public Point(double vx, double vy) {
|
||||
this.x = vx;
|
||||
this.y = vy;
|
||||
this.couleur = Color.green;
|
||||
}
|
||||
|
||||
/** Obtenir l'abscisse du point.
|
||||
* @return abscisse du point
|
||||
*/
|
||||
public double getX() {
|
||||
return this.x;
|
||||
}
|
||||
|
||||
/** Obtenir l'ordonnée du point.
|
||||
* @return ordonnée du point
|
||||
*/
|
||||
public double getY() {
|
||||
return this.y;
|
||||
}
|
||||
|
||||
/** Changer l'abscisse du point.
|
||||
* @param vx nouvelle abscisse
|
||||
*/
|
||||
public void setX(double vx) {
|
||||
this.x = vx;
|
||||
}
|
||||
|
||||
/** Changer l'ordonnée du point.
|
||||
* @param vy nouvelle ordonnée
|
||||
*/
|
||||
public void setY(double vy) {
|
||||
this.y = vy;
|
||||
}
|
||||
|
||||
/** Afficher le point. */
|
||||
public void afficher() {
|
||||
System.out.print("(" + this.x + ", " + this.y + ")");
|
||||
}
|
||||
|
||||
/**
|
||||
* Dessiner sur un écran le point.
|
||||
* @param canvas Écran sur lequel on dessine
|
||||
*/
|
||||
public void dessiner(Afficheur canvas) {
|
||||
canvas.dessinerPoint(this.x, this.y, this.couleur);
|
||||
}
|
||||
|
||||
/** Distance par rapport à un autre point.
|
||||
* @param autre l'autre point
|
||||
* @return distance entre this et autre
|
||||
*/
|
||||
public double distance(Point autre) {
|
||||
return Math.sqrt(Math.pow(autre.x - this.x, 2)
|
||||
+ Math.pow(autre.y - this.y, 2));
|
||||
}
|
||||
|
||||
/** Translater le point.
|
||||
* @param dx déplacement suivant l'axe des X
|
||||
* @param dy déplacement suivant l'axe des Y
|
||||
*/
|
||||
public void translater(double dx, double dy) {
|
||||
this.x += dx;
|
||||
this.y += dy;
|
||||
}
|
||||
|
||||
// Gestion de la couleur
|
||||
|
||||
/** Obtenir la couleur du point.
|
||||
* @return la couleur du point
|
||||
*/
|
||||
public Color getCouleur() {
|
||||
return this.couleur;
|
||||
}
|
||||
|
||||
/** Changer la couleur du point.
|
||||
* @param nouvelleCouleur nouvelle couleur
|
||||
*/
|
||||
public void setCouleur(Color nouvelleCouleur) {
|
||||
this.couleur = nouvelleCouleur;
|
||||
}
|
||||
|
||||
}
|
89
TP04/Segment.java
Normal file
89
TP04/Segment.java
Normal file
|
@ -0,0 +1,89 @@
|
|||
import java.awt.Color;
|
||||
import afficheur.Afficheur;
|
||||
|
||||
/** Un segment est défini pas ses deux points qui constituent ses
|
||||
* extrémités. Un segment peut être affiché et translaté.
|
||||
*
|
||||
* @author Xavier Crégut
|
||||
* @version 1.9
|
||||
*/
|
||||
public class Segment {
|
||||
|
||||
private Point extremite1;
|
||||
private Point extremite2;
|
||||
private Color couleur;
|
||||
|
||||
/** Construire un Segment à partir de ses deux points extrémités.
|
||||
* @param ext1 le premier point extrémité
|
||||
* @param ext2 le deuxième point extrémité
|
||||
*/
|
||||
public Segment(Point ext1, Point ext2) {
|
||||
this.extremite1 = ext1;
|
||||
this.extremite2 = ext2;
|
||||
this.couleur = Color.green;
|
||||
}
|
||||
|
||||
/** Translater le segment.
|
||||
* @param dx déplacement suivant l'axe des X
|
||||
* @param dy déplacement suivant l'axe des Y
|
||||
*/
|
||||
public void translater(double dx, double dy) {
|
||||
extremite1.translater(dx, dy);
|
||||
extremite2.translater(dx, dy);
|
||||
}
|
||||
|
||||
/** Obtenir la longueur du segment.
|
||||
* @return la longueur du segment
|
||||
*/
|
||||
public double getLongueur() {
|
||||
return this.extremite1.distance(this.extremite2);
|
||||
}
|
||||
|
||||
/** @deprecated Cette méthode a changé de nom pour respecter
|
||||
* la convention de nommage préconisée par Sun pour Java.
|
||||
* @see #getLongueur()
|
||||
*/
|
||||
@Deprecated public double longueur() {
|
||||
return this.extremite1.distance(this.extremite2);
|
||||
}
|
||||
|
||||
/** Afficher le segment. Le segment est affiché sous la forme :
|
||||
* <PRE>
|
||||
* [extremite1-extremite2]
|
||||
* </PRE>
|
||||
*/
|
||||
public void afficher() {
|
||||
System.out.print("[");
|
||||
this.extremite1.afficher();
|
||||
System.out.print("-");
|
||||
this.extremite2.afficher();
|
||||
System.out.print("]");
|
||||
}
|
||||
|
||||
/**
|
||||
* Dessiner sur un écran le segment.
|
||||
* @param canvas Écran sur lequel on dessine
|
||||
*/
|
||||
public void dessiner(Afficheur canvas) {
|
||||
canvas.dessinerLigne(this.extremite1.getX(),
|
||||
this.extremite1.getY(),
|
||||
this.extremite2.getX(),
|
||||
this.extremite2.getY(),
|
||||
this.couleur);
|
||||
}
|
||||
|
||||
/** Obtenir la couleur du segment.
|
||||
* @return la couleur du segment
|
||||
*/
|
||||
public Color getCouleur() {
|
||||
return this.couleur;
|
||||
}
|
||||
|
||||
/** Changer la couleur du segment.
|
||||
* @param nouvelleCouleur nouvelle couleur
|
||||
*/
|
||||
public void setCouleur(Color nouvelleCouleur) {
|
||||
this.couleur = nouvelleCouleur;
|
||||
}
|
||||
|
||||
}
|
BIN
TP04/afficheur.jar
Normal file
BIN
TP04/afficheur.jar
Normal file
Binary file not shown.
16
TP04/schema.svg
Normal file
16
TP04/schema.svg
Normal file
|
@ -0,0 +1,16 @@
|
|||
<?xml version='1.0'?>
|
||||
<!-- Car l'axe des Y est inversé en SVG les y sont transformés en 10 - y
|
||||
Toutes les coordonnées sont * 10
|
||||
-->
|
||||
<svg xmlns='http://www.w3.org/2000/svg' version="11" width="600" height="400">
|
||||
<title>ExempleSchema1</title>
|
||||
<desc>schemaSVG</desc>
|
||||
<line x1="30" y1="80" x2="60" y2="10" stroke="rgb(0,255,0)"/>
|
||||
<line x1="60" y1="10" x2="110" y2="60" stroke="rgb(0,255,0)"/>
|
||||
<line x1="110" y1="60" x2="30" y2="80" stroke="rgb(0,255,0)"/>
|
||||
<circle cx="66" cy="50" r="2" fill="rgb(0,255,0)"/>
|
||||
<line x1="110" y1="140" x2="140" y2="70" stroke="rgb(0,255,0)"/>
|
||||
<line x1="140" y1="70" x2="190" y2="120" stroke="rgb(0,255,0)"/>
|
||||
<line x1="190" y1="120" x2="110" y2="140" stroke="rgb(0,255,0)"/>
|
||||
<circle cx="106" cy="80" r="2" fill="rgb(0,255,0)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 778 B |
BIN
TP04/to-1sn-2020-tp-04-sujet.pdf
Normal file
BIN
TP04/to-1sn-2020-tp-04-sujet.pdf
Normal file
Binary file not shown.
8
TP05/.vscode/settings.json
vendored
Normal file
8
TP05/.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"java.project.referencedLibraries": [
|
||||
"lib/**/*.jar",
|
||||
"/usr/share/java/hamcrest-core.jar",
|
||||
"/usr/share/java/junit.jar",
|
||||
"afficheur.jar"
|
||||
]
|
||||
}
|
71
TP05/ExempleSchema1.java
Normal file
71
TP05/ExempleSchema1.java
Normal file
|
@ -0,0 +1,71 @@
|
|||
import afficheur.Ecran;
|
||||
|
||||
/** Construire le schéma proposé dans le sujet de TP avec des points,
|
||||
* et des segments.
|
||||
*
|
||||
* @author Xavier Crégut
|
||||
* @version $Revision: 1.7 $
|
||||
*/
|
||||
public class ExempleSchema1 {
|
||||
|
||||
/** Construire le schéma et le manipuler.
|
||||
* Le schéma est affiché.
|
||||
* Ensuite, il est translaté et affiché de nouveau.
|
||||
* @param args les arguments de la ligne de commande
|
||||
*/
|
||||
public static void main(String[] args)
|
||||
{
|
||||
// Créer les trois segments
|
||||
Point p1 = new Point(3, 2);
|
||||
Point p2 = new Point(6, 9);
|
||||
Point p3 = new Point(11, 4);
|
||||
Segment s12 = new Segment(p1, p2);
|
||||
Segment s23 = new Segment(p2, p3);
|
||||
Segment s31 = new Segment(p3, p1);
|
||||
|
||||
// Créer le barycentre
|
||||
double sx = p1.getX() + p2.getX() + p3.getX();
|
||||
double sy = p1.getY() + p2.getY() + p3.getY();
|
||||
Point barycentre = new Point(sx / 3, sy / 3);
|
||||
|
||||
// Afficher le schéma
|
||||
System.out.println("Le schéma est composé de : ");
|
||||
s12.afficher(); System.out.println();
|
||||
s23.afficher(); System.out.println();
|
||||
s31.afficher(); System.out.println();
|
||||
barycentre.afficher(); System.out.println();
|
||||
// Créer l'écran d'affichage
|
||||
Ecran ecran = new Ecran("ExempleSchema1", 600, 400, 20);
|
||||
ecran.dessinerAxes();
|
||||
|
||||
// Dessiner le schéma sur l'écran graphique
|
||||
s12.dessiner(ecran);
|
||||
s23.dessiner(ecran);
|
||||
s31.dessiner(ecran);
|
||||
barycentre.dessiner(ecran);
|
||||
|
||||
// Translater le schéma
|
||||
System.out.println("Translater le schéma de (4, -3) : ");
|
||||
s12.translater(4, -3);
|
||||
s23.translater(4, -3);
|
||||
s31.translater(4, -3);
|
||||
barycentre.translater(4, -3);
|
||||
|
||||
// Afficher le schéma
|
||||
System.out.println("Le schéma est composé de : ");
|
||||
s12.afficher(); System.out.println();
|
||||
s23.afficher(); System.out.println();
|
||||
s31.afficher(); System.out.println();
|
||||
barycentre.afficher(); System.out.println();
|
||||
|
||||
// Dessiner le schéma sur l'écran graphique
|
||||
s12.dessiner(ecran);
|
||||
s23.dessiner(ecran);
|
||||
s31.dessiner(ecran);
|
||||
barycentre.dessiner(ecran);
|
||||
|
||||
// Forcer l'affichage du schéma (au cas où...)
|
||||
ecran.rafraichir();
|
||||
}
|
||||
|
||||
}
|
71
TP05/ExempleSchema2.java
Normal file
71
TP05/ExempleSchema2.java
Normal file
|
@ -0,0 +1,71 @@
|
|||
import afficheur.Ecran;
|
||||
|
||||
/** Construire le schéma proposé dans le sujet de TP avec des points,
|
||||
* et des segments.
|
||||
*
|
||||
* @author Xavier Crégut
|
||||
* @version $Revision: 1.7 $
|
||||
*/
|
||||
public class ExempleSchema2 {
|
||||
|
||||
/** Construire le schéma et le manipuler.
|
||||
* Le schéma est affiché.
|
||||
* Ensuite, il est translaté et affiché de nouveau.
|
||||
* @param args les arguments de la ligne de commande
|
||||
*/
|
||||
public static void main(String[] args)
|
||||
{
|
||||
// Créer les trois segments
|
||||
Point p1 = new PointNomme(3, 2, "A");
|
||||
Point p2 = new PointNomme(6, 9, "S");
|
||||
Point p3 = new Point(11, 4);
|
||||
Segment s12 = new Segment(p1, p2);
|
||||
Segment s23 = new Segment(p2, p3);
|
||||
Segment s31 = new Segment(p3, p1);
|
||||
|
||||
// Créer le barycentre
|
||||
double sx = p1.getX() + p2.getX() + p3.getX();
|
||||
double sy = p1.getY() + p2.getY() + p3.getY();
|
||||
Point barycentre = new PointNomme(sx / 3, sy / 3, "C");
|
||||
|
||||
// Afficher le schéma
|
||||
System.out.println("Le schéma est composé de : ");
|
||||
s12.afficher(); System.out.println();
|
||||
s23.afficher(); System.out.println();
|
||||
s31.afficher(); System.out.println();
|
||||
barycentre.afficher(); System.out.println();
|
||||
// Créer l'écran d'affichage
|
||||
Ecran ecran = new Ecran("ExempleSchema1", 600, 400, 20);
|
||||
ecran.dessinerAxes();
|
||||
|
||||
// Dessiner le schéma sur l'écran graphique
|
||||
s12.dessiner(ecran);
|
||||
s23.dessiner(ecran);
|
||||
s31.dessiner(ecran);
|
||||
barycentre.dessiner(ecran);
|
||||
|
||||
// Translater le schéma
|
||||
System.out.println("Translater le schéma de (4, -3) : ");
|
||||
s12.translater(4, -3);
|
||||
s23.translater(4, -3);
|
||||
s31.translater(4, -3);
|
||||
barycentre.translater(4, -3);
|
||||
|
||||
// Afficher le schéma
|
||||
System.out.println("Le schéma est composé de : ");
|
||||
s12.afficher(); System.out.println();
|
||||
s23.afficher(); System.out.println();
|
||||
s31.afficher(); System.out.println();
|
||||
barycentre.afficher(); System.out.println();
|
||||
|
||||
// Dessiner le schéma sur l'écran graphique
|
||||
s12.dessiner(ecran);
|
||||
s23.dessiner(ecran);
|
||||
s31.dessiner(ecran);
|
||||
barycentre.dessiner(ecran);
|
||||
|
||||
// Forcer l'affichage du schéma (au cas où...)
|
||||
ecran.rafraichir();
|
||||
}
|
||||
|
||||
}
|
108
TP05/Point.java
Normal file
108
TP05/Point.java
Normal file
|
@ -0,0 +1,108 @@
|
|||
import java.awt.Color;
|
||||
|
||||
/** Point modélise un point géométrique dans un plan équipé d'un
|
||||
* repère cartésien. Un point peut être affiché et translaté.
|
||||
* Sa distance par rapport à un autre point peut être obtenue.
|
||||
* Le point peut être dessiné sur un afficheur.
|
||||
*
|
||||
* @author Xavier Crégut <Prénom.Nom@enseeiht.fr>
|
||||
*/
|
||||
|
||||
// si on met final, aucune des méthodes de Point n’est polymorphe)
|
||||
public /* final */ class Point {
|
||||
private double x; // abscisse
|
||||
private double y; // ordonnée
|
||||
|
||||
//@ private invariant getCouleur() != null;
|
||||
//@ private invariant getCouleur() == couleur; // invariant de liaison
|
||||
private Color couleur; // couleur du point
|
||||
|
||||
/** Construire un point à partir de son abscisse et de son ordonnée.
|
||||
* @param vx abscisse
|
||||
* @param vy ordonnée
|
||||
*/
|
||||
public Point(double vx, double vy) {
|
||||
this.x = vx;
|
||||
this.y = vy;
|
||||
this.couleur = Color.green;
|
||||
}
|
||||
|
||||
/** Obtenir l'abscisse du point.
|
||||
* @return abscisse du point
|
||||
*/
|
||||
//@ pure
|
||||
public double getX() {
|
||||
return this.x;
|
||||
}
|
||||
|
||||
/** Obtenir l'ordonnée du point.
|
||||
* @return ordonnée du point
|
||||
*/
|
||||
//@ pure
|
||||
public double getY() {
|
||||
return this.y;
|
||||
}
|
||||
|
||||
/** Changer l'abscisse du point.
|
||||
* @param vx nouvelle abscisse
|
||||
*/
|
||||
public void setX(double vx) {
|
||||
this.x = vx;
|
||||
}
|
||||
|
||||
/** Changer l'ordonnée du point.
|
||||
* @param vy nouvelle ordonnée
|
||||
*/
|
||||
public void setY(double vy) {
|
||||
this.y = vy;
|
||||
}
|
||||
|
||||
/** Afficher le point. */
|
||||
public /* final */ void afficher() {
|
||||
System.out.print("(" + this.x + ", " + this.y + ")");
|
||||
} // si on met final, on ne peut pas override cette méthode dans pointNomme
|
||||
|
||||
/** Distance par rapport à un autre point.
|
||||
* @param autre l'autre point
|
||||
* @return distance entre this et autre
|
||||
*/
|
||||
//@ pure
|
||||
public double distance(Point autre) {
|
||||
return Math.sqrt(Math.pow(autre.x - this.x, 2)
|
||||
+ Math.pow(autre.y - this.y, 2));
|
||||
}
|
||||
|
||||
/** Translater le point.
|
||||
* @param dx déplacement suivant l'axe des X
|
||||
* @param dy déplacement suivant l'axe des Y
|
||||
*/
|
||||
public void translater(double dx, double dy) {
|
||||
this.x += dx;
|
||||
this.y += dy;
|
||||
}
|
||||
|
||||
/** Dessiner le point sur l'afficheur.
|
||||
* @param afficheur l'afficheur à utiliser
|
||||
*/
|
||||
public void dessiner(afficheur.Afficheur afficheur) {
|
||||
afficheur.dessinerPoint(this.getX(), this.getY(), this.getCouleur());
|
||||
}
|
||||
|
||||
// Gestion de la couleur
|
||||
|
||||
/** Obtenir la couleur du point.
|
||||
* @return la couleur du point
|
||||
*/
|
||||
//@ pure
|
||||
public Color getCouleur() {
|
||||
return this.couleur;
|
||||
}
|
||||
|
||||
/** Changer la couleur du point.
|
||||
* @param nouvelleCouleur nouvelle couleur
|
||||
*/
|
||||
public void setCouleur(Color nouvelleCouleur) {
|
||||
this.couleur = nouvelleCouleur;
|
||||
}
|
||||
|
||||
}
|
50
TP05/PointNomme.java
Normal file
50
TP05/PointNomme.java
Normal file
|
@ -0,0 +1,50 @@
|
|||
/** Un point nommé est un point avec un nom.
|
||||
* @author Xavier Crégut
|
||||
* @version 1.7
|
||||
*/
|
||||
public class PointNomme extends Point {
|
||||
|
||||
private String nom; // le nom du point nommé
|
||||
|
||||
/** Construire un point nommé à partir de son abscisse, son
|
||||
* ordonnée et son nom.
|
||||
* @param vx valeur de l'abscisse
|
||||
* @param vy valeur de l'ordonnée
|
||||
* @param sonNom nom à donner au point
|
||||
*/
|
||||
public PointNomme(double vx, double vy, String sonNom) {
|
||||
super(vx, vy); // toujours en première ligne !
|
||||
this.setNom(sonNom);
|
||||
}
|
||||
|
||||
/** Obtenir le nom du point nommé.
|
||||
* @return le nom du point nommé
|
||||
*/
|
||||
public String getNom() {
|
||||
return this.nom;
|
||||
}
|
||||
|
||||
/** Changer le nom du point nommé.
|
||||
* @param sonNom le nouveau nom
|
||||
*/
|
||||
public void setNom(String sonNom) {
|
||||
this.nom = sonNom;
|
||||
}
|
||||
|
||||
/** Afficher le point nommé. Le point est affiché sous la forme :
|
||||
* <PRE>
|
||||
* nom:(x, y)
|
||||
* </PRE>
|
||||
*/
|
||||
@Override public void afficher() {
|
||||
System.out.print(this.getNom() + ":");
|
||||
super.afficher(); // utiliser afficher de Point
|
||||
}
|
||||
|
||||
@Override public void dessiner(afficheur.Afficheur afficheur) {
|
||||
super.dessiner(afficheur); // utiliser dessiner de Point
|
||||
afficheur.dessinerTexte (this.getX(), this.getY(),
|
||||
this.getNom(), this.getCouleur());
|
||||
}
|
||||
|
||||
}
|
90
TP05/Segment.java
Normal file
90
TP05/Segment.java
Normal file
|
@ -0,0 +1,90 @@
|
|||
import java.awt.Color;
|
||||
|
||||
/** Un segment est défini pas ses deux points qui constituent ses
|
||||
* extrémités. Un segment peut être affiché et translaté.
|
||||
* Le segment peut être dessiné sur un afficheur.
|
||||
*
|
||||
* @author Xavier Crégut
|
||||
* @version 1.9
|
||||
*/
|
||||
public class Segment {
|
||||
|
||||
private Point extremite1;
|
||||
private Point extremite2;
|
||||
private Color couleur;
|
||||
|
||||
/** Construire un Segment à partir de ses deux points extrémités.
|
||||
* @param ext1 le premier point extrémité
|
||||
* @param ext2 le deuxième point extrémité
|
||||
*/
|
||||
public Segment(Point ext1, Point ext2) {
|
||||
this.extremite1 = ext1;
|
||||
this.extremite2 = ext2;
|
||||
this.couleur = Color.green;
|
||||
}
|
||||
|
||||
/** Translater le segment.
|
||||
* @param dx déplacement suivant l'axe des X
|
||||
* @param dy déplacement suivant l'axe des Y
|
||||
*/
|
||||
public void translater(double dx, double dy) {
|
||||
extremite1.translater(dx, dy);
|
||||
extremite2.translater(dx, dy);
|
||||
}
|
||||
|
||||
/** Dessiner le segment sur l'afficheur.
|
||||
* @param afficheur l'afficheur à utiliser
|
||||
*/
|
||||
public void dessiner(afficheur.Afficheur afficheur) {
|
||||
afficheur.dessinerLigne(this.extremite1.getX(), this.extremite1.getY(),
|
||||
this.extremite2.getX(), this.extremite2.getY(),
|
||||
this.getCouleur());
|
||||
|
||||
// Dessiner les deux extrémités : est-ce bien normal ?
|
||||
this.extremite1.dessiner(afficheur);
|
||||
this.extremite2.dessiner(afficheur);
|
||||
}
|
||||
|
||||
/** Obtenir la longueur du segment.
|
||||
* @return la longueur du segment
|
||||
*/
|
||||
public double getLongueur() {
|
||||
return this.extremite1.distance(this.extremite2);
|
||||
}
|
||||
|
||||
/** @deprecated Cette méthode a changé de nom pour respecter
|
||||
* la convention de nommage préconisée par Sun pour Java.
|
||||
* @see #getLongueur()
|
||||
*/
|
||||
@Deprecated public double longueur() {
|
||||
return this.extremite1.distance(this.extremite2);
|
||||
}
|
||||
|
||||
/** Afficher le segment. Le segment est affiché sous la forme :
|
||||
* <PRE>
|
||||
* [extremite1-extremite2]
|
||||
* </PRE>
|
||||
*/
|
||||
public void afficher() {
|
||||
System.out.print("[");
|
||||
this.extremite1.afficher();
|
||||
System.out.print("-");
|
||||
this.extremite2.afficher();
|
||||
System.out.print("]");
|
||||
}
|
||||
|
||||
/** Obtenir la couleur du segment.
|
||||
* @return la couleur du segment
|
||||
*/
|
||||
public Color getCouleur() {
|
||||
return this.couleur;
|
||||
}
|
||||
|
||||
/** Changer la couleur du segment.
|
||||
* @param nouvelleCouleur nouvelle couleur
|
||||
*/
|
||||
public void setCouleur(Color nouvelleCouleur) {
|
||||
this.couleur = nouvelleCouleur;
|
||||
}
|
||||
|
||||
}
|
102
TP05/TestPolymorphisme.java
Normal file
102
TP05/TestPolymorphisme.java
Normal file
|
@ -0,0 +1,102 @@
|
|||
/** Tester le polymorphisme(principe de substitution) et la liaison
|
||||
* dynamique.
|
||||
* @author Xavier Crégut
|
||||
* @version 1.5
|
||||
*/
|
||||
public class TestPolymorphisme {
|
||||
|
||||
/** Méthode principale */
|
||||
public static void main(String[] args) {
|
||||
// Créer et afficher un point p1
|
||||
Point p1 = new Point(3, 4); // Est-ce autorisé ? Pourquoi ?
|
||||
// oui, on utilise le constructeur de la classe
|
||||
|
||||
p1.translater(10,10); // Quel est le translater exécuté ?
|
||||
// celui de Point
|
||||
|
||||
System.out.print("p1 = "); p1.afficher(); System.out.println();
|
||||
// Qu'est ce qui est affiché ?
|
||||
// p1 = (13.0, 14.0)
|
||||
|
||||
|
||||
// Créer et afficher un point nommé pn1
|
||||
PointNomme pn1 = new PointNomme(30, 40, "PN1");
|
||||
// Est-ce autorisé ? Pourquoi ?
|
||||
// oui, on utilise le constructeur de la classe
|
||||
|
||||
pn1.translater(10,10); // Quel est le translater exécuté ?
|
||||
// celui de PointNomme, donc celui de Point par héritage
|
||||
|
||||
System.out.print("pn1 = "); pn1.afficher(); System.out.println();
|
||||
// Qu'est ce qui est affiché ?
|
||||
// pn1 = PN1:(40.0, 50.0)
|
||||
|
||||
// Définir une poignée sur un point
|
||||
Point q;
|
||||
|
||||
// Attacher un point à q et l'afficher
|
||||
q = p1; // Est-ce autorisé ? Pourquoi ?
|
||||
// oui, les types des deux objets sont les mêmes
|
||||
System.out.println("> q = p1;");
|
||||
System.out.print("q = "); q.afficher(); System.out.println();
|
||||
// Qu'est ce qui est affiché ?
|
||||
// q = (13.0, 14.0)
|
||||
|
||||
// Attacher un point nommé à q et l'afficher
|
||||
q = pn1; // Est-ce autorisé ? Pourquoi ?
|
||||
// oui, PointNommé est pas un sous-type de Point
|
||||
System.out.println("> q = pn1;");
|
||||
System.out.print("q = "); q.afficher(); System.out.println();
|
||||
// Qu'est ce qui est affiché ?
|
||||
// q = PN1:(40.0, 50.0)
|
||||
|
||||
// Définir une poignée sur un point nommé
|
||||
PointNomme qn;
|
||||
|
||||
// Attacher un point à q et l'afficher
|
||||
// qn = p1; // Est-ce autorisé ? Pourquoi ?
|
||||
// Non, Point n’est pas un sous-type de PointNommé
|
||||
// System.out.println("> qn = p1;");
|
||||
// System.out.print("qn = "); qn.afficher(); System.out.println();
|
||||
// Qu'est ce qui est affiché ?
|
||||
// rien, ça compile pas
|
||||
|
||||
// Attacher un point nommé à qn et l'afficher
|
||||
qn = pn1; // Est-ce autorisé ? Pourquoi ?
|
||||
// oui, les types des deux objets sont les mêmes
|
||||
System.out.println("> qn = pn1;");
|
||||
System.out.print("qn = "); qn.afficher(); System.out.println();
|
||||
// Qu'est ce qui est affiché ?
|
||||
// qn = PN1:(40.0, 50.0)
|
||||
|
||||
double d1 = p1.distance(pn1); // Est-ce autorisé ? Pourquoi ?
|
||||
// oui, par Liaison dynamique
|
||||
System.out.println("distance = " + d1);
|
||||
|
||||
double d2 = pn1.distance(p1); // Est-ce autorisé ? Pourquoi ?
|
||||
// oui, par héritage
|
||||
System.out.println("distance = " + d2);
|
||||
|
||||
double d3 = pn1.distance(pn1); // Est-ce autorisé ? Pourquoi ?
|
||||
// oui, par héritage
|
||||
System.out.println("distance = " + d3);
|
||||
|
||||
System.out.println("> qn = q;");
|
||||
// qn = q; // Est-ce autorisé ? Pourquoi ?
|
||||
// Non, Point n’est pas un sous-type de PointNommé
|
||||
// System.out.print("qn = "); qn.afficher(); System.out.println();
|
||||
// Qu'est ce qui est affiché ?
|
||||
// rien, erreur de compilation
|
||||
|
||||
System.out.println("> qn = (PointNomme) q;");
|
||||
qn = (PointNomme) q; // Est-ce autorisé ? Pourquoi ?
|
||||
// oui, car q = pn1, transtypage
|
||||
System.out.print("qn = "); qn.afficher(); System.out.println();
|
||||
|
||||
// System.out.println("> qn = (PointNomme) p1;");
|
||||
// qn = (PointNomme) p1; // Est-ce autorisé ? Pourquoi ?
|
||||
// non, p1 ne comporte pas de nom, conversion impossible
|
||||
// System.out.print("qn = "); qn.afficher(); System.out.println();
|
||||
}
|
||||
|
||||
}
|
BIN
TP05/afficheur.jar
Normal file
BIN
TP05/afficheur.jar
Normal file
Binary file not shown.
BIN
TP05/to-1sn-2020-tp-05-sujet.pdf
Normal file
BIN
TP05/to-1sn-2020-tp-05-sujet.pdf
Normal file
Binary file not shown.
8
TP06/.vscode/settings.json
vendored
Normal file
8
TP06/.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"java.project.referencedLibraries": [
|
||||
"lib/**/*.jar",
|
||||
"/usr/share/java/hamcrest-core.jar",
|
||||
"/usr/share/java/junit.jar",
|
||||
"/home/laurent/Documents/Cours/ENSEEIHT/S6 - Technologie objet/tps/TP05/afficheur.jar"
|
||||
]
|
||||
}
|
72
TP06/ExempleSchema2.java
Normal file
72
TP06/ExempleSchema2.java
Normal file
|
@ -0,0 +1,72 @@
|
|||
import afficheur.Ecran;
|
||||
|
||||
/** Construire le schéma proposé dans le sujet de TP avec des points,
|
||||
* des points nommés
|
||||
* et des segments.
|
||||
*
|
||||
* @author Xavier Crégut
|
||||
* @version $Revision: 1.7 $
|
||||
*/
|
||||
public class ExempleSchema2 {
|
||||
|
||||
/** Construire le schéma et le manipuler.
|
||||
* Le schéma est affiché.
|
||||
* Ensuite, il est translaté et affiché de nouveau.
|
||||
* @param args les arguments de la ligne de commande
|
||||
*/
|
||||
public static void main(String[] args)
|
||||
{
|
||||
// Créer les trois segments
|
||||
Point p1 = new PointNomme(3, 2, "A");
|
||||
Point p2 = new PointNomme(6, 9, "S");
|
||||
Point p3 = new Point(11, 4);
|
||||
Segment s12 = new Segment(p1, p2);
|
||||
Segment s23 = new Segment(p2, p3);
|
||||
Segment s31 = new Segment(p3, p1);
|
||||
|
||||
// Créer le barycentre
|
||||
double sx = p1.getX() + p2.getX() + p3.getX();
|
||||
double sy = p1.getY() + p2.getY() + p3.getY();
|
||||
Point barycentre = new PointNomme(sx / 3, sy / 3, "C");
|
||||
|
||||
// Afficher le schéma
|
||||
System.out.println("Le schéma est composé de : ");
|
||||
s12.afficher(); System.out.println();
|
||||
s23.afficher(); System.out.println();
|
||||
s31.afficher(); System.out.println();
|
||||
barycentre.afficher(); System.out.println();
|
||||
// Créer l'écran d'affichage
|
||||
Ecran ecran = new Ecran("ExempleSchema2", 600, 400, 20);
|
||||
ecran.dessinerAxes();
|
||||
|
||||
// Dessiner le schéma sur l'écran graphique
|
||||
s12.dessiner(ecran);
|
||||
s23.dessiner(ecran);
|
||||
s31.dessiner(ecran);
|
||||
barycentre.dessiner(ecran);
|
||||
|
||||
// Translater le schéma
|
||||
System.out.println("Translater le schéma de (4, -3) : ");
|
||||
s12.translater(4, -3);
|
||||
s23.translater(4, -3);
|
||||
s31.translater(4, -3);
|
||||
barycentre.translater(4, -3);
|
||||
|
||||
// Afficher le schéma
|
||||
System.out.println("Le schéma est composé de : ");
|
||||
s12.afficher(); System.out.println();
|
||||
s23.afficher(); System.out.println();
|
||||
s31.afficher(); System.out.println();
|
||||
barycentre.afficher(); System.out.println();
|
||||
|
||||
// Dessiner le schéma sur l'écran graphique
|
||||
s12.dessiner(ecran);
|
||||
s23.dessiner(ecran);
|
||||
s31.dessiner(ecran);
|
||||
barycentre.dessiner(ecran);
|
||||
|
||||
// Forcer l'affichage du schéma (au cas où...)
|
||||
ecran.rafraichir();
|
||||
}
|
||||
|
||||
}
|
68
TP06/ExempleSchemaGroupe.java
Normal file
68
TP06/ExempleSchemaGroupe.java
Normal file
|
@ -0,0 +1,68 @@
|
|||
import afficheur.Ecran;
|
||||
|
||||
/** Construire le schéma proposé dans le sujet de TP avec des points,
|
||||
* des points nommés
|
||||
* et des segments.
|
||||
*
|
||||
* @author Xavier Crégut
|
||||
* @version $Revision: 1.7$
|
||||
*/
|
||||
public class ExempleSchemaGroupe {
|
||||
|
||||
/** Construire le schéma et le manipuler.
|
||||
* Le schéma est affiché.
|
||||
* Ensuite, il est translaté et affiché de nouveau.
|
||||
* @param args les arguments de la ligne de commande
|
||||
*/
|
||||
public static void main(String[] args)
|
||||
{
|
||||
// Créer les trois segments
|
||||
Point p1 = new PointNomme(3, 2, "A");
|
||||
Point p2 = new PointNomme(6, 9, "S");
|
||||
Point p3 = new Point(11, 4);
|
||||
Segment s12 = new Segment(p1, p2);
|
||||
Segment s23 = new Segment(p2, p3);
|
||||
Segment s31 = new Segment(p3, p1);
|
||||
|
||||
// Créer le barycentre
|
||||
double sx = p1.getX() + p2.getX() + p3.getX();
|
||||
double sy = p1.getY() + p2.getY() + p3.getY();
|
||||
Point barycentre = new PointNomme(sx / 3, sy / 3, "C");
|
||||
|
||||
// Définir le schéma (vide)
|
||||
// Geometrique[] schema = new Geometrique[10]; // le schéma
|
||||
// 10 : capacité suffisante ici, non contrôlée dans la suite.
|
||||
//int nb = 0; // Le nombre d'éléments dans le schéma
|
||||
|
||||
Groupe liste = new Groupe();
|
||||
|
||||
// Peupler le schéma
|
||||
liste.ajouter(s12);
|
||||
liste.ajouter(s23);
|
||||
liste.ajouter(s31);
|
||||
liste.ajouter(barycentre);
|
||||
|
||||
// Afficher le schéma
|
||||
liste.afficher();
|
||||
|
||||
// Créer l'écran d'affichage
|
||||
Ecran ecran = new Ecran("ExempleSchemaTab", 600, 400, 20);
|
||||
ecran.dessinerAxes();
|
||||
|
||||
// Dessiner le schéma sur l'écran graphique
|
||||
liste.dessiner(ecran);
|
||||
|
||||
// Translater le schéma
|
||||
liste.translater(4, -3);
|
||||
|
||||
// Afficher le schéma
|
||||
liste.afficher();
|
||||
|
||||
// Dessiner le schéma sur l'écran graphique
|
||||
liste.dessiner(ecran);
|
||||
|
||||
// Forcer l'affichage du schéma (au cas où...)
|
||||
ecran.rafraichir();
|
||||
}
|
||||
|
||||
}
|
96
TP06/ExempleSchemaTab.java
Normal file
96
TP06/ExempleSchemaTab.java
Normal file
|
@ -0,0 +1,96 @@
|
|||
import java.util.ArrayList;
|
||||
|
||||
import afficheur.Ecran;
|
||||
|
||||
/** Construire le schéma proposé dans le sujet de TP avec des points,
|
||||
* des points nommés
|
||||
* et des segments.
|
||||
*
|
||||
* @author Xavier Crégut
|
||||
* @version $Revision: 1.7$
|
||||
*/
|
||||
public class ExempleSchemaTab {
|
||||
|
||||
/** Construire le schéma et le manipuler.
|
||||
* Le schéma est affiché.
|
||||
* Ensuite, il est translaté et affiché de nouveau.
|
||||
* @param args les arguments de la ligne de commande
|
||||
*/
|
||||
public static void main(String[] args)
|
||||
{
|
||||
// Créer les trois segments
|
||||
Point p1 = new PointNomme(3, 2, "A");
|
||||
Point p2 = new PointNomme(6, 9, "S");
|
||||
Point p3 = new Point(11, 4);
|
||||
Segment s12 = new Segment(p1, p2);
|
||||
Segment s23 = new Segment(p2, p3);
|
||||
Segment s31 = new Segment(p3, p1);
|
||||
|
||||
// Créer le barycentre
|
||||
double sx = p1.getX() + p2.getX() + p3.getX();
|
||||
double sy = p1.getY() + p2.getY() + p3.getY();
|
||||
Point barycentre = new PointNomme(sx / 3, sy / 3, "C");
|
||||
|
||||
// Définir le schéma (vide)
|
||||
// Geometrique[] schema = new Geometrique[10]; // le schéma
|
||||
// 10 : capacité suffisante ici, non contrôlée dans la suite.
|
||||
//int nb = 0; // Le nombre d'éléments dans le schéma
|
||||
|
||||
ArrayList<Geometrique> schema = new ArrayList<Geometrique>();;
|
||||
|
||||
// Peupler le schéma
|
||||
schema.add(s12);
|
||||
schema.add(s23);
|
||||
schema.add(s31);
|
||||
schema.add(barycentre);
|
||||
|
||||
// // Afficher le schéma
|
||||
// System.out.println("Le schéma est composé de : ");
|
||||
// for (int i = 0; i < nb; i++) {
|
||||
// schema[i].afficher();
|
||||
// System.out.println();
|
||||
// }
|
||||
schema.forEach(obj -> {
|
||||
obj.afficher();
|
||||
System.out.println();
|
||||
});
|
||||
|
||||
// Créer l'écran d'affichage
|
||||
Ecran ecran = new Ecran("ExempleSchemaTab", 600, 400, 20);
|
||||
ecran.dessinerAxes();
|
||||
|
||||
// // Dessiner le schéma sur l'écran graphique
|
||||
// for (int i = 0; i < nb; i++) {
|
||||
// schema[i].dessiner(ecran);
|
||||
// }
|
||||
schema.forEach(obj -> obj.dessiner(ecran));
|
||||
|
||||
// // Translater le schéma
|
||||
// System.out.println("Translater le schéma de (4, -3) : ");
|
||||
// for (int i = 0; i < nb; i++) {
|
||||
// schema[i].translater(4, -3);
|
||||
// }
|
||||
schema.forEach(obj -> obj.translater(4, -3));
|
||||
|
||||
// // Afficher le schéma
|
||||
// System.out.println("Le schéma est composé de : ");
|
||||
// for (int i = 0; i < nb; i++) {
|
||||
// schema[i].afficher();
|
||||
// System.out.println();
|
||||
// }
|
||||
schema.forEach(obj -> {
|
||||
obj.afficher();
|
||||
System.out.println();
|
||||
});
|
||||
|
||||
// // Dessiner le schéma sur l'écran graphique
|
||||
// for (int i = 0; i < nb; i++) {
|
||||
// schema[i].dessiner(ecran);
|
||||
// }
|
||||
schema.forEach(obj -> obj.dessiner(ecran));
|
||||
|
||||
// Forcer l'affichage du schéma (au cas où...)
|
||||
ecran.rafraichir();
|
||||
}
|
||||
|
||||
}
|
103
TP06/GeneralisationTest.java
Normal file
103
TP06/GeneralisationTest.java
Normal file
|
@ -0,0 +1,103 @@
|
|||
import org.junit.*;
|
||||
import static org.junit.Assert.*;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.awt.Color;
|
||||
|
||||
/**
|
||||
* Programme de test pour vérifier la bonne mise en oeuvre de la généralisation.
|
||||
*
|
||||
* @author Xavier Crégut <Prenom.Nom@enseeiht.fr>
|
||||
*/
|
||||
|
||||
public class GeneralisationTest {
|
||||
|
||||
private Method getDeclaredMethod(Class<?> classe, String name, Class<?>... args) {
|
||||
try {
|
||||
return classe.getDeclaredMethod(name, args);
|
||||
}
|
||||
catch (NoSuchMethodException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private Constructor<?> getDeclaredConstructor(Class<?> classe, Class<?>... args) {
|
||||
try {
|
||||
return classe.getDeclaredConstructor(args);
|
||||
}
|
||||
catch (NoSuchMethodException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private Field getDeclaredField(Class<?> classe, String name) {
|
||||
try {
|
||||
return classe.getDeclaredField(name);
|
||||
}
|
||||
catch (NoSuchFieldException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void verifierLaSuperClasse(Class<?> superClasse) {
|
||||
Method getCouleurMethod = getDeclaredMethod(superClasse, "getCouleur");
|
||||
assertTrue("Pourquoi ne pas factoriser getCouleur() dans "
|
||||
+ superClasse.getName() + " ?",
|
||||
getCouleurMethod != null);
|
||||
|
||||
Method setCouleurMethod = getDeclaredMethod(superClasse, "setCouleur", Color.class);
|
||||
assertTrue("Pourquoi ne pas factoriser setCouleur() dans "
|
||||
+ superClasse.getName() + " ?",
|
||||
setCouleurMethod != null);
|
||||
|
||||
Field couleurField = getDeclaredField(superClasse, "couleur");
|
||||
assertTrue("Pourquoi ne pas factoriser l'attribut 'couleur' dans "
|
||||
+ superClasse.getName() + " ?",
|
||||
couleurField != null);
|
||||
assertTrue("L'attribut 'couleur' devrait être privé !",
|
||||
Modifier.isPrivate(couleurField.getModifiers()));
|
||||
assertFalse("Pourquoi ne pas définir getCouleur() dans "
|
||||
+ superClasse.getName() + " ?",
|
||||
Modifier.isAbstract(getCouleurMethod.getModifiers()));
|
||||
assertFalse("Pourquoi ne pas définir setCouleur() dans "
|
||||
+ superClasse.getName() + " ?",
|
||||
Modifier.isAbstract(setCouleurMethod.getModifiers()));
|
||||
|
||||
Constructor<?> constructeur = getDeclaredConstructor(superClasse, Color.class);
|
||||
assertTrue("Pourquoi ne pas définir un constructeur pour initialiser"
|
||||
+ " la couleur dans " + superClasse.getName() + " ?",
|
||||
constructeur != null);
|
||||
}
|
||||
|
||||
private void verifierGestionCouleur(Class<?> uneClasse) {
|
||||
Class<?> superClasse = uneClasse.getSuperclass();
|
||||
assertFalse("Il faut d'abord faire marcher ExempleSchemaTab !",
|
||||
Object.class.equals(superClasse));
|
||||
|
||||
// Vérifier la super-classe
|
||||
verifierLaSuperClasse(superClasse);
|
||||
|
||||
assertTrue("Pourquoi redéfinir la méthode getCouleur() dans "
|
||||
+ uneClasse.getName() + " ?",
|
||||
null == getDeclaredMethod(uneClasse, "getCouleur"));
|
||||
assertTrue("Pourquoi redéfinir la méthode setCouleur() dans "
|
||||
+ uneClasse.getName() + " ?",
|
||||
null == getDeclaredMethod(uneClasse, "setCouleur", Color.class));
|
||||
assertTrue("Pourquoi ne pas supprimer l'attribut 'couleur' de "
|
||||
+ uneClasse.getName() + " ?",
|
||||
null == getDeclaredField(uneClasse, "couleur"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testerGeneralisationPoint() {
|
||||
verifierGestionCouleur(Point.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testerGeneralisationSegment() {
|
||||
verifierGestionCouleur(Segment.class);
|
||||
}
|
||||
|
||||
}
|
55
TP06/Geometrique.java
Normal file
55
TP06/Geometrique.java
Normal file
|
@ -0,0 +1,55 @@
|
|||
import java.awt.Color;
|
||||
|
||||
/** Point modélise un point géométrique dans un plan équipé d'un
|
||||
* repère cartésien. Un point peut être affiché et translaté.
|
||||
* Sa distance par rapport à un autre point peut être obtenue.
|
||||
* Le point peut être dessiné sur un afficheur.
|
||||
*
|
||||
* @author Xavier Crégut <Prénom.Nom@enseeiht.fr>
|
||||
*/
|
||||
abstract public class Geometrique {
|
||||
|
||||
//@ private invariant getCouleur() != null;
|
||||
//@ private invariant getCouleur() == couleur; // invariant de liaison
|
||||
private Color couleur; // couleur du point
|
||||
|
||||
/** Construire un point à partir de son abscisse et de son ordonnée.
|
||||
*/
|
||||
public Geometrique(Color couleur) {
|
||||
this.couleur = couleur;
|
||||
}
|
||||
|
||||
/** Afficher sur le terminal les caractéristiques de l’objet. */
|
||||
abstract public void afficher();
|
||||
|
||||
/**
|
||||
* Dessiner l’objet.
|
||||
* @param afficheur Ecran sur lequel on dessine
|
||||
* */
|
||||
abstract public void dessiner(afficheur.Afficheur afficheur);
|
||||
|
||||
/**
|
||||
* Translater l’objet géométrique.
|
||||
* @param dx déplacement en X
|
||||
* @param dy déplacement en Y
|
||||
*/
|
||||
abstract public void translater(double dx, double dy);
|
||||
|
||||
// Gestion de la couleur
|
||||
|
||||
/** Obtenir la couleur du point.
|
||||
* @return la couleur du point
|
||||
*/
|
||||
//@ pure
|
||||
public Color getCouleur() {
|
||||
return this.couleur;
|
||||
}
|
||||
|
||||
/** Changer la couleur du point.
|
||||
* @param nouvelleCouleur nouvelle couleur
|
||||
*/
|
||||
public void setCouleur(Color nouvelleCouleur) {
|
||||
this.couleur = nouvelleCouleur;
|
||||
}
|
||||
|
||||
}
|
46
TP06/Groupe.java
Normal file
46
TP06/Groupe.java
Normal file
|
@ -0,0 +1,46 @@
|
|||
import java.awt.Color;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/** Point modélise un point géométrique dans un plan équipé d'un
|
||||
* repère cartésien. Un point peut être affiché et translaté.
|
||||
* Sa distance par rapport à un autre point peut être obtenue.
|
||||
* Le point peut être dessiné sur un afficheur.
|
||||
*
|
||||
* @author Xavier Crégut <Prénom.Nom@enseeiht.fr>
|
||||
*/
|
||||
public class Groupe {
|
||||
|
||||
private ArrayList<Geometrique> list = new ArrayList<Geometrique>();
|
||||
|
||||
public void ajouter(Geometrique obj) {
|
||||
list.add(obj);
|
||||
}
|
||||
|
||||
public void supprimer(Geometrique obj) {
|
||||
list.remove(obj);
|
||||
}
|
||||
|
||||
/** Afficher le point. */
|
||||
public void afficher() {
|
||||
list.forEach(obj -> {
|
||||
obj.afficher();
|
||||
System.out.println();
|
||||
});
|
||||
}
|
||||
|
||||
/** Translater le point.
|
||||
* @param dx déplacement suivant l'axe des X
|
||||
* @param dy déplacement suivant l'axe des Y
|
||||
*/
|
||||
public void translater(double dx, double dy) {
|
||||
list.forEach(obj -> obj.translater(dx, dy));
|
||||
}
|
||||
|
||||
/** Dessiner le point sur l'afficheur.
|
||||
* @param afficheur l'afficheur à utiliser
|
||||
*/
|
||||
public void dessiner(afficheur.Afficheur afficheur) {
|
||||
list.forEach(obj -> obj.dessiner(afficheur));
|
||||
}
|
||||
|
||||
}
|
106
TP06/Point.java
Normal file
106
TP06/Point.java
Normal file
|
@ -0,0 +1,106 @@
|
|||
import java.awt.Color;
|
||||
|
||||
/** Point modélise un point géométrique dans un plan équipé d'un
|
||||
* repère cartésien. Un point peut être affiché et translaté.
|
||||
* Sa distance par rapport à un autre point peut être obtenue.
|
||||
* Le point peut être dessiné sur un afficheur.
|
||||
*
|
||||
* @author Xavier Crégut <Prénom.Nom@enseeiht.fr>
|
||||
*/
|
||||
public class Point extends Geometrique {
|
||||
private double x; // abscisse
|
||||
private double y; // ordonnée
|
||||
|
||||
//@ private invariant getCouleur() != null;
|
||||
//@ private invariant getCouleur() == couleur; // invariant de liaison
|
||||
private Color couleur; // couleur du point
|
||||
|
||||
/** Construire un point à partir de son abscisse et de son ordonnée.
|
||||
* @param vx abscisse
|
||||
* @param vy ordonnée
|
||||
*/
|
||||
public Point(double vx, double vy) {
|
||||
super(Color.green);
|
||||
this.x = vx;
|
||||
this.y = vy;
|
||||
}
|
||||
|
||||
/** Obtenir l'abscisse du point.
|
||||
* @return abscisse du point
|
||||
*/
|
||||
//@ pure
|
||||
public double getX() {
|
||||
return this.x;
|
||||
}
|
||||
|
||||
/** Obtenir l'ordonnée du point.
|
||||
* @return ordonnée du point
|
||||
*/
|
||||
//@ pure
|
||||
public double getY() {
|
||||
return this.y;
|
||||
}
|
||||
|
||||
/** Changer l'abscisse du point.
|
||||
* @param vx nouvelle abscisse
|
||||
*/
|
||||
public void setX(double vx) {
|
||||
this.x = vx;
|
||||
}
|
||||
|
||||
/** Changer l'ordonnée du point.
|
||||
* @param vy nouvelle ordonnée
|
||||
*/
|
||||
public void setY(double vy) {
|
||||
this.y = vy;
|
||||
}
|
||||
|
||||
/** Afficher le point. */
|
||||
public void afficher() {
|
||||
System.out.print("(" + this.x + ", " + this.y + ")");
|
||||
}
|
||||
|
||||
/** Distance par rapport à un autre point.
|
||||
* @param autre l'autre point
|
||||
* @return distance entre this et autre
|
||||
*/
|
||||
//@ pure
|
||||
public double distance(Point autre) {
|
||||
return Math.sqrt(Math.pow(autre.x - this.x, 2)
|
||||
+ Math.pow(autre.y - this.y, 2));
|
||||
}
|
||||
|
||||
/** Translater le point.
|
||||
* @param dx déplacement suivant l'axe des X
|
||||
* @param dy déplacement suivant l'axe des Y
|
||||
*/
|
||||
public void translater(double dx, double dy) {
|
||||
this.x += dx;
|
||||
this.y += dy;
|
||||
}
|
||||
|
||||
/** Dessiner le point sur l'afficheur.
|
||||
* @param afficheur l'afficheur à utiliser
|
||||
*/
|
||||
public void dessiner(afficheur.Afficheur afficheur) {
|
||||
afficheur.dessinerPoint(this.getX(), this.getY(), this.getCouleur());
|
||||
}
|
||||
|
||||
// Gestion de la couleur
|
||||
|
||||
/** Obtenir la couleur du point.
|
||||
* @return la couleur du point
|
||||
*/
|
||||
//@ pure
|
||||
public Color getCouleur() {
|
||||
return this.couleur;
|
||||
}
|
||||
|
||||
/** Changer la couleur du point.
|
||||
* @param nouvelleCouleur nouvelle couleur
|
||||
*/
|
||||
public void setCouleur(Color nouvelleCouleur) {
|
||||
this.couleur = nouvelleCouleur;
|
||||
}
|
||||
|
||||
}
|
50
TP06/PointNomme.java
Normal file
50
TP06/PointNomme.java
Normal file
|
@ -0,0 +1,50 @@
|
|||
/** Un point nommé est un point avec un nom.
|
||||
* @author Xavier Crégut
|
||||
* @version 1.7
|
||||
*/
|
||||
public class PointNomme extends Point {
|
||||
|
||||
private String nom; // le nom du point nommé
|
||||
|
||||
/** Construire un point nommé à partir de son abscisse, son
|
||||
* ordonnée et son nom.
|
||||
* @param vx valeur de l'abscisse
|
||||
* @param vy valeur de l'ordonnée
|
||||
* @param sonNom nom à donner au point
|
||||
*/
|
||||
public PointNomme(double vx, double vy, String sonNom) {
|
||||
super(vx, vy); // toujours en première ligne !
|
||||
this.setNom(sonNom);
|
||||
}
|
||||
|
||||
/** Obtenir le nom du point nommé.
|
||||
* @return le nom du point nommé
|
||||
*/
|
||||
public String getNom() {
|
||||
return this.nom;
|
||||
}
|
||||
|
||||
/** Changer le nom du point nommé.
|
||||
* @param sonNom le nouveau nom
|
||||
*/
|
||||
public void setNom(String sonNom) {
|
||||
this.nom = sonNom;
|
||||
}
|
||||
|
||||
/** Afficher le point nommé. Le point est affiché sous la forme :
|
||||
* <PRE>
|
||||
* nom:(x, y)
|
||||
* </PRE>
|
||||
*/
|
||||
@Override public void afficher() {
|
||||
System.out.print(this.getNom() + ":");
|
||||
super.afficher(); // utiliser afficher de Point
|
||||
}
|
||||
|
||||
@Override public void dessiner(afficheur.Afficheur afficheur) {
|
||||
super.dessiner(afficheur); // utiliser dessiner de Point
|
||||
afficheur.dessinerTexte (this.getX(), this.getY(),
|
||||
this.getNom(), this.getCouleur());
|
||||
}
|
||||
|
||||
}
|
82
TP06/Segment.java
Normal file
82
TP06/Segment.java
Normal file
|
@ -0,0 +1,82 @@
|
|||
import java.awt.Color;
|
||||
|
||||
/** Un segment est défini pas ses deux points qui constituent ses
|
||||
* extrémités. Un segment peut être affiché et translaté.
|
||||
* Le segment peut être dessiné sur un afficheur.
|
||||
*
|
||||
* @author Xavier Crégut
|
||||
* @version 1.9
|
||||
*/
|
||||
public class Segment extends Geometrique {
|
||||
|
||||
private Point extremite1;
|
||||
private Point extremite2;
|
||||
private Color couleur;
|
||||
|
||||
/** Construire un Segment à partir de ses deux points extrémités.
|
||||
* @param ext1 le premier point extrémité
|
||||
* @param ext2 le deuxième point extrémité
|
||||
*/
|
||||
public Segment(Point ext1, Point ext2) {
|
||||
super(Color.green);
|
||||
this.extremite1 = ext1;
|
||||
this.extremite2 = ext2;
|
||||
}
|
||||
|
||||
/** Translater le segment.
|
||||
* @param dx déplacement suivant l'axe des X
|
||||
* @param dy déplacement suivant l'axe des Y
|
||||
*/
|
||||
public void translater(double dx, double dy) {
|
||||
extremite1.translater(dx, dy);
|
||||
extremite2.translater(dx, dy);
|
||||
}
|
||||
|
||||
/** Dessiner le segment sur l'afficheur.
|
||||
* @param afficheur l'afficheur à utiliser
|
||||
*/
|
||||
public void dessiner(afficheur.Afficheur afficheur) {
|
||||
afficheur.dessinerLigne(this.extremite1.getX(), this.extremite1.getY(),
|
||||
this.extremite2.getX(), this.extremite2.getY(),
|
||||
this.getCouleur());
|
||||
|
||||
// Dessiner les deux extrémités : est-ce bien normal ?
|
||||
this.extremite1.dessiner(afficheur);
|
||||
this.extremite2.dessiner(afficheur);
|
||||
}
|
||||
|
||||
/** Obtenir la longueur du segment.
|
||||
* @return la longueur du segment
|
||||
*/
|
||||
public double longueur() {
|
||||
return this.extremite1.distance(this.extremite2);
|
||||
}
|
||||
|
||||
/** Afficher le segment. Le segment est affiché sous la forme :
|
||||
* <PRE>
|
||||
* [extremite1-extremite2]
|
||||
* </PRE>
|
||||
*/
|
||||
public void afficher() {
|
||||
System.out.print("[");
|
||||
this.extremite1.afficher();
|
||||
System.out.print("-");
|
||||
this.extremite2.afficher();
|
||||
System.out.print("]");
|
||||
}
|
||||
|
||||
/** Obtenir la couleur du segment.
|
||||
* @return la couleur du segment
|
||||
*/
|
||||
public Color getCouleur() {
|
||||
return this.couleur;
|
||||
}
|
||||
|
||||
/** Changer la couleur du segment.
|
||||
* @param nouvelleCouleur nouvelle couleur
|
||||
*/
|
||||
public void setCouleur(Color nouvelleCouleur) {
|
||||
this.couleur = nouvelleCouleur;
|
||||
}
|
||||
|
||||
}
|
BIN
TP06/to-1sn-2020-tp-06-sujet.pdf
Normal file
BIN
TP06/to-1sn-2020-tp-06-sujet.pdf
Normal file
Binary file not shown.
399
TP07/Date.java
Normal file
399
TP07/Date.java
Normal file
|
@ -0,0 +1,399 @@
|
|||
/**
|
||||
* Définition d'une date dans le calendrier grégorien.
|
||||
*
|
||||
* @author Xavier Crégut
|
||||
* @version 1.5
|
||||
*/
|
||||
public class Date {
|
||||
|
||||
/*@ // le jour, le mois et l'année sont valides
|
||||
public invariant
|
||||
Date.estValide(this.getJour(), this.getMois(), this.getAnnee());
|
||||
|
||||
// le quantième est valide
|
||||
public invariant
|
||||
Date.estQuantiemeValide(this.getQuantieme(), this.getAnnee());
|
||||
|
||||
private invariant // cumulJoursMois est cohérent avec nbJoursDansMois
|
||||
(\forall int mois; 0 <= mois && mois < Date.cumulJoursMois.length;
|
||||
Date.cumulJoursMois[mois] ==
|
||||
(\sum int m; 0 <= m && m < mois; Date.nbJoursMois[m]));
|
||||
@*/
|
||||
|
||||
/** Tableau du nombre de jours par mois (sans prendre en compte les
|
||||
* années bissextiles). nbJoursMois[i] est le nombre de jours du
|
||||
* mois de numéro i+1.
|
||||
*/
|
||||
private static int nbJoursMois[] =
|
||||
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
||||
|
||||
/** Cumul des jours des mois précédents. cumulJoursMois[i] est le
|
||||
* nombre cumulé des jours des mois dont les numéros sont dans
|
||||
* l'intervalle 1..i-1.
|
||||
*/
|
||||
private static int cumulJoursMois[] =
|
||||
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
|
||||
|
||||
/** le numéro du jour dans le mois */
|
||||
private int jour;
|
||||
|
||||
/** le numéro du mois dans l'année */
|
||||
private int mois;
|
||||
|
||||
/** l'année */
|
||||
private int annee;
|
||||
|
||||
/** Construire une date à partir du numéro du jour, du numéro du mois et de
|
||||
* l'année (qui doivent former une date valide).
|
||||
* @param j le numéro du jour dans le mois m
|
||||
* @param m le numéro du mois
|
||||
* @param a l'année
|
||||
*/
|
||||
//@ requires Date.estValide(j, m, a);
|
||||
//@ ensures getJour() == j;
|
||||
//@ ensures getMois() == m;
|
||||
//@ ensures getAnnee() == a;
|
||||
public Date(int j, int m, int a) {
|
||||
this._set(j, m, a);
|
||||
// On ne peut pas appeler directement set(j, m, a) car comme elle est
|
||||
// publique, elle provoque la vérification des invariants.
|
||||
}
|
||||
|
||||
/** Construire une date à partir du quantième du jour dans l'année et de
|
||||
* l'année.
|
||||
* @param q le quantième du jour dans l'année
|
||||
* @param a l'année
|
||||
*/
|
||||
//@ requires Date.estAnneeValide(a);
|
||||
//@ requires Date.estQuantiemeValide(q, a);
|
||||
//@ ensures getQuantieme() == q;
|
||||
//@ ensures getAnnee() == a;
|
||||
public Date(int q, int a) {
|
||||
this._set(q, a);
|
||||
}
|
||||
|
||||
/** Changer la date à partir du numéro du jour, du numéro du mois et de
|
||||
* l'année.
|
||||
* @param j le numéro du jour dans le mois m
|
||||
* @param m le numéro du mois
|
||||
* @param a l'année
|
||||
*/
|
||||
// Cette méthode est privée et déclarée comme <em>helper</em> de manière à
|
||||
// ce que les invariants de la classe ne soient pas vérifiés quand elle
|
||||
// appelée depuis une autre méthode de la classe.
|
||||
//@ requires Date.estValide(j, m, a);
|
||||
//@ ensures this.jour == j;
|
||||
//@ ensures this.mois == m;
|
||||
//@ ensures this.annee == a;
|
||||
//@ helper
|
||||
private void _set(int j, int m, int a) {
|
||||
this.jour = j;
|
||||
this.mois = m;
|
||||
this.annee = a;
|
||||
}
|
||||
|
||||
/** Changer la date à partir du numéro du jour, du numéro du mois et de
|
||||
* l'année.
|
||||
* @param j le numéro du jour dans le mois m
|
||||
* @param m le numéro du mois
|
||||
* @param a l'année
|
||||
*/
|
||||
//@ requires Date.estValide(j, m, a);
|
||||
//@ ensures getJour() == j;
|
||||
//@ ensures getMois() == m;
|
||||
//@ ensures getAnnee() == a;
|
||||
public void set(int j, int m, int a) {
|
||||
this._set(j, m, a);
|
||||
}
|
||||
|
||||
/** Changer la date à partir du quantième du jour dans l'année et de
|
||||
* l'année.
|
||||
* @param q le quantième du jour dans l'année
|
||||
* @param a l'année
|
||||
*/
|
||||
//@ requires Date.estAnneeValide(a);
|
||||
//@ requires Date.estQuantiemeValide(q, a);
|
||||
//@ ensures getQuantieme() == q;
|
||||
//@ ensures getAnnee() == a;
|
||||
//@ helper
|
||||
private void _set(int q, int a) {
|
||||
// Initialiser l'année
|
||||
this.annee = a;
|
||||
|
||||
// Initialiser le mois
|
||||
this.mois = 1;
|
||||
while (q > nbJoursDansMois(this.mois, a)) { // le mois est terminé
|
||||
q = q - nbJoursDansMois(this.mois, a);
|
||||
this.mois++;
|
||||
}
|
||||
|
||||
// Initialiser les jours
|
||||
this.jour = q;
|
||||
}
|
||||
|
||||
/** Changer la date à partir du quantième du jour dans l'année et de
|
||||
* l'année.
|
||||
* @param q le quantième du jour dans l'année
|
||||
* @param a l'année
|
||||
*/
|
||||
//@ requires Date.estAnneeValide(a);
|
||||
//@ requires Date.estQuantiemeValide(q, a);
|
||||
//@ ensures getQuantieme() == q;
|
||||
//@ ensures getAnnee() == a;
|
||||
public void set(int q, int a) {
|
||||
this._set(q, a);
|
||||
}
|
||||
|
||||
/** Obtenir le numéro du jour dans le mois.
|
||||
* @return le numéro du jour dans le mois
|
||||
*/
|
||||
//@ pure
|
||||
//@ helper
|
||||
public int getJour() {
|
||||
return this.jour;
|
||||
}
|
||||
|
||||
/** Obtenir le numéro du mois dans l'année.
|
||||
* @return le numéro du mois dans l'année
|
||||
*/
|
||||
//@ pure
|
||||
//@ helper
|
||||
public int getMois() {
|
||||
return this.mois;
|
||||
}
|
||||
|
||||
/** Obtenir l'année.
|
||||
* @return l'année
|
||||
*/
|
||||
//@ pure
|
||||
//@ helper
|
||||
public int getAnnee() {
|
||||
return this.annee;
|
||||
}
|
||||
|
||||
/** Obtenir le quantième du jour dans l'année.
|
||||
* @return le quantième du jour dans l'année
|
||||
*/
|
||||
//@ pure
|
||||
//@ helper
|
||||
public int getQuantieme() {
|
||||
int resultat = this.jour // nb de jours dans le mois en cours
|
||||
+ cumulJoursMois[this.mois-1]; // nb de jours des mois précédents
|
||||
// Prendre en compte le cas de l'année bissextile
|
||||
if (this.mois > 2 && estBissextile(this.annee)) {
|
||||
resultat++;
|
||||
}
|
||||
|
||||
return resultat;
|
||||
}
|
||||
|
||||
/** Obtenir le nombres de jours depuis l'an 0.
|
||||
* @return nombres de jours depuis l'an 0.
|
||||
*/
|
||||
//@ pure
|
||||
public int getNbJoursDepuisAn0() {
|
||||
int a = this.annee - 1; // nb d'années pleines
|
||||
return this.getQuantieme() // nb de jours dans l'année en cours
|
||||
+ 365 * a // années considérées non bissextiles
|
||||
+ (a / 4 - a / 100 + a / 400); // nb d'années bissextiles
|
||||
}
|
||||
|
||||
/** Afficher la date sous la forme jour/mois/année. */
|
||||
public void afficher() {
|
||||
System.out.println(this);
|
||||
}
|
||||
|
||||
// Méthode définie dans objet. Je n'utilise pas un commentaire javadoc car
|
||||
// le commentaire défini dans la classe parente est le commentaire à
|
||||
// utiliser.
|
||||
public String toString() {
|
||||
return "" + int2String(this.jour)
|
||||
+ '/' + int2String(this.mois)
|
||||
+ '/' + this.annee;
|
||||
// le "" intial est là pour forcer la conversion en String,
|
||||
// les caractères sont en effet compatibles avec les entiers !
|
||||
}
|
||||
|
||||
/** Obtenir la représentation d'un entier sous la forme d'une chaîne de
|
||||
* caractères avec au moins 2 caractères.
|
||||
* @param entier l'entier à convertir
|
||||
* @return la chaîne de caractères correspondant à entier
|
||||
*/
|
||||
private static String int2String(int entier) {
|
||||
String prefixe = (entier >= 0 && entier < 10) ? "0" : "";
|
||||
return prefixe + entier;
|
||||
}
|
||||
|
||||
/** L'année a est-elle bissextile ?
|
||||
* @param a l'année
|
||||
* @return vrai si l'année est bissextile
|
||||
*/
|
||||
//@ pure
|
||||
public static boolean estBissextile(int a) {
|
||||
return (a % 4 == 0) // divisible par 4
|
||||
&& ((a % 100 != 0) // et non divible par 100
|
||||
|| (a % 400 == 0)); // sauf si divisible par 400
|
||||
}
|
||||
|
||||
/** Nombre de jours dans le mois m de l'année a.
|
||||
* @param m le numéro du mois
|
||||
* @param a l'année
|
||||
* @return le nombre de jours dans le mois m de l'année a
|
||||
*/
|
||||
//@ pure
|
||||
public static int nbJoursDansMois(int m, int a) {
|
||||
int resultat = nbJoursMois[m-1]; // nb de jours dans le mois
|
||||
if (m == 2 && estBissextile(a)) { // cas du mois de février
|
||||
resultat++;
|
||||
}
|
||||
return resultat;
|
||||
}
|
||||
|
||||
/** Est-ce que le numéro de jour j est valide pour le mois m de l'année a ?
|
||||
* @param j le numéro du jour dans le mois m
|
||||
* @param m le numéro du mois
|
||||
* @param a l'année
|
||||
*/
|
||||
//@ requires Date.estAnneeValide(a);
|
||||
//@ requires Date.estMoisValide(m);
|
||||
//@ pure
|
||||
public static boolean estJourValide(int j, int m, int a) {
|
||||
return 1 <= j && j <= nbJoursDansMois(m, a);
|
||||
}
|
||||
|
||||
/** Est-ce que le numéro de mois m est valide ?
|
||||
* @param m le numéro du mois
|
||||
*/
|
||||
//@ ensures \result <==> (1 <= m && m <= 12);
|
||||
//@ pure
|
||||
public static boolean estMoisValide(int m) {
|
||||
return 1 <= m && m <= 12;
|
||||
}
|
||||
|
||||
/** Est-ce que le quantième est valide ?
|
||||
* @param q le numéro du jour dans l'année
|
||||
* @param a l'année
|
||||
*/
|
||||
//@ pure
|
||||
//@ helper
|
||||
public static boolean estQuantiemeValide(int q, int a) {
|
||||
boolean resultat = estAnneeValide(a);
|
||||
int nbJours = 365; // nb de jours dans l'année a;
|
||||
if (estBissextile(a)) {
|
||||
nbJours++;
|
||||
}
|
||||
resultat = resultat && 1 <= q && q <= nbJours;
|
||||
return resultat;
|
||||
}
|
||||
|
||||
/** Est-ce que l'année est valide ?
|
||||
* @param a l'année
|
||||
*/
|
||||
//@ ensures \result <==> a > 0;
|
||||
//@ pure
|
||||
public static boolean estAnneeValide(int a) {
|
||||
return a > 0;
|
||||
}
|
||||
|
||||
/** Est-ce que la date définie par le jour j, le mois m et l'année a est
|
||||
* valide ?
|
||||
* @param j le numéro du jour dans le mois m
|
||||
* @param m le numéro du mois
|
||||
* @param a l'année
|
||||
*/
|
||||
//@ pure
|
||||
//@ helper
|
||||
public static boolean estValide(int j, int m, int a) {
|
||||
return estAnneeValide(a)
|
||||
&& estMoisValide(m)
|
||||
&& estJourValide(j, m, a);
|
||||
}
|
||||
|
||||
// Relation d'ordre sur les dates
|
||||
// ------------------------------
|
||||
|
||||
/** Déterminer si une date est antérieure strictement à une autre date.
|
||||
* @param autre l'autre date (non nulle)
|
||||
* @return cette date est-elle strictement antérieure à l'autre date ?
|
||||
*/
|
||||
/*@ requires autre != null; // l'autre date est définie
|
||||
ensures \result == this.getAnnee() < autre.getAnnee()
|
||||
|| (this.getAnnee() == autre.getAnnee()
|
||||
&& getMois() < autre.getMois())
|
||||
|| (this.getAnnee() == autre.getAnnee()
|
||||
&& this.getMois() == autre.getMois()
|
||||
&& this.getJour() < autre.getJour());
|
||||
pure
|
||||
@*/
|
||||
public boolean lt(Date autre) {
|
||||
if (this.getAnnee() != autre.getAnnee()) {
|
||||
return this.getAnnee() < autre.getAnnee();
|
||||
} else if (this.getMois() != autre.getMois()) {
|
||||
return this.getMois() < autre.getMois();
|
||||
} else {
|
||||
return this.getJour() < autre.getJour();
|
||||
}
|
||||
}
|
||||
|
||||
/** Déterminer si une date est postérieure ou égale à une autre date.
|
||||
* @param autre l'autre date (non nulle)
|
||||
* @return cette date est-elle postérieure ou égale à l'autre date
|
||||
*/
|
||||
//@ ensures \result == ! lt(autre);
|
||||
//@ pure
|
||||
public boolean ge(Date autre) {
|
||||
return ! this.lt(autre);
|
||||
}
|
||||
|
||||
/** Déterminer si une date est strictement postérieure à une autre date.
|
||||
* @param autre l'autre date (non nulle)
|
||||
* @return cette date est-elle strictement postérieure à l'autre date
|
||||
*/
|
||||
//@ ensures \result == autre.lt(this);
|
||||
//@ pure
|
||||
public boolean gt(Date autre) {
|
||||
return autre.lt(this);
|
||||
// Utilisation obligatoire de this (on ne peut pas s'en passer).
|
||||
}
|
||||
|
||||
/** Déterminer si une date est antérieure ou égale à une autre date.
|
||||
* @param autre l'autre date (non nulle)
|
||||
* @return cette date est-elle antérieure ou égale à l'autre date
|
||||
*/
|
||||
//@ ensures \result == !autre.lt(this);
|
||||
//@ pure
|
||||
public boolean le(Date autre) {
|
||||
return ! autre.lt(this);
|
||||
}
|
||||
|
||||
// Égalité de deux dates
|
||||
// ---------------------
|
||||
|
||||
/** Déterminer si deux dates sont égales.
|
||||
* @param autre l'autre date
|
||||
* @return cette date est égale à l'autre date
|
||||
*/
|
||||
//@ ensures \result == (le(autre) && ge(autre));
|
||||
//@ pure
|
||||
public boolean equals(Date autre) {
|
||||
return autre != null
|
||||
&& this.getAnnee() == autre.getAnnee()
|
||||
&& this.getMois() == autre.getMois()
|
||||
&& this.getJour() == autre.getJour();
|
||||
}
|
||||
|
||||
/** Déterminer si cette date est égale à un autre objet.
|
||||
* Ceci est une redéfinition de la méthode définie dans Object
|
||||
* @param objet l'autre objet
|
||||
* @return cette date est égale à l'autre objet
|
||||
*/
|
||||
//@ pure
|
||||
public boolean equals(/*@ nullable @*/ Object objet) {
|
||||
return objet != null
|
||||
&& (objet instanceof Date)
|
||||
// XXX on pourrait faire aussi objet.getClass() == this.getClass()
|
||||
&& equals((Date) objet);
|
||||
}
|
||||
|
||||
}
|
||||
// vi: sw=4 ts=4
|
14
TP07/ExempleDate1.java
Normal file
14
TP07/ExempleDate1.java
Normal file
|
@ -0,0 +1,14 @@
|
|||
// Que penser du programme suivant ?
|
||||
public class ExempleDate1 {
|
||||
public static void main (String args []) {
|
||||
// Construire les dates
|
||||
Date d1 = new Date(20, 5, 1989);
|
||||
Date d2 = new Date(13, 2, 1993);
|
||||
Date d3 = new Date(31, 6, 2001);
|
||||
|
||||
// Afficher les dates
|
||||
System.out.println("d1 = " + d1);
|
||||
System.out.println("d2 = " + d2);
|
||||
System.out.println("d3 = " + d3);
|
||||
}
|
||||
}
|
BIN
TP07/openjml.zip
Normal file
BIN
TP07/openjml.zip
Normal file
Binary file not shown.
7
TP08/.vscode/settings.json
vendored
Normal file
7
TP08/.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"java.project.referencedLibraries": [
|
||||
"lib/**/*.jar",
|
||||
"/usr/share/java/junit.jar",
|
||||
"/usr/share/java/hamcrest-core.jar"
|
||||
]
|
||||
}
|
11
TP08/Cellule.java
Normal file
11
TP08/Cellule.java
Normal file
|
@ -0,0 +1,11 @@
|
|||
public class Cellule<E> {
|
||||
|
||||
public E element;
|
||||
public Cellule<E> suivante;
|
||||
|
||||
public Cellule(E elm, Cellule<E> next) {
|
||||
this.element = elm;
|
||||
this.suivante = next;
|
||||
}
|
||||
|
||||
}
|
5
TP08/Comparateur.java
Normal file
5
TP08/Comparateur.java
Normal file
|
@ -0,0 +1,5 @@
|
|||
public interface Comparateur<E> {
|
||||
|
||||
boolean inf(E n1, E n2);
|
||||
|
||||
}
|
29
TP08/Ensemble.java
Normal file
29
TP08/Ensemble.java
Normal file
|
@ -0,0 +1,29 @@
|
|||
/** Définition d'un ensemble d'entier. */
|
||||
public interface Ensemble<E> {
|
||||
//@ public invariant estVide() <==> cardinal() == 0;
|
||||
//@ public invariant 0 <= cardinal();
|
||||
|
||||
/** Obtenir le nombre d'éléments dans l'ensemble.
|
||||
* @return nombre d'éléments dans l'ensemble. */
|
||||
/*@ pure helper @*/ int cardinal();
|
||||
|
||||
/** Savoir si l'ensemble est vide.
|
||||
* @return Est-ce que l'ensemble est vide ? */
|
||||
/*@ pure helper @*/ boolean estVide();
|
||||
|
||||
/** Savoir si un élément est présent dans l'ensemble.
|
||||
* @param x l'élément cherché
|
||||
* @return x est dans l'ensemble */
|
||||
/*@ pure helper @*/ boolean contient(E x);
|
||||
|
||||
/** Ajouter un élément dans l'ensemble.
|
||||
* @param x l'élément à ajouter */
|
||||
//@ ensures contient(x); // élément ajouté
|
||||
void ajouter(E x);
|
||||
|
||||
/** Enlever un élément de l'ensemble.
|
||||
* @param x l'élément à supprimer */
|
||||
//@ ensures ! contient(x); // élément supprimé
|
||||
void supprimer(E x);
|
||||
|
||||
}
|
59
TP08/EnsembleChaine.java
Normal file
59
TP08/EnsembleChaine.java
Normal file
|
@ -0,0 +1,59 @@
|
|||
public class EnsembleChaine<E> implements Ensemble<E> {
|
||||
|
||||
protected Cellule<E> premiere;
|
||||
|
||||
@Override
|
||||
public int cardinal() {
|
||||
int nb = 0;
|
||||
Cellule<E> curseur = this.premiere;
|
||||
while (curseur != null) {
|
||||
nb++;
|
||||
curseur = curseur.suivante;
|
||||
}
|
||||
return nb;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean estVide() {
|
||||
return this.premiere == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contient(E x) {
|
||||
Cellule<E> curseur = this.premiere;
|
||||
while (curseur != null) {
|
||||
if (curseur.element == x) {
|
||||
return true;
|
||||
}
|
||||
curseur = curseur.suivante;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ajouter(E x) {
|
||||
if (!this.contient(x)) {
|
||||
Cellule<E> newCellule = new Cellule<E>(x, this.premiere);
|
||||
this.premiere = newCellule;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void supprimer(E x) {
|
||||
if (this.contient(x)) {
|
||||
if (this.premiere.element == x) {
|
||||
this.premiere = this.premiere.suivante;
|
||||
} else {
|
||||
Cellule<E> curseur = this.premiere;
|
||||
while (curseur.suivante != null && curseur.suivante.element != x) {
|
||||
curseur = curseur.suivante;
|
||||
}
|
||||
if (curseur.suivante != null) {
|
||||
Cellule<E> save = curseur.suivante;
|
||||
curseur.suivante = curseur.suivante.suivante;
|
||||
save.suivante = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
54
TP08/EnsembleChaineOrdonne.java
Normal file
54
TP08/EnsembleChaineOrdonne.java
Normal file
|
@ -0,0 +1,54 @@
|
|||
public class EnsembleChaineOrdonne<E> extends EnsembleChaine<E> implements EnsembleOrdonne<E> {
|
||||
|
||||
public Comparateur<E> comparateur;
|
||||
|
||||
@Override
|
||||
public int cardinal() {
|
||||
return super.cardinal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean estVide() {
|
||||
return super.estVide();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contient(E x) {
|
||||
return super.contient(x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ajouter(E x) {
|
||||
if (this.estVide()) {
|
||||
super.premiere = new Cellule<E>(x, null);
|
||||
} else if ( comparateur.inf(x, super.premiere.element) ) {
|
||||
Cellule<E> newCellule = new Cellule<E>(x, super.premiere);
|
||||
super.premiere = newCellule;
|
||||
} else if (!this.contient(x)){
|
||||
Cellule<E> curseur = this.premiere;
|
||||
while (curseur != null && comparateur.inf(x, curseur.element) ) {
|
||||
curseur = curseur.suivante;
|
||||
}
|
||||
curseur.suivante = new Cellule<E>(x, curseur.suivante);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void supprimer(E x) {
|
||||
super.supprimer(x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public E min() {
|
||||
E min = super.premiere.element;
|
||||
Cellule<E> curseur = this.premiere;
|
||||
while (curseur != null) {
|
||||
if ( comparateur.inf(curseur.element, min) ) {
|
||||
min = curseur.element;
|
||||
}
|
||||
curseur = curseur.suivante;
|
||||
}
|
||||
return min;
|
||||
}
|
||||
|
||||
}
|
12
TP08/EnsembleChaineTest.java
Normal file
12
TP08/EnsembleChaineTest.java
Normal file
|
@ -0,0 +1,12 @@
|
|||
/**
|
||||
* Classe de test pour EnsembleChaine.
|
||||
*/
|
||||
public class EnsembleChaineTest extends EnsembleTestAbstrait {
|
||||
|
||||
protected Ensemble<Integer> nouvelEnsemble(int capacite) {
|
||||
EnsembleChaineOrdonne<Integer> ens = new EnsembleChaineOrdonne<Integer>();
|
||||
ens.comparateur = new IntOrdreCroissant();
|
||||
return ens;
|
||||
}
|
||||
|
||||
}
|
5
TP08/EnsembleOrdonne.java
Normal file
5
TP08/EnsembleOrdonne.java
Normal file
|
@ -0,0 +1,5 @@
|
|||
public interface EnsembleOrdonne<E> extends Ensemble<E> {
|
||||
|
||||
E min();
|
||||
|
||||
}
|
182
TP08/EnsembleTestAbstrait.java
Normal file
182
TP08/EnsembleTestAbstrait.java
Normal file
|
@ -0,0 +1,182 @@
|
|||
import org.junit.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/** Programme de test JUnit pour les ensembles.
|
||||
* @author Xavier Crégut <prenom.nom@enseeiht.fr>
|
||||
*/
|
||||
abstract public class EnsembleTestAbstrait {
|
||||
|
||||
protected Ensemble<Integer> e1;
|
||||
|
||||
private int[] tab0; // pour faire les tests élémentaires
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
tab0 = new int[] { 10, 15, -5 };
|
||||
this.e1 = nouvelEnsemble(10);
|
||||
// System.out.println("e1 = " + e1);
|
||||
}
|
||||
|
||||
abstract protected Ensemble<Integer> nouvelEnsemble(int capacite);
|
||||
// la capacité sera utile dans le cas d'une ensemble tableau pour
|
||||
// choisir la capacité initiale du tableau utilisé pour stocker les
|
||||
// éléments.
|
||||
|
||||
|
||||
static void ajouterTous(Ensemble<Integer> ens, int... elements) {
|
||||
for (int n : elements) {
|
||||
ens.ajouter(n);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitVide() {
|
||||
assertNotNull(e1);
|
||||
assertTrue(e1.estVide());
|
||||
assertEquals(0, e1.cardinal());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAjouterPremier() {
|
||||
assertTrue(e1.estVide());
|
||||
e1.ajouter(10);
|
||||
assertFalse(e1.estVide());
|
||||
assertEquals(1, e1.cardinal());
|
||||
assertTrue(e1.contient(10));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAjouterPlusieursFois() {
|
||||
assertTrue(e1.estVide());
|
||||
e1.ajouter(10);
|
||||
e1.ajouter(10);
|
||||
e1.ajouter(10);
|
||||
e1.ajouter(10);
|
||||
assertFalse(e1.estVide());
|
||||
assertEquals(1, e1.cardinal());
|
||||
assertTrue(e1.contient(10));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAjouterTroisElements() {
|
||||
e1.ajouter(10);
|
||||
e1.ajouter(15);
|
||||
e1.ajouter(-5);
|
||||
assertEquals(3, e1.cardinal());
|
||||
assertTrue(e1.contient(10));
|
||||
assertTrue(e1.contient(-5));
|
||||
assertTrue(e1.contient(15));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContient() {
|
||||
e1.ajouter(10);
|
||||
e1.ajouter(15);
|
||||
e1.ajouter(-5);
|
||||
assertEquals(3, e1.cardinal());
|
||||
assertTrue(e1.contient(10));
|
||||
assertTrue(e1.contient(-5));
|
||||
assertTrue(e1.contient(15));
|
||||
assertFalse(e1.contient(1));
|
||||
assertFalse(e1.contient(2));
|
||||
assertFalse(e1.contient(100));
|
||||
assertFalse(e1.contient(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSupprimerAbsent() {
|
||||
ajouterTous(e1, tab0);
|
||||
assertFalse(e1.contient(1));
|
||||
assertEquals(3, e1.cardinal());
|
||||
e1.supprimer(1);
|
||||
assertFalse(e1.contient(1));
|
||||
assertEquals(3, e1.cardinal());
|
||||
e1.supprimer(1);
|
||||
e1.supprimer(1);
|
||||
assertTrue(e1.contient(10));
|
||||
assertTrue(e1.contient(-5));
|
||||
assertTrue(e1.contient(15));
|
||||
assertFalse(e1.contient(1));
|
||||
assertFalse(e1.contient(2));
|
||||
assertEquals(3, e1.cardinal());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSupprimerPresent() {
|
||||
ajouterTous(e1, tab0);
|
||||
assertEquals(3, e1.cardinal());
|
||||
assertTrue(e1.contient(10));
|
||||
e1.supprimer(10);
|
||||
assertFalse(e1.contient(10));
|
||||
assertEquals(2, e1.cardinal());
|
||||
assertTrue(e1.contient(-5));
|
||||
assertTrue(e1.contient(15));
|
||||
assertFalse(e1.contient(1));
|
||||
assertFalse(e1.contient(2));
|
||||
assertEquals(2, e1.cardinal());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSupprimerDifferentsCas() {
|
||||
ajouterTous(e1, tab0);
|
||||
e1.supprimer(10);
|
||||
assertFalse(e1.contient(10));
|
||||
e1.supprimer(-5);
|
||||
assertFalse(e1.contient(10));
|
||||
assertFalse(e1.contient(-5));
|
||||
assertTrue(e1.contient(15));
|
||||
assertFalse(e1.contient(1));
|
||||
assertFalse(e1.contient(2));
|
||||
assertEquals(1, e1.cardinal());
|
||||
|
||||
e1.supprimer(15);
|
||||
assertFalse(e1.contient(10));
|
||||
assertFalse(e1.contient(-5));
|
||||
assertFalse(e1.contient(15));
|
||||
assertFalse(e1.contient(1));
|
||||
assertFalse(e1.contient(2));
|
||||
assertEquals(0, e1.cardinal());
|
||||
assertTrue(e1.estVide());
|
||||
}
|
||||
|
||||
/*@
|
||||
requires tab.length > 0;
|
||||
requires // éléments tous différents
|
||||
(\forall int i1; i1 >= 0 && i1 < tab.length;
|
||||
(\forall int i2; i2 >= 0 && i2 < i1;
|
||||
tab[i1] != tab[i2]));
|
||||
@*/
|
||||
protected void testerAvecTab(int... tab) {
|
||||
|
||||
// Au fur et à mesure que l'on ajoute les éléments, on vérifie la
|
||||
// présence des éléments.
|
||||
for (int i = 0; i < tab.length; i++) {
|
||||
e1.ajouter(tab[i]);
|
||||
assertEquals(i+1, e1.cardinal());
|
||||
// vérifier la présence des éléments insérés
|
||||
for (int j = 0; j <= i; j++) {
|
||||
assertTrue(e1.contient(tab[j]));
|
||||
}
|
||||
// vérifier l'absence des éléments à insérer
|
||||
for (int j = i+1; j < tab.length; j++) {
|
||||
assertFalse(e1.contient(tab[j]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testerAvecTab1() {
|
||||
testerAvecTab(10, 15, 12, 5, 20, -5, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testerAvecTab2() {
|
||||
testerAvecTab(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testerAvecTab3() {
|
||||
testerAvecTab(10, 9, 8, 7, 6, 5, 4, 3, 2, 1);
|
||||
}
|
||||
|
||||
}
|
8
TP08/IntOrdreCroissant.java
Normal file
8
TP08/IntOrdreCroissant.java
Normal file
|
@ -0,0 +1,8 @@
|
|||
public class IntOrdreCroissant implements Comparateur<Integer> {
|
||||
|
||||
@Override
|
||||
public boolean inf(Integer n1, Integer n2) {
|
||||
return n1 < n2;
|
||||
}
|
||||
|
||||
}
|
7
TP09/.vscode/settings.json
vendored
Normal file
7
TP09/.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"java.project.referencedLibraries": [
|
||||
"lib/**/*.jar",
|
||||
"/usr/share/java/junit.jar",
|
||||
"/usr/share/java/hamcrest-core.jar"
|
||||
]
|
||||
}
|
48
TP09/Agenda.java
Normal file
48
TP09/Agenda.java
Normal file
|
@ -0,0 +1,48 @@
|
|||
public interface Agenda {
|
||||
|
||||
/** Le plus petit créneau possible. */
|
||||
int CRENEAU_MIN = 1;
|
||||
|
||||
/** Le plus grand créneau possible. */
|
||||
int CRENEAU_MAX = 366;
|
||||
|
||||
/**
|
||||
* Obtenir le nom de l'agenda.
|
||||
* @return le nom de l'agenda
|
||||
*/
|
||||
String getNom();
|
||||
|
||||
/**
|
||||
* Enregistrer un rendez-vous dans cet agenda.
|
||||
*
|
||||
* @param creneau le créneau du rendez-vous
|
||||
* @param rdv le rendez-vous
|
||||
* @throws CreneauInvalideException si le créneau est invalide
|
||||
* @throws IllegalArgumentException si nom vaut null
|
||||
* @throws OccupeException si le créneau n'est pas libre
|
||||
*/
|
||||
void enregistrer(int creneau, String rdv) throws CreneauInvalideException, IllegalArgumentException, OccupeException;
|
||||
|
||||
/**
|
||||
* Annuler le rendez-vous pris à une creneau donnée.
|
||||
* Rien ne se passe si le créneau est libre.
|
||||
* Retourne vrai si l'agenda est modifié (un rendez-vous est annulé),
|
||||
* faux sinon.
|
||||
*
|
||||
* @param creneau créneau du rendez-vous à annuler
|
||||
* @return vrai si l'agenda est modifié
|
||||
* @throws CreneauInvalideException si le créneau est invalide
|
||||
*/
|
||||
boolean annuler(int creneau) throws CreneauInvalideException;
|
||||
|
||||
/**
|
||||
* Obtenir le rendez-vous pris à une creneau donnée.
|
||||
*
|
||||
* @param creneau le créneau du rendez-vous
|
||||
* @return le rendez-vous à le créneau donnée
|
||||
* @throws LibreException si pas de rendez-vous à ce créneau
|
||||
* @throws CreneauInvalideException si le créneau est invalide
|
||||
*/
|
||||
String getRendezVous(int creneau) throws CreneauInvalideException, LibreException;
|
||||
|
||||
}
|
28
TP09/AgendaAbstrait.java
Normal file
28
TP09/AgendaAbstrait.java
Normal file
|
@ -0,0 +1,28 @@
|
|||
/**
|
||||
* AgendaAbstrait factorise la définition du nom et de l'accesseur associé.
|
||||
*/
|
||||
public abstract class AgendaAbstrait extends ObjetNomme implements Agenda {
|
||||
|
||||
/**
|
||||
* Initialiser le nom de l'agenda.
|
||||
*
|
||||
* @param nom le nom de l'agenda
|
||||
* @throws IllegalArgumentException si nom n'a pas au moins un caractère
|
||||
*/
|
||||
public AgendaAbstrait(String nom) throws IllegalArgumentException {
|
||||
super(nom);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tester la validité d'un créneau
|
||||
*
|
||||
* @param creneau créneau que l'on souhaite valider
|
||||
* @throws CreneauInvalideException si le créneau est invalide
|
||||
*/
|
||||
public void verifierCreneauValide(int creneau) throws CreneauInvalideException {
|
||||
if ( creneau < Agenda.CRENEAU_MIN || creneau > Agenda.CRENEAU_MAX ) {
|
||||
throw new CreneauInvalideException();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
59
TP09/AgendaIndividuel.java
Normal file
59
TP09/AgendaIndividuel.java
Normal file
|
@ -0,0 +1,59 @@
|
|||
/**
|
||||
* Définition d'un agenda individuel.
|
||||
*/
|
||||
public class AgendaIndividuel extends AgendaAbstrait {
|
||||
|
||||
/** Le texte des rendezVous */
|
||||
private String[] rendezVous;
|
||||
|
||||
|
||||
/**
|
||||
* Créer un agenda vide (avec aucun rendez-vous).
|
||||
*
|
||||
* @param nom le nom de l'agenda
|
||||
* @throws IllegalArgumentException si nom nul ou vide
|
||||
*/
|
||||
public AgendaIndividuel(String nom) throws IllegalArgumentException {
|
||||
super(nom);
|
||||
this.rendezVous = new String[Agenda.CRENEAU_MAX + 1];
|
||||
// On gaspille une case (la première qui ne sera jamais utilisée)
|
||||
// mais on évite de nombreux « creneau - 1 »
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void enregistrer(int creneau, String rdv) throws CreneauInvalideException, IllegalArgumentException, OccupeException {
|
||||
super.verifierCreneauValide(creneau);
|
||||
|
||||
if (rdv == null || rdv.length() < 1) {
|
||||
throw new IllegalArgumentException();
|
||||
} else if (this.rendezVous[creneau] != null) {
|
||||
throw new OccupeException();
|
||||
} else {
|
||||
this.rendezVous[creneau] = rdv;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean annuler(int creneau) throws CreneauInvalideException {
|
||||
super.verifierCreneauValide(creneau);
|
||||
boolean modifie = this.rendezVous[creneau] != null;
|
||||
this.rendezVous[creneau] = null;
|
||||
return modifie;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getRendezVous(int creneau) throws CreneauInvalideException, LibreException {
|
||||
super.verifierCreneauValide(creneau);
|
||||
String rdv = this.rendezVous[creneau];
|
||||
if (rdv == null) {
|
||||
throw new LibreException();
|
||||
} else {
|
||||
return rdv;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
19
TP09/AgendaIndividuelTest.java
Normal file
19
TP09/AgendaIndividuelTest.java
Normal file
|
@ -0,0 +1,19 @@
|
|||
/**
|
||||
* Classe de test de AgendaIndividuel.
|
||||
*
|
||||
* @author Xavier Crégut <Prenom.Nom@enseeiht.fr>
|
||||
*/
|
||||
public class AgendaIndividuelTest extends AgendaTestAbstrait {
|
||||
|
||||
|
||||
@Override
|
||||
protected AgendaIndividuel nouvelAgenda(String nom) {
|
||||
return new AgendaIndividuel(nom);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ObjetNomme nouvelObjetNomme(String nom) {
|
||||
return nouvelAgenda(nom);
|
||||
}
|
||||
|
||||
}
|
108
TP09/AgendaTestAbstrait.java
Normal file
108
TP09/AgendaTestAbstrait.java
Normal file
|
@ -0,0 +1,108 @@
|
|||
import org.junit.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Programme de test d'un agenda.
|
||||
*/
|
||||
abstract public class AgendaTestAbstrait extends ObjetNommeTest {
|
||||
|
||||
protected Agenda agenda;
|
||||
final protected String jourAn = "Jour de l'an";
|
||||
final protected String premierFevrier = "Février commence";
|
||||
final protected String finAnnee = "Fin de l'année";
|
||||
|
||||
|
||||
protected abstract Agenda nouvelAgenda(String nom);
|
||||
|
||||
@Override
|
||||
protected abstract ObjetNomme nouvelObjetNomme(String nom);
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() throws OccupeException {
|
||||
this.agenda = nouvelAgenda("Agenda");
|
||||
this.agenda.enregistrer(1, jourAn);
|
||||
this.agenda.enregistrer(32, premierFevrier);
|
||||
this.agenda.enregistrer(365, finAnnee);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testerNom() {
|
||||
assertEquals("A1", nouvelAgenda("A1").getNom());
|
||||
assertEquals("A2", nouvelAgenda("A2").getNom());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testerGetRendezVous() throws LibreException {
|
||||
assertEquals(jourAn, agenda.getRendezVous(1));
|
||||
assertEquals(premierFevrier, agenda.getRendezVous(32));
|
||||
assertEquals(finAnnee, agenda.getRendezVous(365));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testerAnnuler() throws Exception {
|
||||
assertTrue(agenda.annuler(1));
|
||||
assertFalse(agenda.annuler(2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testerAnneeBissectile() throws LibreException, OccupeException {
|
||||
agenda.enregistrer(Agenda.CRENEAU_MAX, "OK");
|
||||
assertEquals("OK", agenda.getRendezVous(Agenda.CRENEAU_MAX));
|
||||
}
|
||||
|
||||
|
||||
@Test(expected=OccupeException.class)
|
||||
public void testerRobustesseEnregistrerOccupe() throws Exception {
|
||||
agenda.enregistrer(1, "UN");
|
||||
}
|
||||
|
||||
@Test(expected=CreneauInvalideException.class)
|
||||
public void testerRobustesseEnregistrerCreneauPetit() throws Exception {
|
||||
agenda.enregistrer(Agenda.CRENEAU_MIN - 1, "UN");
|
||||
}
|
||||
|
||||
@Test(expected=CreneauInvalideException.class)
|
||||
public void testerRobustesseEnregistrerCreneauGrand() throws Exception {
|
||||
agenda.enregistrer(Agenda.CRENEAU_MAX + 1, "UN");
|
||||
}
|
||||
|
||||
|
||||
@Test(expected=CreneauInvalideException.class)
|
||||
public void testerRobustesseAnnulerCreneauPetit() throws Exception {
|
||||
agenda.annuler(Agenda.CRENEAU_MIN - 1);
|
||||
}
|
||||
|
||||
@Test(expected=CreneauInvalideException.class)
|
||||
public void testerRobustesseAnnulerCreneauGrand() throws Exception {
|
||||
agenda.annuler(Agenda.CRENEAU_MAX + 1);
|
||||
}
|
||||
|
||||
|
||||
@Test(expected=LibreException.class)
|
||||
public void testerRobustesseGetRendezVousLibre() throws Exception {
|
||||
agenda.getRendezVous(2);
|
||||
}
|
||||
|
||||
@Test(expected=CreneauInvalideException.class)
|
||||
public void testerRobustesseGetRendezVousCreneauPetit() throws Exception {
|
||||
agenda.getRendezVous(Agenda.CRENEAU_MIN - 1);
|
||||
}
|
||||
|
||||
@Test(expected=CreneauInvalideException.class)
|
||||
public void testerRobustesseGetRendezVousCreneauGrand() throws Exception {
|
||||
agenda.getRendezVous(Agenda.CRENEAU_MAX + 1);
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testerEnregistrerIllegalArgumentNull() throws Exception {
|
||||
agenda.enregistrer(10, null);
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testerEnregistrerIllegalArgumentVide() throws Exception {
|
||||
agenda.enregistrer(10, "");
|
||||
}
|
||||
|
||||
|
||||
}
|
5
TP09/CreneauInvalideException.java
Normal file
5
TP09/CreneauInvalideException.java
Normal file
|
@ -0,0 +1,5 @@
|
|||
/**
|
||||
* CreneauInvalideException indique qu'une date n'est pas valide.
|
||||
*/
|
||||
public class CreneauInvalideException extends RuntimeException {
|
||||
}
|
45
TP09/ExceptionsTest.java
Normal file
45
TP09/ExceptionsTest.java
Normal file
|
@ -0,0 +1,45 @@
|
|||
import org.junit.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Vérifier que les exceptions sont correctement définies.
|
||||
*
|
||||
* @author Xavier Crégut <Prenom.Nom@enseeiht.fr>
|
||||
*/
|
||||
public class ExceptionsTest {
|
||||
|
||||
public static boolean isUncheckedException(Class<?> classe) {
|
||||
return Error.class.isAssignableFrom(classe)
|
||||
|| RuntimeException.class.isAssignableFrom(classe);
|
||||
}
|
||||
|
||||
public static boolean isCheckedException(Class<?> classe) {
|
||||
return Throwable.class.isAssignableFrom(classe)
|
||||
&& ! isUncheckedException(classe);
|
||||
}
|
||||
|
||||
public void verifierEstRuntimeException(Class<?> classe) {
|
||||
assertTrue(classe.getName() + " doit être une exception !",
|
||||
Throwable.class.isAssignableFrom(classe));
|
||||
assertTrue(classe.getName() + " doit être non vérifiée !",
|
||||
isUncheckedException(classe));
|
||||
assertFalse(classe.getName() + " : pourquoi en faire une Error ?",
|
||||
Error.class.isAssignableFrom(classe));
|
||||
}
|
||||
|
||||
public void verifierIsCheckedException(Class<?> classe) {
|
||||
assertTrue(classe.getName() + " doit être une exception !",
|
||||
Throwable.class.isAssignableFrom(classe));
|
||||
assertTrue(classe.getName() + " doit être vérifiée !",
|
||||
isCheckedException(classe));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testerExceptions() {
|
||||
verifierEstRuntimeException(CreneauInvalideException.class);
|
||||
verifierIsCheckedException(LibreException.class);
|
||||
verifierIsCheckedException(OccupeException.class);
|
||||
}
|
||||
|
||||
}
|
88
TP09/GroupeAgenda.java
Normal file
88
TP09/GroupeAgenda.java
Normal file
|
@ -0,0 +1,88 @@
|
|||
import java.util.ArrayList;
|
||||
|
||||
public class GroupeAgenda extends AgendaAbstrait {
|
||||
|
||||
private ArrayList<Agenda> agendas;
|
||||
|
||||
public GroupeAgenda(String nom) {
|
||||
super(nom);
|
||||
this.agendas = new ArrayList<Agenda>();
|
||||
}
|
||||
|
||||
public void ajouter(Agenda agenda) {
|
||||
agendas.add(agenda);
|
||||
}
|
||||
|
||||
public void ajouter(GroupeAgenda groupe) {
|
||||
groupe.agendas.forEach(agenda -> {
|
||||
this.ajouter(agenda);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enregistrer(int creneau, String rdv) throws CreneauInvalideException, IllegalArgumentException, OccupeException {
|
||||
// vérif tous libres
|
||||
Boolean rdv_present = false;
|
||||
for (Agenda agenda : this.agendas) {
|
||||
try {
|
||||
agenda.getRendezVous(creneau);
|
||||
rdv_present = true;
|
||||
break;
|
||||
} catch (LibreException e) {}
|
||||
}
|
||||
if (rdv_present) {
|
||||
throw new OccupeException();
|
||||
}
|
||||
|
||||
// si tous libre, enregistrer le rdv
|
||||
for (Agenda agenda : this.agendas) {
|
||||
try {
|
||||
agenda.enregistrer(creneau, rdv);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw e;
|
||||
} catch (OccupeException e) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override // TODO finir
|
||||
public boolean annuler(int creneau) throws CreneauInvalideException {
|
||||
Boolean rep = null;
|
||||
for (Agenda agenda : this.agendas) {
|
||||
rep = agenda.annuler(creneau);
|
||||
}
|
||||
return rep;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRendezVous(int creneau) throws CreneauInvalideException, LibreException {
|
||||
|
||||
String rdv0 = this.agendas.get(0).getRendezVous(creneau);
|
||||
Boolean diff = false;
|
||||
Boolean one_free = false;
|
||||
|
||||
for (Agenda agenda : this.agendas) {
|
||||
try {
|
||||
String rdv = agenda.getRendezVous(creneau);
|
||||
|
||||
if (!rdv.equals(rdv0)) {
|
||||
diff = true;
|
||||
break;
|
||||
}
|
||||
|
||||
} catch (LibreException e) {
|
||||
one_free = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (diff) {
|
||||
return null;
|
||||
} else if (one_free) {
|
||||
throw new LibreException();
|
||||
} else {
|
||||
return rdv0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
46
TP09/GroupeAgendaProposerTest.java
Normal file
46
TP09/GroupeAgendaProposerTest.java
Normal file
|
@ -0,0 +1,46 @@
|
|||
import org.junit.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Classe de test pour la méthode proposer de GroupeAgenda.
|
||||
*/
|
||||
public class GroupeAgendaProposerTest extends GroupeAgendaTest {
|
||||
|
||||
private void testerProposer(GroupeAgenda g) throws Exception {
|
||||
agenda2.enregistrer(15, "FAIT");
|
||||
g.proposer(15, "OK");
|
||||
assertEquals("OK", agenda1.getRendezVous(15));
|
||||
assertEquals(null, g.getRendezVous(15));
|
||||
if (g == superGroupe) {
|
||||
assertEquals("OK", xavier.getRendezVous(15));
|
||||
}
|
||||
assertTrue(g.annuler(15)); // remettre dans l'état initial
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testerProposer() throws Exception {
|
||||
testerProposer(groupe);
|
||||
testerProposer(superGroupe);
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testerProposerIllegalArgumentNull() throws Exception {
|
||||
groupe.proposer(10, null);
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testerProposerIllegalArgumentVide() throws Exception {
|
||||
groupe.proposer(10, "");
|
||||
}
|
||||
|
||||
@Test(expected=CreneauInvalideException.class)
|
||||
public void testerProposerCreaneauInvalideMin() throws Exception {
|
||||
groupe.proposer(Agenda.CRENEAU_MIN - 1, "ERREUR");
|
||||
}
|
||||
|
||||
@Test(expected=CreneauInvalideException.class)
|
||||
public void testerProposerCreaneauInvalideMax() throws Exception {
|
||||
groupe.proposer(Agenda.CRENEAU_MAX + 1, "ERREUR");
|
||||
}
|
||||
|
||||
}
|
74
TP09/GroupeAgendaTest.java
Normal file
74
TP09/GroupeAgendaTest.java
Normal file
|
@ -0,0 +1,74 @@
|
|||
import org.junit.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* GroupeAgendaTest
|
||||
*
|
||||
* @author Xavier Crégut <Prenom.Nom@enseeiht.fr>
|
||||
*/
|
||||
|
||||
public class GroupeAgendaTest extends AgendaTestAbstrait {
|
||||
|
||||
// groupe contient agenda1 et agenda2
|
||||
// superGroupe contient groupe et xavier
|
||||
protected GroupeAgenda groupe;
|
||||
protected Agenda agenda1, agenda2; // les deux sous-groupes
|
||||
protected Agenda xavier;
|
||||
protected GroupeAgenda superGroupe;
|
||||
|
||||
@Override
|
||||
protected GroupeAgenda nouvelAgenda(String nom) {
|
||||
this.groupe = new GroupeAgenda(nom);
|
||||
this.agenda1 = new AgendaIndividuel(nom + "-agenda1");
|
||||
this.agenda2 = new AgendaIndividuel(nom + "-agenda2");
|
||||
groupe.ajouter(agenda1);
|
||||
groupe.ajouter(agenda2);
|
||||
|
||||
this.xavier = new AgendaIndividuel(nom + "-Xavier");
|
||||
this.superGroupe = new GroupeAgenda(nom + "-superGroupe");
|
||||
this.superGroupe.ajouter(this.xavier);
|
||||
this.superGroupe.ajouter(this.groupe);
|
||||
return groupe;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ObjetNomme nouvelObjetNomme(String nom) {
|
||||
return nouvelAgenda(nom);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testerInitialisationCorrecte() {
|
||||
assertTrue(groupe == agenda);
|
||||
}
|
||||
|
||||
|
||||
@Test(expected=OccupeException.class)
|
||||
public void testerEnregistrerPasTousLibres() throws Exception {
|
||||
agenda2.enregistrer(10, "SEUL");
|
||||
agenda.enregistrer(10, "OK ?");
|
||||
}
|
||||
|
||||
@Test(expected=OccupeException.class)
|
||||
public void testerEnregistrerPasTousLibresDansSousSousGroupe() throws Exception {
|
||||
agenda2.enregistrer(10, "SEUL");
|
||||
superGroupe.enregistrer(10, "OK ?");
|
||||
}
|
||||
|
||||
private void testerAnnulerPasTousOccupe(Agenda a) throws Exception {
|
||||
agenda2.enregistrer(10, "SEUL");
|
||||
assertEquals(null, a.getRendezVous(10));
|
||||
assertTrue(a.annuler(10));
|
||||
String rdv = "OK ?";
|
||||
a.enregistrer(10, rdv);
|
||||
assertEquals(rdv, a.getRendezVous(10));
|
||||
assertTrue(a.annuler(10));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testerAnnulerPasToutOccupe() throws Exception {
|
||||
testerAnnulerPasTousOccupe(this.groupe);
|
||||
testerAnnulerPasTousOccupe(this.superGroupe);
|
||||
}
|
||||
|
||||
}
|
2
TP09/LibreException.java
Normal file
2
TP09/LibreException.java
Normal file
|
@ -0,0 +1,2 @@
|
|||
public class LibreException extends Exception {
|
||||
}
|
32
TP09/ObjetNomme.java
Normal file
32
TP09/ObjetNomme.java
Normal file
|
@ -0,0 +1,32 @@
|
|||
/**
|
||||
* Un objet nommé est un objet qui a un nom.
|
||||
*/
|
||||
public abstract class ObjetNomme {
|
||||
|
||||
private String nom;
|
||||
|
||||
/**
|
||||
* Initialiser le nom de l'agenda.
|
||||
*
|
||||
* @param nom le nom de l'agenda
|
||||
* @throws IllegalArgumentException si nom n'a pas au moins un caractère
|
||||
*/
|
||||
public ObjetNomme(String nom) throws IllegalArgumentException {
|
||||
|
||||
if (nom == null || nom.length() < 1) {
|
||||
throw new IllegalArgumentException();
|
||||
} else {
|
||||
this.nom = nom;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtenir le nom de cet objet.
|
||||
* @return le nom de cet objet
|
||||
*/
|
||||
public String getNom() {
|
||||
return this.nom;
|
||||
}
|
||||
|
||||
|
||||
}
|
45
TP09/ObjetNommeTest.java
Normal file
45
TP09/ObjetNommeTest.java
Normal file
|
@ -0,0 +1,45 @@
|
|||
import org.junit.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Classe de test de ObjetNomme.
|
||||
*/
|
||||
public class ObjetNommeTest {
|
||||
|
||||
/**
|
||||
* Retourner un objet de type ObjetNomme qui sera utilisé pour les test.
|
||||
* @param nom le nom à utiliser pour l'objet nommé
|
||||
* @returns un objet nommé du nom fourni
|
||||
*/
|
||||
protected ObjetNomme nouvelObjetNomme(String nom) {
|
||||
return new ObjetNommeConcret(nom);
|
||||
}
|
||||
|
||||
private static class ObjetNommeConcret extends ObjetNomme {
|
||||
public ObjetNommeConcret(String nom) {
|
||||
super(nom);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testerGetNom() {
|
||||
String unNom = "Petit nom";
|
||||
ObjetNomme o = nouvelObjetNomme(unNom);
|
||||
assertEquals(unNom, o.getNom());
|
||||
assertSame("Pourquoi ne pas garder le même nom ?",
|
||||
unNom, o.getNom());
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testerConstructeurNomNul() {
|
||||
nouvelObjetNomme(null);
|
||||
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testerConstructeurNomVide() {
|
||||
nouvelObjetNomme("");
|
||||
|
||||
}
|
||||
|
||||
}
|
2
TP09/OccupeException.java
Normal file
2
TP09/OccupeException.java
Normal file
|
@ -0,0 +1,2 @@
|
|||
public class OccupeException extends Exception {
|
||||
}
|
BIN
TP09/to-1sn-2020-tp-09-sujet.pdf
Normal file
BIN
TP09/to-1sn-2020-tp-09-sujet.pdf
Normal file
Binary file not shown.
157
TP10/editeur-menu.plantuml
Normal file
157
TP10/editeur-menu.plantuml
Normal file
|
@ -0,0 +1,157 @@
|
|||
@startuml
|
||||
skinparam classAttributeIconSize 0
|
||||
|
||||
package menu {
|
||||
|
||||
class Menu {
|
||||
- selection: Commande
|
||||
--
|
||||
+ estQuitté(): boolean
|
||||
+ afficher()
|
||||
+ selectionner()
|
||||
+ valider()
|
||||
+ ajouter(txt: String, op: Commande)
|
||||
}
|
||||
|
||||
class Entree {
|
||||
- texte: String
|
||||
--
|
||||
+ afficher(numéro: int)
|
||||
__constructeurs__
|
||||
+ Entree(texte: String, op: Commande)
|
||||
}
|
||||
|
||||
interface Commande {
|
||||
--
|
||||
+ estExecutable(): boolean
|
||||
+ executer()
|
||||
}
|
||||
|
||||
Menu *-right-> "*\nentree" Entree: " "
|
||||
Entree o-right-> "1\noperation" Commande: " "
|
||||
|
||||
}
|
||||
|
||||
note top of Menu
|
||||
afficher():
|
||||
for(int i = 0; i < entrees.size(); i++):
|
||||
entrees.get(i).afficher(i + 1)
|
||||
|
||||
selectionner():
|
||||
-- demander un entier et
|
||||
-- initialiser 'selection' avec la commande associée
|
||||
|
||||
valider():
|
||||
if (selection.estExecutable()):
|
||||
selection.executer()
|
||||
else:
|
||||
out.println("Opération impossible")
|
||||
end note
|
||||
|
||||
note top of Entree
|
||||
afficher(numéro: int):
|
||||
if (opération.estExecutable):
|
||||
out.print(numéro)
|
||||
else:
|
||||
out.print(" ")
|
||||
out.print(") " + texte)
|
||||
end note
|
||||
|
||||
|
||||
package editeur {
|
||||
|
||||
class Editeur {
|
||||
--
|
||||
+ editer()
|
||||
__constructeurs__
|
||||
+ Editeur(l: Ligne)
|
||||
}
|
||||
|
||||
Editeur o-right-> "1\nligne" Ligne : " "
|
||||
Editeur *--> "1\nmenuPrincipal" Menu
|
||||
|
||||
interface Ligne {
|
||||
}
|
||||
|
||||
class LigneTab implements Ligne {
|
||||
}
|
||||
|
||||
class LigneStringBuffer implements Ligne {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
package commandes {
|
||||
|
||||
abstract class CommandeLigne implements Commande {
|
||||
__constructeurs__
|
||||
CommandeLigne(l: Ligne)
|
||||
}
|
||||
|
||||
class AvancerCurseur extends CommandeLigne {
|
||||
+ estExecutable(): boolean
|
||||
+ executer()
|
||||
}
|
||||
|
||||
class ReculerCurseur extends CommandeLigne {
|
||||
+ estExecutables(): boolean
|
||||
+ executer()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
CommandeLigne o-left-> "1\nligne" Ligne
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
note bottom of AvancerCurseur
|
||||
estExecutable(): boolean:
|
||||
return ligne.getCurseur() < ligne.getLongueur()
|
||||
|
||||
executer():
|
||||
ligne.avancer()
|
||||
end note
|
||||
|
||||
note bottom of ReculerCurseur
|
||||
estExecutable(): boolean:
|
||||
return ligne.getCurseur() > 1
|
||||
|
||||
executer():
|
||||
ligne.reculer()
|
||||
end note
|
||||
|
||||
|
||||
note as noteEditeur
|
||||
editer():
|
||||
do:
|
||||
ligne.afficher()
|
||||
menuPrincipal.afficher()
|
||||
menuPrincipal.sélectionner()
|
||||
menuPrincipal.valider()
|
||||
while (! estQuitté())
|
||||
|
||||
Editeur(l: Ligne):
|
||||
this.ligne = l
|
||||
this.menuPrincipal = new Menu()
|
||||
this.menuPrincipal.ajouter(
|
||||
"Avancer curseur",
|
||||
new AvancerCurseur(l))
|
||||
this.menuPrincipal.ajouter(
|
||||
"Reculer curseur",
|
||||
new ReculerCurseur(l))
|
||||
end note
|
||||
|
||||
Editeur .left. noteEditeur
|
||||
|
||||
|
||||
|
||||
@enduml
|
||||
' vim: sw=4 ts=4:
|
BIN
TP10/editeur-menu.png
Normal file
BIN
TP10/editeur-menu.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 109 KiB |
56
TP10/editeur/EditeurLigne.java
Normal file
56
TP10/editeur/EditeurLigne.java
Normal file
|
@ -0,0 +1,56 @@
|
|||
package editeur;
|
||||
|
||||
import editeur.commande.*;
|
||||
import menu.Menu;
|
||||
|
||||
/** Un éditeur pour une ligne de texte. Les commandes de
|
||||
* l'éditeur sont accessibles par un menu.
|
||||
*
|
||||
* @author Xavier Crégut
|
||||
* @version 1.6
|
||||
*/
|
||||
public class EditeurLigne {
|
||||
|
||||
/** La ligne de notre éditeur */
|
||||
private Ligne ligne;
|
||||
|
||||
/** Le menu principal de l'éditeur */
|
||||
private Menu menuPrincipal;
|
||||
// Remarque : Tous les éditeurs ont le même menu mais on
|
||||
// ne peut pas en faire un attribut de classe car chaque
|
||||
// commande doit manipuler la ligne propre à un éditeur !
|
||||
|
||||
/** Initialiser l'éditeur à partir de la lign à éditer. */
|
||||
public EditeurLigne(Ligne l) {
|
||||
ligne = l;
|
||||
|
||||
// Créer le menu principal
|
||||
menuPrincipal = new Menu("Menu principal");
|
||||
menuPrincipal.ajouter("Ajouter un texte en fin de ligne",
|
||||
new CommandeAjouterFin(ligne));
|
||||
menuPrincipal.ajouter("Supprimer le caractère sous le curseur",
|
||||
new CommandeSupprimer(ligne), "x");
|
||||
menuPrincipal.ajouter("Sous-Menu Curseur",
|
||||
new SousMenuCurseur(ligne));
|
||||
}
|
||||
|
||||
public void editer() {
|
||||
do {
|
||||
// Afficher la ligne
|
||||
System.out.println();
|
||||
ligne.afficher();
|
||||
System.out.println();
|
||||
|
||||
// Afficher le menu
|
||||
menuPrincipal.afficher();
|
||||
|
||||
// Sélectionner une entrée dans le menu
|
||||
menuPrincipal.selectionner();
|
||||
|
||||
// Valider l'entrée sélectionnée
|
||||
menuPrincipal.valider();
|
||||
|
||||
} while (! menuPrincipal.estQuitte());
|
||||
}
|
||||
|
||||
}
|
18
TP10/editeur/EditeurLigneMain.java
Normal file
18
TP10/editeur/EditeurLigneMain.java
Normal file
|
@ -0,0 +1,18 @@
|
|||
package editeur;
|
||||
|
||||
/** Programme de test de EditeurLigne.
|
||||
*
|
||||
* @author Xavier Crégut
|
||||
* @version 1.1
|
||||
*/
|
||||
|
||||
public class EditeurLigneMain {
|
||||
|
||||
public static void main(String[] args) {
|
||||
// Ligne uneLigne = new LigneTab(10);
|
||||
Ligne uneLigne = new LigneStringBuffer();
|
||||
EditeurLigne editeur = new EditeurLigne(uneLigne);
|
||||
editeur.editer();
|
||||
}
|
||||
|
||||
}
|
126
TP10/editeur/Ligne.java
Normal file
126
TP10/editeur/Ligne.java
Normal file
|
@ -0,0 +1,126 @@
|
|||
package editeur;
|
||||
|
||||
/** Spécification d'une ligne de texte.
|
||||
* @author Xavier Crégut (cregut@enseeiht.fr)
|
||||
* @version 1.5
|
||||
*/
|
||||
public interface Ligne {
|
||||
//@ public invariant 0 <= getLongueur(); // La longueur est positive
|
||||
//@
|
||||
//@ // Le curseur est toujours sur un caractère sauf si la ligne est vide.
|
||||
//@ public invariant 0 <= getCurseur() && getCurseur() <= getLongueur();
|
||||
//@ public invariant getCurseur() == 0 <==> getLongueur() == 0;
|
||||
|
||||
/** nombre de caractères dans la ligne */
|
||||
/*@ pure @*/ int getLongueur();
|
||||
|
||||
/** Position du curseur sur la ligne */
|
||||
/*@ pure @*/ int getCurseur();
|
||||
|
||||
/** le ième caractère de la ligne
|
||||
* @param i l'indice du caractère
|
||||
* @return le ième caractère de la ligne
|
||||
*/
|
||||
//@ requires 1 <= i && i <= getLongueur(); // indice valide
|
||||
/*@ pure @*/ char ieme(int i);
|
||||
|
||||
/** Le caractère sous le curseur
|
||||
*/
|
||||
//@ requires getLongueur() > 0; // la ligne est non vide
|
||||
/*@ pure @*/ char getCourant();
|
||||
|
||||
/** Avancer le curseur d'une position à droite. */
|
||||
//@ requires getCurseur() < getLongueur(); // pas à la fin
|
||||
//@ ensures getCurseur() == \old(getCurseur()) + 1; // curseur avancé
|
||||
void avancer();
|
||||
|
||||
/** Avancer le curseur d'une position à gauche. */
|
||||
//@ requires getCurseur() > 1; // pas en début de ligne
|
||||
//@ ensures getCurseur() == \old(getCurseur()) - 1; // curseur reculé
|
||||
void reculer();
|
||||
|
||||
/** Placer le curseur sur le premier caractère. */
|
||||
//@ requires getLongueur() > 0; // ligne non vide
|
||||
//@ ensures getCurseur() == 1; // curseur sur la première position
|
||||
void raz();
|
||||
|
||||
/** Remplacer le caractère sous le curseur par le caractère c. */
|
||||
//@ requires getLongueur() > 0;
|
||||
//@ ensures getCourant() == c;
|
||||
void remplacer(char c);
|
||||
|
||||
/** Supprimer le caractère sous le curseur. La position du curseur reste
|
||||
* inchangée.
|
||||
*/
|
||||
//@ requires getLongueur() > 0;
|
||||
//@ ensures getLongueur() == \old(getLongueur()) - 1; // un caractère ôté
|
||||
//@ ensures getCurseur() == Math.min(\old(getCurseur()), getLongueur());
|
||||
void supprimer();
|
||||
|
||||
/** Ajouter le caractère c avant le curseur.
|
||||
* Le curseur reste sur le même caractère.
|
||||
*/
|
||||
//@ requires getLongueur() > 0; // curseur positionné
|
||||
//@
|
||||
//@ ensures getLongueur() == \old(getLongueur()) + 1; // un caractère ajouté
|
||||
//@ ensures getCurseur() == \old(getCurseur()) + 1; // curseur inchangé
|
||||
//@ ensures getCourant() == \old(getCourant());
|
||||
void ajouterAvant(char c);
|
||||
|
||||
/** Ajouter le caractère c après le curseur.
|
||||
* Le curseur reste sur le même caractère.
|
||||
*/
|
||||
//@ requires getLongueur() > 0; // curseur positionné
|
||||
//@ ensures getLongueur() == \old(getLongueur()) + 1; // caractère ajouté
|
||||
//@ ensures getCurseur() == \old(getCurseur()); // curseur inchangé
|
||||
//@ ensures getCourant() == \old(getCourant());
|
||||
void ajouterApres(char c);
|
||||
|
||||
/** Afficher la ligne en mettant entre crochets [] le caractère courant.
|
||||
* Si la ligne est vide, un seul caractère tilde(~) est affiché.
|
||||
*/
|
||||
/*@ pure @*/ void afficher();
|
||||
|
||||
/** Ajouter le caractère c à la fin de la ligne.
|
||||
* Le curseur reste sur le même caractère.
|
||||
*/
|
||||
//@ ensures getLongueur() == \old(getLongueur()) + 1; // caractère ajouté
|
||||
//@ ensures ieme(getLongueur()) == c; // à la fin
|
||||
//@ ensures (\forall int i; 1 <= i && i <= \old(getLongueur());
|
||||
//@ ieme(i) == \old(ieme(i)));
|
||||
//@ ensures getLongueur() > 1 ==> getCourant() == \old(getCourant());
|
||||
//@ ensures getCurseur() == Math.max(1, \old(getCurseur()));
|
||||
void ajouterFin(char c);
|
||||
|
||||
/** Ajouter le caractère c au début de la ligne
|
||||
* Le curseur reste sur le même caractère.
|
||||
*/
|
||||
//@ ensures getLongueur() == \old(getLongueur()) + 1; // caractère ajouté
|
||||
//@ ensures ieme(1) == c; // en première position
|
||||
//@ ensures (\forall int j; j >= 2 && j <= getLongueur();
|
||||
//@ ieme((int)j) == \old(ieme((int)(j-1))));
|
||||
//@ ensures getLongueur() > 1 ==> getCourant() == \old(getCourant());
|
||||
//@ ensures getCurseur() == \old(getCurseur()) + 1;
|
||||
void ajouterDebut(char c);
|
||||
|
||||
/** supprimer le premier caractère de la ligne. Le curseur reste sur le
|
||||
* même caractère.
|
||||
*/
|
||||
//@ requires getLongueur() > 0;
|
||||
//@ ensures getLongueur() == \old(getLongueur()) - 1;
|
||||
//@ ensures \old(getCurseur()) != 1 ==> getCourant() == \old(getCourant());
|
||||
//@ ensures getCurseur()
|
||||
//@ == Math.min(Math.max((int)(\old(getCurseur())-1), 1), getLongueur());
|
||||
void supprimerPremier();
|
||||
|
||||
/** supprimer le dernier caractère de la ligne. Le curseur reste sur le même
|
||||
* caractère.
|
||||
*/
|
||||
//@ requires getLongueur() > 0;
|
||||
//@ ensures getLongueur() == \old(getLongueur()) - 1;
|
||||
//@ ensures \old(getCurseur()) < \old(getLongueur())
|
||||
//@ ==> getCourant() == \old(getCourant());
|
||||
//@ ensures getCurseur() == Math.min(\old(getCurseur()), getLongueur());
|
||||
void supprimerDernier();
|
||||
|
||||
}
|
131
TP10/editeur/LigneStringBuffer.java
Normal file
131
TP10/editeur/LigneStringBuffer.java
Normal file
|
@ -0,0 +1,131 @@
|
|||
package editeur;
|
||||
|
||||
/** Une ligne de texte représentée par un StringBuffer.
|
||||
* @author Xavier Crégut (cregut@enseeiht.fr)
|
||||
* @version 1.4
|
||||
*/
|
||||
public class LigneStringBuffer implements Ligne {
|
||||
|
||||
//@ private invariant this.curseur == this.getCurseur();
|
||||
//@ private invariant this.getLongueur() == this.caracteres.length();
|
||||
//@ private invariant (\forall int i; i >= 1 && i <= this.getLongueur();
|
||||
//@ this.ieme(i) == this.caracteres.charAt(i-1));
|
||||
//@ private invariant caracteres != null;
|
||||
|
||||
/** Les caractères de la ligne. */
|
||||
private StringBuffer caracteres;
|
||||
|
||||
/** La position du curseur. */
|
||||
private int curseur;
|
||||
|
||||
/** Créer une ligne vide.
|
||||
*/
|
||||
//@ ensures getLongueur() == 0; // la ligne est vide
|
||||
public LigneStringBuffer() {
|
||||
caracteres = new StringBuffer();
|
||||
curseur = 0;
|
||||
}
|
||||
|
||||
public int getLongueur() {
|
||||
return caracteres.length();
|
||||
}
|
||||
|
||||
public int getCurseur() {
|
||||
return curseur;
|
||||
}
|
||||
|
||||
public char ieme(int i) {
|
||||
return caracteres.charAt(i-1);
|
||||
}
|
||||
|
||||
public char getCourant() {
|
||||
return ieme(curseur);
|
||||
}
|
||||
|
||||
public void avancer() {
|
||||
curseur++;
|
||||
}
|
||||
|
||||
public void reculer() {
|
||||
curseur--;
|
||||
}
|
||||
|
||||
public void raz() {
|
||||
curseur = 1;
|
||||
}
|
||||
|
||||
public void remplacer(char c) {
|
||||
caracteres.setCharAt(curseur-1, c);
|
||||
}
|
||||
|
||||
public void supprimer() {
|
||||
// Supprimer le caractère
|
||||
caracteres.deleteCharAt(curseur-1);
|
||||
|
||||
// Mettre à jour le curseur
|
||||
if (curseur > caracteres.length()) {
|
||||
curseur = caracteres.length();
|
||||
}
|
||||
}
|
||||
|
||||
public void ajouterAvant(char c) {
|
||||
caracteres.insert(curseur-1, c);
|
||||
curseur++;
|
||||
}
|
||||
|
||||
public void ajouterApres(char c) {
|
||||
caracteres.insert(curseur, c);
|
||||
}
|
||||
|
||||
public void afficher() {
|
||||
if (caracteres.length() == 0) { // La chaîne est vide
|
||||
System.out.print("~");
|
||||
} else {
|
||||
// Afficher les caractères avant le curseur
|
||||
System.out.print(caracteres.substring(0, curseur-1));
|
||||
|
||||
// Afficher le caractère sous le curseur
|
||||
System.out.print("" + '[' + ieme(curseur) + ']');
|
||||
|
||||
// Afficher les caractères après le curseur
|
||||
System.out.print(caracteres.substring(curseur));
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "caractères = \"" + caracteres + '"'
|
||||
+ " et curseur = " + curseur;
|
||||
}
|
||||
|
||||
public void ajouterFin(char c) {
|
||||
caracteres.append(c);
|
||||
if (curseur == 0) {
|
||||
curseur = 1;
|
||||
}
|
||||
}
|
||||
|
||||
public void ajouterDebut(char c) {
|
||||
caracteres.insert(0, c); // Ajouter le caractère
|
||||
curseur++; // Rétablir le curseur
|
||||
}
|
||||
|
||||
public void supprimerPremier() {
|
||||
caracteres.deleteCharAt(0);
|
||||
|
||||
// Mettre à jour le curseur
|
||||
if (caracteres.length() == 0) {
|
||||
curseur = 0;
|
||||
} else if (curseur > 1) {
|
||||
curseur--;
|
||||
}
|
||||
}
|
||||
|
||||
public void supprimerDernier() {
|
||||
caracteres.deleteCharAt(caracteres.length() - 1);
|
||||
if (curseur > caracteres.length()) {
|
||||
curseur--;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
34
TP10/editeur/commande/CommandeAjouterFin.java
Normal file
34
TP10/editeur/commande/CommandeAjouterFin.java
Normal file
|
@ -0,0 +1,34 @@
|
|||
package editeur.commande;
|
||||
|
||||
import editeur.Ligne;
|
||||
import util.Console;
|
||||
|
||||
/** Ajouter un caractère à la fin de la ligne.
|
||||
* @author Xavier Crégut
|
||||
* @version 1.4
|
||||
*/
|
||||
public class CommandeAjouterFin
|
||||
extends CommandeLigne
|
||||
{
|
||||
|
||||
/** Initialiser la ligne sur laquelle travaille
|
||||
* cette commande.
|
||||
* @param l la ligne
|
||||
*/
|
||||
//@ requires l != null; // la ligne doit être définie
|
||||
public CommandeAjouterFin(Ligne l) {
|
||||
super(l);
|
||||
}
|
||||
|
||||
public void executer() {
|
||||
String texte = Console.readLine("Texte à insérer : ");
|
||||
for (int i = 0; i < texte.length(); i++) {
|
||||
ligne.ajouterFin(texte.charAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
public boolean estExecutable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
30
TP10/editeur/commande/CommandeCurseurAvancer.java
Normal file
30
TP10/editeur/commande/CommandeCurseurAvancer.java
Normal file
|
@ -0,0 +1,30 @@
|
|||
package editeur.commande;
|
||||
|
||||
import editeur.Ligne;
|
||||
|
||||
/** Avancer le curseur d'une position.
|
||||
* @author Xavier Crégut
|
||||
* @version 1.4
|
||||
*/
|
||||
public class CommandeCurseurAvancer
|
||||
extends CommandeLigne
|
||||
{
|
||||
|
||||
/** Initialiser la ligne sur laquelle travaille
|
||||
* cette commande.
|
||||
* @param l la ligne
|
||||
*/
|
||||
//@ requires l != null; // la ligne doit être définie
|
||||
public CommandeCurseurAvancer(Ligne l) {
|
||||
super(l);
|
||||
}
|
||||
|
||||
public void executer() {
|
||||
ligne.avancer();
|
||||
}
|
||||
|
||||
public boolean estExecutable() {
|
||||
return ligne.getCurseur() < ligne.getLongueur();
|
||||
}
|
||||
|
||||
}
|
30
TP10/editeur/commande/CommandeCurseurReculer.java
Normal file
30
TP10/editeur/commande/CommandeCurseurReculer.java
Normal file
|
@ -0,0 +1,30 @@
|
|||
package editeur.commande;
|
||||
|
||||
import editeur.Ligne;
|
||||
|
||||
/** Reculer le curseur d'une position.
|
||||
* @author Xavier Crégut
|
||||
* @version 1.4
|
||||
*/
|
||||
public class CommandeCurseurReculer
|
||||
extends CommandeLigne
|
||||
{
|
||||
|
||||
/** Initialiser la ligne sur laquelle travaille
|
||||
* cette commande.
|
||||
* @param l la ligne
|
||||
*/
|
||||
//@ requires l != null; // la ligne doit être définie
|
||||
public CommandeCurseurReculer(Ligne l) {
|
||||
super(l);
|
||||
}
|
||||
|
||||
public void executer() {
|
||||
ligne.reculer();
|
||||
}
|
||||
|
||||
public boolean estExecutable() {
|
||||
return ligne.getCurseur() > 1;
|
||||
}
|
||||
|
||||
}
|
27
TP10/editeur/commande/CommandeLigne.java
Normal file
27
TP10/editeur/commande/CommandeLigne.java
Normal file
|
@ -0,0 +1,27 @@
|
|||
package editeur.commande;
|
||||
|
||||
import editeur.Ligne;
|
||||
import menu.Commande;
|
||||
|
||||
|
||||
/** Une CommandeLigne est une commande qui travaille sur une
|
||||
* ligne de l'éditeur orienté ligne.
|
||||
* @author Xavier Crégut
|
||||
* @version 1.4
|
||||
*/
|
||||
abstract public class CommandeLigne
|
||||
implements Commande
|
||||
{
|
||||
/** La ligne manipulée par la commande. */
|
||||
protected Ligne ligne;
|
||||
|
||||
/** Initialiser la ligne sur laquelle travaille
|
||||
* cette commande.
|
||||
* @param l la ligne
|
||||
*/
|
||||
//@ requires l != null; // la ligne doit être définie
|
||||
public CommandeLigne(Ligne l) {
|
||||
ligne = l;
|
||||
}
|
||||
|
||||
}
|
20
TP10/editeur/commande/CommandeMenu.java
Normal file
20
TP10/editeur/commande/CommandeMenu.java
Normal file
|
@ -0,0 +1,20 @@
|
|||
package editeur.commande;
|
||||
|
||||
import editeur.Ligne;
|
||||
import menu.Menu;
|
||||
|
||||
abstract public class CommandeMenu extends CommandeLigne {
|
||||
/** La ligne manipulée par la commande. */
|
||||
|
||||
protected Menu sousMenu;
|
||||
|
||||
/** Initialiser la ligne sur laquelle travaille
|
||||
* cette commande.
|
||||
* @param l la ligne
|
||||
*/
|
||||
//@ requires l != null; // la ligne doit être définie
|
||||
public CommandeMenu(Ligne l) {
|
||||
super(l);
|
||||
}
|
||||
|
||||
}
|
30
TP10/editeur/commande/CommandeRAZ.java
Normal file
30
TP10/editeur/commande/CommandeRAZ.java
Normal file
|
@ -0,0 +1,30 @@
|
|||
package editeur.commande;
|
||||
|
||||
import editeur.Ligne;
|
||||
|
||||
/** Ajouter un caractère à la fin de la ligne.
|
||||
* @author Xavier Crégut
|
||||
* @version 1.4
|
||||
*/
|
||||
public class CommandeRAZ
|
||||
extends CommandeLigne
|
||||
{
|
||||
|
||||
/** Initialiser la ligne sur laquelle travaille
|
||||
* cette commande.
|
||||
* @param l la ligne
|
||||
*/
|
||||
//@ requires l != null; // la ligne doit être définie
|
||||
public CommandeRAZ(Ligne l) {
|
||||
super(l);
|
||||
}
|
||||
|
||||
public void executer() {
|
||||
ligne.raz();
|
||||
}
|
||||
|
||||
public boolean estExecutable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
30
TP10/editeur/commande/CommandeSupprimer.java
Normal file
30
TP10/editeur/commande/CommandeSupprimer.java
Normal file
|
@ -0,0 +1,30 @@
|
|||
package editeur.commande;
|
||||
|
||||
import editeur.Ligne;
|
||||
|
||||
/** Ajouter un caractère à la fin de la ligne.
|
||||
* @author Xavier Crégut
|
||||
* @version 1.4
|
||||
*/
|
||||
public class CommandeSupprimer
|
||||
extends CommandeLigne
|
||||
{
|
||||
|
||||
/** Initialiser la ligne sur laquelle travaille
|
||||
* cette commande.
|
||||
* @param l la ligne
|
||||
*/
|
||||
//@ requires l != null; // la ligne doit être définie
|
||||
public CommandeSupprimer(Ligne l) {
|
||||
super(l);
|
||||
}
|
||||
|
||||
public void executer() {
|
||||
ligne.supprimer();
|
||||
}
|
||||
|
||||
public boolean estExecutable() {
|
||||
return ligne.getLongueur() > 0;
|
||||
}
|
||||
|
||||
}
|
53
TP10/editeur/commande/SousMenuCurseur.java
Normal file
53
TP10/editeur/commande/SousMenuCurseur.java
Normal file
|
@ -0,0 +1,53 @@
|
|||
package editeur.commande;
|
||||
|
||||
import editeur.Ligne;
|
||||
import menu.Menu;
|
||||
|
||||
/** Reculer le curseur d'une position.
|
||||
* @author Xavier Crégut
|
||||
* @version 1.4
|
||||
*/
|
||||
public class SousMenuCurseur extends CommandeMenu {
|
||||
|
||||
Menu sousMenu = new Menu("Sous menu curseur");
|
||||
|
||||
/** Initialiser la ligne sur laquelle travaille
|
||||
* cette commande.
|
||||
* @param l la ligne
|
||||
*/
|
||||
//@ requires l != null; // la ligne doit être définie
|
||||
public SousMenuCurseur(Ligne l) {
|
||||
super(l);
|
||||
|
||||
this.sousMenu.ajouter("Avancer le curseur d'un caractère",
|
||||
new CommandeCurseurAvancer(ligne));
|
||||
this.sousMenu.ajouter("Reculer le curseur d'un caractère",
|
||||
new CommandeCurseurReculer(ligne));
|
||||
this.sousMenu.ajouter("Ramener le curseur au premier caractère",
|
||||
new CommandeRAZ(ligne));
|
||||
}
|
||||
|
||||
public void executer() {
|
||||
do {
|
||||
// Afficher la ligne
|
||||
System.out.println();
|
||||
ligne.afficher();
|
||||
System.out.println();
|
||||
|
||||
// Afficher le menu
|
||||
sousMenu.afficher();
|
||||
|
||||
// Sélectionner une entrée dans le menu
|
||||
sousMenu.selectionner();
|
||||
|
||||
// Valider l'entrée sélectionnée
|
||||
sousMenu.valider();
|
||||
|
||||
} while (! sousMenu.estQuitte());
|
||||
}
|
||||
|
||||
public boolean estExecutable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
18
TP10/menu/Commande.java
Normal file
18
TP10/menu/Commande.java
Normal file
|
@ -0,0 +1,18 @@
|
|||
package menu;
|
||||
|
||||
/** Définition d'une commande générale.
|
||||
* @author Xavier Crégut
|
||||
* @version 1.4
|
||||
*/
|
||||
public interface Commande {
|
||||
|
||||
/** Exécuter la commande. */
|
||||
//@requires estExecutable();
|
||||
void executer();
|
||||
|
||||
/** La commande est-elle exécutable ?
|
||||
* @return la commande est-elle exécutable ?
|
||||
*/
|
||||
/*@ pure @*/ boolean estExecutable();
|
||||
|
||||
}
|
81
TP10/menu/Entree.java
Normal file
81
TP10/menu/Entree.java
Normal file
|
@ -0,0 +1,81 @@
|
|||
package menu;
|
||||
|
||||
// À NOTER : La classe n'est pas déclarée « public » car elle n'a
|
||||
// pas à être utilisée à l'extérieur du paquetage. Plus
|
||||
// précisément, elle n'est utilisée que par la classe Menu. À ce
|
||||
// titre, il aurait été possible d'en faire une classe interne à
|
||||
// la classe Menu. Elle aurait alors été déclarée << static >>.
|
||||
|
||||
/** Définition d'une entrée de Menu.
|
||||
* @author Xavier Crégut
|
||||
* @version 1.6
|
||||
*/
|
||||
class Entree {
|
||||
|
||||
/** L'intitulé de l'entrée. */
|
||||
private String intitule;
|
||||
|
||||
/** La commande associée à l'entrée. */
|
||||
private Commande commande;
|
||||
|
||||
public String shortcut;
|
||||
|
||||
/** Construire une entrée à partir d'un intitulé et d'une commande.
|
||||
* @param unIntitule l'intitulé de l'entrée
|
||||
* @param uneCommande l'intitulé de la commande
|
||||
*/
|
||||
//@ requires uneCommande != null; // la commande existe
|
||||
//@ requires unIntitule != null && unIntitule.length() > 0;
|
||||
//@ // l'intitulé existe
|
||||
//@ ensures getIntitule() == unIntitule;
|
||||
//@ ensures getCommande() == uneCommande;
|
||||
public Entree(String unIntitule, Commande uneCommande) {
|
||||
intitule = unIntitule;
|
||||
commande = uneCommande;
|
||||
}
|
||||
|
||||
public Entree(String unIntitule, Commande uneCommande, String shortcut) {
|
||||
intitule = unIntitule;
|
||||
commande = uneCommande;
|
||||
this.shortcut = shortcut;
|
||||
}
|
||||
|
||||
/** L'intitulé de l'entrée. */
|
||||
public /*@ pure @*/ String getIntitule() {
|
||||
return intitule;
|
||||
}
|
||||
|
||||
/** La commande associée à l'entrée. */
|
||||
public /*@ pure @*/ Commande getCommande() {
|
||||
return commande;
|
||||
}
|
||||
|
||||
/** Afficher l'entrée.
|
||||
* @param numero le numéro de l'entrée dans le menu
|
||||
*/
|
||||
public /*@ pure @*/ void afficher(int numero) {
|
||||
if (commande.estExecutable()) {
|
||||
String num = "" + numero;
|
||||
if (num.length() < 2) {
|
||||
System.out.print(" ");
|
||||
}
|
||||
System.out.print(num);
|
||||
} else {
|
||||
System.out.print(" -");
|
||||
}
|
||||
System.out.print(") ");
|
||||
System.out.print(getIntitule());
|
||||
|
||||
if (this.shortcut != null) {
|
||||
int space = 46 - getIntitule().length() - shortcut.length();
|
||||
|
||||
for (int i = 0; i < space; i++) {
|
||||
System.out.print(' ');
|
||||
}
|
||||
System.out.format("[%s]", shortcut);
|
||||
}
|
||||
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
}
|
165
TP10/menu/Menu.java
Normal file
165
TP10/menu/Menu.java
Normal file
|
@ -0,0 +1,165 @@
|
|||
package menu;
|
||||
|
||||
import java.util.*;
|
||||
import util.Console;
|
||||
import menu.commande.*;
|
||||
|
||||
/** Définition de menus textuels avec les entrées non
|
||||
* sélectionnables désactivées.
|
||||
* @author Xavier Crégut (cregut@enseeiht.fr)
|
||||
* @version 1.9
|
||||
*/
|
||||
public class Menu {
|
||||
|
||||
//@ public invariant 0 <= getNbEntrees();
|
||||
|
||||
//@ private invariant titre != null;
|
||||
//@ private invariant selection != CMD_QUITTER && selection != null ==>
|
||||
//@ (\exists int i; i >= 0 && i <= getNbEntrees();
|
||||
//@ selection == getEntree(i).getCommande());
|
||||
//@ private invariant estQuitte() ==> selection == CMD_QUITTER;
|
||||
//@ private invariant getNbEntrees() == entrees.size();
|
||||
//@ private invariant entreeQuitter != null;
|
||||
|
||||
private String titre; // Le titre
|
||||
private List<Entree> entrees; // Les entrées du menu
|
||||
static final private Commande CMD_QUITTER = new CommandeNOP();
|
||||
static final private Entree entreeQuitter = new Entree("Quitter", CMD_QUITTER);
|
||||
private Commande selection; // Commande sélectionnée
|
||||
private boolean estQuitte; // le menu a-t-il été quitté ?
|
||||
|
||||
/** Construire un menu vide (sans entrées).
|
||||
* @param sonTitre le titre du menu
|
||||
*/
|
||||
//@ requires sonTitre != null; // le titre existe
|
||||
//@ ensures getNbEntrees() == 0; // le menu est vide
|
||||
//@ ensures estQuitte() == false; // pas encore quitter !
|
||||
public Menu(String sonTitre) {
|
||||
this.entrees = new ArrayList<Entree>();
|
||||
this.titre = sonTitre;
|
||||
this.selection = null;
|
||||
this.estQuitte = false;
|
||||
}
|
||||
|
||||
/** le nombre d'entrées du menu. */
|
||||
public /*@ pure @*/ int getNbEntrees() {
|
||||
return this.entrees.size();
|
||||
}
|
||||
|
||||
/** Obtenir une entrée du menu.
|
||||
* @param i position de l'entrée
|
||||
* @retrun l'entrée correspondant à i
|
||||
*/
|
||||
//@ requires 0 <= i && i <= getNbEntrees();
|
||||
private /*@ pure @*/ Entree getEntree(int i) {
|
||||
if (i > 0) {
|
||||
return this.entrees.get(i-1);
|
||||
} else {
|
||||
return entreeQuitter;
|
||||
}
|
||||
}
|
||||
|
||||
public /*@ pure @*/ boolean estQuitte() {
|
||||
return this.estQuitte;
|
||||
}
|
||||
|
||||
/** Ajouter une entrée dans le menu.
|
||||
* @param texte l'intitulé dans le menu
|
||||
* @param cmd la commande associée
|
||||
*/
|
||||
//@ requires texte != null && texte.length() > 0; // texte défini
|
||||
//@ requires cmd != null; // commande définie
|
||||
public void ajouter(String texte, Commande cmd) {
|
||||
this.entrees.add(new Entree(texte, cmd));
|
||||
}
|
||||
|
||||
public void ajouter(String texte, Commande cmd, String shortcut) {
|
||||
this.entrees.add(new Entree(texte, cmd, shortcut));
|
||||
}
|
||||
|
||||
/** Tracer une séparation du menu. */
|
||||
private static void tracerSeparation() {
|
||||
String separation =
|
||||
"----------------------------------------------------";
|
||||
System.out.println(separation);
|
||||
}
|
||||
|
||||
/** Afficher le menu. Les numéros des commandes non
|
||||
* exécutables ne sont pas affichés.
|
||||
*/
|
||||
public /*@ pure @*/ void afficher() {
|
||||
// Afficher le titre du menu
|
||||
tracerSeparation();
|
||||
System.out.println(titre);
|
||||
tracerSeparation();
|
||||
|
||||
// Afficher les entrées de l'utilisateur
|
||||
for (int i = 1; i <= this.getNbEntrees(); i++) {
|
||||
this.getEntree(i).afficher(i);
|
||||
}
|
||||
|
||||
// Afficher la possibilité de quitter
|
||||
this.getEntree(0).afficher(0);
|
||||
|
||||
// Dessiner la fin du menu
|
||||
tracerSeparation();
|
||||
}
|
||||
|
||||
/** Saisir le choix de l'utilisateur. Le choix correspond à
|
||||
* une entrée du menu (y compris 0 pour quitter).
|
||||
* L'utilisateur peut sélectionner une entrée dont la
|
||||
* commande associée n'est pas exécutable.
|
||||
*/
|
||||
//@ ensures ! estQuitte();
|
||||
public void selectionner() {
|
||||
// Choisir une entrée
|
||||
this.estQuitte = false;
|
||||
String choix;
|
||||
boolean choix_valide = false;
|
||||
|
||||
do {
|
||||
System.out.print("Votre choix: ");
|
||||
choix = Console.readString();
|
||||
|
||||
try {
|
||||
int choix_entier = Integer.parseInt(choix);
|
||||
choix_valide = 0 <= choix_entier && choix_entier <= this.getNbEntrees();
|
||||
if (!choix_valide) {
|
||||
System.out.println("Le numéro doit être compris entre "
|
||||
+ 0 + " et "
|
||||
+ this.getNbEntrees() + " !");
|
||||
} else {
|
||||
this.selection = this.getEntree(choix_entier).getCommande();
|
||||
}
|
||||
} catch (java.lang.NumberFormatException e) {
|
||||
|
||||
for (Entree entry : entrees) {
|
||||
if (entry.shortcut != null && entry.shortcut.equals(choix)) {
|
||||
choix_valide = true;
|
||||
this.selection = entry.getCommande();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} while (!choix_valide);
|
||||
}
|
||||
|
||||
/** Valider la sélection. Ceci consiste à exécuter la
|
||||
* commande associée à l'entrée sélectionnée. Si l'entrée
|
||||
* sélectionnée est non exécutable, un message d'erreur est
|
||||
* signalé.
|
||||
*/
|
||||
public void valider() {
|
||||
if (this.selection == CMD_QUITTER) {
|
||||
this.estQuitte = true;
|
||||
} else {
|
||||
if (this.selection.estExecutable ()) {
|
||||
this.selection.executer();
|
||||
} else {
|
||||
System.out.println("Opération non réalisable !");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
18
TP10/menu/commande/CommandeNOP.java
Normal file
18
TP10/menu/commande/CommandeNOP.java
Normal file
|
@ -0,0 +1,18 @@
|
|||
package menu.commande;
|
||||
|
||||
import menu.Commande;
|
||||
|
||||
/** Commande... qui ne fait rien !
|
||||
* @author Xavier Crégut
|
||||
* @version $Revision: 1.1 $
|
||||
*/
|
||||
final public class CommandeNOP implements Commande {
|
||||
|
||||
public void executer() {
|
||||
}
|
||||
|
||||
public boolean estExecutable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
BIN
TP10/to-1sn-2020-tp-10-sujet.pdf
Normal file
BIN
TP10/to-1sn-2020-tp-10-sujet.pdf
Normal file
Binary file not shown.
141
TP10/util/Console.java
Normal file
141
TP10/util/Console.java
Normal file
|
@ -0,0 +1,141 @@
|
|||
package util;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/** Quelques méthodes pour lire des entiers et des réels.
|
||||
* @author Xavier Crégut (très largement inspiré par Cay Horstmann)
|
||||
* @version $Revision: 1.2 $
|
||||
*/
|
||||
public class Console
|
||||
{
|
||||
/** Afficher un prompt à l'écran (sans passage à la ligne)
|
||||
* @param prompt texte à afficher à l'écran
|
||||
*/
|
||||
public static void printPrompt(String prompt) {
|
||||
System.out.print(prompt + " ");
|
||||
System.out.flush(); // forcer l'écriture en l'absence de '\n'
|
||||
}
|
||||
|
||||
/** Lire une chaîne de caractères à partir du clavier. La chaîne de
|
||||
* caractères est terminée par un retour à la ligne (qui ne fait pas partie
|
||||
* du résultat). (cf corejava)
|
||||
*
|
||||
* @return la ligne lue à partir du clavier (sans le retour à la ligne)
|
||||
*/
|
||||
public static String readLine() {
|
||||
int ch;
|
||||
String r = "";
|
||||
boolean done = false;
|
||||
while (!done) {
|
||||
try {
|
||||
ch = System.in.read();
|
||||
if (ch < 0 || (char) ch == '\n') {
|
||||
done = true;
|
||||
} else if ((char) ch != '\r') {
|
||||
// weird--it used to do \r\n translation
|
||||
r = r + (char) ch;
|
||||
}
|
||||
} catch (java.io.IOException e) {
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
public static String readString() {
|
||||
return readLine();
|
||||
}
|
||||
|
||||
/** Même méthode que readLine avec en plus l'affichage d'une invite.
|
||||
* @param invite texte à afficher à l'écran
|
||||
* @return la ligne lue à partir du clavier (sans le retour à la ligne)
|
||||
*/
|
||||
public static String readLine(String invite) {
|
||||
printPrompt(invite);
|
||||
return readLine();
|
||||
}
|
||||
|
||||
/** Lire un caractère après avoir affiché une invite. Tous les caractères
|
||||
* suivants, jusqu'au retour à la ligne sont considérés consommés.
|
||||
* @param invite texte à afficher à l'écran
|
||||
* @return le caractère lu au clavier.
|
||||
*/
|
||||
public static char readChar(String invite) {
|
||||
printPrompt(invite);
|
||||
String line = readLine();
|
||||
return line.length() > 0 ? line.charAt(0) : '\n';
|
||||
}
|
||||
|
||||
public static char readChar() {
|
||||
return readChar("");
|
||||
}
|
||||
|
||||
/** Lire un entier à partir du clavier après avoir affiché une invite.
|
||||
* Resaisie dans le cas d'une erreur de l'utilisateur.
|
||||
* @return l'entier lu
|
||||
*/
|
||||
public static int readInt(String invite) {
|
||||
int resultat = 0;
|
||||
boolean saisieOK = false;
|
||||
while(! saisieOK) {
|
||||
printPrompt(invite);
|
||||
try {
|
||||
String s = readLine().trim();
|
||||
resultat = Integer.parseInt(s);
|
||||
saisieOK = true;
|
||||
} catch (NumberFormatException e) {
|
||||
System.out.println ("Ce n'est pas un entier. Recommencez !");
|
||||
}
|
||||
}
|
||||
return resultat;
|
||||
}
|
||||
|
||||
public static int readInt() {
|
||||
return readInt("");
|
||||
}
|
||||
|
||||
/** Lire un réel à partir du clavier après avoir affiché une invite.
|
||||
* Resaisie dans le cas d'une erreur de l'utilisateur.
|
||||
* @return le réel lu
|
||||
*/
|
||||
public static double readDouble(String invite) {
|
||||
double resultat = 0;
|
||||
boolean saisieOK = false;
|
||||
while(! saisieOK) {
|
||||
printPrompt(invite);
|
||||
try {
|
||||
String s = readLine().trim();
|
||||
resultat = Double.parseDouble(s);
|
||||
saisieOK = true;
|
||||
} catch (NumberFormatException e) {
|
||||
System.out.println ("Ce n'est pas un réel. Recommencez !");
|
||||
}
|
||||
}
|
||||
return resultat;
|
||||
}
|
||||
|
||||
public static double readDouble() {
|
||||
return readDouble("");
|
||||
}
|
||||
|
||||
/** Lire un entier à partir du << flot >> d'entrée après avoir affiché une invite.
|
||||
* Resaisie dans le cas d'une erreur de l'utilisateur.
|
||||
* @return l'entier lu
|
||||
*/
|
||||
public static int readInt(BufferedReader in, String invite) throws IOException {
|
||||
int resultat = 0;
|
||||
boolean saisieOK = false;
|
||||
while(! saisieOK) {
|
||||
printPrompt(invite);
|
||||
try {
|
||||
String s = in.readLine().trim();
|
||||
resultat = Integer.parseInt(s);
|
||||
saisieOK = true;
|
||||
} catch (NumberFormatException e) {
|
||||
System.out.println ("Ce n'est pas un entier. Recommencez !");
|
||||
}
|
||||
}
|
||||
return resultat;
|
||||
}
|
||||
|
||||
}
|
9
TP12/CaseOccupeeException.java
Normal file
9
TP12/CaseOccupeeException.java
Normal file
|
@ -0,0 +1,9 @@
|
|||
/** Un joueur essaie de jouer dans une case occupée.
|
||||
* @author Xavier Crégut
|
||||
* @version $Revision: 1.1 $
|
||||
*/
|
||||
public class CaseOccupeeException extends Exception {
|
||||
public CaseOccupeeException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
44
TP12/ModeleMorpion.java
Normal file
44
TP12/ModeleMorpion.java
Normal file
|
@ -0,0 +1,44 @@
|
|||
/** Définition du « modèle » du jeu du Morpion.
|
||||
* @author Xavier Crégut
|
||||
* @version $Revision: 1.2 $
|
||||
*/
|
||||
public interface ModeleMorpion {
|
||||
|
||||
// Modéliser (coder !) le contenu d'une case
|
||||
enum Etat { VIDE, CROIX, ROND };
|
||||
|
||||
int TAILLE = 3; // taille du jeu de Morpion
|
||||
|
||||
// Définition des événements qui vont influencer le modèle.
|
||||
|
||||
/** Quitter le jeu. */
|
||||
void quitter();
|
||||
|
||||
/** Recommencer une nouvelle partie.*/
|
||||
void recommencer();
|
||||
|
||||
/** Cocher la case (x,y). */
|
||||
//@ requires x >= 0 && x < TAILLE;
|
||||
//@ requires y >= 0 && y < TAILLE;
|
||||
void cocher(int x, int y) throws CaseOccupeeException;
|
||||
|
||||
// Requêtes sur le modèle
|
||||
|
||||
/** Est-ce que la partie est terminée ? */
|
||||
boolean estTerminee();
|
||||
|
||||
/** Est-ce qu'il y a un gagnant ? */
|
||||
boolean estGagnee();
|
||||
|
||||
/** Obtenir le joueur dont c'est le tour de jouer. */
|
||||
Etat getJoueur();
|
||||
|
||||
/** Obtenir le contenu d'une case.
|
||||
* @param x colonne de la case
|
||||
* @param y ligne de la case
|
||||
*/
|
||||
//@ requires x >= 0 && x < TAILLE;
|
||||
//@ requires y >= 0 && y < TAILLE;
|
||||
Etat getValeur(int x, int y);
|
||||
|
||||
}
|
139
TP12/ModeleMorpionSimple.java
Normal file
139
TP12/ModeleMorpionSimple.java
Normal file
|
@ -0,0 +1,139 @@
|
|||
/**
|
||||
* ModeleMorpionSimple est une réalisation de l'interface ModeleMorpion en
|
||||
* utilisant un damier (tableau 3 par 3) pour stocker les symboles...
|
||||
*
|
||||
* @author Xavier Crégut
|
||||
* @version $Revision: 1.2 $
|
||||
*/
|
||||
|
||||
public class ModeleMorpionSimple implements ModeleMorpion {
|
||||
|
||||
/** La zone de jeu */
|
||||
private Etat[][] cases;
|
||||
|
||||
/** Le joueur dont c'est le tour de jouer */
|
||||
private Etat joueur;
|
||||
|
||||
/** Le nombres de cases cochées */
|
||||
private int nbCoups;
|
||||
|
||||
/** Est-ce que la partie est gagnée ? */
|
||||
private boolean gagnee;
|
||||
|
||||
public ModeleMorpionSimple() {
|
||||
// Créer le damier
|
||||
this.cases = new Etat[ModeleMorpion.TAILLE][ModeleMorpion.TAILLE];
|
||||
|
||||
// Commencer une partie
|
||||
initialiser();
|
||||
}
|
||||
|
||||
/** Est-ce que la partie est terminée ? */
|
||||
public boolean estTerminee() {
|
||||
return estGagnee()
|
||||
|| this.nbCoups >= ModeleMorpion.TAILLE * ModeleMorpion.TAILLE;
|
||||
}
|
||||
|
||||
/** Est-ce qu'il y a un gagnant ? */
|
||||
public boolean estGagnee() {
|
||||
return gagnee;
|
||||
}
|
||||
|
||||
/** Est-ce que la case (i,j) est vide ? */
|
||||
private boolean estVide(int i, int j) {
|
||||
return getValeur(i,j) == Etat.VIDE;
|
||||
}
|
||||
|
||||
public Etat getValeur(int x, int y) {
|
||||
return this.cases[x][y];
|
||||
}
|
||||
|
||||
/** Initialiser le jeu pour faire une nouvelle partie */
|
||||
private void initialiser() {
|
||||
// Initialiser les cases
|
||||
for (int i = 0; i < this.cases.length; i++) {
|
||||
for (int j = 0; j < this.cases[i].length; j++) {
|
||||
this.cases[i][j] = Etat.VIDE;
|
||||
}
|
||||
}
|
||||
|
||||
// Initialiser le nb de coups
|
||||
this.nbCoups = 0;
|
||||
|
||||
// Initialiser gagnée
|
||||
gagnee = false;
|
||||
|
||||
// Initialiser le joueur
|
||||
this.joueur = Etat.CROIX;
|
||||
}
|
||||
|
||||
public Etat getJoueur() {
|
||||
return this.joueur;
|
||||
}
|
||||
|
||||
/** Changer de joueur */
|
||||
private void changer() {
|
||||
if (this.joueur == Etat.CROIX) {
|
||||
this.joueur = Etat.ROND;
|
||||
} else {
|
||||
this.joueur = Etat.CROIX;
|
||||
}
|
||||
}
|
||||
|
||||
/** Jouer en (i,j) pour le joueur */
|
||||
//@ requires estVide(i,j);
|
||||
//@ ensures getValeur(i,j) == joueur;
|
||||
private void jouer(int i, int j) {
|
||||
this.cases[i][j] = this.joueur;
|
||||
this.nbCoups++;
|
||||
|
||||
// Mettre à jour gagnee
|
||||
// XXX: Ceci ne marche que pour un Morpion de taille 3 !
|
||||
gagnee = gagnee ||
|
||||
((cases[i][0] == cases[i][1] // ligne pleine
|
||||
&& cases[i][1] == cases[i][2])
|
||||
|| (cases[0][j] == cases[1][j] // colonne pleine
|
||||
&& cases[1][j] == cases[2][j])
|
||||
|| (i == j // première diagonale pleine
|
||||
&& cases[0][0] == cases[1][1]
|
||||
&& cases[1][1] == cases[2][2])
|
||||
|| (i + j == 2 // deuxième diagonale pleine
|
||||
&& cases[0][2] == cases[1][1]
|
||||
&& cases[1][1] == cases[2][0]));
|
||||
}
|
||||
|
||||
|
||||
/////// « Événements » de haut niveau déclenchées par l'utilisateur ////////////
|
||||
|
||||
|
||||
// Remarque : dans cette partie j'ai laissé le paramètre implicite this car
|
||||
// il me semble qu'il faudrait mettre tout ceci dans une classe spécifique,
|
||||
// par exemple LogiqueMorpion. Dans ce cas, this serait remplacé par
|
||||
// getModele() ou getMorpion().
|
||||
|
||||
|
||||
public void quitter() {
|
||||
}
|
||||
|
||||
public void recommencer() {
|
||||
this.initialiser();
|
||||
}
|
||||
|
||||
public void cocher(int x, int y) throws CaseOccupeeException {
|
||||
if (!this.estTerminee()) { // La partie est en cours
|
||||
if (this.estVide(x, y)) {
|
||||
// Jouer la case
|
||||
this.jouer(x, y);
|
||||
|
||||
// Passer à la suite
|
||||
if (! this.estTerminee()) {
|
||||
// Faire jouer l'autre joueur
|
||||
this.changer();
|
||||
}
|
||||
} else {
|
||||
throw new CaseOccupeeException("Impossible, la case est occupée !");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
170
TP12/MorpionSwing.java
Normal file
170
TP12/MorpionSwing.java
Normal file
|
@ -0,0 +1,170 @@
|
|||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import javax.swing.event.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.*;
|
||||
|
||||
/** Programmation d'un jeu de Morpion avec une interface graphique Swing.
|
||||
*
|
||||
* REMARQUE : Dans cette solution, le patron MVC n'a pas été appliqué !
|
||||
* On a un modèle (?), une vue et un contrôleur qui sont fortement liés.
|
||||
*
|
||||
* @author Xavier Crégut
|
||||
* @version $Revision: 1.4 $
|
||||
*/
|
||||
|
||||
public class MorpionSwing {
|
||||
|
||||
// les images à utiliser en fonction de l'état du jeu.
|
||||
private static final Map<ModeleMorpion.Etat, ImageIcon> images
|
||||
= new HashMap<ModeleMorpion.Etat, ImageIcon>();
|
||||
static {
|
||||
images.put(ModeleMorpion.Etat.VIDE, new ImageIcon("blanc.jpg"));
|
||||
images.put(ModeleMorpion.Etat.CROIX, new ImageIcon("croix.jpg"));
|
||||
images.put(ModeleMorpion.Etat.ROND, new ImageIcon("rond.jpg"));
|
||||
}
|
||||
|
||||
// Choix de réalisation :
|
||||
// ----------------------
|
||||
//
|
||||
// Les attributs correspondant à la structure fixe de l'IHM sont définis
|
||||
// « final static » pour montrer que leur valeur ne pourra pas changer au
|
||||
// cours de l'exécution. Ils sont donc initialisés sans attendre
|
||||
// l'exécution du constructeur !
|
||||
|
||||
private ModeleMorpion modele; // le modèle du jeu de Morpion
|
||||
|
||||
// Les éléments de la vue (IHM)
|
||||
// ----------------------------
|
||||
|
||||
/** Fenêtre principale */
|
||||
private JFrame fenetre;
|
||||
|
||||
/** Bouton pour quitter */
|
||||
private final JButton boutonQuitter = new JButton("Q");
|
||||
|
||||
/** Bouton pour commencer une nouvelle partie */
|
||||
private final JButton boutonNouvellePartie = new JButton("N");
|
||||
|
||||
/** Cases du jeu */
|
||||
private final JLabel[][] cases = new JLabel[3][3];
|
||||
|
||||
/** Zone qui indique le joueur qui doit jouer */
|
||||
private final JLabel joueur = new JLabel();
|
||||
|
||||
|
||||
// Le constructeur
|
||||
// ---------------
|
||||
|
||||
/** Construire le jeu de morpion */
|
||||
public MorpionSwing() {
|
||||
this(new ModeleMorpionSimple());
|
||||
}
|
||||
|
||||
/** Construire le jeu de morpion */
|
||||
public MorpionSwing(ModeleMorpion modele) {
|
||||
// Initialiser le modèle
|
||||
this.modele = modele;
|
||||
|
||||
// Créer les cases du Morpion
|
||||
for (int i = 0; i < this.cases.length; i++) {
|
||||
for (int j = 0; j < this.cases[i].length; j++) {
|
||||
this.cases[i][j] = new JLabel();
|
||||
}
|
||||
}
|
||||
|
||||
// Initialiser le jeu
|
||||
this.recommencer();
|
||||
|
||||
// Construire la vue (présentation)
|
||||
// Définir la fenêtre principale
|
||||
this.fenetre = new JFrame("Morpion");
|
||||
this.fenetre.setLocation(100, 200);
|
||||
|
||||
// Construire le contrôleur (gestion des événements)
|
||||
this.fenetre.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
|
||||
// Création du contenu
|
||||
Container contenu = fenetre.getContentPane();
|
||||
contenu.setLayout(new BorderLayout());
|
||||
|
||||
// Ajout de la bar
|
||||
JMenuBar bar = new JMenuBar();
|
||||
this.fenetre.setJMenuBar(bar);
|
||||
|
||||
// Ajout d'un menu dans la bar
|
||||
JMenu menu = new JMenu("Jeu");
|
||||
bar.add(menu);
|
||||
|
||||
// Ajout d'items dans le menu
|
||||
JMenuItem newGame = new JMenuItem("Nouvelle Partie");
|
||||
menu.add(newGame);
|
||||
JMenuItem quitter = new JMenuItem("Quitter");
|
||||
menu.add(quitter);
|
||||
|
||||
// Définir le Panel de la grille
|
||||
JPanel boutons_grid = new JPanel(new GridLayout(3, 3));
|
||||
contenu.add(boutons_grid, BorderLayout.NORTH);
|
||||
|
||||
// Ajout de la grille
|
||||
for (int i = 0; i < 9; i++) {
|
||||
JButton b = new JButton("", new ImageIcon("blanc.jpg"));
|
||||
b.setBorder(BorderFactory.createEmptyBorder());
|
||||
b.setContentAreaFilled(false);
|
||||
boutons_grid.add(b);
|
||||
}
|
||||
|
||||
// Définir le Panel des actions
|
||||
JPanel boutons_actions = new JPanel(new GridLayout(1, 3));
|
||||
contenu.add(boutons_actions, BorderLayout.SOUTH);
|
||||
|
||||
// Ajout des Buttons Next, Current et Quit
|
||||
JButton next = new JButton("N");
|
||||
boutons_actions.add(next);
|
||||
|
||||
JButton current = new JButton("", new ImageIcon("rond.jpg"));
|
||||
current.setBorder(BorderFactory.createEmptyBorder());
|
||||
current.setContentAreaFilled(false);
|
||||
boutons_actions.add(current);
|
||||
|
||||
JButton quit = new JButton("Q");
|
||||
boutons_actions.add(quit);
|
||||
|
||||
// afficher la fenêtre
|
||||
this.fenetre.pack(); // redimmensionner la fenêtre
|
||||
this.fenetre.setVisible(true); // l'afficher
|
||||
|
||||
}
|
||||
|
||||
// Quelques réactions aux interactions de l'utilisateur
|
||||
// ----------------------------------------------------
|
||||
|
||||
/** Recommencer une nouvelle partie. */
|
||||
public void recommencer() {
|
||||
this.modele.recommencer();
|
||||
|
||||
// Vider les cases
|
||||
for (int i = 0; i < this.cases.length; i++) {
|
||||
for (int j = 0; j < this.cases[i].length; j++) {
|
||||
this.cases[i][j].setIcon(images.get(this.modele.getValeur(i, j)));
|
||||
}
|
||||
}
|
||||
|
||||
// Mettre à jour le joueur
|
||||
joueur.setIcon(images.get(modele.getJoueur()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
// La méthode principale
|
||||
// ---------------------
|
||||
|
||||
public static void main(String[] args) {
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
new MorpionSwing();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
BIN
TP12/blanc.jpg
Normal file
BIN
TP12/blanc.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.8 KiB |
BIN
TP12/croix.jpg
Normal file
BIN
TP12/croix.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.4 KiB |
BIN
TP12/rond.jpg
Normal file
BIN
TP12/rond.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.5 KiB |
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue