Partage
  • Partager sur Facebook
  • Partager sur Twitter

Manipulation de List

    20 mai 2018 à 12:33:22

    Bonjour , 

    je recherches depuis ce matin , et je ne trouves pas comment récupérer une List qui est dans une classe dans un package et j'aimerais la récupéré dans une classe qui est dans autre package.

    la list est dans le menu controller du package accueil et j'aimerais l'avoir dans le menu controller du package jeu aussi 

    j'ai eu l'idée de base d'instancier ma list dans les deux classes mais après je suis perdu j'ai essayer avec un setList(List uneListe)

    mais je ne réussiss pas a le récuperer ... 

    edit : J'ai commencé par changer la list en static mais cela ne fonctionne toujours pas ...

    Merci d'avances pour votre aides ou vos pistes 

    JP

    -
    Edité par JeanPierreTompe 20 mai 2018 à 13:56:55

    • Partager sur Facebook
    • Partager sur Twitter
      20 mai 2018 à 14:04:54

      Salut. En "static" ça ne fonctionne pas? La liste est "figée" ou tu comptes la modifier plus tard dans le programme?
      • Partager sur Facebook
      • Partager sur Twitter
        20 mai 2018 à 14:16:43

        Je compte la modifier dans le programme en passant par la premiere class d'abord et ensuite la récuperer dans l'autres class mais en static je n'ai pas l'impression de la récuperer 
        	
        		setCouleur(application.accueil.MenuController.getCouleur());
        couleur est ma list
        • Partager sur Facebook
        • Partager sur Twitter
          21 mai 2018 à 20:49:08

          Bonjour,

          Une solution peut être de créer un liste dans chacun de tes controllers et de synchroniser les listes à chaque ajout/suppression d'un élément de cette liste. Le couplage entre les controllers étant réalisé par la classe Main.

          Voici par exemple le code de la class MenuController du package accueil (celle du package jeu étant identique à quelques détails près):

          package application.accueil;
          
          import java.awt.Color;
          import java.util.ArrayList;
          
          import javafx.fxml.FXML;
          
          public class MenuController {
          	
          	@FXML
          	private ArrayList<Color> listCouleur = new ArrayList<Color>();
          	
          	@FXML
          	private application.jeu.MenuController autreController;
          
          	public MenuController() {
          		
          	}
          	
          	public void initialize() {
          		
          	}
          	
          	public void addCouleur(Color color) {
          		listCouleur.add(color);
          		autreController.setListCouleur(listCouleur);
          	}
          	
          	public void removeCouleur(Color color) {
          		listCouleur.remove(color);
          		autreController.setListCouleur(listCouleur);
          	}
          
          	public ArrayList<Color> getListCouleur() {
          		return listCouleur;
          	}
          
          	public void setListCouleur(ArrayList<Color> listCouleur) {
          		this.listCouleur = listCouleur;
          	}
          
          	public void setAutreController(application.jeu.MenuController autreController) {
          		this.autreController = autreController;
          	}
          }
          

          et voici la class Main avec le couplage:

          package application;
          	
          import java.io.IOException;
          
          import javafx.application.Application;
          import javafx.fxml.FXMLLoader;
          import javafx.scene.Scene;
          import javafx.scene.layout.AnchorPane;
          import javafx.stage.Stage;
          
          
          public class Main extends Application {
          
          	public void start(Stage stageAccueil) {
          			
          			try {
          				//Accueil
          				FXMLLoader loaderAccueil = new FXMLLoader(this.getClass().getResource("accueil/accueil.fxml"));
          				Scene sceneAccueil = new Scene((AnchorPane) loaderAccueil.load());
          				stageAccueil.setScene(sceneAccueil);
          				application.accueil.MenuController controllerAccueil = loaderAccueil.getController();
          				
          				//Jeux
          				FXMLLoader loaderJeu = new FXMLLoader(this.getClass().getResource("jeu/jeu.fxml"));
          				Stage stageJeu = new Stage();
          				Scene sceneJeu = new Scene((AnchorPane) loaderJeu.load());
          				stageJeu.setScene(sceneJeu);
          				application.jeu.MenuController controllerJeu = loaderJeu.getController();
          				
          				//Couplage Accueil-Jeux
          				controllerAccueil.setAutreController(controllerJeu);
          				controllerJeu.setAutreController(controllerAccueil);
          				
          			} catch (IOException e) {
          				e.printStackTrace();
          			}
          	}
          	
          	public static void main(String[] args) {
          		launch(args);
          	}
          }
          

          A noter qu'avoir deux classes avec des noms identiques (MenuController) est source d'erreur et donc il serait préférable d'éviter...


          • Partager sur Facebook
          • Partager sur Twitter
            21 mai 2018 à 22:03:01

            Salut,

            De manière générale, il n'est jamais très bon de permettre à un module d'aller "chipoter" à une variable issue d'un autre module :p

            Si c'est simplement pour l'interroger sur son (ou un de ses) états, cela peut encore passer, mais, si c'est carrément pour aller la modifier, tu dois te dire que tu ouvre toutes les voies d'un autoroute à 2 fois 8 bandes dont la seule destination possible est la création de bugs!!!

            Même si tu es le seul utilisateur d'une classe que tu as toi-même créée, tu dois partir du principe que l'utilisateur de ta classe est un imbécile distrait qui saisira toutes les occasions de faire une connerie qui pourront se présenter.

            C'est déjà vrai lorsque l'on se trouve dans le module dans lequel la classe existe, c'est encore pire lorsque l'on utilise une classe issue d'un "module externe".  Les raisons en sont simple:

            • la documentation, c'est fait pour les chiens : l'utilisateur peut avoir la meilleure doc qui soit, il n'y aura recours que contraint et forcé;
            • même si tu es l'utilisateur d'une classe que tu as créée, il s'est sans doute passé tellement de temps entre le moment où tu as créée cette classe et le moment où tu l'utilises que tu auras eu tout le temps d'oublier ses particularités
            • quand l'utilisateur travaille sur un module donné, il y a déjà tellement de particularités propres à ce module que tu ne voudrais pas en plus qu'il ait toutes les particularités propre au module externe qu'il utilise en tête

            Tu veux récupérer une liste dis tu ? Je ne crois pas...

            Je crois -- très sincèrement -- que ce que tu veux récupérer en réalité, c'est une abstraction qui utilise une List en interne et qui est destinée à un usage bien particulier.

            Quel type d'abstraction? j'en ai aucune idée.  Cela dépend beaucoup trop du type de projet sur lequel tu planches, et de l'usage que tu veux faire des éléments qui se trouvent dans la liste.

            Mais par contre, je peux sans -- sans risque réel de me tromper (mais au risque d'en oublier quelques uns) -- dresser la liste des services que tu pourrais attendre de la part de cette abstraction:

            1. la possibilité d'ajouter des éléments
            2. la possibilité de retirer des éléments
            3. la possibilité (cela peut toujours être utile) de connaitre le nombre d'éléments contenus dans la liste
            4. la possibilité de récupérer l'un des éléments de la liste, en fonction de sa position dans celle-ci
            5. (éventuellement) la possibilité d'obtenir un itérateur sur le début de la liste et un autre sur "ce qui suit" le dernier élément de la liste
            6. (éventuellement) la possibilité de vider la liste
            7. la possibilité d' "enregister" un élément qui est intéressé par le fait d'être tenu au courant des modifications apportées (ajout, suppression, vidange, autres?); à charge de cet élément de réagir correctement lorsqu'il reçoit la signification d'une modification

            Autant le dire tout de suite: je suis bien plus à l'aise avec C++ et sa bibliothèque standard qu'avec java et sa bibliothèque standard.  Cette liste de services correspond à celle que j'aurais dressée en C++ et il se peut donc que certains d'entre eux ne soient pas faciles à mettre en oeuvre (voire, soient carrément jugés comme "inutiles" par un développeur java).

            Mais, pour ce que j'en sais, la bibliothèque standard de java fournit des interfaces permettant d'implémenter le patron de conception observateur. Il ne faut sans doute pas beaucoup plus (n'y aurait-il pas un système de signaux et de slots déjà implémenté???) les derniers services auxquels j'ai fait allusion en (7) ;)

            • Partager sur Facebook
            • Partager sur Twitter
            Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
              23 mai 2018 à 7:10:36

              @koala01:

              Bonjour,

              Tout comme JeanPierreTomb, j'ai bien souvent des classes dans différents packages qui communiquent via constructeur/getter/interface. Par exemple quand je fais une application sous les modèle MVC (comme ici), je créé un package pour le modèle, un autre pour la vue et un troisième pour le/les contrôleurs. Je comprends de ta réponse que cela n'est pas judicieux. Quelles sont les bonnes pratiques pour hiérarchiser le code en package? Comment organiserais tu le projet de Jean-Pierre?

              • Partager sur Facebook
              • Partager sur Twitter
                23 mai 2018 à 13:15:45

                Je n'ai pas dit que ce n'est pas judicieux, j'ai dit qu'il faut le faire prudemment.  Parce qu'une classe est bien plus que la somme de ses attributs: c'est un fournisseur de services.

                Un service, c'est un ordre (move, draw, add, copy, ...) ou la capacité à répondre à une question (where are you? what's your name? what's your Xth element?, ...)

                Un fournisseur de services, ce doit être dans un état cohérent et valide dés le moment où on le construit: on ne doit pas avoir à commencer par lui donner trois ordres avant de pouvoir en profiter. Parce que si il faut "faire quelque chose"  entre le moment où on le crée et le moment où il sera près à être utilisé, tu dois t'attendre à ce qu'il y ait toujours "quelqu'un" qui oublie l'une des étapes "d'initialisation", ou pire, toutes.

                Comme l'a si bien dit Scott Meyers:

                Make your interfaces easy to use correctly and hard to use incorrectly

                 De plus, tu as la loi de Déméter qui dit, en substance:

                Si un type A utilise en interne le type B, l'utilisateur d'un objet de type A ne devrait pas avoir à connaître le type B pour manipuler son A

                Un exemple pour bien me faire comprendre:

                Mettons que j'ai une voiture.  En tant qu'utilisateur de la voiture, je sais pertinemment qu'il y a "planqué quelque part" un réservoir à carburant.  Ou du moins, je m'en doute :  je sais bien que le carburant ne va pas tenir "tout seul" "comme cela, par magie" dans mon véhicule.

                Et pourtant, je n'aurai jamais à manipuler directement le réservoir de ma voiture, parce que je vais le faire au travers de l'interface que la voiture me donne comme :

                • la jauge à carburant
                • l'ordinateur de bord
                • la trappe à carburant.

                Mieux encore : il y a 99% de chance pour que même un garagiste n'ait jamais à devoir manipuler directement un réservoir.  Après, il y a les cas particuliers: j'ai moi-même du faire changer un réservoir une fois sur plus de vingt ans de conduite, parce qu'il avait une fuite.  Mais ca arrive combien de fois sur les millions de véhicules en circulation ?

                Revenons à nos classes.

                J'ai une liste d'éléments qui traîne dans une de mes classes.  Mais qu'est ce que j'en ai a foutre que ce soit une liste! Pour moi, ce serait un tableau, une pile ou une map, ca serait encore pareil!  Ce qui m'intéresse, ce sont les actions que je peux entreprendre sur ces éléments, à savoir

                • en ajouter
                • en supprimer
                • les parcourir
                • obtenir le Xieme élément
                • (éventuellement) tous les supprimer

                La manière dont les éléments sont maintenus en mémoire n'a aucun rapport avec l'utilisation que j'en fais : pour moi, ce n'est qu'un ... sordide détail d'implémentation.  Je n'ai donc pas besoin de le connaître.

                Et si je peux disposer d'une classe à laquelle je peux donner des ordres ou poser des questions sans même me rendre compte qu'elle ajoute ou qu'elle supprime des éléments dans la (on va utiliser un terme générique) collection d'objets, c'est encore mieux :D

                Alors, oui, bien sur: les accesseurs  peuvent représenter un service que l'on est en droit d'attendre de la part de la classe.  Et quand je fais user.getName(), je m'attend à le nom de la personne, nous sommes bien d'accord.

                Mais est ce que le nom de la personne est vraiment un attribut de la classe, ou est ce que c'est l'un des éléments que l'on trouve dans une collection de chaines de caractères?  Ben, je n'ai pas à le savoir...  Et pour tout dire: je m'en fous!

                Donc, pour répondre à ta question: 

                Je l'ai dit, ta classe doit être utilisable dés qu'elle est créée. On a donc, effectivement, besoin d'un constructeur.

                On vient de le voir, certains accesseurs correspondent à des services que l'on est en droit d'attendre de la part de la classe, et ils sont donc tout à fait judicieux

                Et la notion de "services" ne correspond jamais qu'à la notion "d'interface publique".  Et, si tu peux regrouper certains services pour désigner un "concept plus général" (par exemple le concept de "conteneur d'objets"), vas-y : crée une interface représentant ce concept.

                De la même manière, il est tout à fait judicieux de créer un module pour le modèle, un deuxième pour la vue et un troisième pour les contrôleurs. 

                Et nous pourrions même aller plus loin, en considérant que l'enregistrement d'un fichier, l'envoi de données à un serveur ou l'émission de sons représentent autant de notion de "vues" différentes et qu'il est utile de créer un module pour chacune de ces "sortes de vues".

                Et comme nous sommes bien d'accord sur le fait que l'on ne gère sans doute pas le résultat d'une requête SQL que la même manière que celle utilisée pour gérer un fichier ou que celle utilisée pour gérer la communication avec un site web, il est même parfaitement cohérent d'envisager de se retrouver avec plusieurs modules pour les contrôleurs de telle manière à ce que chaque module ne doive s'inquiéter de gérer qu'un ensemble de responsabilités qui lui est propre.

                Et si cela signifie que la vue graphique doit pouvoir discuter, selon le cas, avec trois modules de contrôleurs différents, hé bien : ainsi soit-il!

                La seule chose, c'est que les modules doivent être aussi indépendants les un des autres:

                Les modules SQL (vue et controleurs) n'ont rien à foutre des modules web qui n'ont rien à foutre des modules fichiers, qui n'a rien à foutre des modules son.

                Et le modèle n'a rien à foutre de tous ces modules: il se fout pas mal de connaitre l'origine des données qu'il manipule.  Tout ce qu'il veut, c'est des données, peu importe d'où elle viennent!

                Alors, oui, bien sur : il y a toujours des besoins de communication, non seulement à l'intérieur des modules, mais également entre les modules qui "ont quelque chose en commun" (la "vue" SQL avec le controleur SQL, la "vue" fichier avec le controleur fichier, etc.  Et toutes ces paires avec... le modèle).

                Mais la communication doit porter essentiellement sur le "quoi", et non sur le "comment".

                Le "quoi", c'est "récupère moi tel jeu de données".  Le "comment tu vas le récupérer?"... j'en ai rien à foutre (c'est ton taf).

                Le "quoi", c'est "file moi telle information". le "comment tu vas t'y prendre pour me la donner?"... j'en ai rien à foutre (c'est ton taf).

                Pour faire simple : chaque module a sa mécanique interne bien particulière, mais, quand un module s'adresse à un autre, tout ce qu'il doit savoir, c'est : comment lui poser les bonnes questions, comment lui donner des ordres compréhensible.  En un mot : c'est le principe du patron de conception facade : chaque module ne montre que ce qu'il veut bien que l'on voie ;)

                • Partager sur Facebook
                • Partager sur Twitter
                Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait

                Manipulation de List

                × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                • Editeur
                • Markdown