IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Collection et Stream Java Discussion :

Problème généricité sur ArrayList


Sujet :

Collection et Stream Java

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Août 2008
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 256
    Points : 85
    Points
    85
    Par défaut Problème généricité sur ArrayList
    Bonjour à tous !

    Désolé d'être de retour mais j'ai encore un problème, j'ai essayé d'harmoniser mon code (créer des classes correspondant à mes besoins) mais ça m'a mis pas mal la pagaille et plus particulièrement sur une classe où je gère les fichiers txt.
    J'ai une méthode qui me permet d'écrire dans un fichier temporaire dans laquelle je luis passe un paramètre de type List, avant de la transformer elle était écrite ainsi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
        /** ECRITURE DES DONNEE POUR LE CLIENT */
        void WriteFileTmp(List<String[]> listData, String sTypeAction, int iDimensionArray) throws IOException{       
     
            ArrayList<String[]> array = new ArrayList<>(listData);
     
            try (FileWriter ffw = new FileWriter(f)) {
                ffw.write(sTypeAction);
                ffw.write("\r\n");
                for (String[] next : array) {
                    try{
                        for(int i = 0; i <= iDimensionArray; i++){
                            ffw.write(next[i]);
                            ffw.write("\r\n");
                        }                  
                    }catch (Exception e){
                        jop1.showMessageDialog(null, "Impossible d'écrire dans le fichier temporaire\n" +
                                "Détail de l'erreur :\n" + e.toString(), "Erreur", JOptionPane.ERROR_MESSAGE);
                    }
                }
                ffw.write(sTypeAction);
                ffw.write("\r\n");
                ffw.close(); // fermer le fichier à la fin des traitements 
            }
        }
    et maintenant je veux que celle-ci soit générique car j'ai une créé une classe Client qui contient toutes les méthodes dont j'ai besoin (getFirstname, getLastname, etc.) et dont je fais hériter ma collection de type List qui est déclarée ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    private static List<Client> listCustomer;
    Pour finir, j'ai tenté d'écrire ma méthode comme ci-dessous mais ça ne fonctionne au moment où je veux écrire via le code "ffw.write(toto);"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
        void WriteFileTmp(List<T[]> listData, String sTypeAction, int iDimensionArray) throws IOException{       
     
            ArrayList<T[]> array = new ArrayList<>(listData);
     
            try (FileWriter ffw = new FileWriter(f)) {
                ffw.write(sTypeAction);
                ffw.write("\r\n");
                for (int u = 0; u < array.size(); u++) {
                    try{
                        for(int i = 0; i <= iDimensionArray; i++){
                        	T[] toto = array.get(i);
                            ffw.write(toto);
                            ffw.write("\r\n");
                        }                  
                    }catch (Exception e){
                        jop1.showMessageDialog(null, "Impossible d'écrire dans le fichier temporaire\n" +
                                "Détail de l'erreur :\n" + e.toString(), "Erreur", JOptionPane.ERROR_MESSAGE);
                    }
                }
                ffw.write(sTypeAction);
                ffw.write("\r\n");
                ffw.close(); // fermer le fichier à la fin des traitements 
            }
        }
    Je vous remercie à tous pour votre aide.

  2. #2
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    List<T[]> et List<Client> ne pourront jamais correspondre. Le premier attends un tableau dans chaque case de la liste, le second attents un Client. Et un Client ce n'est pas un tableau.

    Tu devrais prendre les List<T> pas des List<T[]>


    Et si ça ne plante qu'à l'exécution, c'est que t'as foutu la pagaille lors de l'appel avec des typecasting foireux, car le compilateur aurait du interdire ça directement.

  3. #3
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    En dehors de ton problème de type, tu devrais au moins encapsuler ton FileWriter dans un BufferedWriter (new BufferedWriter(new FileWriter(...), voire tout simplement Files.newBufferedWriter(f.toPath()). Et utiliser sa méthode newLine() pour les passages à la ligne : le caractère étant différent selon les plateformes, le mettre en dur peut-être problématique.

    Tu peux ensuite encapsuler le BufferedWriter dans un PrintWriter, ce qui te permettra de faire comme avec System.out : des print(), println(), format(), printf()...

    Sinon tu n'as pas besoin d'appeler close() explicitement : tu utilises la structure try-with-resource(try (FileWriter ffw = new FileWriter(f)) {), qui fait que le writer sera automatiquement fermé à la sortie du bloc try.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Août 2008
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 256
    Points : 85
    Points
    85
    Par défaut
    Merci tchize_ pour ta réponse, j'ai fait quelques modifs dont celle que tu m'as noté et le compilateur ne m'a pas insulté. Après essai en débogage, je remplis bien mon attribut "array" et je me suis rendu compte que je ne vais certainement pas pouvoir récupérer son contenu dans le sens ou, l'attribut "array" a hérité de ma classe client et que celle-ci contient que des méthodes get (firstname, lastname, ...).

    Je ne vois pas comment faire une boucle pour récupérer les valeurs ?

    Je post mon code que j'ai modifié pour l'écriture dans le fichier ainsi que ma classe Client où je pense qu'il va falloir que j'apporte une modif

    Méthode pour écrire dans le fichier texte :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
        <T> void WriteFileTmp(List<T> listData, String sTypeAction, int iDimensionArray) throws IOException{       
     
            ArrayList<T> array = new ArrayList<>(listData);
     
            try (FileWriter ffw = new FileWriter(f)) {
                ffw.write(sTypeAction);
                ffw.write("\r\n");
                for (T next : array) {
                    try{
                        for(int i = 0; i <= iDimensionArray; i++){
                            ffw.write(array.get(i).toString());
                            ffw.write("\r\n");
                        }                  
                    }catch (Exception e){
                        jop1.showMessageDialog(null, "Impossible d'écrire dans le fichier temporaire\n" +
                                "Détail de l'erreur :\n" + e.toString(), "Erreur", JOptionPane.ERROR_MESSAGE);
                    }
                }
                ffw.write(sTypeAction);
                ffw.write("\r\n");
                ffw.close(); // fermer le fichier à* la fin des traitements 
            }
        }
    La classe Client :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
     
    public class Client {
     
        private final String firstname;
        private final String lastname;
        private final String id;
        private final String type;    
        private final String streetnumber;
        private final String streetname;
        private final String zipcode;
        private final String city;
        private final String country;
        private final String phone;
        private final String email;
        private final String memoid;
     
        public Client(String firstname, String lastname, String id, String type, 
                      String streetnumber, String streetname, String zipcode, String city, 
                      String country, String phone, String email, String memoid){
     
            this.firstname = firstname;
            this.lastname = lastname;
            this.id = id;
            this.type = type;    
            this.streetnumber = streetnumber;
            this.streetname = streetname;
            this.zipcode = zipcode;
            this.city = city;
            this.country = country;
            this.phone = phone;
            this.email = email;
            this.memoid = memoid;
        }
     
        public String getLastname() {
            return lastname;
        }
     
        public String getFirstname() {
            return firstname;
        }
     
        public String getId() {
            return id;
        }
     
        public String getType() {
            return type;
        }
     
        public String geStreetnumber() {
            return streetnumber;
        }
     
        public String getStreetname() {
            return streetname;
        }
     
        public String getZipcode() {
            return zipcode;
        }
     
        public String getCity() {
            return city;
        }
     
        public String getCountry() {
            return country;
        }
     
        public String getPhone() {
            return phone;
        }
     
        public String getEmail() {
            return email;
        }
     
        public String getMemoId() {
            return memoid;
        }    
    }
    Merci d'avance.

  5. #5
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Tu ne peux plus en effet faire de boucle pour écrire les propriétés : tu es obligé d'appeler chaque méthode successivement, pour écrire chaque propriété à la suite (enfin, il y aurait moyen par réflexion éventuellement). Par contre, il y a un petit truc que je ne comprends pas : dans tes autres posts tu parles de fichier xml. Pourquoi ici un fichier texte ?

    Sinon, autre chose que je n'avais pas bien vu tout à l'heure, mais le JOptionPane pour le message d'erreur, n'est peut-être pas une solution très viable : s'il y a des erreurs d'I/O, tu vas avoir une répétion agaçante de message, et le fichier sera pourri à la fin, voire absent : autant abandonner direct à la première erreur.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Août 2008
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 256
    Points : 85
    Points
    85
    Par défaut
    Merci Joël pour tes réponses alors à mon tour de t'en apporter :

    1) J'ai appliqué ce que tu m'as dit de faire dans ton 1er message c'est à dire passer de write à bufferwriter et donc ça me donne ça (je n'ai pas pu essayer dans le sens ou je suis bloqué dans la boucle) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
        <T> void WriteFileTmp(List<T> listData, String sTypeAction, int iDimensionArray) throws IOException{
     
            ArrayList<T> array = new ArrayList<>(listData);
     
            try (BufferedWriter ffw = Files.newBufferedWriter(f.toPath())) {
                ffw.write(sTypeAction);
                ffw.newLine();
                for (T next : array) {
                    for(int i = 0; i <= iDimensionArray; i++){
                        ffw.write(array.get(i).toString());
                        ffw.newLine();
                    }                  
                }
                ffw.write(sTypeAction);
                ffw.newLine();
            }catch (Exception e){
                jop1.showMessageDialog(null, "Impossible d'écrire dans le fichier temporaire\n" +
                                             "Détail de l'erreur :\n" + e.toString(), "Erreur", JOptionPane.ERROR_MESSAGE);
            }
        }
    tu es obligé d'appeler chaque méthode successivement
    2) Si j'utilise la généricité comment je peux récupérer les méthodes de ma classe ? Tu veux parler de la réflexivité? Si c'est ça je me suis lancé dans une aventure digne de la Indiana Jones mais je crois que c'est ça.

    Pourquoi ici un fichier texte ?
    3) Justement dans un de mes autres posts tu m'avais notifié d'utiliser un fichier texte, pourquoi ? Parce que dans le sujet de mon projet il faut que en cas de plantage du logiciel je puisse récupérer les données donc ce que je fais :
    1 - A l'ouverture de la jFrame ou jDialog je charge dans une collection de type List les données qui sont dans mon fichier XML.
    2 - Ensuite, lorsque l'utilisateur agit sur les menus d'action (ajouter, modifier et supprimer) j'enregistre les données dans un fichier texte pour ne pas polluer mon fichier XML.
    3 - Dès que l'utilisateur ferme la jFrame ou la jDialog, je met à jour le fichier XML via les données enregistrés dans le fichier et si tout est bon je supprime celui-ci. Ainsi, si l'application se ferme par inadvertance les fichiers texte seront toujours présent et par conséquent je pourrais récupérer les données.

    Après, est ce que j'ai bien fait ou est ce que j'ai bien compris ce que tu m'as dit ... Je ne sais pas ?

    Sinon, autre chose que je n'avais pas bien vu tout à l'heure, mais le JOptionPane pour le message d'erreur, n'est peut-être pas une solution très viable : s'il y a des erreurs d'I/O, tu vas avoir une répétion agaçante de message, et le fichier sera pourri à la fin, voire absent : autant abandonner direct à la première erreur.
    4) Je me suis rendu compte effectivement qu'il était mal placé et que d'ailleur j'avais un try catch en trop, je les donc modifié et apporté la mise dans le code ci-dessus. Est ce que c'est ce que tu voulais me dire ?

    Désolé, si je met du temps à répondre mais avant j'essais de mettre en place et forme les différentes remarques que vous m'apportez pour ensuite les poster, vu que je ne suis pas une flèche ça prend du temps.

    Merci.

  7. #7
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Jb_One73 Voir le message

    2) Si j'utilise la généricité comment je peux récupérer les méthodes de ma classe ? Tu veux parler de la réflexivité? Si c'est ça je me suis lancé dans une aventure digne de la Indiana Jones mais je crois que c'est ça.
    1. A la base avec la généricité, tu ne peux effectivement pas récupérer les méthodes de ta classe
    2. Mais le but de la généricité c'est de faire la partie générique, pas la partie spécifique. On doit déléguer la partie spécifique.

      Par exemple, on peut faire :

      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      public abstract class AbstractPropertySaver<T> {
       
         public void write(List<T> objects) {
       
             ...
       
             for(T object : objects) {
                  Map<String, String> properties = getProperties(object);
                  for(Map.entry<String, String> entry : properties.entrySet()) {
                      ffw.write( entry.getKey() + " = " + writer.writer( entry.getValue() ) );
                      ffw.newLine();
                  }
             }
       
             ...
       
         }
       
         protected abstract Map<String, String> getProperties(T object);
       
      }
      Ensuite, on fait
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      public class ClientPropertySaver extends PropertySave<Client> {
       
           ...
       
      }
    3. Ensuite, on peut faire de la réflexion mais en générique, mais il faut une base (par exemple, parcourir les méthodes dont le nom commence par get)



    Citation Envoyé par Jb_One73 Voir le message

    3) Justement dans un de mes autres posts tu m'avais notifié d'utiliser un fichier texte, pourquoi ? Parce que dans le sujet de mon projet il faut que en cas de plantage du logiciel je puisse récupérer les données donc ce que je fais :
    1 - A l'ouverture de la jFrame ou jDialog je charge dans une collection de type List les données qui sont dans mon fichier XML.
    2 - Ensuite, lorsque l'utilisateur agit sur les menus d'action (ajouter, modifier et supprimer) j'enregistre les données dans un fichier texte pour ne pas polluer mon fichier XML.
    3 - Dès que l'utilisateur ferme la jFrame ou la jDialog, je met à jour le fichier XML via les données enregistrés dans le fichier et si tout est bon je supprime celui-ci. Ainsi, si l'application se ferme par inadvertance les fichiers texte seront toujours présent et par conséquent je pourrais récupérer les données.

    Après, est ce que j'ai bien fait ou est ce que j'ai bien compris ce que tu m'as dit ... Je ne sais pas ?
    Non, j'ai parlé d'écrire dans un fichier temporaire au lieu d'écrire directement dans le fichier final. Mais j'ai parlé de renommer le fichier temporaire. Quand je parlais de fichier temporaire, je parlais de fichier xml.

    En gros, si ton fichier s'appelle "fichier.xml", tu fais un truc comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    File file = new File("fichier.xml");
    ecrireEnXmlDans(file);
    Je parlais de faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    File file = new File("fichier.xml");
    File tmpfile = new File("fichier.xml.tmp");
    ecrireEnXmlDans(tmpfile);
    if ( file.exists() ) file.delete();
    tmpFile.renameTo( file );
    Ou en version "étendue"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
     
    File oldFile = new File("fichier.xml.bak");
    if ( oldFile.exists() ) { // on supprime l'ancien .bak (on pourrait gérer ça plus finement : s'il y a un .bak, c'est qu'il y a eu un problème précédement : on aurait dû faire une procédure manuelle de récupération)
        oldFile.delete();
    }
    File realFile = new File("fichier.xml");
    File file = new File("fichier.xml.temp");
    ecrireEnXmlDans(file); // on fait la sauvegarde dans le tmp
    if ( file.exists() ) { // s'il existe c'est que la sauvegarde a réussie
       if( realFile.exists() ) { // s'il exisre un fichier sauvegardé précédemment
          if ( !realFile.renameTo( oldFile ) ) { // on le renomme en .bak (on pourra récupérer les données manuellement en cas de problème)
              // on préfère abandonner la sauvegarde, plutôt que de risquer de perdre le bon fichier
              throw new IOException("Impossible de renommer " + file.getName() +" en " + oldFile.getName() );
          }
      }
      if ( file.renameTo( realFile ) ) { // on renomme le fichier temporaire vers le bon nom
         if ( oldFile.exists( ) ) {
             oldFile.delete(); // on peut supprimer le .bak
         }
      }
      else {
          // il y a eu un problème : 
          if (oldFile.exist() && !oldFile.renameTo(realFile) ) {
              throw new IOException("Erreur pendant la sauvegarde : impossible de récupérer le fichier " + oldFile.getName() + ".\n Veuillez récupérer ce fichier manuellement");
          }
             throw new IOException("Sauvegarde échouée : impossible de renommer " + file.getName() +" en " + realFile.getName() + " - les données peuvent être récupérées manuellement dans " + file );
      }
    }
    Les tests et exception gérées pour "!renameTo" risque peu d'arriver : c'est juste par sécurité.


    Citation Envoyé par Jb_One73 Voir le message
    4) Je me suis rendu compte effectivement qu'il était mal placé et que d'ailleur j'avais un try catch en trop, je les donc modifié et apporté la mise dans le code ci-dessus. Est ce que c'est ce que tu voulais me dire ?
    Oui, on peut faire comme ça. Juste pour le catch(Exception) : à priori un catch(IOException) devrait suffire (les RuntimeException, genre NullPointerException, tu devrais les résoudre lors du développement, et ne devrait pas apparaitre pendant l'exécution final, si tu as tout correctement fait (mais ça peu arriver certes)). Toujours catcher les exceptions au plus spécifique, plutôt qu'au plus large (c'est consommateur en temps de catcher trop large, et en plus tu risques de catcher des exceptions qu'il faudrait ne pas traiter de cette manière - je parle généralement - et surtout ne pas les voir). Je te conseille par ailleurs de toujours loguer les stacktraces : la plupart des utilisateurs ferment ce genre de messages sans même les lire et t'appellent pour te dire "ça marche pas", et toi tu n'as rien pour savoir ce qui s'est passé...)
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Août 2008
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 256
    Points : 85
    Points
    85
    Par défaut
    Ouh ! Là ! Ça pique ! Alors j'ai fait tout ce que tu m'as dit et pour le code ci-dessous c'est pas d'erreur enfin du moins à la compilation.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    public abstract class FileTmp<T> {
        void WriteFileTmp(List<T> objects, String sTypeAction, int iDimensionArray) throws IOException, ClassNotFoundException{
     
            /** Mise en place d'une réfléxivité pour récupérer les méthodes de lisData */
            BufferedWriter ffw = Files.newBufferedWriter(f.toPath());
            for(T object : objects) {
                Map<String, String> properties = getProperties((T) object);
                for(Entry<String, String> entry : properties.entrySet()) {
                    ffw.write( entry.getKey() + " = " + entry.getValue());
                    ffw.newLine();
                }
           }
        }
     
        protected abstract Map<String, String> getProperties(T object);
    }
    Après, moi je sais pas où tu vas chercher tout ça ??? C'est toi le créateur de JAVA (j'ai regardé dans Wikipédia mais j'ai pas vu ton nom) ??? Trêve de plaisanterie ! Pour la partie du code cité ci-dessus OK ! par contre maintenant, dans la classe ou j'appel la méthode WriteFileTmp, j'ai une erreur au niveau de l'instanciation de la FileTmp (code ci-dessus).
    Normal, puisque j'attend un paramètre quelconque mais cependant si je dois rajouter ta 2ème partie je vais avoir un soucis dans le sens ou j'ai déjà un extends donc là je crois que c'est mal barrer.
    Je vais le code de la classe ou j'instancie le code ci-dessus afin d'être plus claire.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    public class BuildCustomer extends javax.swing.JFrame {
     
        public BuildCustomer() throws ParserConfigurationException, SAXException, IOException {
     
    initComponents();
     
            filetmp = new FileTmp(System.getProperty("user.dir") + "\\tmpCustomer.txt");
     
        }
    }
    Sinon, pour revenir au fichier XML, j'ai donc rien compris et je n'avais pas vu ça comme ça, donc en gros il fallait que je fasse 2 fichiers XML :
    1 - Le fichier original
    2 - Le fichier XML temporaire qui à la base était en txt et ensuite je le renomme en Xml

    Est-ce que c'est ça ?

    Merci d'avance Joël

  9. #9
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Je reprends : le but de faire une abstraction est d'avoir une base de classe qui fait ce qu'on ne veut pas avoir à répéter à chaque fois. Mais on ne peut pas instancier directement une abstraction. Il faut créer une nouvelle classe qui l'étend.

    FileTmp<T> dans ton cas est l'abstraction : elle est fait pour sauver n'importe quelle des classes de ton modèle. Elle a une méthode abstraite qui est la méthode spécifique qu'il va falloit implémenter pour chacune des classes spécifiques de ton modèle.

    Pour sauver la classe Client, il faut faire une classe :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public class ClientFileTmp extends FileTmp<Client> {
     
       /**
         * IMPLEMENTATION SPECIFIQUE de getProperties() pour récupérer les propriétés de 'instance à sauvegarder
          */
       protected Map<String, String> getProperties(Client client) { // dans cette classe T est "remplacé" par Client (c'est le but du paramètre)
            Map<String, String> properties = new LinkedHashMap<String, String>(); // j'utilise un LinkedHashMap pour conserver les propriétés dans l'ordre d'ajout (avec une HashMap, on ne garanti pas l'ordre)
            properties.put("lastName", client.getLastName());
            ... 
            return properties;
       }
     
    }
    Et ensuite dans le code de sauvegarde, tu l'appelles comme ça :


    Bien sûr, si tu n'as qu'une seule classe, inutile de t'embêter avec une abstraction et des types paramétrés : tu fais une classe de sauvegarde qui manipule directement ta classe Client, sans paramètre T.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class BuildCustomer extends javax.swing.JFrame {
     
        public BuildCustomer() throws ParserConfigurationException, SAXException, IOException {
     
    initComponents();
     
            clientfiletmp = new ClientFileTmp(System.getProperty("user.dir") + "\\tmpCustomer.txt");
     
     
     
        }
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  10. #10
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Jb_One73 Voir le message
    Sinon, pour revenir au fichier XML, j'ai donc rien compris et je n'avais pas vu ça comme ça, donc en gros il fallait que je fasse 2 fichiers XML :
    1 - Le fichier original
    2 - Le fichier XML temporaire qui à la base était en txt et ensuite je le renomme en Xml

    Est-ce que c'est ça ?

    Merci d'avance Joël
    Tu as fais une méthode qui sauvegarde je ne sais quoi (ton Client, tes hotels, etc...) dans un fichier xml. Pour sauvegarder dans fichier (xml, ou n'importe quoi), il faut écrire dedans. Et quand on écrit dans un fichier, soit on le remplace, soit on écrit à la fin (mode append()). Ici, forcément tu est en mode remplacement. Pour remplacer un fichier, il faut donc l'ouvrir en écriture, ce qui efface tout son contenu (sauf exception du RandomAccessFile, mais ça c'est une autre histoire).

    Donc si la sauvegarde plante en plein milieu de la création du xml, tu n'as pas le nouveau fichier. Ni l'ancien, puisqu'il a été effacé pour écrire le nouveau. Donc tu n'as plus rien, plus aucune données, nada. Perdus, l'ensemble du boulot fait dans les derniers mois.

    Pour éviter ça, lorsqu'on ouvre le fichier pour écrire dedans, on a 2 solutions :

    1. soit sauvegarde l'ancien, pour pouvoir le restaurer si ça plante en plein milieu de l'écriture du nouveau
    2. soi écrire le nouveau dans un fichier temporaire, et remplacer l'ancien par le fichier temporaire si tout s'est bien passé
      C'est la méthode que je te propose. Avec une seconde méthode encore plus "sécurité", qui garde l'ancien, au cas où ça planterait aussi pendant qu'on remplace l'ancien par le nouveau (ce qui est très très rare, j'en conviens, donc tu pourrais te contenter de la version simple)


    Ici, dans la méthode 2, que je t'ai indiquée donc, la création du fichier temporaire utilise la même méthode que tu utilises pour créer ton fichier. C'est juste qu'on écrit pas directement dans le fichier final. Il n'y a pas besoin de créer un autre fichier, ni texte, ni xml, ni rien.

    C'est plus clair comme ça ?
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  11. #11
    Membre régulier
    Profil pro
    Inscrit en
    Août 2008
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 256
    Points : 85
    Points
    85
    Par défaut
    Purée ! Ça me rend dingue ! Je fais tout comme tu me l'indiques et à chaque fois ce maudit compilateur m'insulte !
    C'est pas possible ... sérieux ! J'ai envie d'hurler tellement que ça m'agace, depuis ce matin je n'ai pas avancé à part le temps. Pour être le plus précis possible je vais mettre le code complet (en enlevant bien sur ce qui correspond à l'initialisation des composants et autres).
    Je comprend pas ? Soit je suis fou (ce qui est fort probable) soit je ne comprend rien à ce que l'on me dit (ça aussi c'est fort probable) ... je crois que je vais allez voir un psy !!!

    Classe contenant le GUI Client avec les fonctions Ajouter, Modifier et Supprimer, c'est avec elle que j'appelle ma classe pour écrire dans mon fichier texte
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
    public class BuildCustomer extends javax.swing.JFrame {
     
        private static JOptionPane jop1;
        private static String xmlDoc;
        private static final long serialVersionUID = 1L;
        private static CustomerScanner ScanCustomer;
        private static List<Client> listCustomer;    
        private static List<Client> listCustomerTmp;    
        private static ClientFileTmp filetmp;
        private static String sIdType;
     
        /**
         * Creates new form BuildCustomer
         * @throws javax.xml.parsers.ParserConfigurationException
         * @throws org.xml.sax.SAXException
         * @throws java.io.IOException
         */
        public BuildCustomer() throws ParserConfigurationException, SAXException, IOException {
            initComponents();
     
            filetmp = new ClientFileTmp(System.getProperty("user.dir") + "\\tmpCustomer.txt");
     
        }
    Cette méthode est dans le GUI cité ci-dessus et c'est elle qui appelle la méthode pour écrire, je vais mettre le code que j'avais avant et le code que j'ai maintenant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    /** AVANT */
        /** SAUVEGARDE LES DONNEES DES CLIENTS
         * @param sTypeAction */
        public void SaveDataCustomer(String sTypeAction) throws ClassNotFoundException{
            try {
                filetmp.WriteFileTmp(listCustomerTmp, "[" + sTypeAction + "]", 11);
            } catch (IOException ex) {
                //Boîte du message d'erreur
                jop1.showMessageDialog(null, "Problème durant la sauvegarde des données\n" +
                                             "Détails de l'erreur :\n" + ex, "Erreur", JOptionPane.ERROR_MESSAGE);
            } 
        }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    /** APRES */
        /** SAUVEGARDE LES DONNEES DES CLIENTS
         * @param sTypeAction */
        public void SaveDataCustomer(String sTypeAction) throws IOException{
            filetmp.getProperties(listCustomerTmp);//.WriteFileTmp(listCustomerTmp, "[" + sTypeAction + "]", 11); 
        }
    La classe pour écrire dans mon texte
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
     
    public abstract class FileTmp<T> {
     
        private JOptionPane jop1;
        private final File f;
     
        /** CONSTRUCTEUR DE LA CLASSE
         * @param Path
         * @throws java.io.IOException */
        public FileTmp(String Path) throws IOException{
            f = new File(Path);
            f.createNewFile();
        }
     
        /** ECRITURE DES DONNEE POUR LE CLIENT */
        void WriteFileTmp(List<T> objects, String sTypeAction, int iDimensionArray) throws IOException, ClassNotFoundException{
     
            /** Mise en place d'une réfléxivité pour récupérer les méthodes de lisData */
            BufferedWriter ffw = Files.newBufferedWriter(f.toPath());
            for(T object : objects) {
                Map<String, String> properties = getProperties((T) object);
                for(Entry<String, String> entry : properties.entrySet()) {
                    ffw.write( entry.getKey() + " = " + entry.getValue());
                    ffw.newLine();
                }
           }
        }
     
        protected abstract Map<String, String> getProperties(T object);
    }
    Pour finir la nouvelle classe que j'ai créé en fonction de ce que tu m'as indiqué
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    public abstract class ClientFileTmp extends FileTmp<Client> {
     
       public ClientFileTmp(String Path) throws IOException {
    		super(Path);
    	}
     
       /** IMPLEMENTATION SPECIFIQUE de getProperties() pour récupérer les propriétés de 'instance à sauvegarder */
       protected Map<String, String> getProperties(Client client) { // dans cette classe T est "remplacé" par Client (c'est le but du paramètre)
            Map<String, String> properties = new LinkedHashMap<String, String>(); // j'utilise un LinkedHashMap pour conserver les propriétés dans l'ordre d'ajout (avec une HashMap, on ne garanti pas l'ordre)
            properties.put("lastName", ((Client) client).getLastname());
            return properties;
       }
    }
    Je deviens un dingue ! A aucun endroit j'ai lu qu'il fallait allez voir un psy après avoir utilisé JAVA ... C'est normal ?

    Merci d'avance.

  12. #12
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Calme et sérénité. Quelles erreurs te donne le compilateur ?

    Sinon, pourquoi remplacer :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    /** AVANT */
        /** SAUVEGARDE LES DONNEES DES CLIENTS
         * @param sTypeAction */
        public void SaveDataCustomer(String sTypeAction) throws ClassNotFoundException{
            try {
                filetmp.WriteFileTmp(listCustomerTmp, "[" + sTypeAction + "]", 11);
            } catch (IOException ex) {
                //Boîte du message d'erreur
                jop1.showMessageDialog(null, "Problème durant la sauvegarde des données\n" +
                                             "Détails de l'erreur :\n" + ex, "Erreur", JOptionPane.ERROR_MESSAGE);
            } 
        }
    par

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    /** APRES */
        /** SAUVEGARDE LES DONNEES DES CLIENTS
         * @param sTypeAction */
        public void SaveDataCustomer(String sTypeAction) throws IOException{
            filetmp.getProperties(listCustomerTmp);//.WriteFileTmp(listCustomerTmp, "[" + sTypeAction + "]", 11); 
        }
    Déjà, la méthode getProperties est appelée dans writeFileTmp (qui devrait être public d'ailleurs) de (ton code) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    public abstract class FileTmp<T> {
        void WriteFileTmp(List<T> objects, String sTypeAction, int iDimensionArray) throws IOException, ClassNotFoundException{
     
            /** Mise en place d'une réfléxivité pour récupérer les méthodes de lisData */
            BufferedWriter ffw = Files.newBufferedWriter(f.toPath());
            for(T object : objects) {
                Map<String, String> properties = getProperties((T) object); // CE N'EST PAS UTILE DE CASTER ICI D'AILLEURS : object c'est déjà du T 
                for(Entry<String, String> entry : properties.entrySet()) {
                    ffw.write( entry.getKey() + " = " + entry.getValue());
                    ffw.newLine();
                }
           }
        }
     
        protected abstract Map<String, String> getProperties(T object);
    }
    La méthode getProperties() est protected : tu ne devrais pas l’appeler directement, et ce n'est peut-être même pas possible (par exemple, si les classes ne sont pas dans le même package).
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  13. #13
    Membre régulier
    Profil pro
    Inscrit en
    Août 2008
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 256
    Points : 85
    Points
    85
    Par défaut
    Pour être calme ça va devenir compliqué, je me met la pression car je vois que je fais 1 pas en avant et 3 en arrière. J'ai voulu rendre mon code plus lisible et je m'aperçois que je galère ! galère ! galère ! à m'en arracher les cheveux !
    J'ai pas avancé et ça m'angoisse, il ne me reste plus que 14 jours pour être exact et à partir de ce soir ... vacance fini ! Donc demain reprise et je n'aurai plus que le soir pour travailler et là j'ai la pression. Je m'étais dit qu'une semaine aurait été suffisant pour l'avoir pratiquement fini et je me rend compte qu'il m'aurait fallu 1 voir 2 mois ... pour un faire un simple logiciel.

    Alors effectivement je me suis rendu compte que j'avais fait n'importe quoi dans la méthode "SaveDataCustomer" donc je l'ai remise comme avant à quelques détails prêt mais j'ai gardé l'essentiel dont en voici le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
        /** SAUVEGARDE LES DONNEES DES CLIENTS
         * @param sTypeAction 
         * @throws ClassNotFoundException */
        public void SaveDataCustomer(String sTypeAction) throws IOException, ClassNotFoundException{
            filetmp.WriteFileTmp(listCustomerTmp, "[" + sTypeAction + "]", 11); 
        }
    Après concernant le code ou tu indiques
    Déjà, la méthode getProperties est appelée dans writeFileTmp (qui devrait être public d'ailleurs) de (ton code) :
    c'est la méthode que tu m'as donnée précédemment qui me permet d'écrire mon fichier texte, elle dans la classe FileTmp qui gère les fonctions texte ... j'en ai fait une ???

    Je viens de la mettre en public comme tu me l'as demandé, je te remettre le code complet de la classe qui me gère les fichiers texte et où j'ai implémenté getProperties :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
     
    public abstract class FileTmp<T> {
     
        private JOptionPane jop1;
        private final File f;
     
        /** CONSTRUCTEUR DE LA CLASSE
         * @param Path
         * @throws java.io.IOException */
        public FileTmp(String Path) throws IOException{
            f = new File(Path);
            f.createNewFile();
        }
     
        /** ECRITURE DES DONNEE POUR LE CLIENT */
        public void WriteFileTmp(List<T> objects, String sTypeAction, int iDimensionArray) throws IOException, ClassNotFoundException{
     
            /** Mise en place d'une réfléxivité pour récupérer les méthodes de lisData */
            BufferedWriter ffw = Files.newBufferedWriter(f.toPath());
            for(T object : objects) {
                Map<String, String> properties = getProperties((T) object);
                for(Entry<String, String> entry : properties.entrySet()) {
                    ffw.write( entry.getKey() + " = " + entry.getValue());
                    ffw.newLine();
                }
           }
        }
     
        protected abstract Map<String, String> getProperties(T object);
    }
    Après ce charmant compilateur bloque sur la classe que j'ai créé en fonction de ce que tu m'as indiqué mais toujours pareil, j'ai peut être tout fait de travers ??? Je remet le code de la classe en question.
    En revanche, ici le compilateur me souligne en rouge la déclaration de la classe et m'indique (je le note en anglais) "the type ClientFileTmp must implement the inherited abstract method FileTmp<Client>.getProperties(Client)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    public class ClientFileTmp extends FileTmp<Client> {
     
       public ClientFileTmp(String Path) throws IOException {
    		super(Path);
    	}
     
       /** IMPLEMENTATION SPECIFIQUE de getProperties() pour récupérer les propriétés de 'instance à sauvegarder */
       protected Map<String, String> getProperties(List<Client> client) { // dans cette classe T est "remplacé" par Client (c'est le but du paramètre)
            Map<String, String> properties = new LinkedHashMap<String, String>(); // j'utilise un LinkedHashMap pour conserver les propriétés dans l'ordre d'ajout (avec une HashMap, on ne garanti pas l'ordre)
            properties.put("lastName", ((Client) client).getLastname());
            return properties;
       }
    }
    Un truc de malade !!! Non mais sérieux !! Je ne comprend plus rien

  14. #14
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Jb_One73 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    public class ClientFileTmp extends FileTmp<Client> {
     
       public ClientFileTmp(String Path) throws IOException {
    		super(Path);
    	}
     
       /** IMPLEMENTATION SPECIFIQUE de getProperties() pour récupérer les propriétés de 'instance à sauvegarder */
       protected Map<String, String> getProperties(List<Client> client) { // dans cette classe T est "remplacé" par Client (c'est le but du paramètre)
            Map<String, String> properties = new LinkedHashMap<String, String>(); // j'utilise un LinkedHashMap pour conserver les propriétés dans l'ordre d'ajout (avec une HashMap, on ne garanti pas l'ordre)
            properties.put("lastName", ((Client) client).getLastname());
            return properties;
       }
    }
    La plupart du temps les messages d'erreurs indiquent l'endroit et la cause de l'erreur (ce n'est pas toujours vrai, certes). Là, si tu regardes bien, tu as déclaré que le premier argument de getProperties() est une List<Client>, or on implémente une méthode abstraite dont l'argument était T, avec T déclaré comme étant Client dans ClientFileTemp. Donc ce n'est pas List<Client> ici, mais Client tout simplement. Normalement, l'IDE est même censé créer cette méthode automatiquement avec le bon type (en tout cas c'est comme ça dans Eclipse, je ne peux pas garantir que ça le fasse aussi dans NetBeans, mais ça m'étonnerait).

    Du coup, tu n'es pas obligé de caster client en Client dans (c'est déjà du Client) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    properties.put("lastName", ((Client) client).getLastname());
    C'est un peu le but d'ailleurs des types paramétrés : définir un comportement général dans une classe, et adapter ce comportement général en spécifique avec le type spécifique, sans avoir à caster sans arrêt. A partir du moment où tu as dit que le type paramétré T serait Client dans ta classe (par le extends FileTmp<Client>), tu ne travaille plus qu'avec du Client (partout où on avait dit qu'on travaillait avec du T, dans la classe parente).
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  15. #15
    Membre régulier
    Profil pro
    Inscrit en
    Août 2008
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 256
    Points : 85
    Points
    85
    Par défaut
    Alors ! Comment dire ??? S'il y a un Dieu sur terre ... Je dirai que c'est toi !!! Franchement (désolé pour la comparaison) mais là c'est comme si j'avais été chez le dentiste pour un abcès et qu'il me l'avait soigné ... C'est la délivrance !!!!!!!!!!!!!!!!!!!

    Joël ? Je sais pas comment te remercie mais là ... je suis dessus depuis 8h ce matin (toi aussi d'ailleurs), il est 15h22 et ça fonctionne.

    MERCI ! MERCI ! MERCI ! MERCI ! MERCI ! MERCI ! MERCI ! MERCI ! MERCI ! MERCI ! ........................ Joël !!!!!!!!!

  16. #16
    Membre régulier
    Profil pro
    Inscrit en
    Août 2008
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 256
    Points : 85
    Points
    85
    Par défaut
    Mince ! J'ai un dernier petit soucis après normalement c'est bon. Le code ci-dessous ne me permet pas de lire ma liste de Client.
    Je n'ai pas d'erreur de compilation mais lorsque j'arrive sur la dernière ligne du code ci dessous j'ai un vilain message d'erreur.
    Alors je me suis dit, plutôt que d'utiliser l'itérateur autant utiliser la méthode get et c'était presque bon mais vu que c'est une collection List de Client et bien je n'arrive pas à accéder aux éléments de celle-ci.

    Je sais pas si j'ai été très claire dans mon discours ? Tu aurais une petite idée ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
                    Iterator<Client> iterator = listCustomerTmp.iterator();
                    iterator.hasNext();
                    Client next = iterator.next();

  17. #17
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Il faut absolument que tu nous donnes l’intitulé des messages d'erreur (et de préférence la stackTrace) : ils ont beau être vilains, affreux, insultants, flippants, agaçants, condescendants,... si on n'a pas le message, on ne peut que chercher à deviner. Et on ne veut pas jouer aux devinettes.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Iterator<Client> iterator = listCustomerTmp.iterator();
    iterator.hasNext();
    Client next = iterator.next();
    En tout cas, ce code peut effectivement soulever une exception si la liste est vide, parce qu'il faut tester la valeur retournée par hasNext(). Si hasNext() retourne false, c'est qu'il n'y a pas de next(), et que si on l’appelle, on obtient une NoSuchElementException.

    D'ailleurs, à part si on veut uniquement le premier élément, on appelle iterator() toujours dans une boucle :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Iterator<Client> iterator = listCustomerTmp.iterator();
    while( iterator.hasNext() ) {
    Client next = iterator.next();
    }
    Ou mieux dans un for, ce qui limite la portée de iterator :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for( Iterator<Client> iterator = listCustomerTmp.iterator(); iterator.hasNext(); ) {
    Client next = iterator.next();
    }
    Depuis l'apparition du foreach en Java 5, on évite d'ailleurs d'utiliser un iterator() au profit d'un foreach (le truc comme ça for(Client client : listCustomerTmp) sauf si on veut supprimer des éléments au court du parcourt (auquel cas, on veut appeler la méthode remove() de Iterator).
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  18. #18
    Membre régulier
    Profil pro
    Inscrit en
    Août 2008
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 256
    Points : 85
    Points
    85
    Par défaut
    Alors je sais pas si c'est ça que tu appels le stackTrace mais si tel est le cas voici ce qu'il m'affiche :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
     
    Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: [Ljava.lang.String; cannot be cast to xxx.projet.Client
    	at xxxx.projet.BuildCustomer.jBFermerActionPerformed(BuildCustomer.java:526)
    	at xxx.projet.BuildCustomer.access$200(BuildCustomer.java:27)
    	at xxx.projet.BuildCustomer$3.actionPerformed(BuildCustomer.java:303)
    	at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
    	at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2346)
    	at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
    	at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
    	at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
    	at java.awt.Component.processMouseEvent(Component.java:6525)
    	at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
    	at java.awt.Component.processEvent(Component.java:6290)
    	at java.awt.Container.processEvent(Container.java:2234)
    	at java.awt.Component.dispatchEventImpl(Component.java:4881)
    	at java.awt.Container.dispatchEventImpl(Container.java:2292)
    	at java.awt.Component.dispatchEvent(Component.java:4703)
    	at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4898)
    	at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4533)
    	at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4462)
    	at java.awt.Container.dispatchEventImpl(Container.java:2278)
    	at java.awt.Window.dispatchEventImpl(Window.java:2739)
    	at java.awt.Component.dispatchEvent(Component.java:4703)
    	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:746)
    	at java.awt.EventQueue.access$400(EventQueue.java:97)
    	at java.awt.EventQueue$3.run(EventQueue.java:697)
    	at java.awt.EventQueue$3.run(EventQueue.java:691)
    	at java.security.AccessController.doPrivileged(Native Method)
    	at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
    	at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:86)
    	at java.awt.EventQueue$4.run(EventQueue.java:719)
    	at java.awt.EventQueue$4.run(EventQueue.java:717)
    	at java.security.AccessController.doPrivileged(Native Method)
    	at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
    	at java.awt.EventQueue.dispatchEvent(EventQueue.java:716)
    	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
    	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    	at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
    J'avoue que c'est pas très jolie comme message, ils auraient pu mettre de la déco, une perceuse, un marteau et pour moi un lance roquette

  19. #19
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    C'est exactement ça la stacktrace (ou en français, la pile d'appels : la liste de tous les appels de méthodes successifs qui ont convergé vers l'endroit où s'est passé l'exception, en partant de la dernière - la plus proche de l'exception - vers la première - le début du thread - ).

    Dans une stackTrace, la première chose à regarder est la première ligne (comme dans beaucoup d'autres choses) :

    Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: [Ljava.lang.String; cannot be cast to xxx.projet.Client
    On t'indique que dans un thread de AWT (donc dans une action SWING, ou un affichage SWING, pour simplifier), il y a une erreur ClassCastException. C'est à dire que tu as essayé de caster un truc en un autre pas compatible. En plus, bonheur, on te dit quel type tu essayes de caster en quoi : On ne peut pas caster du String en Client, parce que ces classes n'ont rien à voir (la classe String n'étend pas la classe Client, et vice versa).

    C'est étrange que tu aies cette exception dans le code que tu as indiqué (parce que dans un autre poste tu as défini private static List<Client> listCustomerTmp;.

    Mais si on continue de lire la stacktrace, on voit dans la deuxième ligne :

    at xxxx.projet.BuildCustomer.jBFermerActionPerformed(BuildCustomer.java:526)
    à la fin, le fichier .java et le numéro de la ligne où s'est passé l'exception : quelle est cette ligne ?

    On voit aussi que l'exception à eu lieu dans la méthode jBFermerActionPerformed de BuildCustomer : avoir le code complet (ou au moins les parages de la ligne 526, et les déclarations de variables qui y entrent en jeu) de cette méthode pourrait nous aider à t'aider plus rapidement.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  20. #20
    Membre régulier
    Profil pro
    Inscrit en
    Août 2008
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 256
    Points : 85
    Points
    85
    Par défaut
    Ok ! Bien compris pour le stackTrace après pour faire suite à ta demande je te joins le code complet de la méthode en question.

    J'ai noté la ligne 526 en commentaire de façon à ce qu'elle soit localisable :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
     
        /** FERME LA FENETRE ET VALIDE LES DONNEES DANS LE FICHIER XML */
        private void jBFermerActionPerformed(java.awt.event.ActionEvent evt) {                                         
            try {
                /** Sauvegarde les données si des données ont été modifiés */
                if(listCustomerTmp != null){
     
                    listCustomerTmp = filetmp.ReadFileTmp(System.getProperty("user.dir") + "\\tmpCustomer.txt", 12);
     
                    XMLCustomer mXml = new XMLCustomer(xmlDoc);
     
                    Iterator<Client> iterator = listCustomerTmp.iterator();
                    iterator.hasNext();
                    Client next = iterator.next();    // ICI SE TROUVE LA LIGNE 526
     
                    switch (next.getMemoId()){
                        case "[AJOUT]" :
                            mXml.AddXMLCustomer(listCustomerTmp);
                            break;
                        case "[MODIF]" :
                            mXml.ModifXmlCustomer(listCustomerTmp);
                            break;
                        case "[SUP]" :
                            mXml.deleteCustomer(listCustomerTmp);
                            break;
                    }
                }
            } catch (ParserConfigurationException | IOException | SAXException ex) {
                jop1.showMessageDialog(null, "Erreur durant la mise à jour des données\n" +
                                             "Détail de l'erreur :\n" + ex.toString(), "Erreur", JOptionPane.ERROR_MESSAGE);
            }
     
            /** Supprime le fichier temporaire */
            filetmp.DeleteFileTmp();       
     
            /** Ferme le formulaire */
            this.dispose();
        }
    Merci d'avance.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Problème de pointeur sur ArrayList
    Par Diablo_22 dans le forum Collection et Stream
    Réponses: 4
    Dernier message: 01/05/2008, 10h39
  2. Problème de warning sur ArrayList
    Par chadnour dans le forum Collection et Stream
    Réponses: 10
    Dernier message: 27/01/2008, 19h49
  3. Problème innerHTML sur div !!!
    Par aburner dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 27/01/2005, 09h23
  4. [CR8] Problème tableau sur plusieurs pages???
    Par christophe28 dans le forum SAP Crystal Reports
    Réponses: 5
    Dernier message: 02/11/2004, 15h46
  5. [MFC] Problème pointeur sur une classe
    Par mick74 dans le forum MFC
    Réponses: 7
    Dernier message: 14/04/2004, 14h17

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo