Page d'accueilFindIt !Contact Cahier Swing

Cahier Swing

 Forum Cahier Swing

Ce forum est dédié au Cahier du Programmeur Swing et Sweet Home 3D son étude de cas.
Utilisez-le pour toute demande d'information supplémentaire ou pour toute suggestion au sujet de cet ouvrage et de cette application.
Pour les informations relatives à l'ouvrage Bien programmer en Java 7 et au Cahier du programmeur Java, merci d'utiliser le forum qui leur est dédié.
Vous pouvez consulter ces forums librement. Pour y participer, inscrivez-vous tout d'abord.

Sujets Messages récents Identification Inscription
Messages du sujet Errata Cahier du programmeur Swing

Manu

Ville : Paris / France
Membre depuis : 29 avr. 2003
Messages : 394
 10 déc. 2006 à 12:32
Malgré toute l'attention portée à la relecture du Cahier du Programmeur Swing, quelques erreurs sont passées inaperçues. Voici donc la liste des errata connues de cet ouvrage :

- Erratum en page 47
La classe "JFormattedTextField" doit être placée dans la colonne Swing du tableau "Composants AWT, Swing et SWT".


- Erratum en page 55
Dans la première phrase de l'aparté "Astuce Renommer le nom du champ d’un composant", lire "renommer les champs jContentPane ou jJMenuBar" au lieu de "renommer les champs jContentPanejJMenuBar".


- Erratum en page 83
Des caractères incorrects se sont glissés à l'impression dans la portion de code en bas de page. Voici le code qu'il faut lire :
-------------------------------------------------------------
package com.eteks.sweethome3d.junit;

import java.util.*;
import javax.swing.*;

import com.eteks.sweethome3d.model.Catalog;
import com.eteks.sweethome3d.model.Category;
import com.eteks.sweethome3d.model.CatalogPieceOfFurniture;
import com.eteks.sweethome3d.swing.CatalogTree;
import com.eteks.sweethome3d.io.DefaultCatalog;

import junit.framework.TestCase;

public class CatalogTreeTest extends TestCase {
  public void testCatalogTreeCreation() {
    Locale.setDefault(Locale.US);
    Catalog catalog = new DefaultCatalog();
    List<Category> categories = catalog.getCategories();
    Category firstCategory = categories.get(0);
    String firstCategoryEnglishName = firstCategory.getName();
    List<CatalogPieceOfFurniture> categoryFurniture =
        firstCategory.getFurniture();
-------------------------------------------------------------
La page sans erreur d'impression est disponible ici :
http://www.editions-eyrolles.com/Chapitres/9782212120196/Page_83_Puybaret.pdf


- Erratum en page 86
A la 3eme ligne du point 2, lire "SweetHome3D/src" au lieu de "SweetHome3Dysrc".


- Erratum en page 93
Dans la légende des figures 4-9 et 4-10, lire "Figure 4-9" au lieu de "Figure 4-10", et lire "Figure 4-10" au lieu de "Figure 4-9".


- Erratum en page 95
Dans l'aparté "Attention Force de la comparaison", lire "Collator.IDENTICAL" au lieu de "Collator.IDENITICAL".


- Erratum en page 110
A la fin du texte de l'aparté "Java Lecture d’un flux contenant une image", lire "ce que montre la figure 4-16" au lieu de "ce que montre la figure 4-17".


- Erratum en page 112
A la fin du premier paragraphe, lire "figure 4-17" au lieu de "figure 4-16".


- Erratum en page 138
Au début du texte de la seconde puce, lire "getRenderedDepth (5) appelée (2) (3)" au lieu de "getRenderedDepth (5) appelée (5) (6)".


- Erratum en page 144
Dans la figure 5-6, lire "TableColumnModel" au lieu de "ListColumnModel".


- Erratum en page 146
Au début du paragraphe de la section "Lecture du nom des colonnes du tableau", lire "La lecture des noms des colonnes s’effectue dans la méthode getColumnNames à partir du fichier en ressource de famille FurnitureTable." au lieu de "La lecture des noms des colonnes s’effectue dans la méthode getColumnNames à partir du fichier en ressource passé en paramètre."


- Erratum en page 147
En bas de page dans le code, lire "piece.getWidth(), piece.getHeight(), piece.getDepth()," au lieu de "piece.getWidth(), piece.getHeight(), piece.getHeight(),".


- Erratum en page 148
Au début de la dernière phrase de l'aparté "Swing TableModel et DefaultTableModel", lire "Nous verrons ensuite dans ce chapitre comment créer un modèle de tableau" au lieu de "Nous verrons ensuite dans ce chapitre comment créer un modèle d’arbre".


- Erratum en page 158
A la fin du premier paragraphe, lire "DefaultCatalog_en_US.properties" au lieu de "DefaultFurniture_en_US.properties".


- Erratum en page 163
La légende de la figure 6-1 est incorrecte ; lire "Diagramme des classes modifiées de la couche métier".


- Erratum en page 168
A la seconde puce, lire "javax.swing" au lieu de "javax.swin"


- Erratum en page 177
Dans les cinq dernières lignes de code en bas de page, les lettres c, d et e ont remplacé les chiffres 0, 1 et 2 à l'impression. Voici le code qu'il faut lire :
-------------------------------------------------------------
    catalogTree.expandRow(0);
    catalogTree.addSelectionInterval(1, 2);
    homeController.addHomeFurniture();

    assertEquals(2, furnitureTable.getRowCount());
    assertEquals(2, furnitureTable.getSelectedRowCount());
-------------------------------------------------------------


- Erratum en page 180
Dans l'instruction if de la méthode addHomeFurniture, cinq caractères incorrects se sont glissés à l'impression. Voici le code qu'il faut lire :
-------------------------------------------------------------
    if (!selectedFurniture.isEmpty()) {
      List<HomePieceOfFurniture> newFurniture =
          new ArrayList<HomePieceOfFurniture>();
-------------------------------------------------------------
Les pages 180 à 185 sans erreur d'impression sont disponibles ici :
http://www.editions-eyrolles.com/Errata/9782212120196/Pages_180_185_Puybaret.pdf


- Erratum en page 181
A la dernière ligne de la page, les symboles < et > ont été remplacés par les caractères o et r à l'impression. Voici la ligne qu'il faut lire :
public void addFurniture(List<HomePieceOfFurniture> furniture) {


- Erratum en page 184
A l'avant dernière ligne de l'aparté dans la colonne gauche, lire "entre les symboles < >" au lieu de "entre les symboles o r".
A l'avant dernière ligne du premier paragraphe, lire "SelectionEvent" au lieu de "SelectionEventF".


- Erratum en page 185
Dans les quatre dernières lignes de la page, les symboles < et > ont été remplacés par les caractères o et r à l'impression. Voici les lignes qu'il faut lire :
-------------------------------------------------------------
  private List<HomePieceOfFurniture> furniture;
  private List<Object> selectedItems;
  private List<FurnitureListener> furnitureListeners;
  private List<SelectionListener> selectionListeners;
-------------------------------------------------------------


- Erratum en page 215
Deux des classes mentionnées dans la figure 7-4 sont imprimées incorrectement. Sous "ActionListener", lire "Action" et "AbstractAction".


- Erratum en page 215
Deux des classes mentionnées dans la figure 7-4 sont imprimées incorrectement. Sous "ActionListener", lire "Action" et "AbstractAction".


- Erratum en pages 219 & 223
Dans les programmes présentés à ces pages, lire "HomePane.ActionType.UNDO" et "HomePane.ActionType.REDO" au lieu de "HomePane.ActionType.undo" et "HomePane.ActionType.redo".


- Erratum en page 260
A la fin du commentaire en marge de la méthode "assertCoordinatesEqualWallPoints", lire "10 à la puissance -10" au lieu de "1 à la puissance -10".


- Erratum en page 323
Dans la légende de la figure 9-7, lire "Parallélépipède construit dans l’application BoxGeometryTest" au lieu de "Parallélépipède construit dans l’application Rotation3DTest".


- Erratum en page 325
Dans la légende des figures 9-8 et 9-9, lire "Figure 9-8" au lieu de "Figure 9-9", et lire "Figure 9-9" au lieu de "Figure 9-8".


- Erratum en page 333
A la dernière ligne de l'aparté "Regard du développeur TransformGroup et Behavior", lire "matrice identité" au lieu de "matrice identifiée".


- Erratum en page 343
L'instruction home.addWallListener(new WallListener() { [...] }); en bas de la page a été dupliquée (le code source disponible sur Internet est lui correct).


- Erratum en page 472
A la fin du second paragraphe, lire "(voir figure 12-13)" au lieu de "(voir figure 12-14)". A la fin de l'aparté "Java Services JNLP", lire "figure 12-14" au lieu de "figure 12-13".


- Erratum en page 475
Au milieu de la page, séparer par un espace "keytool" et "-genkey", puisque la commande est "keytool".


- Erratum en page 483
Ajouter la ligne de code suivante après la ligne numérotée 4 (le code source disponible sur Internet est lui correct) :
    home.setName(args [1]);


D'avance, merci de nous excuser pour ces erreurs.

[Message mis à jour le 22/05/2008]
---
Manu (moderator/modérateur)

sly_xp

Ville : Metz
Membre depuis : 1 avr. 2007
Messages : 1
 1 avr. 2007 à 00:26
Bonjour,

juste pour signaler un autre erratum sans importance visiblement non indiqué dans la liste ci-dessus.
p95, dans le bloc "ATTENTION", il faut lire Collator.IDENTICAL et non pas Collator.IDENITICAL.

BàV

[Note du modérateur : cette erratum a été intégrée dans la liste précédente]
---
Sly

GrandCanyon

Ville : Lyon
Membre depuis : 18 juil. 2007
Messages : 6
 24 juil. 2007 à 17:36
Bonjour,

juste pour signaler également qu'il me semble qu'à la page 177 les trois lettres c, d et e qui apparaissent dans le code de la méthode testHomeFurniture() doivent être remplacées par 0, 1 et 2 (respectivement).

[Note du modérateur : cette erratum a été intégrée dans la liste en début de sujet]

Manu

Ville : Paris / France
Membre depuis : 29 avr. 2003
Messages : 394
 24 juil. 2007 à 18:38
Merci pour vos remarques, et désolé si ces errata ont perturbé le fil de votre lecture.
---
Manu (moderator/modérateur)

GrandCanyon

Ville : Lyon
Membre depuis : 18 juil. 2007
Messages : 6
 10 août 2007 à 22:31
Merci à toi pour le SAV sur le forum !!

On se rend bien compte qu'un tel ouvrage représente un travail titanesque et c'est presque surprenant qu'il y ait aussi peu d'erreurs ! En tout cas elles ne gênent aucunement la lecture et la compréhension.

Je signale donc une toute petite coquille au passage si jamais il y a une nouvelle édition du livre (avec les scénarios suivants ?) : à la page 168 à la puce traitant du design pattern composite de MVC il manque le "g" à la fin du package "javax.swin".

Merci encore !

[Note du modérateur : cette erratum a été intégrée dans la liste en début de sujet]

GrandCanyon

Ville : Lyon
Membre depuis : 18 juil. 2007
Messages : 6
 13 août 2007 à 12:45
Bonjour,

il me semble qu'à la page 223, dans la méthode addUndoSupportListener, il faut lire :

view.setEnabled(HomePane.ActionType.UNDO, true);
view.setEnabled(HomePane.ActionType.REDO, false);

au lieu de

view.setEnabled(HomePane.ActionType.undo, true);
view.setEnabled(HomePane.ActionType.redo, false);

[Note du modérateur : cette erratum a été intégrée dans la liste en début de sujet]

Niss

Ville : Braine l'alleud
Membre depuis : 1 sept. 2007
Messages : 2
 1 sept. 2007 à 21:36
Hello tout le monde.

Je pense avoir trouvé une petite erreur (qui n'en est pas vraiment une).

Dans la classe IconManager.java, la méthode createIcon prend quatre arguments dont un non utilisé dans celle-ci : il s'agit de waitingComponent.

private Icon createIcon(Content content, int height, Component waitingComponent, Icon errorIcon)

deviendrait donc :

private Icon createIcon(Content content, int height, Icon errorIcon)

Plusieurs pages devraient être modifiées (appels de cette méthode y compris) : 121 (3 modifications), 124 (1 modification) et 125 (1 modification)

@+ :)

Niss

Ville : Braine l'alleud
Membre depuis : 1 sept. 2007
Messages : 2
 8 sept. 2007 à 15:21
Hello,

Voici encore plusieurs erreurs et améliorations, concernant l'entièreté du chapitre 4. Certaines améliorations que je propose proviennent peut-être du fait que je n'ai pas compris certaines choses (j'ouvrirai un topic nouveau topic pour en parler dans ce cas)

@+ ;-)


---------------------------------------------------------------------

p137: Amélioration, assertFalse sans explication

assertFalse(widthInInch.equals(widthInMeter));

Je pense que ça serait mieux d'afficher un message d'erreur au
testeur, du genre :

assertFalse("Les deux valeurs sont identiques",widthInInch.equals(widthInMeter));



---------------------------------------------------------------------

p138: Erreur, Mauvais numéros

getRenderedDepth (5) appelée (5)(6) pour récupérer la chaîne ...

deviendrait :

getRenderedDepth (5) appelée (2)(3) pour récupérer la chaîne ...


---------------------------------------------------------------------

p141 : Amélioration, erreur ? Initialisation d'un attribut manquante

Dans le constructeur, tous les attributs sont initialisés,
sauf l'attribut color.


---------------------------------------------------------------------

p141 : Erreur, Commentaire innaproprié

Le commentaire "Liste des meubles et des listeners" en rapport
avec la ligne de code suivante :

private List<HomePieceOfFurniture> furniture;

devrait être :

"Liste des meubles"


---------------------------------------------------------------------

p143: Amélioration, erreur ?

Le point 6 nous propose de mettre l'accès de la méthode setCatalog
à protected. Je me pose dès lors quelques questions :

- Si nous utilisons protected pour cette méthode, pourquoi setUnit
ne serait pas aussi protected (au lieu de public) ?

Si nous laissons setUnit public,
- Pourquoi ne pas laisser setCatalog public ?



---------------------------------------------------------------------

p143: Erreur, faute de frappe

Dans le code de cette page, il faut remplacer :
- centimerToInch par centimeterToInch
- inchToCentimer par inchToCentimeter



---------------------------------------------------------------------

p146: Amélioration, phrase confuse

"La lecture des noms des colonnes s'effectue dans la méthode
getColumnNames à partir du fichier en ressource passé en paramètre."

A chaque fois que je lis cette phrase, je pense qu'on envoie le
fichier de ressource à la méthode getColumnName, ce qui n'est pas
le cas.

Je modifierais la phrase pour quelque chose comme ceci :

"La lecture des noms des colonnes s'effectue dans la methode
getColumnNames à partir du fichier en ressource
FurnitureTable.properties que Margaux crée ..."

Ca serait moins "confus" je pense.



---------------------------------------------------------------------

p147: Erreur, dans le code de FurnitureTableModel

Object [] rowValues = {
piece,
piece.getWidth(),
piece.getHeight(),
piece.getHeight(),
piece.getColor(),
piece.isMovable(),
piece.isDoorOrWindow(),
piece.isVisible()};

Deux fois l'appel à getHeight()

deviendrait donc :

Object [] rowValues = {
piece,
piece.getWidth(),
piece.getHeight(),
piece.getDepth(),
piece.getColor(),
piece.isMovable(),
piece.isDoorOrWindow(),
piece.isVisible()};



---------------------------------------------------------------------

p148: Erreur, apparté Swing, mauvais terme

"Nous verrons ensuite dans ce chapitre comment créer un modèle
d'arbre à partir de ..."

On parle de tableau, pas d'arbre.

deviendrait :

"Nous verrons ensuite dans ce chapitre comment créer un modèle
de tableau à partir de ..."


De même, le mot "squelette" pour le classe AbstractTableModel me
semble un peu bizarre. C'est plutôt un squelette avec de la chair
pour moi :D



---------------------------------------------------------------------

p150: Amélioration

for (int i=0, n=getColumnCount(); i<n; i++)

deviendrait :

for (int i=0; i<getColumnCount(); i++)


Je trouve plus simple. Il faut appeler la méthode à chaque itération,
mais on le fait bien comme ça ailleur ... (voir p156, apparté "Swing
- Modèle d'un tableau JTable")



---------------------------------------------------------------------

p150: Erreur, Mauvais numéro

getColumn(getColumnName(i)).setCellRenderer(columnRenderers[i]); (1)

deviendrait :

getColumn(getColumnName(i)).setCellRenderer(columnRenderers[i]); (4)



---------------------------------------------------------------------

p150-151: Erreur, Mauvais numéro dans méthode getNameWithIconRenderer

Il y a deux fois le numéro 1. En modifiant, les numéros suivants
seront à modifier (+modification dans le texte explicatif).



---------------------------------------------------------------------

p150-152: Amélioration, infos supplémentaires

Pourquoi choisir l'une méthode plutôt que l'autre ?
- getSizeRenderer : retourne un TableCellRenderer
- getNameWithIconRenderer et getColorRenderer : retourne un DefaultTableCellRenderer

J'ai un peu de mal à m'y retrouver dans ce truc. Ca semble identique,
à part qu'on renvoie un label pour les deux dernières méthodes ...



---------------------------------------------------------------------

p151: Erreur, Mauvais nom de méthode dans la méthode getSizeRenderer

value = centimerToInch((Float)value);

deviendrait :

value = centimeterToInch((Float)value);



---------------------------------------------------------------------

p152: Amélioration, apparté Import static

On parle de centimerToInch qui à subit un import static, mais
on ne le voit nul part dans le code. C'est un peu confus, je
me serais attendu à avoir quelque part une demande d'ajout
de cette ligne d'import qui ferait que centimerToInch
puisse être appelé comme cela.



---------------------------------------------------------------------

p152: Erreur, apparté Import static

Contient un "centimerToInch" à changer en "centimeterToInch"



---------------------------------------------------------------------

p155: Amélioration, phrase en code

Cette phrase : "Cette fonctionnalité est active par défaut ...
d'en-tête d'un tableau", pourrait peut-être être remplacée par
du code. Je pense que ça serait plus clair. Ou rajouter du code.



---------------------------------------------------------------------

p158: Amélioration

On parle du fichier DefaultFurniture_en_US.properties à créer soi-même. Où se trouve t'il dans les sources ?
Est-ce que nous ne pourrions pas le coder dans le programme (arrondi, création ?).
Si on a une centaine de meuble, ça risque d'être long :(

[Note du modérateur : les errata les plus gênantes pour la lecture ont été intégrées dans la liste en début de sujet]

Manu

Ville : Paris / France
Membre depuis : 29 avr. 2003
Messages : 394
 8 sept. 2007 à 17:56
Merci pour ces informations détaillées. Au cours de la rédaction du livre, les chapitre 6, 7 et 8 sont ceux qui ont le plus bougé, mais j'espère que vous trouverez moins d'erreurs dans la suite.
Je reprends ici les points qui méritent discussion :

> p141 : Amélioration, erreur ? Initialisation d'un attribut manquante
> Dans le constructeur, tous les attributs sont initialisés, sauf l'attribut color.

Ca n'est pas une erreur, et l'attribut color gardera la valeur null qui lui sera affectée par defaut tel que décrit dans les spécifications du langage. Un objet sans couleur garde sa (ses) couleur(s) définie(s) dans son modèle 3D... jusqu'à ce qu'on puisse en changer dans le scénario 12. J'aurais peut-être du omettre cet attribut mais c'était aussi pour montrer comment programmer son renderer p 152.
J'aurais du ajouter un commentaire pour dire qu'il a cette valeur null par défaut.


> Le point 6 nous propose de mettre l'accès de la méthode setCatalog
> à protected. Je me pose dès lors quelques questions :
>
> - Si nous utilisons protected pour cette méthode, pourquoi setUnit
> ne serait pas aussi protected (au lieu de public) ?
>
> Si nous laissons setUnit public,
> - Pourquoi ne pas laisser setCatalog public ?

Tant qu'on ne peut pas changer l'unité (ce qui n'arrive pas avant le chapitre 12 p 457 !), cette méthode devrait être protected par homogénéité avec setCatalog et pour éviter qu'un programmeur ne modifie l'unité de n'importe où. Mais page 137, il fallait pouvoir modifier l'unité pour le test FurnitureTableTest. J'aurais pu créer une sous-classe de DefaultUserPreferences dans la classe de test pour faire ça proprement, mais alors il aurait fallu me justifier à ce sujet !!!
C'est un bon exemple qui montre que pédagogie et programmation XP ne se marie pas forcément bien... ;-)


> p146: Amélioration, phrase confuse
>
> "La lecture des noms des colonnes s'effectue dans la méthode
> getColumnNames à partir du fichier en ressource passé en paramètre."
>
> A chaque fois que je lis cette phrase, je pense qu'on envoie le
> fichier de ressource à la méthode getColumnName, ce qui n'est pas
> le cas.
>
> Je modifierais la phrase pour quelque chose comme ceci :
> "La lecture des noms des colonnes s'effectue dans la methode
> getColumnNames à partir du fichier en ressource
> FurnitureTable.properties que Margaux crée ..."

Il y a eu une période où cette méthode où cette méthode prenait l'objet ResourceBundle en paramètre !
Une preuve ? http://sweethome3d.cvs.sourceforge.net/sweethome3d/SweetHome3D/src/com/eteks/sweethome3d/swing/FurnitureTable.java?revision=1.11&view=markup ;-)
J'ai changé d'avis mais j'ai oublié de changer le texte en conséquence. Merci de l'avoir relevé.


> p148: mauvais terme
>
> De même, le mot "squelette" pour le classe AbstractTableModel me
> semble un peu bizarre. C'est plutôt un squelette avec de la chair
> pour moi :D

Mais c'est justement le terme consacré (il y a même une page Wiki sur les squelettes informatiques : http://fr.wikipedia.org/wiki/Squelette_d%27un_site_web ) ! Peut-être que le mot skeleton non francisé vous aurait fait moins peur !!! :D


> p150: Amélioration
>
> for (int i=0, n=getColumnCount(); i<n; i++)
> deviendrait :
> for (int i=0; i<getColumnCount(); i++)
>
> Je trouve plus simple. Il faut appeler la méthode à chaque itération,
> mais on le fait bien comme ça ailleurs

C'est une juste optimisation qui ne coûte pas cher à faire !


> p150-152: Amélioration, infos supplémentaires
>
> Pourquoi choisir l'une méthode plutôt que l'autre ?
> - getSizeRenderer : retourne un TableCellRenderer
> - getNameWithIconRenderer et getColorRenderer : retourne un DefaultTableCellRenderer
>
> J'ai un peu de mal à m'y retrouver dans ce truc. Ca semble identique,
> à part qu'on renvoie un label pour les deux dernières méthodes ...

C'est surtout pour montrer les différentes possibilités pour créer un CellRenderer.
- getSizeRenderer utilise la délégation car on veut juste modifier la valeur affichée dans un renderer de nombres en fonction de l'unité.
- getNameWithIconRenderer et getColorRenderer sont des sous-classes de DefaultTableCellRenderer car ce sont des renderers qui affichent des types que ne se sait pas afficher Swing par défaut.


> p152: Amélioration, apparté Import static
>
> On parle de centimerToInch qui à subit un import static, mais
> on ne le voit nul part dans le code [...]

J'ai hésité à laisser cet aparté à cette page ou à la page 145, là où apparaît la clause import static en question ! Mais à l'opposé, la méthode centimeterToInch mentionnée dans l'aparté n'est pas "encore" utilisée à la page 145. Grave dilemme...
L'éditeur nous interdit des renvois à des numéros de page, mais c'est vrai que j'aurais du insister sur ce point là !


> On parle du fichier DefaultFurniture_en_US.properties à créer soi-même.
> Où se trouve t'il dans les sources ?

C'est une erreur, c'est en fait le fichier DefaultCatalog_en_US.properties qui est forcément voisin des fichiers properties de la famille DefaultCatalog, donc dans le répertoire src/com/eteks/sweethome3d/io


> Est-ce que nous ne pourrions pas le coder dans le programme (arrondi, création ?).

C'est une bonne idée... à laquelle je ne suis même pas sur d'avoir pensé !
En fait, il y a quand même deux raisons pour lesquelles je ne l'ai pas envisagé :
- l'approximation doit faire apparaître le moins de chiffres possible, sans faire perdre ses proportions au meuble
- certains meubles ont des dimensions complètement différentes aux USA. N'avez vous jamais entendu des lits "king size', "queen size"... Ces lits n'ont pas les mêmes dimensions qu'en France.

> Si on a une centaine de meuble, ça risque d'être long :(

A qui le dites-vous ? Dans la dernière version de Sweet Home 3D, il y a 50 meubles ! ;-)

Merci encore pour vos remarques
---
Manu (moderator/modérateur)


Page d'accueilFindIt !ContactDébut de la page

© Copyrights 1997-2023 eTeks - Tous droits réservés

Cahier Swing